Skip to content

Commit 8872f77

Browse files
fix(v2): pin strict:false on function tools that omit it
The Codex backend reads an omitted strict flag as strict-mode structured output: every declared schema property becomes required, so the model fabricates values for optional args like the task tool's sessionID and fresh subagent calls die with "Subagent session not found". Closes #293
1 parent a76a9b5 commit 8872f77

1 file changed

Lines changed: 12 additions & 2 deletions

File tree

‎lib/opencode-v2.ts‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,20 @@ function createV2Language(model: ReturnType<ReturnType<typeof createOpenAI>["res
3838
delete openai.conversation;
3939
return { ...options, providerOptions: { ...options.providerOptions, openai } };
4040
};
41+
// The SDK only writes `strict` for tools that declare it, and the Codex
42+
// backend treats an omitted flag as strict mode: every declared schema
43+
// property becomes required, so the model fills optional args (e.g. the
44+
// task tool's sessionID) with fabricated values. Pin strict:false unless
45+
// the tool opted in itself.
46+
const relaxTools = (options: Options): Options => ({
47+
...options,
48+
tools: options.tools?.map((tool) =>
49+
tool.type === "function" ? { ...tool, strict: tool.strict ?? false } : tool),
50+
});
4151
return new Proxy(model, {
4252
get(target, property, receiver) {
43-
if (property === "doGenerate") return (options: Options) => target.doGenerate(stateless(options));
44-
if (property === "doStream") return (options: Options) => target.doStream(stateless(options));
53+
if (property === "doGenerate") return (options: Options) => target.doGenerate(stateless(relaxTools(options)));
54+
if (property === "doStream") return (options: Options) => target.doStream(stateless(relaxTools(options)));
4555
return Reflect.get(target, property, receiver);
4656
},
4757
});

0 commit comments

Comments
 (0)