From 5803d73476963b405728ce46bd3b8b265030509b Mon Sep 17 00:00:00 2001 From: josephkehan-prog Date: Sat, 25 Jul 2026 04:30:15 -0400 Subject: [PATCH] fix(kosong/kimi): move parent type into anyOf/oneOf/allOf items MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moonshot's tool schema validator rejects nodes that declare `type` on the same level as a combinator: 400 tools.function.parameters is not a valid moonshot flavored json schema, details: normalizeKimiToolSchema had two gaps: 1. The root schema object was never normalized — ensureKimiPropertyTypes only recursed into child schemas. 2. No node (root or nested) handled the type+combinator rule, so tools whose parameters root is e.g. { type: 'object', anyOf: [...] } (or that nest that shape under properties / not / if-then-else) were sent as-is and rejected with HTTP 400. Add fixCombinatorParentType(), which copies the parent `type` into each combinator item that lacks one and removes it from the parent (the parent type constrained every variant anyway, so semantics are preserved). It runs on the root and on every visited node. Items that already declare their own `type` are left untouched. Refs #792 --- packages/kosong/src/providers/kimi-schema.ts | 33 ++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/packages/kosong/src/providers/kimi-schema.ts b/packages/kosong/src/providers/kimi-schema.ts index 93b428c642..913e113257 100644 --- a/packages/kosong/src/providers/kimi-schema.ts +++ b/packages/kosong/src/providers/kimi-schema.ts @@ -116,8 +116,9 @@ const NUMERIC_STRUCTURE_KEYS = new Set([ * a provider-compatibility normalizer, not a complete JSON Schema compiler: * it resolves local refs, preserves combinator nodes, infers obvious * scalar/object/array types, and falls back to `string` only for nested - * typeless property schemas. The root schema object is treated as a container - * and is not itself normalized. + * typeless property schemas. It also rewrites nodes that declare `type` + * alongside a combinator (`anyOf` / `oneOf` / `allOf`), which Moonshot + * rejects, by moving the parent `type` into each combinator item. */ export function normalizeKimiToolSchema(schema: Record): Record { return ensureKimiPropertyTypes(derefJsonSchema(schema)); @@ -128,10 +129,36 @@ function ensureKimiPropertyTypes(schema: Record): Record hasUnresolvedDefinitionRef(child, bucketKey)); @@ -300,6 +327,8 @@ function normalizeProperty(node: unknown): void { return; } + fixCombinatorParentType(node); + if (!hasOwn(node, 'type') && !hasAnyKey(node, TYPE_COMPLETION_SKIP_KEYS)) { const enumValues = node['enum']; if (Array.isArray(enumValues) && enumValues.length > 0) {