fix: normalize tool schemas so required ⊇ properties for OpenAI/Codex
OpenAI and Codex enforce strict JSON Schema validation — every key in `properties` must also appear in `required`. Anthropic schemas often mark fields as optional (omitted from `required`), which causes 400 errors on OpenAI/Codex endpoints. Example: the Agent tool has `subagent_type` in `properties` but not in `required`, producing: "Invalid schema for function 'Agent': Missing 'subagent_type' in required array" Fix: add `normalizeSchemaForOpenAI()` in `convertTools()` that ensures `required` is a superset of all `properties` keys before the schema is sent to the API. Existing `required` entries are preserved; missing ones are appended. Schemas without `properties` pass through unchanged. Fixes #46. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -217,6 +217,21 @@ function convertMessages(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OpenAI requires every key in `properties` to also appear in `required`.
|
||||||
|
* Anthropic schemas often mark fields as optional (omitted from `required`),
|
||||||
|
* which causes 400 errors on OpenAI/Codex endpoints. This normalizes the
|
||||||
|
* schema by ensuring `required` is a superset of `properties` keys.
|
||||||
|
*/
|
||||||
|
function normalizeSchemaForOpenAI(schema: Record<string, unknown>): Record<string, unknown> {
|
||||||
|
if (schema.type !== 'object' || !schema.properties) return schema
|
||||||
|
const properties = schema.properties as Record<string, unknown>
|
||||||
|
const existingRequired = Array.isArray(schema.required) ? schema.required as string[] : []
|
||||||
|
const allKeys = Object.keys(properties)
|
||||||
|
const required = Array.from(new Set([...existingRequired, ...allKeys]))
|
||||||
|
return { ...schema, required }
|
||||||
|
}
|
||||||
|
|
||||||
function convertTools(
|
function convertTools(
|
||||||
tools: Array<{ name: string; description?: string; input_schema?: Record<string, unknown> }>,
|
tools: Array<{ name: string; description?: string; input_schema?: Record<string, unknown> }>,
|
||||||
): OpenAITool[] {
|
): OpenAITool[] {
|
||||||
@@ -227,7 +242,7 @@ function convertTools(
|
|||||||
function: {
|
function: {
|
||||||
name: t.name,
|
name: t.name,
|
||||||
description: t.description ?? '',
|
description: t.description ?? '',
|
||||||
parameters: t.input_schema ?? { type: 'object', properties: {} },
|
parameters: normalizeSchemaForOpenAI(t.input_schema ?? { type: 'object', properties: {} }),
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user