From d5b37964415b99a81a077392deba3d2d831f0bbf Mon Sep 17 00:00:00 2001 From: Wibias <37517432+Wibias@users.noreply.github.com> Date: Wed, 22 Jul 2026 05:40:26 +0200 Subject: [PATCH] fix(adapter): ensure root object type for Kimi tool schemas Kimi requires function.parameters.type to be exactly 'object' at the root. Codex tools with oneOf/anyOf schemas (like automation_update) omit the root type, causing 400 errors: 'tools.function.parameters.type is required and must be object'. Add provider-scoped normalization for api.kimi.com that ensures type: 'object' at the root while preserving oneOf, \, descriptions, and other schema keys. Similar to the existing xAI and Zen schema handling. Fixes #228 --- src/adapters/openai-chat.ts | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/adapters/openai-chat.ts b/src/adapters/openai-chat.ts index 06c1783cc3a..02d22767441 100644 --- a/src/adapters/openai-chat.ts +++ b/src/adapters/openai-chat.ts @@ -337,6 +337,28 @@ function isXaiSchemaTarget(provider: OcxProviderConfig): boolean { } } +function isKimiSchemaTarget(provider: OcxProviderConfig): boolean { + try { + return new URL(provider.baseUrl).hostname === "api.kimi.com"; + } catch { + return false; + } +} + +/** + * Kimi requires function.parameters.type to be exactly "object" at the root. + * Codex tools with oneOf/anyOf schemas omit the root type, causing 400 errors. + * Add type: "object" at the root while preserving oneOf, $defs, and other schema keys. + */ +function ensureKimiRootObjectType(parameters: unknown): Record { + if (!parameters || typeof parameters !== "object" || Array.isArray(parameters)) { + return { type: "object", properties: {} }; + } + const obj = parameters as Record; + if (obj.type === "object") return obj; + return { ...obj, type: "object" }; +} + function expandXaiRootObjectSchemas(schema: unknown): Record[] | undefined { if (!schema || typeof schema !== "object" || Array.isArray(schema)) return undefined; const obj = schema as Record; @@ -379,8 +401,13 @@ function toolsToChatFormat(parsed: OcxParsedRequest, provider: OcxProviderConfig : parsed.context.tools; if (tools.length === 0) return undefined; const xaiTarget = isXaiSchemaTarget(provider); + const kimiTarget = isKimiSchemaTarget(provider); const formatted = tools.flatMap(t => { - const parameters = xaiTarget ? normalizeXaiToolParameters(t.parameters) : t.parameters; + const parameters = xaiTarget + ? normalizeXaiToolParameters(t.parameters) + : kimiTarget + ? ensureKimiRootObjectType(t.parameters) + : t.parameters; if (parameters === undefined) return []; return [{ type: "function",