From e035861516bf662dbeca1936a3adcd77aa940667 Mon Sep 17 00:00:00 2001 From: dawn <90008@klbr.net> Date: Wed, 29 Jul 2026 05:43:22 +0300 Subject: [PATCH] fix(kimi): preserve root tool parameter object type --- internal/runtime/executor/helps/moonshot_schema.go | 14 ++++++++++++++ .../runtime/executor/helps/moonshot_schema_test.go | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/internal/runtime/executor/helps/moonshot_schema.go b/internal/runtime/executor/helps/moonshot_schema.go index 57d7c6c8..21e89313 100644 --- a/internal/runtime/executor/helps/moonshot_schema.go +++ b/internal/runtime/executor/helps/moonshot_schema.go @@ -75,6 +75,20 @@ func normalizeMoonshotToolParameters(tool map[string]json.RawMessage) (json.RawM return nil, false } normalized, changed := normalizeMoonshotSchema(rawParameters, "", false) + parameters, ok := moonshotJSONObject(normalized) + if !ok { + return normalized, changed + } + // Moonshot requires every function's top-level parameters schema to be an + // object, even when that schema also contains a union. Nested union parents + // must omit type; this boundary is the exception. + parameterType, hasType := moonshotSchemaType(parameters["type"]) + if !hasType || parameterType != "object" { + parameters["type"] = json.RawMessage(`"object"`) + if updated, errMarshal := json.Marshal(parameters); errMarshal == nil { + return updated, true + } + } return normalized, changed } diff --git a/internal/runtime/executor/helps/moonshot_schema_test.go b/internal/runtime/executor/helps/moonshot_schema_test.go index 9e61a6af..8f12eb49 100644 --- a/internal/runtime/executor/helps/moonshot_schema_test.go +++ b/internal/runtime/executor/helps/moonshot_schema_test.go @@ -68,8 +68,8 @@ func TestNormalizeMoonshotToolSchemasInfersObjectBranchesAndPreservesExistingTyp ]}`) out := NormalizeMoonshotToolSchemas(payload) - if gjson.GetBytes(out, "tools.0.function.parameters.type").Exists() { - t.Fatalf("root union parent type should be absent; payload=%s", out) + if got := gjson.GetBytes(out, "tools.0.function.parameters.type").String(); got != "object" { + t.Fatalf("root union parameters.type = %q, want object; payload=%s", got, out) } for index := range []int{0, 1} { if got := gjson.GetBytes(out, fmt.Sprintf("tools.0.function.parameters.anyOf.%d.type", index)).String(); got != "object" { -- 2.51.2