57 lines
1.4 KiB
Go
57 lines
1.4 KiB
Go
package platform
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
)
|
|
|
|
func validCanvasAI(value any, kind string) bool {
|
|
if !canvasChoice(kind, "text", "script", "plain-text", "image", "plain-image") {
|
|
return false
|
|
}
|
|
ai, ok := value.(map[string]any)
|
|
if !ok || !canvasFields(ai, "enabled", "modelId", "prompt", "propagate", "parameters") {
|
|
return false
|
|
}
|
|
for key, value := range ai {
|
|
switch key {
|
|
case "enabled", "propagate":
|
|
if _, ok := value.(bool); !ok {
|
|
return false
|
|
}
|
|
case "modelId":
|
|
id, ok := value.(string)
|
|
if !ok || len(id) == 0 || len(id) > 256 || strings.TrimSpace(id) != id {
|
|
return false
|
|
}
|
|
case "prompt":
|
|
if !canvasString(value, 16000) {
|
|
return false
|
|
}
|
|
case "parameters":
|
|
params, ok := value.(map[string]any)
|
|
if !ok {
|
|
return false
|
|
}
|
|
raw, err := json.Marshal(params)
|
|
if err != nil || len(raw) > 16<<10 {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Fingerprints exclude geometry and visual styles so a result can be applied
|
|
// after a concurrent drag. Content/configuration edits invalidate the result.
|
|
func canvasTargetFingerprint(board, node string, data map[string]any) string {
|
|
target := map[string]any{"board_id": board, "node_id": node, "kind": data["kind"], "ai": data["ai"]}
|
|
if canvasChoice(data["kind"], "image", "plain-image") {
|
|
target["src"] = data["src"]
|
|
target["assetId"] = data["assetId"]
|
|
} else {
|
|
target["text"] = data["text"]
|
|
}
|
|
return payloadDigest(target)
|
|
}
|