Commit Graph
314 Commits
Author SHA1 Message Date
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
chess 41f9084b30 Remove WebSocket headers and tool payloads from info logs (#48686)
Stop logging response headers on successful WebSocket connections and payload
previews for tool calls. Keep the connection URL, tool name, and thread ID in
their respective log entries.

GitOrigin-RevId: 1d410b6aef8f12153da9bfc60c515b8e797a9de0
2026-09-27 11:30:52 +00:00
pakrym-oai 12de0e395d Preserve WebSocket continuations when steering a turn (#48508)
## Why

Steering an active WebSocket response previously dropped the connection and
resent the full history. Draining the response preserves the connection and
allows the follow-up request to continue with `previous_response_id`.

## What changed

- Drain WebSocket responses when steering. For models using
  `use_responses_lite`, first send `response.interrupt` with
  `mode: "discard_partial_items"` once the response ID is available.
- Treat `response.incomplete` with reason `interrupted` as completion with
  `end_turn: false`, preserving token usage and allowing the turn to continue.
  Other incomplete reasons remain errors.

## Testing

Update the steering integration test to cover completed and discarded reasoning
items, asserting connection reuse, incremental follow-up input, and token usage
from the interrupted response.

GitOrigin-RevId: bc714b713e797cf1a67e3b26ffbf7664cb92eb33
2026-09-26 18:36:55 +00:00
Adam Perry @ OpenAI 10fd75bba7 Extract Responses failure parsing into a dedicated module (#48229)
## What changed

Move `response.failed` classification and rate-limit retry-delay parsing into `responses_error.rs`, preserving existing error mappings, fallback messages, and malformed-payload behavior. Replace the inline classification logic in the SSE event handler with `parse_failed_response`.

## Testing

Add regression coverage for missing or malformed failed-response payloads, including invalid values in unused error fields. Move the existing retry-delay parsing tests alongside the extracted parser.

GitOrigin-RevId: 6faa09b3fb312f1990509eef7088c8a086724615
2026-09-25 22:43:58 +00:00
Adam Perry @ OpenAI dd9a7101d9 Extract Responses header conversion into a shared module (#48200)
Move JSON-to-HTTP header conversion from `responses_websocket` into the
crate-wide `responses_headers` module and update the WebSocket code to use it.
Preserve conversion of string, number, and boolean values, while continuing to
ignore invalid header names and unsupported or invalid values.

GitOrigin-RevId: f179de214cf763549b5b8a898dc4bcda3ce07ebd
2026-09-25 20:12:54 +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
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
Krish Chainani 51d66fdd3b Support file references in image edit requests (#47956)
## Why

Editing recent conversation images failed when the selected images included a file reference from a message or tool output.

## What changed

Use `ImageReference` in `ImageEditRequest` to accept both `image_url` and `file_id` inputs. Pass file references from conversation history through to image edit requests while preserving image selection order.

## Testing

Update tests to cover file references from messages and tool outputs, and serialization of mixed inline and file references in image edit requests.

GitOrigin-RevId: 2764bf36a81a62ddd25cf9df27346a434a10c449
2026-09-24 22:48:10 +00:00
mtsui-oai 0037b39cc1 Retry file blob uploads on HTTP 502 and 504 (#47926)
## Why

File blob uploads previously failed immediately on HTTP 502 and 504 responses, even though these transient gateway errors can recover on retry.

## What changed

Treat HTTP 502 and 504 as retryable alongside 503, using the existing attempt limit, upload deadline, and server-provided retry delays.

## Testing

Expand upload retry tests to cover recovery from 502 and 504, mixed transient responses, exhausted attempts, and retry delays exceeding the remaining budget. Verify that 403, 409, and 500 responses are not retried, including responses without an Azure error code.

GitOrigin-RevId: a8e2f6bcf69338fb6d24f4c2d1ee333fb77bdbc0
2026-09-24 19:52:26 +00:00
Ahmed Ibrahim f5960fcc22 Reduce dependency coupling in shared configuration crates (#47713)
## What changed

- Move `Provider` and `RetryConfig` into `codex-client`, retaining re-exports from `codex-api`, and switch `codex-model-provider-info` to depend on `codex-client`.
- Move feature-state metric emission into `codex-core`, preserving its behavior while removing the `codex-features` dependency on `codex-otel`.
- Explicitly enable TLS features for `tonic` in `codex-config` and `reqwest` in `codex-http-client`.
- Enable `png`'s `zlib-rs` feature directly in `codex-utils-image` to keep encoded PNG bytes stable when WebSocket dependencies are absent.

GitOrigin-RevId: 91fd63ab01b55d516b3e80e3644d06af8d5a01f6
2026-09-24 01:50:36 +00:00
vkg-oai d838c2346d Allow idle threads to prewarm and repair WebSocket connections (#47701)
## Why

A previously used WebSocket can close while a thread is idle. Hosts need a way to prepare the connection before the next turn without repeating warmup on a healthy connection.

## What changed

- Expose `CodexThread::prewarm()` using the existing startup warmup and next-turn handoff.
- Reuse healthy connections and pending warmups, retry failed warmups, and repair closed connections. Treat a finished WebSocket reader task as a closed connection.
- Skip scheduling during an active turn or shutdown, and stop warmup admission before shutdown takes the pending task.
- Expose `active_turn_environment_selections()` so hosts can inspect the environments captured by the active turn, including those still starting or failed, when authorizing steering.

## Testing

Add regression coverage for repeated idle prewarm calls, healthy connection reuse with preserved response continuation, reconnection with `generate: false`, and warmup rejection after shutdown. Update delayed MCP discovery coverage to verify prewarm repairs an eagerly closed socket and the first turn reuses it.

GitOrigin-RevId: aa164b91a399de2375eda3bf28397725439fce93
2026-09-24 00:37:56 +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
Dylan Hurd ae132dc50a Serialize numeric custom reasoning effort as JSON numbers (#47590)
## What changed

Serialize custom reasoning effort values that parse as `u64` as JSON numbers in API requests. For example, `model_reasoning_effort = "64"` now sends `reasoning.effort` as `64`. Keep named values and custom values that cannot parse as `u64` as strings.

## Testing

Expand the request integration test to cover configured named effort, zero, a positive integer, an unknown name, a negative value, and an integer exceeding `u64`.

GitOrigin-RevId: 18ad03a1cd97dfa3f1a3cc49a43b3f7ca7d9b657
2026-09-23 17:02:51 +00:00
mtsui-oai 2c3295306f Retry transient OpenAI file blob upload failures (#47393)
## Why

A single blob upload failure previously aborted the file upload, even for a temporary `503` response or an interrupted stream.

## What changed

- Retry `503` responses and timeout, connection, body, or request errors, with at most five attempts within a shared five-minute deadline.
- Honor `x-ms-retry-after-ms` and `Retry-After`, falling back to backoff when no valid server delay is available.
- Reopen the contents for each retry while reusing the same file record and upload URL. Preserve the initial read permission check and reopen MCP file streams under the same sandbox policy.
- Record retry, recovery, and terminal failure events with a fresh client request ID for each attempt.

## Testing

Add coverage for recovery after `503` responses and interrupted streams, attempt and deadline limits, non-retryable responses, retry delay parsing, and unique request IDs. Extend the restricted-read MCP upload test to verify that both attempts send the complete file contents.

GitOrigin-RevId: 78089ecfd5076313f5784cbbc864df12d082e3b1
2026-09-22 23:56:23 +00:00
acrognale-oai 888e02db34 Enforce network policy throughout HTTP and WebSocket requests (#47389)
## Why

Destination restrictions and policy revocation must remain effective during redirects, response body reads, and established WebSocket traffic. Policy denials must also survive error handling so callers do not retry them or report a revoked operation as successful.

## What changed

- Route managed HTTP clients through a shared `RequestBuilder` and policy-aware execution, checking each redirect destination before route resolution and retaining a network permit while consuming response bodies.
- Guard WebSocket connection setup, reads, and writes with revocable permits, including independent wakeups for split readers and writers.
- Preserve `TransportError::Policy` through HTTP, SSE, and realtime error handling, and treat policy denials as non-retryable.
- Keep the supplied network policy in plugin startup HTTP requests and propagate response body failures from backend and plugin requests.

## Testing

Add regression coverage for rejection before connecting, revocation during redirect routing and streamed body reads, split WebSocket revocation, realtime writer error propagation, and revoked plugin upload responses.

GitOrigin-RevId: fba36700444c98a8364c09b4dc5452c4d78a90fb
2026-09-22 23:37:39 +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
Chris Dong 6cfe299849 Preserve image generation request IDs on failure (#47327)
## Why

Failed image requests discarded the `x-codex-imagegen-request-id` header, leaving failure analytics without the request ID.

## What changed

Carry the request ID through `ImageRequestError` and backend errors for image generation and editing. Preserve it on failed image generation items for HTTP errors, response decoding errors, and responses with no image data.

## Testing

Extend the app-server failure test to verify that a request ID returned with an HTTP 500 response reaches `codex_image_generation_event` analytics.

GitOrigin-RevId: 57cddacc0221e5b58877ac375d5eca0afb99d853
2026-09-22 17:37:45 +00:00
Celia Chen 6ea62c4396 Resolve proxy routes for standalone web search redirects (#47204)
## Why

Standalone web search selected a proxy route only for the initial endpoint. Redirect destinations can require a different system proxy route.

## What changed

- Add `RouteAwareClientPool` support to `ReqwestTransport` for both buffered and streaming requests, and use it for standalone web search.
- Preserve default Codex headers and Cloudflare cookie handling across routes, while retaining the default client behavior when route-aware handling is disabled or Codex is sandboxed.
- Share request construction so URL authentication and header precedence follow `reqwest` semantics, applying them once before redirects and TLS retries.
- Map route-aware failures to transport errors and remove request URLs from those errors.

## Testing

Add regression coverage for redirects through distinct proxies, preservation of POST bodies and default headers, URL authentication and header precedence, and transport error classification without URL leakage.

GitOrigin-RevId: 19a10a62118846db09dd95265dc277e54aac09ef
2026-09-22 06:24:49 +00:00
Celia Chen b045757052 Honor system proxy settings for standalone web search (#47142)
## Why

Standalone web search used a default HTTP client, bypassing the configured system proxy route when `respect_system_proxy` was enabled.

## What changed

Pass the configured `HttpClientFactory` to the web search tool and create its client asynchronously for the provider's search URL using the API route policy. Export and reuse `SEARCH_ENDPOINT` so route selection and search requests use the same endpoint.

## Testing

Add an isolated regression test with environment proxies removed and a mock system proxy. Verify that standalone web search reaches the proxy and returns its result in the follow-up model request.

GitOrigin-RevId: 3b64803a777b9d1eb0ccf694e06658b0fd562129
2026-09-22 00:59:54 +00:00
Andrew Wilkes 171dd0d39c Increase OpenAI file blob upload timeout from 60 seconds to 5 minutes (#47122)
GitOrigin-RevId: 11069394b3cfe24af4d5efb709ee4f65b88c90de
2026-09-21 23:00:40 +00:00
Celia Chen 142360dac8 Honor configured proxies for realtime WebSocket connections (#47101)
## Why

Realtime WebSockets connected directly, bypassing the configured proxy policy for Voice's WebRTC sideband.

## What changed

Pass the configured `HttpClientFactory` into `RealtimeWebsocketClient` and connect through the shared `WebSocketConnector`. Add support for supplying an existing Rustls configuration to preserve custom CA handling and Windows platform trust.

## Testing

Add an integration test that enables `respect_system_proxy`, starts a WebRTC conversation, and verifies that the sideband establishes its session through an HTTP `CONNECT` proxy and closes successfully.

GitOrigin-RevId: d974c9275d7fe29f388d56a9d5d8ce0c483eb8d0
2026-09-21 20:05:21 +00:00
Eric Traut d1e3f9dfe3 Fix realtime V3 transcript reconciliation for handoffs (#46922)
## Why

Interleaved speaker transcripts can fragment handoff context, and delayed final transcripts can overwrite newer speech.

## What changed

- Reconcile V3 transcript deltas and finals with the latest entry for the same speaker.
- Replace accumulated text only when the final transcript extends it, preserving newer speech when a final arrives late.
- Start a new entry after each completed utterance, keeping repeated speech and final-only turns distinct even when empty deltas arrive.
- Preserve live transcript notifications and legacy protocol behavior.

## Testing

Add unit coverage for interleaved speakers across reconnects, either completion order, repeated utterances, final-only turns, and empty deltas. Add app-server integration coverage for expanded and delayed finals, checking live notifications and reconciled handoff context.

GitOrigin-RevId: 961729281f61b95fd3e0c5cc3ec72512987980b3
2026-09-21 02:02:41 +00:00
andrewgu-oai 888be42a20 Support explicit provider model catalog URLs (#46561)
## Why

Providers need to serve Codex model metadata independently of their inference endpoint. A custom inference `base_url` alone should not opt API-key sessions into remote catalog discovery.

## What changed

- Add `model_catalog_url` to provider configuration and thread-config serialization. Fetch the full catalog URL with provider authentication, headers, query parameters, and `client_version`, while preserving inference routing.
- Require an explicit catalog URL for API-key discovery with a custom base URL. Keep default OpenAI discovery on the Codex backend, and apply `api_key_model_discovery` gating to provider API keys and cached catalogs.
- Include the catalog URL in cache identity so different catalogs do not share cached metadata.
- Limit explicitly configured catalog responses to 1 MiB, reject redirects, and suppress URL and response diagnostics that could expose credentials.

## Testing

Add coverage for catalog configuration round-trips, query encoding, authentication and header reuse, cache identity and discovery gating, oversized responses, and redirect rejection without credential forwarding. Add an integration test verifying that catalog model metadata and instructions reach conversation requests.

GitOrigin-RevId: 7f6ac5eec257278685e1867a6bcebae6514a365a
2026-09-19 01:36:53 +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
felixxia-oai 78d4d983d3 Gate reasoning effort updates on explicit model support (#46530)
## Why

Using Responses Lite does not establish whether a model accepts reasoning-effort `configuration_update` items. Unsupported models need to use the selected request-level effort, including when resuming history containing saved updates.

## What changed

- Add `supports_reasoning_effort_updates` model metadata, defaulting to `false`.
- Require the override feature, an OpenAI provider, and explicit model support for reasoning effort updates, independently of `use_responses_lite`.
- Filter saved configuration updates from unsupported requests without changing persisted history.
- Clear the pinned effort baseline when sampling with an unsupported model so returning to a supported model establishes a fresh baseline. Compaction uses the selected effort without clearing the pin.

## Testing

Add coverage for supported models with either Responses mode, unsupported-model history filtering over HTTP and WebSocket, switching to an unsupported model and back, and compaction versus sampling pin behavior. Verify missing capability metadata defaults to `false`.

GitOrigin-RevId: 8a0fbc141964bd854dbcdd6f31e1c8e97697cf22
2026-09-19 00:18:56 +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
jif 977193486d Bound model catalog decode errors and classify request timeouts (#45928)
## Why

Model catalog decode errors can include the full response body and payload values from deserialization errors. Catalog request deadlines also report a generic timeout instead of a request timeout.

## What changed

- Report only the JSON error category, line, column, and response byte count when model catalog decoding fails.
- Return `CodexErr::RequestTimeout` when the model catalog refresh deadline expires.

## Testing

Add regression tests for invalid response shapes, large payload values, malformed and truncated JSON, and a delayed catalog response that must return `RequestTimeout`.

GitOrigin-RevId: 6fe5111a3e3b113d79942b3c213f8e94d773eb5a
2026-09-16 11:46:37 +00:00
sergio-oai ced02c5c38 Add opt-in response body limits to the HTTP transport (#45822)
## Why

HTTP callers currently cannot bound response bodies. Callers accepting provider-controlled model catalogs need a size limit before decoding the response.

## What changed

- Add per-request `response_body_limit_bytes` for buffered, streaming, and error responses, leaving requests unbounded by default. Reject oversized declared lengths early and count observed bytes across chunks.
- Return a non-retryable `ResponseTooLarge` error that reports only the byte limit. Preserve HTTP status and headers when a bounded error body fails to read without exceeding the limit.
- Expose `ModelsClient::list_models_raw` to fetch bytes and an optional ETag using provider authentication and retries, with an optional body limit. Keep existing `list_models` decoding behavior.

## Testing

Add HTTP fixture tests covering size boundaries, chunked and missing-length responses, early rejection, stream termination, interrupted bodies, error text decoding, and request isolation. Add a models-client test verifying that limits survive authentication retries without affecting subsequent ordinary requests.

GitOrigin-RevId: 61b8940bc8a549588cee6865a3b5d1cff789074d
2026-09-16 01:01:57 +00:00
jif eeded5ba1a Route Guardian requests through /responses with identifying headers (#45736)
## What changed

- Replace dedicated Guardian endpoints with `/responses`, sending `x-codex-guardian: reviewer` or `x-codex-guardian: classifier` for eligible Codex backend requests over HTTP and WebSocket.
- Add model-scoped thread headers, recheck backend authentication on each request attempt, and reconnect WebSockets when the applicable headers change.
- Retain `features.guardianv2.free_guardian` for configuration compatibility while removing its routing gate; the backend now controls Guardian billing.

## Testing

Update tests for reviewer and classifier headers, model and authentication scoping, HTTP fallback, WebSocket reuse, and parent-response metadata across retries.

GitOrigin-RevId: 1c2b3c458ab77fb40aae4ee6784f6d827c60e76c
2026-09-15 17:09:11 +00:00
Steve Coffey 31ffe2bc9a Fix retry classification for throttling and quota errors (#45602)
## Why

`slow_down` errors were treated as terminal server overloads, while exhausted credit balances and spend limits fell through to retryable stream errors.

## What changed

- Classify `slow_down` as a retryable rate limit in HTTP 503 responses and SSE failures, preserving the server message and parsing retry delays from SSE error messages.
- Map `credit_balance_exhausted`, `organization_spend_limit_exceeded`, and `project_spend_limit_exceeded` SSE errors to quota exhaustion so they terminate without retries.

## Testing

Extend tests to cover HTTP error classification and retryability, `slow_down` stream retry exhaustion and message-provided delays, and a single `UsageLimitExceeded` error with no retries for each quota error code.

GitOrigin-RevId: 7985eba71ba4a6fe897a45957e448fadd42f3963
2026-09-15 04:20:38 +00:00
Krish Chainani 5a66d460d3 Refactor image content to use a shared ImageReference type (#45543)
## What changed

Represent images in `ContentItem` and `FunctionCallOutputContentItem` with `ImageReference::Inline`, flattened to preserve the existing `image_url` wire format. Update image producers and consumers and regenerate app-server schemas and SDK artifacts.

Preserve the Python SDK's `InputImageContentItem` and `InputImageFunctionCallOutputContentItem` class names during generation.

## Testing

Add a regression test for stable Python image class names and adapt existing image tests to the shared representation.

GitOrigin-RevId: c38a780ac3314c2ac2deb3afc1b93b94b6f93fec
2026-09-14 23:25:09 +00:00
jif b6a5d5bb14 Preserve Guardian parent response IDs across sampling requests (#45441)
## Why

Running code-mode cells can request Guardian review while the next response is in flight. Clearing the response ID before that response emits `response.created` leaves those reviews without a `parent_response_id`.

## What changed

Keep the latest response ID received in the turn until a later `response.created` replaces it, including across sampling retries.

## Testing

Add regression coverage for reviews before and after a response handoff and for a fresh turn that must not inherit the previous turn's ID. Update retry coverage to expect the last known parent when the retry supplies no response ID.

GitOrigin-RevId: af0a08de09edad59e1a7ade7904a42d616b05679
2026-09-14 15:13:13 +00:00
Benjamin Carlsson ce7fbb373b Bundle native voice runtimes in Windows releases (#44922)
## Why

Windows release packages need the voice helper and native audio libraries. Realtime TLS connections on fresh Windows installations also need platform certificate validation so Windows can retrieve missing trusted roots on demand.

## What changed

- Build and sign the voice helper and audio DLLs for Windows x64 and ARM64, bundle a pinned Microsoft CRT DLL, and verify signatures and runtime receipts before packaging.
- Add verified, pinned Cygwin and native build tools plus MSVC linker, compiler, and path handling fixes for the Windows Bazel builds.
- Include voice resources in primary release archives and WinGet packages. Preserve WinGet executable names, update manifest hashes, and recognize the package root through matching entrypoint metadata. Keep Python runtime wheels voice-free to preserve their existing Windows support floor.
- Use Windows platform TLS validation for realtime WebSockets when no custom CA bundle is configured, preserving custom CA behavior.

## Testing

Add coverage for build-input integrity and unsafe paths, signed Windows runtime assembly, WinGet file and hash preservation, package discovery, and TLS trust selection, untrusted certificate rejection, and hostname validation.

GitOrigin-RevId: 423da35872fa5549d69fd4ca97d922bb49599386
2026-09-11 21:59:24 +00:00
faizan-oai e3a52b87b2 Expose available access programs in model discovery (#44893)
## What changed

Carry optional `available_access_programs` metadata through model information, presets, caches, and the TUI, and expose it as `availableAccessPrograms` in app-server `model/list` responses. Update the generated JSON schemas, TypeScript types, and Python models.

Preserve the distinction between missing metadata and an empty `cyber` list. Ignore unknown cyber program names when reading the catalog so new server programs do not prevent older clients from loading it. Discovery metadata does not grant access; inference still enforces authorization.

## Testing

Add coverage for absent, null, empty, and populated metadata, unknown program names, and app-server serialization. Extend cache tests and verify that online refreshes persist changed access metadata even when the catalog ETag stays unchanged.

GitOrigin-RevId: b3ef5805c1c61b8d64b9b896c9c0a79120143667
2026-09-11 19:13:04 +00:00
jif 102fc57e4a Distinguish HTTP quota errors from rate limits (#44492)
## Why

HTTP 429 responses for exhausted quota, credit balances, and spending or usage limits were reported as retry-limit failures instead of usage-limit errors.

## What changed

Parse the API error's `code` and map `insufficient_quota`, `credit_balance_exhausted`, `organization_spend_limit_exceeded`, `project_spend_limit_exceeded`, and `organization_usage_limit_exceeded` to `CodexErr::QuotaExceeded`. Also recognize `insufficient_quota` in the error's `type` field.

## Testing

Add a regression test covering all recognized quota errors and verifying that `rate_limit_exceeded` and `slow_down` HTTP 429 errors retain their existing retry-limit mapping.

GitOrigin-RevId: b075dba199e08d29563630f5ada846e3e7fd11ff
2026-09-10 10:31:15 +00:00
rka-oai 1ac689cc7d Remove the unused legacy remote compaction implementation (#44273)
## Why

Remote compaction already uses the normal Responses API, leaving the legacy `/responses/compact` runner unused.

## What changed

- Remove the legacy runner, endpoint client, request types, analytics variant, and obsolete test helpers and snapshots.
- Move tool-output trimming and its metadata tests into `compact_remote_history` for reuse by remote compaction v2.
- Consolidate retained-history filtering in the v2 implementation and remove redundant `RemoteCompactionV2` settings from tests.

## Testing

Extend the retained-history unit test to explicitly check that hook prompts survive compaction.

GitOrigin-RevId: 999bb1391aa22c3c281d6a96f98817d6c9e46ed9
2026-09-09 18:40:53 +00:00
Chris Dong 929389f596 Preserve per-image generation IDs in image generation analytics (#43953)
## What changed

Parse optional `generation_id` values from image API responses and carry the selected image's ID through the image generation tool into analytics events. Keep the ID out of serialized extension items, JSON schemas, and TypeScript types. Responses without an ID remain supported.

## Testing

Add coverage for distinct IDs in multi-image responses and responses without IDs. Extend analytics and app-server tests to verify that the selected image's ID reaches analytics, and item tests to verify that it is omitted from serialization and TypeScript types.

GitOrigin-RevId: 70a600856990140b76fdbda51a0d73b3414338b1
2026-09-09 00:34:45 +00:00
jif 7769bccbb2 Avoid WebSocket connection waits in Guardian v2 classification (#43408)
## Why

When no healthy pooled WebSocket is available, classification waits for a new connection to open and can stall on its handshake.

## What changed

- Use HTTP streaming when no healthy idle WebSocket is ready, and replenish the pool in the background with a five-minute cooldown after connection timeouts.
- Share concurrency limits and the sampling retry budget across both transports, and bound the wait for HTTP response headers.
- Cancel superseded requests while awaiting response headers and stop SSE polling when the consumer closes.

## Testing

Add coverage for HTTP fallback and recovery after cooldown, shared transport capacity, stalled response headers, and cancellation before headers or during body draining. Update sampler and extension tests to cover fallback after socket expiry, authentication changes, and transient failures.

GitOrigin-RevId: 0b23ccc1bfb2dfdbc8d2791d097706cd4dd44f39
2026-09-07 09:24:03 +00:00
pmccrary-oai 6af345407d Gate experimental context by model capability at session startup (#43147)
## Why

Experimental context activation previously checked the provider and account eligibility without checking model support. Child sessions also inherited token-budget activation from their parent, even when starting fresh with a different model.

## What changed

- Add `ModelInfo.supports_experimental_context`, defaulting to `false`, and enable it for the bundled `gpt-6-astra` model. Require this capability when activating experimental context.
- Snapshot configured token-budget preferences before startup activation. Restore them for fresh child sessions before applying their starting model's defaults, while history forks retain their parent's activation.
- Pass unresolved token-budget preferences to child sessions so they can use their own model's prompts.

## Testing

Extend coverage for unsupported models, model-switch guidance under explicit and experimental activation, and child configuration from both active and inactive parents. Verify that omitted capability metadata defaults to `false`.

GitOrigin-RevId: 02df9e171682267232fa923d5ea3f7af36527808
2026-09-06 02:28:38 +00:00
jif dee21ec1bc Replace Guardian tickets with parent response IDs (#43002)
## What changed

Capture the ID from `response.created` and pass it as `parent_response_id` in Guardian review and classifier request metadata. Clear the current response ID before sampling retries so tool reviews cannot inherit a failed response's ID.

Request Guardian credits with `guardian_credits_requested` on eligible parent requests. Remove the ticket protocol, transport attachment, and ticket-specific body redaction. Keep ordinary app-server client `parent_response_id` values inside `x-codex-turn-metadata` rather than promoting them to Guardian request metadata.

## Testing

Update coverage for HTTP fallback, WebSocket review reuse, missing response IDs, classifier transport retries, and code-mode yield/resume attribution. Extend app-server tests to verify client metadata placement over HTTP and WebSocket.

GitOrigin-RevId: c1665e56382ecec8d260fc2ca0ecd5e20b0b2391
2026-09-05 13:02:49 +00:00
jif cc4b8bdeb8 Propagate response tickets to Guardian reviews (#42758)
## What changed

- Request and parse server-issued Guardian tickets for eligible Codex backend responses.
- Scope each ticket to the response that produced a Guardian review or classifier request, including HTTP and WebSocket retries, without adding it to model-visible or persisted context.
- Validate ticket shape, reserve its metadata keys, redact it from debug and request-body logging, and attach it only at the Guardian transport boundary.

## Testing

- Cover ticket parsing, endpoint and authentication routing, retry scoping, classifier retries, and redaction for compressed and uncompressed requests.

GitOrigin-RevId: 6219dd15c9f19ed3387de516aac1b8e7c9cdb0e3
2026-09-04 12:56:26 +00:00
jif 4e48cd02da Honor model-provided Guardian review policies (#42744)
## What changed

- Add optional per-model Guardian modes for computer use, shell, code mode,
  file changes, MCP, network, and permission requests.
- Apply disabled, synchronous, or adaptive review by action category while
  preserving legacy configuration when model policy is absent.
- Bind cached risk scores to the active model policy, thread settings, and
  environment selections so outdated scores cannot approve later actions.
- Keep unknown review modes on the synchronous path and ignore unknown policy
  fields for forward compatibility.

## Testing

- Cover policy serialization, legacy fallback, scoped tool classification,
  disabled categories, and score invalidation after policy changes.

GitOrigin-RevId: f334a5f4fffb198da66cde3a400233e0df650516
2026-09-04 11:59:18 +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
sayan-oai e017e93ace Preserve raw response usage metadata (#41980)
## What changed

- Include the complete upstream `response.usage` object in
  `ResponseUsageMetadata.metadata` while retaining the existing `amount` field.
- Expose the metadata through `rawResponse/completed` notifications and update
  the generated JSON and TypeScript schemas.

## Testing

- Cover SSE, WebSocket, turn, and compaction completion paths.

GitOrigin-RevId: 6d79b1b4c92ac11abf43ec98f380b4868288a701
2026-09-01 05:17:11 +00:00
guinness-oai 64c9cde458 Record realtime conversation history in Core (#41924)
## Why

Realtime history should be recorded consistently for every Core host, including
when no app-server event listener is attached.

## What changed

- Move transcript segmentation, session boundaries, and backing-agent artifact
  promotion into Core for paginated threads.
- Persist canonical realtime items through the thread store in event order and
  emit dedicated history lifecycle events for hosts to present.
- Translate those Core events into the existing app-server realtime item
  notifications without app-server persisting the items a second time.

## Testing

- Cover Core-only persistence across repeated sessions, ephemeral sessions,
  accepted and rejected steering, typed input ordering, and artifact promotion.
- Verify app-server notifications correspond to the persisted timeline.

GitOrigin-RevId: 7cbef14129d77f6d6d7099b733be91f5279c55f5
2026-08-31 22:38:23 +00:00
Shijie Rao 7f135e1314 Make Ultra reasoning fallback model-aware (#41206)
## What changed

- Add an optional `multi_agent_reasoning_effort` field to model metadata.
- When `Ultra` is selected, use a supported catalog override when present. Otherwise, prefer `max`, then the highest supported non-`ultra` effort, and finally `medium` when the model has no reasoning levels.
- Preserve existing request behavior for other reasoning efforts, including mapping `persistent` to `disabled`.

## Testing

- Cover configured, missing, unsupported, and empty-catalog fallbacks for both parent and spawned-agent requests.

GitOrigin-RevId: b7ef576f32e0ea95ef38bf95c25789ed16aae94e
2026-08-27 21:03:09 +00:00
Dylan Hurd 2c4a95736b Expose response usage metadata in completion events (#41087)
## What changed

- Parse optional `usage_metadata.amount` values from Responses API completion events without converting their string representation.
- Propagate the metadata through SSE and WebSocket streams, regular turns, and remote compaction.
- Add `usageMetadata` to the app-server `rawResponse/completed` notification and its generated schemas.

## Testing

- Cover missing, null, zero, and high-precision amounts, including completion events emitted during compaction.

GitOrigin-RevId: b16d81e8350eab0dc7ff613d0dc9dbed73041713
2026-08-27 07:50:05 +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
jif bde9db1375 Record actual Responses endpoints in tracing spans (#40906)
## Why

Responses-compatible requests can use routes other than `/responses`, but their
tracing spans reported the default route regardless of the selected endpoint.

## What changed

- Populate `api.path` from the selected `ResponsesEndpoint` for HTTP and
  WebSocket requests.
- Retain the endpoint on WebSocket connections so stream-request spans report
  the same route as connection spans.

GitOrigin-RevId: 349eca94b27d4cc3a1adde8b257313506bdaf0f4
2026-08-26 15:31:30 +00:00