feat(core): add per-model-request timeouts#1466
Conversation
🦋 Changeset detectedLatest commit: 38d8249 The changes in this PR will be included in the next version bump. This PR includes changesets to release 5 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 285d46bc0f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 51c6d9ffd6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d9d0c7605b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Note You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 31a0f9b84b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Note You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 47d1e6d877
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Note You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a1aeb486d4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Note You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 38d8249a47
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| requestMayHaveReachedServer = true; | ||
| } | ||
| webSocket.send(frame as any); | ||
| markReplayUnsafe?.(); |
There was a problem hiding this comment.
Mark queued hosted WebSocket frames unsafe for provider timeouts
When this helper is handed a hosted ResponsesWS that is still connecting, send() queues the response.create/response.inject frame and the SDK flushes that queue on socket open before the iterator yields the open message that flips requestMayHaveReachedServer. A client frame-read timeout in that small post-flush/pre-open window is now an ETIMEDOUT error matched by retryPolicies.timeout()/networkError(), but the catch path will not set unsafeToReplay, so the hosted turn can be replayed after the first frame already left the socket. Please mark provider errors unsafe once a frame has been queued/sent, or otherwise distinguish definitely-unsent queued frames.
Useful? React with 👍 / 👎.
kalyanamdewri
left a comment
There was a problem hiding this comment.
Non-blocking cancellation test on 38d8249a4751d2e51c94e94499c69c3dacf77191
Environment: macOS 26.1 (25B78), arm64, Node v22.14.0, pnpm 11.10.0; base 901fb94c0fb9ffc8cb2d8275d99622475f77f401; seed none-deterministic-v1 (no randomness).
I injected the deadline after stream event 3 (third response.function_call_arguments.delta), with partial tool arguments 17/35 received.
| Branch | Caller result | Completion latency | Producer tasks after 2000 ms |
Abort listeners after settle |
|---|---|---|---|---|
| base | resolved (cancelled=true), 3/3 |
2.079 ms median (1.904–2.185 ms) |
0 |
0 |
| PR | resolved (cancelled=true), 3/3 |
2.149 ms median (2.044–2.170 ms) |
0 |
0 |
The measured invariant was Cancellation must propagate to the producer and converge to the baseline live-task/resource count. It HELD because all 3/3 runs on both branches observed the provider abort, finalized the producer, and returned from one active producer task to baseline 0 with 0 visible abort listeners after 2000 ms; the PR also cleared its one 30000 ms request timer, leaving 0 timers.
Trace and minimized fixture: /tmp/cancellation-test/slot2-cancellation-artifact.tar.gz (sha256:5a863f8d23c94d88a8484ecd0e3bf604c43797816423cc36840f5a293076d99e). I did not test a real network socket, a non-cooperative provider, or expiry into ModelRequestTimeoutError. Producer tasks are the fixture model’s exact active-task count, not all SDK/Node Promise tasks; listener counts cover direct JavaScript listeners on retained signals, while native AbortSignal.any parent links are not exposed.
This pull request resolves #894.
It adds a provider-agnostic per-attempt deadline so one slow model request can time out and participate in runner-managed retry without cancelling the entire agent run.
Changes
ModelSettings.requestTimeoutMsandModelRequestTimeoutErrorfor non-streaming and complete streaming attempts.retryPolicies.timeout()and normalizedisTimeoutfacts for SDK and provider transport timeouts.response.createorresponse.injectafter send, for both runner and provider client deadlines, while keeping pre-send timeouts retryable.ETIMEDOUT, including deadlines already exhausted between setup steps, soretryPolicies.timeout()handles auth, connection, queue, and frame-read deadlines consistently.@openai/agents-coreand@openai/agents-openai.Validation
bash .agents/skills/code-change-verification/scripts/run.sh(3,146 tests passed; 2 skipped)pnpm -F docs build(4,637 pages)pnpm changeset:validate-lite