Files
Luminary/internal/prediction/params.go
T
renjue 76ba500417
CI / docker (push) Successful in 2m4s
Initial commit: Luminary AI Gateway
OpenAI-compatible AI gateway with Vue admin UI, multi-provider egress,
ingress key governance, monitoring, and security controls.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-23 21:46:16 +08:00

123 lines
3.1 KiB
Go

package prediction
import (
"fmt"
"github.com/rose_cat707/luminary/internal/model"
)
type ParamType string
const (
ParamString ParamType = "string"
ParamInt ParamType = "int"
ParamFloat ParamType = "float"
)
type ParamDef struct {
Name string `json:"name"`
Label string `json:"label"`
Type ParamType `json:"type"`
Required bool `json:"required"`
Default any `json:"default,omitempty"`
}
var Txt2ImgParams = []ParamDef{
{Name: "prompt", Label: "正向提示词", Type: ParamString, Required: true},
{Name: "negative_prompt", Label: "负向提示词", Type: ParamString, Default: ""},
{Name: "seed", Label: "随机种子", Type: ParamInt, Default: -1},
{Name: "width", Label: "宽度", Type: ParamInt, Default: 1024},
{Name: "height", Label: "高度", Type: ParamInt, Default: 1024},
{Name: "steps", Label: "采样步数", Type: ParamInt, Default: 20},
{Name: "cfg_scale", Label: "CFG", Type: ParamFloat, Default: 7.0},
}
var Img2ImgParams = []ParamDef{
{Name: "prompt", Label: "正向提示词", Type: ParamString, Required: true},
{Name: "negative_prompt", Label: "负向提示词", Type: ParamString, Default: ""},
{Name: "image", Label: "输入图 URL", Type: ParamString, Required: true},
{Name: "seed", Label: "随机种子", Type: ParamInt, Default: -1},
{Name: "steps", Label: "采样步数", Type: ParamInt, Default: 20},
{Name: "cfg_scale", Label: "CFG", Type: ParamFloat, Default: 7.0},
{Name: "denoise", Label: "重绘幅度", Type: ParamFloat, Default: 0.75},
}
func ParamsForWorkflowType(wt model.WorkflowType) []ParamDef {
switch wt {
case model.WorkflowImg2Img:
return Img2ImgParams
default:
return Txt2ImgParams
}
}
func RequiredBindings(wt model.WorkflowType) []string {
switch wt {
case model.WorkflowImg2Img:
return []string{"prompt", "image"}
default:
return []string{"prompt"}
}
}
func ValidateInput(wt model.WorkflowType, input map[string]any) (map[string]any, error) {
defs := ParamsForWorkflowType(wt)
out := make(map[string]any, len(defs))
for _, d := range defs {
v, ok := input[d.Name]
if !ok || v == nil {
if d.Required {
return nil, fmt.Errorf("missing required field: %s", d.Name)
}
if d.Default != nil {
out[d.Name] = d.Default
}
continue
}
coerced, err := coerceValue(d, v)
if err != nil {
return nil, fmt.Errorf("%s: %w", d.Name, err)
}
out[d.Name] = coerced
}
return out, nil
}
func coerceValue(d ParamDef, v any) (any, error) {
switch d.Type {
case ParamString:
s, ok := v.(string)
if !ok {
return nil, fmt.Errorf("expected string")
}
if d.Required && s == "" {
return nil, fmt.Errorf("cannot be empty")
}
return s, nil
case ParamInt:
switch n := v.(type) {
case float64:
return int(n), nil
case int:
return n, nil
case int64:
return int(n), nil
default:
return nil, fmt.Errorf("expected integer")
}
case ParamFloat:
switch n := v.(type) {
case float64:
return n, nil
case int:
return float64(n), nil
case int64:
return float64(n), nil
default:
return nil, fmt.Errorf("expected number")
}
default:
return v, nil
}
}