Files
ttstd-infinite-canvas/backend/internal/app/cloud_agent_json.go

61 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package app
import (
"bytes"
"encoding/json"
"errors"
"io"
"strings"
)
var errCloudAgentJSONSingleObject = errors.New("参数必须是单个 JSON 对象")
// Only syntax/schema errors may be repaired by the model; authorization and
// unsupported mutations still fail admission before any write or approval.
type cloudAgentArgumentError struct{ error }
func (e *cloudAgentArgumentError) Unwrap() error { return e.error }
func canvasArgumentError() error {
return &cloudAgentArgumentError{BadAuthRequest("画布工具参数无效:仅允许一个 JSON 对象;顶层只含 snapshotHash 和 ops,snapshotHash 不得放入 ops。请按工具 schema 修正后重试")}
}
// Report the failure category without echoing model-controlled keys or values.
// The runtime attaches the advertised schema so the model can correct its call.
func cloudAgentJSONArgumentError(err error) error {
message := "工具参数 JSON 格式无效,请按参数规范修正后重试"
var typeErr *json.UnmarshalTypeError
switch {
case errors.Is(err, errCloudAgentJSONSingleObject):
message = "工具参数必须是单个 JSON 对象,不能是字符串、数组、null 或多个对象;无参数时传 {}"
case errors.As(err, &typeErr):
message = "工具参数字段类型不匹配,请按参数规范使用整数、字符串或数组,不要把数字或数组写成字符串"
case strings.HasPrefix(err.Error(), "json: unknown field "):
message = "工具参数含有不支持的字段,请移除参数规范以外的字段后重试"
}
return &cloudAgentArgumentError{BadAuthRequest(message)}
}
// decodeCloudAgentJSONObject is used for model tool arguments. Tool arguments
// are an untrusted protocol boundary: reject non-objects, unknown fields and
// trailing JSON instead of silently accepting an ambiguous payload.
func decodeCloudAgentJSONObject(raw string, target any) error {
data := bytes.TrimSpace([]byte(raw))
if len(data) == 0 || data[0] != '{' {
return errCloudAgentJSONSingleObject
}
decoder := json.NewDecoder(bytes.NewReader(data))
decoder.DisallowUnknownFields()
if err := decoder.Decode(target); err != nil {
return err
}
var extra any
if err := decoder.Decode(&extra); err != io.EOF {
if err == nil {
return errCloudAgentJSONSingleObject
}
return err
}
return nil
}