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:
gnanam1990
2026-04-01 20:26:21 +05:30
parent 00744a814b
commit 6c46974bf9

View File

@@ -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: {} }),
}, },
})) }))
} }