Skip to content

Commit dd9e202

Browse files
Fix Codex image generation tool timeout
1 parent 94d8391 commit dd9e202

5 files changed

Lines changed: 31 additions & 6 deletions

File tree

docs/plugins/codex-harness-reference.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,8 @@ available timeout in this order:
256256

257257
- A positive per-call `timeoutMs` argument.
258258
- For `image_generate`, `agents.defaults.imageGenerationModel.timeoutMs`.
259+
- For `image_generate` without a configured timeout, the 120 second
260+
image-generation default.
259261
- For the media-understanding `image` tool, `tools.media.image.timeoutSeconds`
260262
converted to milliseconds, or the 60 second media default.
261263
- The 30 second dynamic-tool default.

docs/plugins/codex-harness.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -530,9 +530,10 @@ Supported `appServer` fields:
530530
OpenClaw-owned dynamic tool calls are bounded independently from
531531
`appServer.requestTimeoutMs`: Codex `item/tool/call` requests use a 30 second
532532
OpenClaw watchdog by default. A positive per-call `timeoutMs` argument extends
533-
or shortens that specific tool budget. The `image_generate` tool also uses
533+
or shortens that specific tool budget. The `image_generate` tool uses
534534
`agents.defaults.imageGenerationModel.timeoutMs` when the tool call does not
535-
provide its own timeout, and the media-understanding `image` tool uses
535+
provide its own timeout, or a 120 second image-generation default otherwise.
536+
The media-understanding `image` tool uses
536537
`tools.media.image.timeoutSeconds` or its 60 second media default. Dynamic tool
537538
budgets are capped at 600000 ms. On timeout, OpenClaw aborts the tool signal
538539
where supported and returns a failed dynamic-tool response to Codex so the turn

docs/tools/image-generation.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,9 @@ from each attempt.
237237
backends. A per-call `timeoutMs` tool parameter overrides the configured
238238
default. Google, OpenRouter, and xAI hosted image providers use 180 second
239239
defaults; Azure OpenAI image generation uses 600 seconds. Codex dynamic-tool
240-
calls honor the same timeout budget, bounded by OpenClaw's 600000 ms
241-
dynamic-tool bridge maximum.
240+
calls use a 120 second `image_generate` bridge default and honor the same
241+
timeout budget when configured, bounded by OpenClaw's 600000 ms dynamic-tool
242+
bridge maximum.
242243
</Accordion>
243244
<Accordion title="Inspect at runtime">
244245
Use `action: "list"` to inspect the currently registered providers,

extensions/codex/src/app-server/run-attempt.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,6 +1889,22 @@ describe("runCodexAppServerAttempt", () => {
18891889
).toBe(180_000);
18901890
});
18911891

1892+
it("uses a media-safe default for Codex image generation dynamic tool calls", () => {
1893+
expect(
1894+
testing.resolveDynamicToolCallTimeoutMs({
1895+
call: {
1896+
threadId: "thread-1",
1897+
turnId: "turn-1",
1898+
callId: "call-image-generate-default",
1899+
namespace: null,
1900+
tool: "image_generate",
1901+
arguments: { prompt: "cat" },
1902+
},
1903+
config: undefined,
1904+
}),
1905+
).toBe(testing.CODEX_DYNAMIC_IMAGE_GENERATION_TOOL_TIMEOUT_MS);
1906+
});
1907+
18921908
it("uses the media image timeout for Codex image dynamic tool calls", () => {
18931909
expect(
18941910
testing.resolveDynamicToolCallTimeoutMs({

extensions/codex/src/app-server/run-attempt.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ import { filterToolsForVisionInputs } from "./vision-tools.js";
179179

180180
const CODEX_DYNAMIC_TOOL_TIMEOUT_MS = 30_000;
181181
const CODEX_DYNAMIC_TOOL_MAX_TIMEOUT_MS = 600_000;
182+
const CODEX_DYNAMIC_IMAGE_GENERATION_TOOL_TIMEOUT_MS = 120_000;
182183
const CODEX_DYNAMIC_IMAGE_TOOL_TIMEOUT_MS = 60_000;
183184
const CODEX_APP_SERVER_STARTUP_CONNECTION_CLOSE_MAX_ATTEMPTS = 3;
184185
const CODEX_APP_SERVER_STARTUP_TIMEOUT_FLOOR_MS = 100;
@@ -2991,9 +2992,12 @@ function readConfiguredDynamicToolTimeoutMs(
29912992
if (toolName === "image_generate") {
29922993
const imageGenerationModel = config?.agents?.defaults?.imageGenerationModel;
29932994
if (!imageGenerationModel || typeof imageGenerationModel !== "object") {
2994-
return undefined;
2995+
return CODEX_DYNAMIC_IMAGE_GENERATION_TOOL_TIMEOUT_MS;
29952996
}
2996-
return readPositiveFiniteTimeoutMs(imageGenerationModel.timeoutMs);
2997+
return (
2998+
readPositiveFiniteTimeoutMs(imageGenerationModel.timeoutMs) ??
2999+
CODEX_DYNAMIC_IMAGE_GENERATION_TOOL_TIMEOUT_MS
3000+
);
29973001
}
29983002

29993003
if (toolName === "image") {
@@ -4649,6 +4653,7 @@ function handleApprovalRequest(params: {
46494653
export const testing = {
46504654
CODEX_DYNAMIC_TOOL_TIMEOUT_MS,
46514655
CODEX_DYNAMIC_TOOL_MAX_TIMEOUT_MS,
4656+
CODEX_DYNAMIC_IMAGE_GENERATION_TOOL_TIMEOUT_MS,
46524657
CODEX_DYNAMIC_IMAGE_TOOL_TIMEOUT_MS,
46534658
CODEX_TURN_COMPLETION_IDLE_TIMEOUT_MS,
46544659
CODEX_TURN_TERMINAL_IDLE_TIMEOUT_MS,

0 commit comments

Comments
 (0)