76ba500417
CI / docker (push) Successful in 2m4s
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>
58 lines
1.3 KiB
Go
58 lines
1.3 KiB
Go
package prediction
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
type NodeField struct {
|
|
Node string `json:"node"`
|
|
Field string `json:"field"`
|
|
}
|
|
|
|
type InputBinding map[string]*NodeField
|
|
|
|
func ParseBinding(raw string) (InputBinding, error) {
|
|
if raw == "" {
|
|
return InputBinding{}, nil
|
|
}
|
|
var b InputBinding
|
|
if err := json.Unmarshal([]byte(raw), &b); err != nil {
|
|
return nil, err
|
|
}
|
|
return b, nil
|
|
}
|
|
|
|
func (b InputBinding) Validate(workflow map[string]any, required []string) error {
|
|
for _, name := range required {
|
|
f, ok := b[name]
|
|
if !ok || f == nil || f.Node == "" || f.Field == "" {
|
|
return fmt.Errorf("required binding missing: %s", name)
|
|
}
|
|
}
|
|
for name, f := range b {
|
|
if f == nil || f.Node == "" || f.Field == "" {
|
|
continue
|
|
}
|
|
if err := validateNodeField(workflow, f.Node, f.Field); err != nil {
|
|
return fmt.Errorf("binding %s: %w", name, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func validateNodeField(workflow map[string]any, nodeID, field string) error {
|
|
node, ok := workflow[nodeID].(map[string]any)
|
|
if !ok {
|
|
return fmt.Errorf("node %s not found", nodeID)
|
|
}
|
|
inputs, ok := node["inputs"].(map[string]any)
|
|
if !ok {
|
|
return fmt.Errorf("node %s has no inputs", nodeID)
|
|
}
|
|
if _, ok := inputs[field]; !ok {
|
|
return fmt.Errorf("field %s not found on node %s", field, nodeID)
|
|
}
|
|
return nil
|
|
}
|