Skip to content

Commit 1c23d62

Browse files
committed
Simplify tool schema transformation for OpenAI strict mode
OpenAI's Structured Outputs requires all properties to be in the 'required' array, even optional ones (which use nullable types). The simplified transformation: - Only ensures all properties are listed in required array - Recursively processes nested objects and array items - Doesn't modify type definitions (already correct in our tools) - Much simpler than the original complex transformation
1 parent 807c414 commit 1c23d62

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

src/api/providers/openai-native.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,38 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio
190190
reasoningEffort: ReasoningEffortExtended | undefined,
191191
metadata?: ApiHandlerCreateMessageMetadata,
192192
): any {
193+
// Ensure all properties are in the required array for OpenAI's strict mode
194+
// This recursively processes nested objects and array items
195+
const ensureAllRequired = (schema: any): any => {
196+
if (!schema || typeof schema !== "object" || schema.type !== "object") {
197+
return schema
198+
}
199+
200+
const result = { ...schema }
201+
202+
if (result.properties) {
203+
const allKeys = Object.keys(result.properties)
204+
result.required = allKeys
205+
206+
// Recursively process nested objects
207+
const newProps = { ...result.properties }
208+
for (const key of allKeys) {
209+
const prop = newProps[key]
210+
if (prop.type === "object") {
211+
newProps[key] = ensureAllRequired(prop)
212+
} else if (prop.type === "array" && prop.items?.type === "object") {
213+
newProps[key] = {
214+
...prop,
215+
items: ensureAllRequired(prop.items),
216+
}
217+
}
218+
}
219+
result.properties = newProps
220+
}
221+
222+
return result
223+
}
224+
193225
// Build a request body for the OpenAI Responses API.
194226
// Ensure we explicitly pass max_output_tokens based on Roo's reserved model response calculation
195227
// so requests do not default to very large limits (e.g., 120k).
@@ -266,7 +298,7 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio
266298
type: "function",
267299
name: tool.function.name,
268300
description: tool.function.description,
269-
parameters: tool.function.parameters,
301+
parameters: ensureAllRequired(tool.function.parameters),
270302
strict: true,
271303
})),
272304
}),

0 commit comments

Comments
 (0)