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>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user