Commit Graph
39 Commits
Author SHA1 Message Date
Hung 5a7353f040 Treat audio validation failures as non-retryable input errors (#58434)
## What changed

Map audio size, data, format, and sample-rate validation failures to `InvalidAudioInput` for HTTP 400 responses and streamed errors. Preserve the provider's message, falling back to `Invalid audio input.` when it is absent or blank.

Classify these errors as non-retryable and expose them as `BadRequest`. Redact their messages in doctor diagnostics and group them as invalid requests in telemetry.

## Testing

Add coverage for all six audio validation codes across HTTP errors, streamed `error` events, and `response.failed` events, checking error classification, message preservation, and the absence of retries. Extend doctor diagnostic redaction coverage for `InvalidAudioInput`.

GitOrigin-RevId: 0a59964bcabd83997bdb32fc9318a5482dac33b0
2026-10-30 21:01:23 +00:00
Tom Leach (@toml) 6a6e2fb1f0 Distinguish policy-restricted capacity failures from server overloads (#57452)
## What changed

- Recognize `policy_capacity_unavailable` in HTTP and streaming API errors and expose it as `policyCapacityUnavailable` through the app-server protocol and generated bindings.
- Display “Policy-restricted capacity is unavailable. Please try again later.” while preserving overload retry behavior based on `Retry-After`.
- Handle the new error in TUI overload rendering, reviewer retries, and error telemetry.

## Testing

Add coverage for HTTP and streaming error classification, retry advice, WebSocket terminal error attribution, protocol serialization, and TUI rendering with and without an upstream message.

GitOrigin-RevId: 1b9536fba1e11cc891dcf689aee35410d82f5412
2026-10-27 13:31:38 +00:00
Charlie Marsh 60adfa8513 Treat model-not-found provider errors as terminal failures (#56445)
## Why

Provider errors with code `model_not_found` should end the turn immediately and preserve the provider's message instead of triggering retries.

## What changed

- Recognize `model_not_found` in HTTP 400, 403, and 404 responses and in streamed `error` and `response.failed` events.
- Preserve the provider message and any available HTTP status, and expose `modelNotFound` through the app-server protocol and generated schemas and SDK types.

## Testing

Add coverage for HTTP classification, statusless stream errors, and terminal failures without retries across HTTP, SSE, and WebSocket responses. Verify that `thread/read` preserves the error reported by the live notification.

GitOrigin-RevId: 88f824ac03c8c9669915b1e40c67b76c08326fbe
2026-10-23 11:43:14 +00:00
Abhinav 067249a283 Preserve provider model catalogs when refreshes fail (#55958)
## Why

A failed provider catalog refresh could discard model metadata and disable tool search on subsequent turns, even after a successful discovery.

## What changed

Keep the last successful catalog, ETag, and original freshness when refreshes fail without an access rejection. Continue invalidating cached catalogs for HTTP `401`/`403`, rejected refresh tokens, and gateway credentials that require login. Distinguish `GatewayLoginRequired` from login in progress so only the former invalidates the catalog.

Successful empty responses remain authoritative, and cached catalogs remain scoped to the provider and authentication identity.

## Testing

Add regression coverage for catalog preservation across refresh errors and restarts, access rejection invalidation, identity isolation, and tool search and instruction stability on the next turn after a failed refresh.

GitOrigin-RevId: 9dd7c73ac2cc1fd49664efd93b839baa94e05c49
2026-10-21 18:43:15 +00:00
Eric Traut fea1d7f7d1 Add support for Academic Researchers plans (#55387)
## What changed

- Recognize `sci` and `sci_plus` in authentication, account responses, rate limits, and generated client schemas.
- Treat both plans as workspace accounts eligible for cloud configuration, and use business analytics routes.
- Display “Academic Researchers” and “Academic Researchers Plus” in the TUI and direct users to their admin when usage limits are reached.

## Testing

Add coverage for plan parsing, workspace classification, account and rate-limit responses, cloud configuration eligibility, analytics routing, TUI labels, and usage-limit guidance. Exercise installed-app refresh and listing with `sci_plus` authentication.

GitOrigin-RevId: b51c5df03029b8bc249d44f11b353a7755e7dd04
2026-10-19 21:43:19 +00:00
jif 816fa702ec Account for token usage from incomplete responses (#53670)
## Why

Terminal `response.incomplete` errors discard reported token usage. Counting that usage as a new context baseline can also double-count input and trigger unnecessary compaction on the next turn.

## What changed

- Carry the response ID and valid reported usage with incomplete-response errors.
- Record usage for sampling and foreground compaction in cumulative totals, rollout records, budgets, and token-usage contributors without replacing the context baseline. Preserve the original terminal error, including when accounting exhausts the budget or cancellation races the error.
- Charge incomplete background compaction requests to the rollout budget without publishing foreground token usage.
- Ignore missing or malformed usage rather than estimating it.

## Testing

Extend coverage for SSE and WebSocket incomplete responses, rollout usage records, compaction accounting, deferred token-count events, and token-usage contributors. Add regressions for unnecessary compaction on the next turn and background compaction publishing foreground usage.

GitOrigin-RevId: bf1ee6df3912052ab7c19e1c6af8ad3dc4b07675
2026-10-13 13:36:24 +00:00
jif bc9cad3473 Treat incomplete responses as terminal errors (#53451)
## Why

Incomplete responses such as `max_output_tokens` were classified as stream errors, allowing retries and compaction model fallback after the response had hit its output limit.

## What changed

Introduce `ResponseIncomplete` errors that preserve the server-provided reason and stop stream processing immediately. Make these errors non-retryable and stop compaction without falling back to the selected model. Record incomplete responses separately in sampler failure metrics.

## Testing

Add regression tests that verify incomplete responses surface a terminal error without retries over SSE and WebSocket, and that compaction stops without retrying or switching models for both local and remote compaction.

GitOrigin-RevId: 6e107d441b9bf03fa47ea47b88eeb94b71a9f729
2026-10-12 18:53:49 +00:00
jif c0c230e673 Add bounded diagnostics for agent spawn failures (#51355)
## Why

Spawn failures can share an error kind and message despite different causes, such as execution and residency capacity limits. Telemetry needs enough detail to distinguish these failures without using error messages or correlation IDs as metric labels.

## What changed

- Add `AgentErrorContext` annotations for capacity limits, registry rejections, runtime availability, and spawn stages. Preserve the first annotation so outer stages retain the more precise failure origin.
- Add bounded `detail` and `error_kind` labels to spawn failure metrics, using `unknown` when no context is available.
- Emit spawn failure trace events with these classifications and the call and turn IDs for both multi-agent versions.

## Testing

Add tests for distinct capacity and registry failure contexts, preservation of manager, fork, and shutdown errors, and metric aggregation across different error messages and correlation IDs. Verify that annotations preserve existing error kinds and user-visible messages.

GitOrigin-RevId: 5bbe3d32f6ce408622f38e559fddeab05b8ccb65
2026-10-06 12:32:27 +00:00
Eric Traut bdfbab9f4f Point usage and credit links to ChatGPT settings (#49874)
## What changed

Replace `https://chatgpt.com/codex/settings/usage` with
`https://chatgpt.com/settings/usage` in usage-limit errors, the `/status`
card, and backend banner actions. Credit purchase actions retain
`?credits_modal=true`.

## Testing

Update error-message assertions, banner action tests, status hyperlink
assertions, and TUI snapshots to expect the new URL.

GitOrigin-RevId: 1e1db971284a25a781120da30a6dea5ff9c3d957
2026-10-01 05:16:40 +00:00
Adam Perry @ OpenAI 6ba4bf9e64 Honor server retry advice across Responses retries and fallback (#49441)
## Why

Responses overload and exhausted-request errors could terminate despite server retry advice, and WebSocket-to-HTTP fallback could issue a request before the advised deadline.

## What changed

- Allow `ServerOverloaded` and `RetryLimit` errors to retry when server advice is present, within the configured retry budgets.
- Preserve `Retry-After` headers from rejected WebSocket upgrades and wait for the server deadline before falling back to HTTP.
- Keep quota, usage-limit, and policy failures terminal even when they include retry advice.

## Testing

Add coverage for HTTP overload and rate-limit recovery, WebSocket upgrade rejection and fallback timing, retry deadline preservation through error mapping, and retry limits for sampling and manual and automatic compaction.

GitOrigin-RevId: 72d30a9f078652664754dfa971fd7dc7a78f20e8
2026-09-30 02:12:42 +00:00
Won Park 8bd5a136ff Add recovery guidance to content-filter retries (#49119)
## Why

Responses stopped by `content_filter` previously followed generic stream-error retry handling without guidance about the block. Retried requests need instructions to explain the limitation and offer a permitted alternative.

## What changed

- Recognize content-filter failures as a distinct error while preserving retryability and the existing public error representation.
- Append developer guidance to the conversation after each sampling block, retaining delivered output and using the existing retry handling.
- Support a model catalog override through `model_messages.content_filter_guidance`. Missing, null, blank, or values exceeding 512 UTF-8 bytes fall back to bundled guidance.
- The bundled guidance tells the model to avoid reproducing or working around blocked content, briefly explain the limitation, offer a permitted alternative, and continue unrelated authorized work.

## Testing

Add a scenario and request-history snapshot covering repeated blocks, catalog guidance on each retry, retained partial output, and eventual completion. Add error-mapping assertions for retryability, public error classification, and error text.

GitOrigin-RevId: ba0c201b3a5a3acf5cfa971332027240e0690225
2026-09-29 01:14:41 +00:00
rhan-oai 44a9bfa145 Preserve usage limit windows in turn and compaction analytics (#48174)
## Why

Usage limit errors discarded the server-selected window responsible for the limit, leaving turn and compaction analytics unable to distinguish five-hour limits from weekly limits.

## What changed

Preserve optional `limit_window_minutes` from usage limit error responses in `UsageLimitReachedError` and report it as `usage_limit_window_minutes` in turn and compaction events. Accept unsigned integers that fit in `u16`; treat missing, null, malformed, or out-of-range values as unknown. Events for other error kinds report `null`.

## Testing

Add coverage for HTTP and wrapped WebSocket error mapping, analytics serialization and reduction, and app-server propagation to turn and local/remote compaction events. Cases include five-hour and weekly windows, missing or invalid values, and unrelated errors.

GitOrigin-RevId: a32066a007559d91a3c868a756bfd0f976777176
2026-09-25 19:05:15 +00:00
Eric Traut b725da3b6d Add Pro Max plan support and update Pro display names (#47971)
## What changed

- Recognize `promax` in authentication, account responses, and backend rate limits; update generated schemas and client types.
- Display `prolite` as “Pro”, `pro` as “Pro (More)”, and `promax` as “Pro (Max)” in account labels, status, and analytics.
- Include Pro Max in experimental context eligibility, paid-plan tooltips, and usage-limit guidance for purchasing credits.

## Testing

Extend coverage for Pro Max plan parsing, account and rate-limit responses, experimental context eligibility, and plan display names. Update the login token test to expect “Pro (More)”.

GitOrigin-RevId: 197e00fa7a99cbce125c8f1d43a451ec1ed5c1fb
2026-09-25 00:20:02 +00:00
Steve Coffey dafb133c5b Surface Flex capacity failures as a distinct terminal error (#47967)
## What changed

- Recognize `flex_unavailable` in HTTP 429 responses and streamed `error` and `response.failed` events. End normal turns without retries and report `Flex capacity unavailable.`
- Expose `flexUnavailable` through the core and app-server protocols and generated schemas and SDK types.
- Keep Flex capacity failures eligible for Guardian review and sampler retries, with a distinct telemetry classification.
- Map unexpected HTTP responses to `HttpConnectionFailed`, preserving their status codes.

## Testing

Add regression coverage for terminal Flex failures over HTTP, SSE, and WebSocket, HTTP 504 status preservation after a stream retry, and protocol serialization. Update Guardian retry and sampler recovery tests to cover Flex failures.

GitOrigin-RevId: f2e03a6d2d36a6d9748c35952e40397f8670d121
2026-09-24 23:33:38 +00:00
Adam Perry @ OpenAI 9d8de19674 Honor Retry-After and preserve server retry deadlines (#47641)
## Why

HTTP retries used local backoff even when the server supplied `Retry-After`. Relative retry delays also failed to account for time spent propagating errors or reporting retries.

## What changed

- Parse `Retry-After` delay seconds and HTTP dates into a monotonic deadline captured when response headers arrive.
- Honor that deadline for HTTP retries, falling back to local backoff when valid advice is absent.
- Preserve deadlines through API and Bedrock error mapping, stream retries, and exhausted retry state. Expired advice remains a zero delay instead of triggering local backoff.

## Testing

Add coverage for header parsing, deadline countdown and expiry, error mapping after exhausted HTTP retries, and delayed stream retry notifications. Update Responses and remote compaction tests to verify that HTTP retries honor `Retry-After`.

GitOrigin-RevId: a2eff02946e5524f29e06f7ba1431e3d339261a4
2026-09-23 19:53:11 +00:00
Rennie 559264d92e Preserve invalid_prompt as a distinct error classification (#47353)
## Why

`invalid_prompt` responses were classified as generic invalid requests, losing the server's specific error classification.

## What changed

Add `InvalidPrompt` variants to the API and core error types and serialize the core protocol classification as `invalid_prompt`. Recognize the code in HTTP 400 responses, wrapped WebSocket errors, and SSE `response.failed` events while preserving server messages and keeping the error non-retryable. Map it to `other` in the app-server v2 protocol.

## Testing

Extend coverage for typed error mapping, missing and blank messages, protocol conversion, and guardian retry handling. Exercise HTTP and SSE failures in core integration tests, asserting the error message, serialized classification, and a single request without retry.

GitOrigin-RevId: 5d9a299a013b06158a4dc27a4054f3dbc5fd0f4d
2026-09-22 20:07:50 +00:00
Adam Perry @ OpenAI d5b29951ac Centralize retry decisions and delays in CodexErr (#46540)
## What changed

Replace `is_retryable()` with `retry_delay(retry_count)`, which returns `None` for terminal errors and a delay for retryable errors. Prefer server advice when present; otherwise use exponential backoff with jitter. Keep `server_retry_delay()` for callers that need only the server-provided delay.

Route sampling and remote compaction errors through the shared response stream handler, which now checks retryability and obtains the delay together. Preserve server-only retry timing when the retry budget is exhausted.

## Testing

Add coverage for attempt-dependent backoff, zero-duration server advice, and terminal errors that remain non-retryable despite server advice. Update API mapping and provider tests to use the combined retry API.

GitOrigin-RevId: 903f92935e71dea043afe1fad8ccb9389471aa75
2026-09-19 00:46:30 +00:00
Rennie fa8cf44985 Preserve bio policy errors as a distinct non-retryable error (#46306)
## Why

Streaming `bio_policy` failures were classified as generic invalid requests, losing their policy-specific classification.

## What changed

- Add `BioPolicy` errors across the API and core protocol, recognizing streaming failures and HTTP 400 responses, including wrapped WebSocket errors.
- Preserve server messages and use a biological-risk fallback when the message is missing or blank.
- Treat bio policy errors as non-retryable in core and guardian handling, and classify them in diagnostics and telemetry.
- Map `BioPolicy` to `other` in the app-server v2 protocol.

## Testing

Add coverage for error classification, message preservation and fallbacks, HTTP and wrapped WebSocket responses, guardian retry decisions, and app-server conversion. Extend the core integration test to verify that bio policy failures emit a typed error and complete the turn after a single request.

GitOrigin-RevId: 78c2647e8fc8f80297cb8a23fff06ab141099632
2026-09-17 21:25:55 +00:00
mingze-openai 8c72f2ff56 Use curly apostrophes in protocol error messages (#43961)
## What changed

Replace straight apostrophes with curly apostrophes in usage-limit and high-demand error messages, and update usage-limit test expectations. Document that the context-window error's ASCII prefix is matched by the iOS input-limit classifier.

GitOrigin-RevId: 93484aaf805b9e6f8785fd1b43fe6ff9f1a13efa
2026-09-09 01:19:07 +00:00
dhruvgupta-oai 5037919777 Add Luna Reserve usage fallback to the TUI (#42372)
## Why

When ordinary included usage is exhausted, eligible users need a way to keep working with the backend-provided Luna Reserve quota and return to their previous model once ordinary usage recovers.

## What changed

- Automatically switch eligible TUI tasks to Luna Reserve after an authoritative account usage read, preserving the prior model and reasoning effort per task.
- Restrict model selection while on Reserve to its supported reasoning levels, keep queued turns on the accepted model, and restore the saved model after a fresh read confirms recovery.
- Surface Reserve usage in the composer and `/status`, and expose `normalModelSlug` in app-server rate-limit snapshots so clients can use the associated model's display metadata without changing the request model.
- Poll account limits more frequently near exhaustion and retain compatibility with app servers that only accept the legacy null request parameters.

## Testing

- Added coverage for Reserve entry, queued-turn handling, task reconstruction, recovery authorization, account changes, model selection, usage rendering, and banner dismissal.

GitOrigin-RevId: 46a435e9531051f8cec3f6a46c4b9f7cfa479747
2026-09-02 21:50:51 +00:00
Francis Chalissery 7276d67081 Expose resumable misalignment details through app server (#40952)
## Why

App-server clients need the explanation and steering instruction returned with a
misalignment policy violation to offer a user-confirmed continuation. Missing or
incomplete details must continue to behave as a terminal block.

## What changed

- Parse optional misalignment classification, explanation, and steering details
  from streamed and HTTP Responses errors and propagate them through core errors.
- Include the details in live app-server `error` and `turn/completed` payloads and
  export the corresponding protocol schemas and TypeScript types.
- Keep explanations and steering messages out of serialized rollout events and
  redact them from debug output.
- Document how clients can resume with `turn/start` after user confirmation.

## Testing

- Cover streamed, HTTP, and WebSocket-wrapped errors, including malformed and
  classification-only details.
- Verify live app-server notifications expose resumable details without writing
  the explanation or steering message to the rollout.

GitOrigin-RevId: 329258a444c2cd91d0c57ab1720830b33ddcfac5
2026-08-26 18:42:44 +00:00
Steve Coffey e0c727de04 Classify streaming rate-limit errors (#40931)
## What changed

- Classify `response.failed` events with the `rate_limit_exceeded` code as a distinct retryable error while preserving any parsed retry delay.
- Expose the error as `rateLimitExceeded` through the core protocol and app-server schemas after stream retries are exhausted.
- Preserve the upstream message for TUI display while keeping it out of telemetry summaries.

## Testing

- Cover SSE classification, retry metadata, protocol conversion and serialization, exhausted stream retries, telemetry redaction, and TUI rendering.

GitOrigin-RevId: 02dab4d3477dcd7653a58c49c4bd38687a616579
2026-08-26 17:45:42 +00:00
joeflorencio-openai 657bd889ae Support Edu Plus and Edu Pro account plans (#39316)
## What changed

- Recognize `edu_plus` and `edu_pro` as distinct education workspace plans across authentication, backend rate-limit mapping, and app-server account schemas.
- Include both plans in cloud configuration eligibility and use the education usage-limit behavior.
- Display the plans as `Edu Plus` and `Edu Pro` in the TUI status view.

## Testing

- Cover parsing, workspace classification, account and rate-limit responses, cloud configuration eligibility, usage-limit messages, and TUI display names for the new variants.

GitOrigin-RevId: bf8add780ae03a3c6d10c4f4afa0da262c37928e
2026-08-18 23:47:00 +00:00
Francis Chalissery eb147c0db3 Surface misalignment policy violations as typed errors (#38682)
## What changed

- Recognize `misalignment_policy_violation` errors from response streams and HTTP 400 or 403 responses.
- Preserve the upstream message, use a fallback for blank messages, and treat the error as non-retryable.
- Expose `misalignmentPolicyViolation` through the app-server protocol and generated schemas so turns fail with a typed terminal error.

## Testing

- Cover streamed and HTTP policy violations, fallback messages, retry behavior, and app-server turn completion.

GitOrigin-RevId: fd3485bf0be7bfe3d51c078bbc36a081692fd57f
2026-08-15 01:34:33 +00:00
rka-oai 1e489adad0 Enforce strict tool name collision errors (#37020)
## What changed

- Track the first duplicate effective tool name while assembling the tool registry, including collisions introduced by external tools, code mode, and tool search.
- When `[features.tool_registry].error_on_tool_collisions` is enabled, fail the turn with a `duplicate tool: <namespace>.<name>` error before sending a model request.
- Continue allowing identical tool names in different namespaces, and preserve the existing collision behavior when strict checking is disabled.

## Testing

- Cover registry collision tracking, strict tool planning across tool sources, namespace isolation, failure before sampling, and pre-sampling compaction.

GitOrigin-RevId: 4cf83538fb513cec0b9c8b567780caaaadd3243d
2026-08-05 04:00:50 +00:00
sashank-oai 3016671bb0 Support Enterprise automation account plans (#36228)
## What changed

- Recognize `enterprise_cbp_automation` as an Enterprise workspace plan in authentication, backend responses, and app-server account and rate-limit APIs.
- Expose the plan in generated protocol schemas and display it as `Enterprise (Automation)` in account status.
- Apply existing workspace eligibility and Business usage-limit behavior to the new plan.

## Testing

- Cover JWT parsing, plan conversion and serialization, app-server responses, workspace eligibility, usage-limit formatting, and TUI status rendering.

GitOrigin-RevId: d84ae2be3dd60fe398f226e6dc434efe27a387a5
2026-07-30 21:49:53 +00:00
Celia Chen 5989dcc470 Use the shared HTTP client in codex-protocol (#36033)
## What changed

- Replace direct `reqwest` error types in `codex-protocol` with
  `codex_http_client::HttpError`.
- Build the response-stream error test through
  `codex_http_client::HttpResponse`.
- Remove `codex-protocol` from the direct `reqwest` dependency allowlist.

## Testing

- Update the response-stream failure test to cover status and URL propagation
  through the shared HTTP response wrapper.

GitOrigin-RevId: 7abcbbe55f994acb13cccefef806a53c7008acde
2026-07-29 21:47:22 +00:00
Arun Eswara cf7e9cfe6a Support self-serve Business ProLite accounts (#35785)
## What changed

- Recognize `self_serve_business_prolite` across authentication, account and rate-limit APIs, generated schemas, workspace classification, status display, cloud configuration gating, and usage-limit messaging.
- Keep the Python SDK's `PlanType` enum compatible with non-empty string values introduced by newer Codex runtimes while preserving its known constants.

## Testing

- Cover token parsing, account reads and notifications, backend rate-limit mapping, workspace behavior, error formatting, and Python SDK response coercion for the new plan value.

GitOrigin-RevId: 70bc17a7c4ba4028cb10e4333cc1f2ac64da361f
2026-07-28 15:50:45 +00:00
bwanner-oai 544007d006 Support the ent26 enterprise plan (#35238)
## What changed

- Recognize `ent26` in authentication, account protocol, backend rate-limit
  payloads, and generated app-server schemas.
- Treat it as an enterprise workspace plan for cloud-config eligibility and
  business-style usage-limit guidance.
- Cover token parsing, serialization, backend mapping, plan classification,
  cloud-config access, and usage-limit formatting with tests.

GitOrigin-RevId: 537d897c8b1d80bcdb66d0fd402563fbb8c5a277
2026-07-24 20:00:59 +00:00
Adam Perry @ OpenAI 7bafdada8b Separate Codex error details from retry metadata (#34996)
## What changed

- Wrap `CodexErrorDetails` and an optional retry delay in `CodexErr`, allowing any mapped error to preserve server-provided retry timing.
- Generate the payload-free `CodexErrKind` classification alongside the error details and reuse it for analytics.
- Update error handling sites to inspect `CodexErr::details()` while preserving existing display, debug, protocol mapping, and retryability behavior.

## Testing

- Add coverage for legacy debug formatting, error-specific retryability, and retry-delay propagation through API error mapping.

GitOrigin-RevId: d3ab8a305f2a2ee21d0c0a8c8c388b06dda9c59a
2026-07-23 19:32:26 +00:00
rka-oai 1ec3def0b5 [codex] rename rollout budget error to session budget error (#29744)
## Summary

- rename the rollout-budget exhaustion error from
`RolloutBudgetExceeded` to `SessionBudgetExceeded`
- expose the matching app-server v2 wire value as
`sessionBudgetExceeded`
- regenerate JSON/TypeScript schema fixtures and update the app-server
docs and focused tests

This is a naming-only follow-up to #29715 based on [Pavel's review
suggestion](https://github.com/openai/codex/pull/29715#discussion_r3463183480).
Runtime behavior is unchanged.

## Tests

- `just test -p codex-core rollout_budget`
- `just test -p codex-app-server-protocol`
- `just fmt`
- `just write-app-server-schema`
2026-06-23 16:49:13 -07:00
rka-oai bbbea91960 [codex] surface rollout budget exhaustion (#29715)
## Summary
- surface shared rollout-budget exhaustion as
`CodexErr::RolloutBudgetExceeded` instead of a generic interrupted turn
- map it through the existing `CodexErrorInfo` and app-server v2
`codexErrorInfo` path
- keep local compaction from retrying after the shared rollout budget is
exhausted

This gives app-server clients a stable `rolloutBudgetExceeded` error
they can classify without guessing from `status="interrupted"`.

## Tests
- `just test -p codex-core rollout_budget`
2026-06-23 15:01:28 -07:00
Celia Chen e65e480e0d chore: improve expired Bedrock credential errors (#28992)
## Why

Amazon Bedrock returns a `401 Unauthorized` response containing
`Signature expired:` when an AWS credential, including a short-lived
`AWS_BEARER_TOKEN_BEDROCK`, has expired. Codex currently surfaces that
response as a generic `unexpected status` error, which does not explain
how to recover.

Environment-provided bearer tokens cannot be refreshed automatically, so
the error should direct users to refresh their AWS credentials or
replace or remove the environment token and restart Codex. This
classification belongs to the Amazon Bedrock provider so similar
responses from other providers retain their existing behavior.

## What changed

- Add a synchronous `ModelProvider::map_api_error` hook that defaults to
the existing provider-neutral API error mapping, and route model
request, stream, WebSocket, and terminal unauthorized errors through the
active provider.
- Override the hook for Amazon Bedrock. After preserving the structured
status, body, URL, and request metadata, recognize `401` responses
containing `Signature expired:` and attach actionable credential
guidance.
- Keep `codex-protocol` provider-neutral by representing the guidance as
an optional `user_message`. Error rendering prefers this message while
continuing to append the URL, request ID, Cloudflare ray, and
authorization diagnostics.
- Add model-provider coverage for expired signatures and negative cases,
core coverage for provider dispatch after unauthorized recovery, and a
TUI snapshot for the rendered error.

## Testing
Tested with a real request with expired bedrock key:
<img width="962" height="126" alt="Screenshot 2026-06-22 at 3 56 51 PM"
src="https://github.com/user-attachments/assets/7e21cc7c-798e-4662-8467-7f304a2f2b59"
/>
2026-06-23 00:53:09 +00:00
dhruvgupta-oai 4bcabbfbec Display workspace usage limit error copy from response header (#24114)
## Why

`openai/openai#947613` adds `X-Codex-Rate-Limit-Reached-Type` for Codex
workspace credit-depletion and spend-cap responses. The CLI currently
reads the adjacent promo header but otherwise renders generic
usage-limit copy, so those responses do not explain the
workspace-specific action the user needs to take.

Backend dependency: https://github.com/openai/openai/pull/947613

## What Changed

- Parse `X-Codex-Rate-Limit-Reached-Type` in the usage-limit error
handling path alongside `x-codex-promo-message`.
- Keep the header value parsing with the shared `RateLimitReachedType`
enum.
- Carry the parsed type on `UsageLimitReachedError` and render
client-owned copy for the four workspace owner/member credit and
spend-cap values.
- Preserve existing promo and plan-based text for absent, generic, or
unknown header values.
- Keep the existing TUI workspace-owner nudge state path unchanged; the
response header only selects the displayed error string.
- Add focused display coverage for all specific type values and the
generic fallback case.

## Test Plan

- Added `usage_limit_reached_error_formats_rate_limit_reached_types`
coverage.
- Not run manually, per request; CI runs validation on the pushed
commit.
2026-05-22 23:58:49 +00:00
jif-oai 18cefba922 Add timeout for remote compaction requests (#23451)
## Why

Remote compaction currently sends a unary `POST /responses/compact` and
waits for the full response before replacing history or emitting the
completed `ContextCompaction` item. Unlike normal `/responses` streaming
requests, this unary compact request had no timeout boundary. If the
backend accepts the request and then stalls before returning a body, the
existing request retry policy never sees a transport error, so the
compact turn can remain stuck after the started item with no completion
or actionable error.

That matches the reported hang shape in issues such as #18363, where
logs show `responses/compact` was posted but no corresponding compact
completion followed. A bounded request timeout gives the existing retry
policy a concrete timeout error to retry instead of letting the user sit
indefinitely on automatic context compaction.

## What

- Add a request timeout to legacy `/responses/compact` calls.
- Size that timeout from the provider stream idle timeout with a
conservative multiplier, so the default compact attempt gets 20 minutes
rather than the 5 minute stream idle window.
- Map API transport timeouts to a request timeout error instead of the
child-process timeout message.

## Testing

- Not run (per request; CI will cover).
2026-05-20 11:56:00 +02:00
jif-oaiandCodex f8c527e529 multi_agent_v2: move thread cap into feature config (#19792)
## Why

`features.multi_agent_v2.max_concurrent_threads_per_session` is meant to
be the MultiAgentV2-specific session thread cap: it counts the root
thread and all open subagent threads. The previous implementation kept
this surface tied to `agents.max_threads`, which made it a global
subagent-only cap and allowed the legacy setting to coexist with
MultiAgentV2.

## What Changed

- Added `max_concurrent_threads_per_session` to
`[features.multi_agent_v2]` with default `4`.
- Removed the `[agents] max_concurrent_threads_per_session` alias to
`agents.max_threads`.
- When MultiAgentV2 is enabled, reject `agents.max_threads` and derive
the existing internal subagent slot limit as
`max_concurrent_threads_per_session - 1`.
- Regenerated `core/config.schema.json` and added coverage for the new
config semantics.

## Result
```
➜  codex git:(jif/clean-multi-agent-v2-config) codex -c features.multi_agent_v2.enabled=true -c features.multi_agent_v2.max_concurrent_threads_per_session=3
╭────────────────────────────────────────────────────╮
│ >_ OpenAI Codex (v0.0.0)                           │
│                                                    │
│ model:     gpt-5.5 xhigh   fast   /model to change │
│ directory: ~/code/codex                            │
╰────────────────────────────────────────────────────╯

  Tip: Update Required - This version will no longer be supported starting May 8th. Please upgrade to the latest version (https://github.com/openai/codex/releases/latest) using your preferred package manager.

› Can you try to spawn 4 agents


• I’ll try to start four lightweight agents at once and report exactly what the runtime accepts.

• Spawned Russell [no-apps] (gpt-5.5 xhigh)
  └ Spawn probe 1: reply briefly that you started, then wait for further instructions. Do not do any repo work.

• Spawned Descartes [no-apps] (gpt-5.5 xhigh)
  └ Spawn probe 2: reply briefly that you started, then wait for further instructions. Do not do any repo work.

• Agent spawn failed
  └ Spawn probe 3: reply briefly that you started, then wait for further instructions. Do not do any repo work.

• Agent spawn failed
  └ Spawn probe 4: reply briefly that you started, then wait for further instructions. Do not do any repo work.

• The runtime accepted the first two and rejected the next two with agent thread limit reached. I’m checking whether the two accepted probes have returned cleanly, then I’ll close them if needed.
```

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-27 13:31:56 +02:00
Eric Traut bbff4ee61a Add safety check notification and error handling (#19055)
Adds a new app-server notification that fires when a user account has
been flagged for potential safety reasons.
2026-04-22 22:24:12 -07:00
Eric Traut 3b948d9dd8 Support prolite plan type (#17419)
Addresses #17353

Problem: Codex rate-limit fetching failed when the backend returned the
new `prolite` subscription plan type.

Solution: Add `prolite` to the backend/account/auth plan mappings, keep
unknown WHAM plan values decodable, and regenerate app-server plan
schemas.
2026-04-11 13:58:16 -07:00
Ahmed IbrahimandCodex 6fff9955f1 extract models manager and related ownership from core (#16508)
## Summary
- split `models-manager` out of `core` and add `ModelsManagerConfig`
plus `Config::to_models_manager_config()` so model metadata paths stop
depending on `core::Config`
- move login-owned/auth-owned code out of `core` into `codex-login`,
move model provider config into `codex-model-provider-info`, move API
bridge mapping into `codex-api`, move protocol-owned types/impls into
`codex-protocol`, and move response debug helpers into a dedicated
`response-debug-context` crate
- move feedback tag emission into `codex-feedback`, relocate tests to
the crates that now own the code, and keep broad temporary re-exports so
this PR avoids a giant import-only rewrite

## Major moves and decisions
- created `codex-models-manager` as the owner for model
cache/catalog/config/model info logic, including the new
`ModelsManagerConfig` struct
- created `codex-model-provider-info` as the owner for provider config
parsing/defaults and kept temporary `codex-login`/`codex-core`
re-exports for old import paths
- moved `api_bridge` error mapping + `CoreAuthProvider` into
`codex-api`, while `codex-login::api_bridge` temporarily re-exports
those symbols and keeps the `auth_provider_from_auth` wrapper
- moved `auth_env_telemetry` and `provider_auth` ownership to
`codex-login`
- moved `CodexErr` ownership to `codex-protocol::error`, plus
`StreamOutput`, `bytes_to_string_smart`, and network policy helpers to
protocol-owned modules
- created `codex-response-debug-context` for
`extract_response_debug_context`, `telemetry_transport_error_message`,
and related response-debug plumbing instead of leaving that behavior in
`core`
- moved `FeedbackRequestTags`, `emit_feedback_request_tags`, and
`emit_feedback_request_tags_with_auth_env` to `codex-feedback`
- deferred removal of temporary re-exports and the mechanical import
rewrites to a stacked follow-up PR so this PR stays reviewable

## Test moves
- moved auth refresh coverage from `core/tests/suite/auth_refresh.rs` to
`login/tests/suite/auth_refresh.rs`
- moved text encoding coverage from
`core/tests/suite/text_encoding_fix.rs` to
`protocol/src/exec_output_tests.rs`
- moved model info override coverage from
`core/tests/suite/model_info_overrides.rs` to
`models-manager/src/model_info_overrides_tests.rs`

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-02 23:00:02 -07:00