Commit Graph
95 Commits
Author SHA1 Message Date
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
Zahan Malkani 34c4f7e72d Allow per-call sideband endpoints for existing realtime calls (#41923)
## What changed

- Add an in-process `sideband_base_url` override to `ConversationStartTransport::ExistingCall`, while keeping app-server requests on the configured or default endpoint.
- Prefer the per-call endpoint when attaching and reconnecting a sideband, falling back to `experimental_realtime_ws_base_url` when no override is supplied.
- Preserve runtime authentication headers on the selected endpoint without adding bearer authorization.

## Testing

- Cover configured and per-call endpoint selection, authentication headers, call-specific handshake paths, and reconnect behavior.

GitOrigin-RevId: 16c439fe0a9ff8bcdda4ec615bb9983e30935052
2026-08-31 22:29:40 +00:00
guinness-oai 18b9e7fd9e Include thread source in realtime connection metadata (#41250)
## Why

Realtime voice calls can span zero or many backing turns, so they need the
saved thread source to identify their origin consistently.

## What changed

- Add `thread_source` to `x-codex-turn-metadata` when starting realtime
  WebSocket, existing-call, and WebRTC transports.
- Encode the metadata as header-safe ASCII and omit absent, invalid, or
  larger-than-256-byte source values.

## Testing

- Cover source propagation, escaping, and size limits across realtime
  transports, including child threads that share a parent session.

GitOrigin-RevId: b5a9eef8dfdbb83387bd0e364a4922b15030f4d6
2026-08-28 02:39:47 +00:00
pakrym-oai 538900ee76 Add turn trigger metadata (#40665)
## What changed

- Add an optional `turnTrigger` field to app-server `turn/start` requests and
  expose it in the generated protocol schemas.
- Propagate non-empty trigger values to Responses request metadata as the
  reserved `turn_trigger` field, while preserving the original value when a
  request steers an active turn.
- Classify turns started by queue dispatch, goal continuation, retry recovery,
  and realtime handoff.

## Testing

- Cover HTTP and WebSocket metadata forwarding, steering behavior, reserved
  metadata handling, and the built-in trigger classifications.

GitOrigin-RevId: c12fe2c522286db21b76081ae6154fbf6bfb3639
2026-08-25 18:11:04 +00:00
Eric Traut 068c49f075 Update the frameless realtime default model (#40321)
## What changed

- Use `gpt-live-1-codex` as the default model for frameless realtime sessions.
- Preserve an explicitly supplied per-session model override.

## Testing

- Cover both default and explicit model selection in the WebRTC frameless conversation test.
- Update the app-server live session request expectation for the new default.

GitOrigin-RevId: ce5dc978911ff0289d677b60fae2dd8cb1058d22
2026-08-24 03:34:15 +00:00
Zahan Malkani 536f86e5cc Support attaching to existing realtime calls (#39876)
## Why

Clients that create and negotiate realtime calls themselves need Codex to join
those calls without creating another call or overwriting the client-owned
session configuration.

## What changed

- Add the `existingCall` transport to `thread/realtime/start`, accepting a
  client-provided `callId` and optional `realtimeSessionId`.
- Attach Codex over the call's sideband WebSocket without SDP negotiation or a
  session update, and reconnect that sideband while preserving transcript
  state.
- Default existing calls to realtime v1, support v1 and v3, and reject v2 or
  options that would reconfigure the client-owned session.
- Encode call IDs as a single URL path segment for v3 sideband connections.

## Testing

Add protocol, app-server, core, reconnection, authentication-header, and URL
encoding coverage for existing-call attachments.

GitOrigin-RevId: 2046b70566f98efa55381bb1e461ea3cc68256c5
2026-08-21 06:41:28 +00:00
Peter Bakkum ecb8013dfa Reconnect WebRTC Realtime sideband transports (#39257)
## What changed

- Reconnect frameless bidirectional WebRTC sideband sockets after unexpected transport loss with capped exponential backoff.
- Preserve pending text or handoff output and bounded transcript state across reconnects.
- Treat `404 Not Found` and `410 Gone` handshake responses as terminal session completion, and preserve HTTP status information from failed WebSocket handshakes.
- Bound Realtime delegation input and transcript fields while retaining the most relevant portion of each.

## Testing

- Add unit coverage for reconnect backoff, terminal status handling, transport error classification, transcript continuity and truncation, and pending outbound messages.
- Add an end-to-end WebRTC conversation test covering an unclean disconnect, reconnect, transcript reconciliation, outbound progress during sustained inbound traffic, and terminal session completion.

GitOrigin-RevId: 544fd7e542c3434d0bb42cfbcc7143604419a037
2026-08-18 18:41:40 +00:00
Owen Lin cbb7e82a8b Unify turn input submission and routing (#38275)
## What changed

- Add `TurnInputRequest` and typed submission results for atomically starting a turn, steering the active turn, or declining input with a specific reason.
- Expose `start_or_steer_turn`, `start_turn_if_idle`, and `steer_turn` on `CodexThread`, and migrate Core consumers to these APIs.
- Make app-server `turn/start` steer an active regular turn and return that turn's ID. Reject incompatible output schemas and non-steerable turns without applying settings or enqueueing input.

## Testing

- Cover concurrent start-or-steer submissions, accepted and rejected settings updates, output-schema compatibility, idle-start rejection, and app-server steering.

GitOrigin-RevId: dd9b5528d76ec650c019e97af420bc13190ea86a
2026-08-13 00:00:16 +00:00
rka-oai 3a6f747d77 Preserve harness metadata across conversation history (#38058)
## What changed

- Wrap response items with optional harness-owned metadata while keeping the persisted response payload shape backward compatible.
- Store compacted-history metadata in an aligned sidecar and reject malformed sidecars.
- Carry metadata through history normalization, compaction, resume, fork, truncation, migration, and rollout recording without sending it to model providers.

## Testing

- Cover legacy rollout compatibility, metadata serialization and validation, compaction retention, and resume/fork reconstruction.

GitOrigin-RevId: 17a6127c9048ff984cb4df4d97c0751a38c29f5f
2026-08-11 19:30:12 +00:00
Adam Perry @ OpenAI 63002bdb26 Extract persisted history types into a dedicated crate (#37871)
## What changed

- Add `codex-history` for model-history and persisted-rollout domain types, including `RolloutItem`, `RolloutLine`, `CompactedItem`, and initial/resumed history state.
- Re-export the persisted types from `codex-rollout` and update consumers to use the new crate boundary instead of `codex-protocol`.
- Preserve existing rollout serialization, including legacy numeric compacted-window IDs.

## Testing

- Add `codex-history` tests for rollout JSON round trips, compacted-history compatibility, persisted history modes, and multi-agent version selection.

GitOrigin-RevId: 944daa9297ddd231d3aebbdcb05fff4adf8b4e1b
2026-08-10 19:26:52 +00:00
Martin Au-Yeung ee46c5ba0e Negotiate MCP extensions per app-server session (#36910)
## Why

App-server clients need to advertise structured MCP extension settings, including supported MCP App UI MIME types, rather than only opting into OpenAI form elicitation with a boolean.

## What changed

- Add an `extensions` map to initialize capabilities and preserve `mcpServerOpenaiFormElicitation` as a legacy alias for `openai/form`.
- Capture the declared extension profile when a thread is started, resumed, or forked, propagate it to subagents, and advertise it to downstream MCP servers during initialization.
- Keep the profile stable for the lifetime of the loaded session instead of changing it on later turns or direct tool calls.

## Testing

- Cover extension conversion, downstream MCP initialization, session isolation, legacy form support, and subagent inheritance.

GitOrigin-RevId: fbcedbb74ce788e574b0f884a4c45c4cedb9de54
2026-08-04 15:23:43 +00:00
jiayuhuang-openai 6751b54cae Add a realtime delegation acknowledgement control (#36413)
## What changed

- Add the optional `delegationAckFiller` field to `thread/realtime/start`.
- Forward explicit `true` or `false` values to V3 Frameless Bidi session payloads as `delegation.ack_filler`; leave the field absent when unspecified so the Realtime API default is preserved.
- Document that V1 and V2 ignore this setting.

## Testing

- Cover both boolean values in Frameless Bidi serialization and verify the WebRTC V3 session creation payload.

GitOrigin-RevId: 9fe8efd14e42738c3e86e3e9a8af81d0f4521244
2026-08-01 01:17:26 +00:00
guinness-oai 670f69416b Allow custom Codex instructions for realtime transitions (#36408)
## What changed

- Add optional `realtimeStartInstructions` and `realtimeEndInstructions` fields to `thread/realtime/start`.
- Apply the instructions when Codex enters and leaves realtime mode, while preserving the existing defaults when either field is omitted.
- Limit each field to 8,192 estimated tokens.

## Testing

- Cover custom entry and exit instructions across realtime state transitions.
- Cover token-limit validation for both fields.

GitOrigin-RevId: b9cfa1ff22e084d8a6b2ed56bd27d95ffdd6b6bd
2026-07-31 23:51:33 +00:00
jif 856bf5a33a Make pending realtime sideband test deterministic (#36166)
## What changed

- Replace fixed delays with explicit signals that pause the sideband connection after its HTTP handshake request begins.
- Release the handshake after closing the realtime conversation and verify that the connection ends before the handshake completes.
- Shut down the test session while rejecting stale realtime errors or duplicate close events from the canceled sideband task.

GitOrigin-RevId: 37072842b973fff41ec47235ceb9cfe3cf1a5a37
2026-07-30 14:20:21 +00:00
jiayuhuang-openai 4ebd976312 Support configurable realtime BEM channel prefixes (#34816)
## What changed

- Route realtime V3 `bemTags` handoffs using `[ANALYSIS]`, `[COMMENTARY]`, and `[FINAL]` prefixes by default.
- Add `codexResponseHandoffChannelPrefixes` to realtime start requests so clients can replace the accepted prefixes for individual channels. Each channel may accept multiple prefixes, and omitted channels retain their defaults.
- Apply the configured prefixes to both complete and streamed handoff messages, without treating empty prefixes as matches.

## Testing

- Cover request deserialization, default and custom routing, partial streamed prefixes, empty-prefix handling, and end-to-end V3 handoffs.

GitOrigin-RevId: d0aef50aa71362a5beef2c6f6d28b8633da4e529
2026-07-22 19:43:35 +00:00
Peter Bakkum 963cda85aa Add session headers to realtime conversation starts (#34681)
## What changed

- Include the Codex `session-id` and `thread-id` headers when starting realtime conversations over WebSocket or WebRTC.
- Add coverage confirming that WebRTC call creation forwards both identifiers while preserving the existing realtime request metadata and SDP payload.

GitOrigin-RevId: 668bee9a7d4797ad0a396e9ca4dc56b2c379cba7
2026-07-22 04:54:54 +00:00
jiayuhuang-openai 312caf176a Seed realtime V3 sessions with initial text items (#34067)
## What changed

- Add an optional `initialItems` field to `thread/realtime/start` for seeding
  realtime V3 session history with `user`, `developer`, and `assistant` text.
- Encode the items in Frameless Bidi session bootstrap payloads for websocket
  and WebRTC transports while preserving existing payloads when the list is
  omitted or empty.
- Reject non-empty initial items for V1 and V2, more than 128 items, any item
  over 8,192 estimated tokens, or a combined total over 8,192 estimated tokens.

## Testing

- Cover protocol serialization, app-server forwarding, websocket and WebRTC
  payloads, empty-list compatibility, version checks, and size limits.

GitOrigin-RevId: 09af367f9a07543e3f8d59b7fa5387f932dc5a6a
2026-07-18 20:59:57 +00:00
jiayuhuang-openai 025db22058 Route realtime V3 handoffs by response channel (#33903)
## What changed

- Add `codexResponseHandoffMode` to `thread/realtime/start` for V3 sessions, with `thinking` as the default and `commentary` and `bemTags` routing modes.
- Map BEM `analysis` and `commentary` output to the commentary channel and `final` output to the speakable channel, while preserving the original BEM envelope. Unrecognized output falls back to speakable.
- Mark explicit speech appends as speakable and stop adding the legacy `"Agent Final Message"` prefix to V3 handoffs. V1 and V2 continue to ignore the new setting.

## Testing

- Cover channel selection for every routing mode, streamed BEM header parsing, fallback behavior, explicit speech, and V1 compatibility.

GitOrigin-RevId: 1974578257488f2914b252c9c1990ba38831c96b
2026-07-17 21:12:40 +00:00
jiayuhuang-openai b03545b5b8 Stream realtime V3 Codex handoff output (#33856)
## What changed

- Stream V3 agent message deltas to `delegation.context.append` at 200 ms intervals instead of waiting for each completed message.
- Send commentary without a prefix and label final or phase-less V1/V3 output with `"Agent Final Message":`.
- Bound streamed output while preserving both its beginning and final tail when truncation is required.
- Remove `codexResponseHandoffPrefix` from `thread/realtime/start`; unknown fields from older clients remain ignored.

## Testing

- Cover incremental V3 commentary and final output, Unicode-safe truncation, V1/V3 phase labeling, and legacy request compatibility.

GitOrigin-RevId: 633c18b5eb9a4f5756a264b63b7bfc185b073951
2026-07-17 15:54:33 +00:00
guinness-oai 22f413bdbf Tag realtime transcript tail flush delegations (#33855)
## What changed

- Add `<source>transcript_tail_flush</source>` to realtime delegation payloads
  emitted when a session flushes its remaining transcript tail.
- Keep explicit realtime handoff payloads unchanged.
- Render both delegation variants through a shared contextual user fragment.

## Testing

- Update realtime conversation tests to cover tagged transcript-tail flushes and
  preserve the existing handoff format and XML escaping behavior.

GitOrigin-RevId: 33f70d16cf45b3af8068565c4cf2b1785be3f1d9
2026-07-17 15:50:13 +00:00
guinness-oai c976741124 [codex] Flush trailing realtime transcript tail (#29918)
## Why

A realtime session can end after more transcript has accumulated than
was included in its last handoff. That tail already lives in core's
active transcript state, but the stop path aborted the realtime
input/fanout tasks before routing it, so the final bit of the
conversation could disappear before `thread/realtime/closed`.

This behavior is still being evaluated, so clients must opt in per
realtime session. Omitted or false leaves shutdown behavior unchanged.

## What changed

- Add optional `flushTranscriptTailOnSessionEnd` to
`thread/realtime/start`, defaulting to false in app-server.
- Expose an idempotent `take_transcript_tail()` from the existing active
transcript state using `last_handoff_entry_count`.
- When enabled, let shutdown cancel the input owner cleanly and publish
at most one final existing `<realtime_delegation>` with the remaining
text in `<transcript_delta>`.
- Have the existing fanout drain already-parsed events before routing
that final delegation, so a queued handoff wins first and is not
duplicated in the tail.
- Flush realtime shutdown before ordinary session task abort during core
cleanup.

## Validation

- `just test -p codex-app-server-protocol`
- `just test -p codex-app-server
realtime_conversation_stop_emits_closed_notification`
- `just test -p codex-core conversation_transport_close_`
- `just test -p codex-core
conversation_close_routes_only_remaining_transcript_tail_once`
- scoped `just fix` for `codex-app-server-protocol`, `codex-app-server`,
`codex-protocol`, and `codex-core`
- `just fmt`
2026-07-06 14:12:54 -07:00
Owen Lin 5b95745eae core: rename metadata -> internal_chat_message_metadata_passthrough (#28968)
## Description
This PR cuts Codex over from generic `ResponseItem.metadata` (introduced
here: https://github.com/openai/codex/pull/28355) to
`ResponseItem.internal_chat_message_metadata_passthrough`, which is the
blessed path and has strongly-typed keys.

For now we have to drop this MAv2 usage of `metadata`:
https://github.com/openai/codex/pull/28561 until we figure out where
that should live.
2026-06-22 11:11:25 -07:00
Peter Bakkum 8e7c213f8f Always use AVAS for realtime WebRTC calls (#28856)
## Summary

- Remove the realtime `architecture` selector from core protocol,
app-server protocol, config parsing, generated schemas, and callers.
- Always create WebRTC realtime calls with the AVAS query params:
`intent=quicksilver&architecture=avas`.
- Keep direct websocket realtime behavior on the existing config/default
path, while WebRTC starts without an explicit version now default to
realtime v1 because AVAS requires v1.

## Notes

- WebRTC realtime now means AVAS. If a caller explicitly asks to start
WebRTC with realtime v2, Codex rejects that request because the AVAS
WebRTC path only supports realtime v1. Websocket realtime is separate
and can still use realtime v2.
- The old `[realtime] architecture = "realtimeapi" | "avas"` config knob
is removed. Local configs that still set it will need to delete that
line.
- Some app-server tests that were only trying to exercise realtime v2
protocol behavior now use websocket transport, because WebRTC is
intentionally locked to AVAS/v1. Separate WebRTC tests cover the AVAS
query params, v1 startup, SDP flow, and sideband join.

## Validation

- Merged fresh `origin/main` at `83e6a786a2`.
- `just fmt`
- `just write-config-schema`
- `just write-app-server-schema`
- `git diff --check`
- `just test -p codex-api -p codex-core -p codex-app-server-protocol -p
codex-app-server realtime` (176 passed)
- `just test -p codex-protocol -p codex-config` (413 passed)
2026-06-18 19:11:21 -05:00
Gabriel Peal 21a599fa56 Support openai/form extended form elicitations (#27500)
# Summary
Allow App Server clients to opt into `openai/form` MCP elicitations.
2026-06-18 11:54:49 -07:00
jiayuhuang-openai 683bd170dc [codex] control automatic realtime handoff delivery (#27986)
## What

Built on the realtime speech-control plumbing merged in #27917.

- Add optional `codexResponseHandoffPrefix` to `thread/realtime/start`.
- Apply that prefix only to automatic V1 commentary sent through
`conversation.handoff.append`; final answers remain unprefixed.
- Add opt-in `clientManagedHandoffs`. When true, core suppresses
automatic response handoffs and completion output so delivery is
controlled by explicit client append APIs.
- Preserve existing automatic behavior by default.
`codexResponsesAsItems: true` continues to select item routing when
client-managed mode is disabled.

## Why

Voice clients need two delivery policies: automatic background context
with silent commentary instructions and fully client-owned handoffs.
Phase-aware prefixing keeps routine commentary silent without
suppressing the final answer, while client-managed mode lets an app
decide exactly which updates to append.

## Validation

- `just fmt`
- `cargo test -p codex-app-server-protocol
serialize_thread_realtime_start`
- `RUST_MIN_STACK=16777216 cargo test -p codex-core --test all
conversation_handoff_persists_across_item_done_until_turn_complete`
- `RUST_MIN_STACK=16777216 cargo test -p codex-app-server --test all
webrtc_v1_client_managed_handoffs_disable_automatic_output`
- `RUST_MIN_STACK=16777216 cargo test -p codex-app-server --test all
webrtc_v1_final_automatic_handoff_omits_silent_prefix`
- `cargo build -p codex-cli --bin codex`
- Local Codex Apps compatibility check: 43 focused webview tests passed,
and a live voice session routed through the source-built app-server.

The explicit `RUST_MIN_STACK` avoids a macOS Tokio test-worker stack
overflow seen with the default test environment.
2026-06-18 02:22:29 +00:00
guinness-oai a306ac4ee3 [codex] Use unique IDs for realtime-routed turns (#28826)
## Why

A durable realtime voice orchestrator can reconnect and resume through
multiple fresh `Session` instances. Realtime handoffs were using the
Session-local `auto-compact-N` counter as their turn identity, but that
counter restarts at zero for every resumed Session. The durable thread
could therefore accumulate duplicate turn IDs, violating the uniqueness
assumptions made by app-server and web clients. In Codex Apps, a new
delegated response stream could be attached to an older turn with the
same ID, placing live output higher in history and putting turn-scoped
actions at risk.

Persisted rollout and reconstructed model-context order were already
correct because raw response items remain append-only and chronological.
This change restores unique identity for reconstructed and live turn
surfaces.

## What changed

- Generate a UUIDv7 specifically for each realtime-routed delegation.
- Leave the existing `auto-compact-N` identity path unchanged for actual
internal auto-compaction turns.
- Extend the inbound realtime handoff integration test to require a UUID
turn ID from `turn/started`.

## Verification

- `just test -p codex-core inbound_handoff_request_starts_turn`
- `just fix -p codex-core`
- `just fmt`
2026-06-17 19:13:38 -07:00
pakrym-oai e752f7b4ae [codex] Use expect in integration tests (#28441)
The workspace denies `clippy::expect_used` in production. Although
`clippy.toml` allows `expect` in tests, Bazel Clippy compiles
integration-test helper code in a way that does not receive that
exemption, which encouraged verbose `unwrap_or_else(... panic!(...))`
and equivalent `match`/`let else` forms.

This allows `clippy::expect_used` once at each integration-test crate
root (including aggregated suites and test-support libraries), then
replaces manual panic-based Result and Option unwraps with
`expect`/`expect_err`. Standalone `tests/*.rs` files remain their own
crate roots. Intentional assertion and unexpected-variant panics remain
unchanged, and the production `expect_used = "deny"` lint remains in
place.

The cleanup is mechanical and net-negative in line count.
2026-06-15 21:53:47 -07:00
guinness-oai d5b4b98370 Add a toggle for realtime startup context (#28405)
## Summary
- Add `includeStartupContext` to realtime start requests so callers can
explicitly skip Codex startup context while keeping the backend prompt
- Thread the new flag through protocol types, request processing, and
realtime session config
- Update app-server docs and coverage for the new default and opt-out
behavior

## Testing
- Added protocol serialization coverage for `includeStartupContext`
- Added realtime integration coverage for starting a session with
startup context disabled
2026-06-15 17:14:22 -07:00
guinness-oai 1d8ff89aa3 Add realtime speech append control (#27917)
## Why

Realtime voice harness tuning needs app-side control over what backend
Codex text is spoken. Backend orchestrator text is written for a reading
UI, so automatically speaking every preamble, progress update, or final
assistant message can make the realtime voice model too chatty.

For experimentation, clients need two simple controls: keep app/client
text-item injection on the existing item-create path, and add an
explicit speakable path that app code can call only when it wants
realtime to speak. Automatic Codex output also needs an opt-in way to
switch from the protocol's default speakable path to regular realtime
items, with a caller-provided prefix so prompt wording can be tuned
outside core.

The default remains unchanged: if a client omits the new start fields
and never calls `appendSpeech`, automatic backend output continues down
the existing speakable path for the selected realtime protocol.

## What Changed

- Adds experimental `thread/realtime/appendSpeech` for app-provided
speakable text.
- Keeps existing `thread/realtime/appendText` as the item-create API for
app-provided realtime text items.
- Adds `codexResponsesAsItems` / `codex_responses_as_items` on
`thread/realtime/start` to send automatic Codex responses with
`conversation.item.create` instead of the protocol's default speakable
output path.
- Adds `codexResponseItemPrefix` / `codex_response_item_prefix` so
clients can prepend experiment instructions to those automatic Codex
response items.
- Keeps literal `conversation.handoff.append` routing scoped to the v1
speakable path; v2 default speech uses its item/function-output plus
`response.create` behavior.
- Removes the earlier public silent-context API and hardcoded
silent-context prefix.
- Updates realtime tests to cover default automatic speakable behavior,
opt-in automatic item-create behavior, and explicit `appendSpeech`
behavior.

## Validation

- `cargo check -p codex-core -p codex-app-server -p codex-api`
- `just test -p codex-app-server realtime_conversation`
- `just test -p codex-core realtime_conversation` (50/51 passed in the
filtered parallel run; the lone failure passed when rerun in isolation)
- `just test -p codex-core
conversation_mirrors_assistant_message_text_to_realtime_handoff`
- `just test -p codex-api
e2e_connect_and_exchange_events_against_mock_ws_server`
- `just fix -p codex-core`
- `just fix -p codex-app-server`
- `cargo build -p codex-cli`
2026-06-15 16:15:58 -07:00
felixxia-oai db8927a8e2 Deflake realtime handoff steering test (#28300)
## Summary
- keep the realtime mock websocket open for the handoff steering test
after scripted responses
- avoid racing the mock server close before the standalone handoff
append is observed, which was showing up as a Windows timeout in CI

__Details__:
Failures in samples seem to be caused by:
1. The mock websocket sends conversation.handoff.requested.
2. The mock immediately closes the websocket because
start_websocket_server(...) defaults to close_after_requests: true.
3. On Windows, that close often surfaces as os error 10053 / 10054.
4. The realtime stream shuts down before the routed handoff finishes
creating/steering the follow-up request.
5. The test waits for the expected follow-up event and times out.

The PR changes only step 2: for this test, the mock websocket stays open
after sending the scripted handoff event. The same handoff event is
still sent, and the test still asserts the important steering behavior:
1. first Responses request has the original prompt
2. first request does not contain realtime delegation
3. second Responses request does contain the realtime delegation

## Validation
- `just fmt`
- `just test -p codex-core --test all
suite::realtime_conversation::inbound_handoff_request_steers_active_turn`

## Recent CI failures with the same signature

-
https://github.com/openai/codex/actions/runs/27538033492/job/81392362858
  - 2026-06-15, `[codex] update multi-agent v2 prompts`
- same test failed after `conversation.handoff.requested`; websocket
read failed with `os error 10053`

-
https://github.com/openai/codex/actions/runs/27543877820/job/81412200651
- 2026-06-15, `feat: dispatch queued user messages through core idle
extensions`
  - same test failed; websocket read failed with `os error 10054`

-
https://github.com/openai/codex/actions/runs/27544342375/job/81413801641
  - 2026-06-15, `[codex] Make marketplace loading capability aware`
  - same test failed; websocket read failed with `os error 10053`
2026-06-15 23:50:11 +01:00
Owen Lin 040dafa32d feat(core): add metadata field to ResponseItem (#28355)
## Description

This PR adds an optional `metadata` field to `ResponseItem` for
Responses API calls. Only mechanical plumbing, no actual values
populated and sent yet. Turns out just adding a new field to
`ResponseItem` has quite a large blast radius already.

This change is backwards compatible because `metadata` is optional and
omitted when absent, so existing response items and rollout history
without it still deserialize and requests that do not set it keep the
same wire shape. For provider compatibility, we strip out `metadata`
before non-OpenAI Responses requests so Azure and AWS Bedrock never see
this field.

My followup PR here will actually make use of it to start storing and
passing along `turn_id`: https://github.com/openai/codex/pull/28360

## What changed

- Added `ResponseItemMetadata` with optional `turn_id`, plus optional
`metadata` on Responses API item variants and inter-agent communication.
- Preserved item metadata through response-item rewrites such as
truncation, missing tool-output synthesis, compaction history
rebuilding, visible-history conversion, rollout/resume, and generated
app-server schemas/types.
- Strip item metadata from non-OpenAI Responses requests while
preserving it for OpenAI-shaped requests.
- Updated the mechanical fixture/test construction churn required by the
new optional field.
2026-06-15 15:05:28 -07:00
Alex Gamble 216dee1189 [codex] add roles to realtime append text (#27936)
## Summary

Add an explicit `user` or `developer` role to
`thread/realtime/appendText` and propagate it through the realtime input
queue into `conversation.item.create`. Older JSON clients that omit the
field continue to default to `user`.

This lets app-provided context such as memory retain developer authority
without bypassing app-server through a renderer-owned data channel. The
app-server schemas, API documentation, and focused protocol and
websocket coverage are updated with the new contract.

The Codex Apps consumer is tracked in
[openai/openai#1025261](https://github.com/openai/openai/pull/1025261).
2026-06-12 15:05:37 -07:00
Peter Bakkum 6652e82dd0 realtime: add AVAS architecture override (#27720)
## Summary

Adds a `RealtimeConversationArchitecture` option for realtime
conversation startup, with `realtimeapi` as the default and `avas` as an
opt-in architecture.

The AVAS path is limited to realtime v1 conversational WebRTC starts,
and WebRTC call creation appends `intent=quicksilver&architecture=avas`
to `/v1/realtime/calls`. The existing sideband websocket still joins by
`call_id`.

This also exposes the per-session architecture override through
app-server v2 `thread/realtime/start` params and updates the config
schema for `[realtime].architecture`.

## Validation

- `just fmt`
- `just write-config-schema`
- `just test -p codex-api sends_avas_session_call_query_params`
- `just test -p codex-core -E
'test(~conversation_webrtc_start_uses_avas_architecture_query)'`
- `just test -p codex-core -E 'test(realtime_loads_from_config_toml)'`
- `just test -p codex-app-server-protocol -E
'test(~serialize_thread_realtime_start) |
test(generated_ts_optional_nullable_fields_only_in_params)'`
- `just test -p codex-app-server -E
'test(realtime_webrtc_start_emits_sdp_notification)'`
2026-06-12 18:11:13 +00:00
guinness-oai 4a3eac2144 Add per-session realtime model and version overrides (#24999)
## Why

Clients need to select a realtime session configuration for an
individual start without rewriting persisted configuration or restarting
the app-server process.

## What Changed

- Add optional `model` and `version` fields to `thread/realtime/start`
- Forward those optional values through the realtime start operation and
apply them only for that session
- Preserve existing configured/default behavior when the new fields are
omitted
- Update generated protocol schema and app-server documentation

## Validation

- Added/updated protocol serialization coverage for the new optional
request fields
- Added focused core coverage for a session override taking precedence
over configured realtime selection
- Added focused app-server coverage that a request override reaches the
realtime WebSocket handshake
2026-06-09 17:54:32 -07:00
guinness-oai cc8325f181 Stop mirroring Codex user input into realtime (#27116)
## Why

The realtime frontend model and the backing Codex thread should present
one coherent assistant. Raw typed messages, steers, and worker reports
belong to the orchestrator; the frontend model should receive the
orchestrator's user-facing result rather than a second copy of those
inputs.

Today normal `turn/start` input is automatically inserted into the
realtime conversation, while `turn/steer` is not. Besides creating
inconsistent context, this can make the frontend model react
independently before Codex has produced the response it should speak.

## What changed

- Remove automatic accepted-user-input mirroring into realtime
- Remove the mirror-only echo-suppression flag and dead V2 prefix helper
- Preserve explicit app-to-realtime text injection and FEM-to-Codex
delegation
- Replace the positive mirror tests and obsolete snapshots with a
negative routing regression test

## Test plan

- `cargo test -p codex-core
conversation_user_text_turn_is_not_sent_to_realtime`
- `cargo test -p codex-core
conversation_startup_context_is_truncated_and_sent_once_per_start`
- `cargo test -p codex-core inbound_handoff_request_starts_turn`
2026-06-09 15:20:01 -07:00
pakrym-oai f3c1283411 Pair thread environment settings (#26687)
## Why

Thread cwd and environment selections are a single logical setting in
core: updating one without the other can silently desynchronize the
next-turn execution context. This change makes that relationship
explicit in the internal thread settings flow while preserving the
existing app-server public API shape.

## What changed

- Moved the cwd/environment pair through internal
`ThreadSettingsOverrides.environment_settings` instead of a top-level
internal `cwd` field.
- Kept `thread/settings/update` public params unchanged, with app-server
translating top-level `cwd` into the paired internal settings shape.
- Moved `Op::UserInput` environment overrides into thread settings so
user turns and settings updates use the same core path.
- Updated core, app-server, MCP, memories, sample, and test callsites to
construct the paired settings shape.

## Verification

- `git diff --check`
- Local test run starting after PR creation.
2026-06-08 13:55:15 -07:00
Owen Lin 11e0f3d3ae app-server: remove experimental persist_extended_history bool flag (#25712)
## Summary

Remove the dead experimental `persistExtendedHistory` app-server flag
and collapse rollout persistence to the single policy app-server already
used.

## What Changed

- Removed `persistExtendedHistory` from v2 thread start/resume/fork
params and deleted its deprecation notice path.
- Removed the persistence-mode enums and plumbing through core, rollout,
and thread-store.
- Made rollout filtering mode-free, keeping the existing limited
persisted-history behavior.

## Test Plan

- `just write-app-server-schema`
- `cargo nextest run --no-fail-fast -p codex-app-server-protocol
schema_fixtures`
- `cargo nextest run --no-fail-fast -p codex-app-server
thread_shell_command_history_responses_exclude_persisted_command_executions`
- `cargo nextest run --no-fail-fast -p codex-rollout -p
codex-thread-store`
- final `rg` for removed flag/type names
2026-06-01 23:33:42 +00:00
Adam Perry @ OpenAI ba2b67f9cd [codex] Consolidate shared prompts in codex-prompts (#25151)
## Why

`codex_core` is consistently a bottleneck for incremental builds during
iteration. The simplest fix is to make the crate smaller.

## Summary

`codex-core` owns several reusable prompt renderers and static prompt
assets, which makes the crate harder to split apart.

Rename `codex-review-prompts` to `codex-prompts` and move shared review,
goal, permissions, compaction, realtime, hierarchical AGENTS.md, and
`apply_patch` prompts into it. Move prompt-only tests and update
consumers and `CODEOWNERS`.

## Validation

- `just test -p codex-prompts -p codex-apply-patch`
- `just test -p codex-core prompt_caching`
- Bazel builds for the affected crates
2026-06-01 18:45:07 +00:00
Adam Perry @ OpenAI cca1e0ba1d Uprev Rust toolchain pins to 1.95.0 (#24684)
## Summary
- Bump the workspace Rust toolchain from `1.93.0` to `1.95.0` across
Cargo, Bazel, CI, release workflows, devcontainers, and the Codex
environment config.
- Refresh `MODULE.bazel.lock` so the Bazel Rust toolchain artifacts
match the new version.
- Leave purpose-specific toolchains unchanged, including the
`argument-comment-lint` nightly and the upstream `rusty_v8` `1.91.0`
build pin.
- Includes fixes for new lints from `just fix` and a few codex-authored
fixes for lints without a suggestion.
2026-05-26 20:59:47 -07:00
pakrym-oai 768848ab6f Add experimental turn additional context (#24154)
## Summary

Adds experimental `additionalContext` support to `turn/start` and
`turn/steer` so clients can provide ephemeral external context, such as
browser or automation state, without turning that plumbing into a
visible user prompt or triggering user-prompt lifecycle behavior.

## API Shape

The parameter shape is:

```ts
additionalContext?: Record<string, {
  value: string
  kind: "untrusted" | "application"
}> | null
```

Example:

```json
{
  "additionalContext": {
    "browser_info": {
      "value": "Active tab is CI failures.",
      "kind": "untrusted"
    },
    "automation_info": {
      "value": "CI rerun is in progress.",
      "kind": "application"
    }
  }
}
```

The keys are opaque and caller-defined.

## Context Injection

When provided, accepted entries are inserted into model context as
hidden contextual message items, not as visible thread user-message
items.

`kind: "untrusted"` entries are inserted with role `user`:

```text
<external_${key}>${value}</external_${key}>
```

`kind: "application"` entries are inserted with role `developer`:

```text
<${key}>${value}</${key}>
```

Values are not escaped. Each value is truncated to 1k approximate tokens
before wrapping.

For `turn/start`, accepted additional context is inserted before normal
user input. For `turn/steer`, additional context is merged only when the
steer includes non-empty user input; context-only steers still reject as
empty input.

## Dedupe Strategy

`AdditionalContextStore` lives on session state and stores the latest
complete additional-context map.

Each `turn/start` or non-empty `turn/steer` treats its
`additionalContext` as the current complete set of values. Entries are
injected only when the key is new or the exact entry for that key
changed, including `value` or `kind`. After merging, the store is
replaced with the provided map, so omitted keys are removed from the
retained set and can be injected again later if reintroduced.

Omitting `additionalContext`, passing `null`, or passing an empty object
resets the store to empty and injects nothing.

## What Changed

- Threads experimental v2 `additionalContext` through app-server into
core turn start and steer handling.
- Adds separate contextual fragment types for untrusted user-role
context and application developer-role context.
- Uses pending response input items so additional context can be
combined with normal user input without treating it as prompt text.
- Adds integration coverage for start/steer flow, role routing,
dedupe/reset behavior, deletion/re-add behavior, hook-blocked input
behavior, empty context-only steer rejection, external-fragment marker
matching, and truncation.
2026-05-26 13:02:34 -07:00
Eric Traut 84d941d07f [1 of 7] Add thread settings to UserInput (#23080)
**Stack position:** [1 of 7]

## Summary

The first three PRs in this stack are a cleanup pass before the actual
thread settings API work.

Today, core has several overlapping "user input" ops: `UserInput`,
`UserInputWithTurnContext`, and `UserTurn`. They differ mostly in how
much next-turn state they carry, which makes the later queued thread
settings update harder to reason about and review.

This PR starts that cleanup by adding the shared
`ThreadSettingsOverrides` payload and allowing `Op::UserInput` to carry
it. Existing variants remain in place here, so this layer is mostly a
behavior-preserving API shape change plus mechanical constructor
updates.

## End State After PR3

By the end of PR3, `Op::UserInput` is the only "user input" core op. It
can carry optional thread settings overrides for callers that need to
update stored defaults with a turn, while callers without updates use
empty settings. `Op::UserInputWithTurnContext` and `Op::UserTurn` are
deleted.

## End State After PR5

By the end of PR5, core will have only two ops for this area:

- `Op::UserInput` for user-input-bearing submissions.
- `Op::ThreadSettings` for settings-only updates.

## Stack

1. [1 of 7] [Add thread settings to
UserInput](https://github.com/openai/codex/pull/23080) (this PR)
2. [2 of 7] [Remove
UserInputWithTurnContext](https://github.com/openai/codex/pull/23081)
3. [3 of 7] [Remove
UserTurn](https://github.com/openai/codex/pull/23075)
4. [4 of 7] [Placeholder for OverrideTurnContext
cleanup](https://github.com/openai/codex/pull/23087)
5. [5 of 7] [Replace OverrideTurnContext with
ThreadSettings](https://github.com/openai/codex/pull/22508)
6. [6 of 7] [Add app-server thread settings
API](https://github.com/openai/codex/pull/22509)
7. [7 of 7] [Sync TUI thread
settings](https://github.com/openai/codex/pull/22510)
2026-05-18 18:48:35 -07:00
pakrym-oai 408e6218ab Reapply "Move skills watcher to app-server" (#21652)
## Why

PR #21460 reverted the earlier move of skills change watching from
`codex-core` into app-server. This reapplies that boundary change so
app-server owns client-facing `skills/changed` notifications and core no
longer carries the watcher.

## What

- Restore the app-server `SkillsWatcher` and register it from thread
listener setup.
- Remove the core-owned skills watcher and its core live-reload
integration surface.
- Restore app-server coverage for `skills/changed` notifications after a
watched skill file changes.

## Validation

- `cargo test -p codex-app-server --test all
suite::v2::skills_list::skills_changed_notification_is_emitted_after_skill_change
-- --exact --nocapture`
- `cargo test -p codex-core --lib --no-run`
2026-05-08 17:41:15 -07:00
kmeelu-oaiandCodex e7e6267ab3 Make realtime sideband startup async (#20715)
## Summary

Moves the WebRTC realtime sideband websocket join out of the voice start
critical path. Call creation still posts the SDP offer and session
config synchronously so the client gets the SDP answer, but the sideband
websocket now connects in the input task async and doesn't block
conversation state installation.

This lets the normal realtime input channels buffer text, handoff
output, and audio while the WebRTC sideband websocket is connecting. If
the sideband join fails while the conversation is still active, the task
sends a RealtimeEvent::Error through the existing events_tx / fanout
path.

To rephrase this:
* No longer blocked on sideband: the client can receive the SDP answer
earlier, set up the WebRTC peer connection, and let the media leg
progress while the sideband websocket joins.
* Still blocked on sideband: queued text, handoff output, and sideband
server events cannot flow until connect_webrtc_sideband(...).await
finishes and then run_realtime_input_task(...) starts

## Validation

- `env CODEX_SKIP_VENDORED_BWRAP=1 cargo test --manifest-path
codex-rs/Cargo.toml -p codex-core --test all
conversation_webrtc_start_posts_generated_session`

`CODEX_SKIP_VENDORED_BWRAP=1` is needed in this local environment
because `libcap.pc` is not installed for the vendored bubblewrap build.

## Testing
I tested this locally by running `cargo run -p codex-cli --bin codex --
--enable realtime_conversation` and invoking `/realtime`. Then, we get
logs emitted in `~/.codex/log/codex-tui.log`.

### Before the Change
Logging commit
(https://github.com/openai/codex/commit/c0299e6edf1222fa0c43c1796e4811976c26fecd)
```
2026-05-04T16:06:09.251956Z  INFO session_loop{thread_id=019df3b9-e3d8-7271-b13a-b880119aa4c2}:submission_dispatch{otel.name="op.dispatch.realtime_conversation_start" submission.id="019df3bd-65df-7ee2-8125-1d6701fe39d2" codex.op="realtime_conversation_start"}: codex_core::realtime_conversation: starting realtime conversation
2026-05-04T16:06:09.251980Z  INFO session_loop{thread_id=019df3b9-e3d8-7271-b13a-b880119aa4c2}:submission_dispatch{otel.name="op.dispatch.realtime_conversation_start" submission.id="019df3bd-65df-7ee2-8125-1d6701fe39d2" codex.op="realtime_conversation_start"}: codex_core::realtime_conversation: creating realtime call transport="webrtc"
2026-05-04T16:06:10.365722Z  INFO session_loop{thread_id=019df3b9-e3d8-7271-b13a-b880119aa4c2}:submission_dispatch{otel.name="op.dispatch.realtime_conversation_start" submission.id="019df3bd-65df-7ee2-8125-1d6701fe39d2" codex.op="realtime_conversation_start"}: codex_core::realtime_conversation: realtime call created; sdp answer ready transport="webrtc" call_id=rtc_u0_Dbq65nhak5eLjQZ73yhAy elapsed_ms=1113 total_elapsed_ms=1113
2026-05-04T16:06:10.365843Z  INFO session_loop{thread_id=019df3b9-e3d8-7271-b13a-b880119aa4c2}:submission_dispatch{otel.name="op.dispatch.realtime_conversation_start" submission.id="019df3bd-65df-7ee2-8125-1d6701fe39d2" codex.op="realtime_conversation_start"}: codex_core::realtime_conversation: connecting realtime sideband websocket call_id=rtc_u0_Dbq65nhak5eLjQZ73yhAy
2026-05-04T16:06:10.784528Z  INFO session_loop{thread_id=019df3b9-e3d8-7271-b13a-b880119aa4c2}:submission_dispatch{otel.name="op.dispatch.realtime_conversation_start" submission.id="019df3bd-65df-7ee2-8125-1d6701fe39d2" codex.op="realtime_conversation_start"}: codex_core::realtime_conversation: connected realtime sideband websocket call_id=rtc_u0_Dbq65nhak5eLjQZ73yhAy elapsed_ms=418 total_elapsed_ms=1532
2026-05-04T16:06:10.784665Z  INFO session_loop{thread_id=019df3b9-e3d8-7271-b13a-b880119aa4c2}:submission_dispatch{otel.name="op.dispatch.realtime_conversation_start" submission.id="019df3bd-65df-7ee2-8125-1d6701fe39d2" codex.op="realtime_conversation_start"}: codex_core::realtime_conversation: realtime conversation started
```

### After the Change
Logging commit
(https://github.com/openai/codex/commit/c8b00ac21adf4f8dd1fe3a81403a2bb6183fe13b)
```
2026-05-04T15:41:24.080363Z  INFO ... codex_core::realtime_conversation: starting realtime conversation
2026-05-04T15:41:24.080434Z  INFO ... codex_core::realtime_conversation: creating realtime call transport="webrtc"
2026-05-04T15:41:25.106906Z  INFO ... codex_core::realtime_conversation: realtime call created; sdp answer ready transport="webrtc" call_id=rtc_u0_Dbpi8nhak5eLjQZ73yhAy elapsed_ms=1026 total_elapsed_ms=1026
2026-05-04T15:41:25.107067Z  INFO ... codex_core::realtime_conversation: spawned realtime sideband connection task transport="webrtc" total_elapsed_ms=1026
2026-05-04T15:41:25.107160Z  INFO ... codex_core::realtime_conversation: realtime conversation started
2026-05-04T15:41:25.107185Z  INFO codex_core::realtime_conversation: connecting realtime sideband websocket call_id=rtc_u0_Dbpi8nhak5eLjQZ73yhAy
2026-05-04T15:41:25.107352Z  INFO ... codex_core::realtime_conversation: sent realtime sdp answer to client
2026-05-04T15:41:26.076685Z  INFO codex_core::realtime_conversation: connected realtime sideband websocket call_id=rtc_u0_Dbpi8nhak5eLjQZ73yhAy elapsed_ms=969 total_elapsed_ms=1996
2026-05-04T15:41:26.573893Z  INFO codex_core::realtime_conversation: realtime session updated realtime_session_id=sess_u0_Dbpi8nhak5eLjQZ73yhAy
2026-05-04T15:41:26.573970Z  INFO codex_core::realtime_conversation: received realtime conversation event event=SessionUpdated { ... }
```

### Conclusion
Here we see that we saved about a half a second in conversation startup
(1532ms -> 969ms). This also checks out with my sanity tests; I was
seeing at most a second of saving.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-05-04 22:28:14 +00:00
Tom fe05acad23 Make thread store process-scoped (#19474)
- Build one app-server process ThreadStore from startup config and share
it with ThreadManager and CodexMessageProcessor.
- Remove per-thread/fork store reconstruction so effective thread config
cannot switch the persistence backend.
- Add params to ThreadStore create/resume for specifying thread
metadata, since otherwise the metadata from store creation would be used
(incorrectly).
2026-04-30 21:24:59 -07:00
Ahmed IbrahimandCodex 8a97f3cf03 realtime: rename provider session ids (#20361)
## Summary

Codex is repurposing `session` to mean a thread group, so the realtime
provider session id should no longer use `session_id` / `sessionId` in
Codex-facing protocol payloads. This PR renames that provider-specific
field to `realtime_session_id` / `realtimeSessionId` and intentionally
breaks clients that still send the old field names.

## What Changed

- Renamed realtime provider session fields in `ConversationStartParams`,
`RealtimeConversationStartedEvent`, and `RealtimeEvent::SessionUpdated`.
- Renamed app-server v2 realtime request and notification fields to
`realtimeSessionId`.
- Removed legacy serde aliases for `session_id` / `sessionId`; clients
must send the new names.
- Propagated the rename through core realtime startup, app-server
adapters, codex-api websocket handling, and TUI realtime state.
- Regenerated app-server protocol schema/TypeScript outputs and updated
app-server README examples.
- Kept upstream Realtime API concepts unchanged: provider `session.id`
parsing and `x-session-id` headers still use the upstream wire names.

## Testing

- CI is running on the latest pushed commit.
- Earlier local verification on this PR:
  - `cargo test -p codex-protocol`
- `CODEX_SKIP_VENDORED_BWRAP=1 cargo test -p codex-core
realtime_conversation`
  - `cargo test -p codex-app-server-protocol`
- `CODEX_SKIP_VENDORED_BWRAP=1 cargo test -p codex-app-server
realtime_conversation`
- attempted `CODEX_SKIP_VENDORED_BWRAP=1 cargo test -p codex-tui` (local
linker bus error while linking the test binary)

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-30 13:39:48 +03:00
pakrym-oai 8356806fc9 Add ThreadManager sample crate (#20141)
Summary:
- Add codex-thread-manager-sample, a one-shot binary that starts a
ThreadManager thread, submits a prompt, and prints the final assistant
output.
- Pass ThreadStore into ThreadManager::new and expose
thread_store_from_config for existing callsites.
- Build the sample Config directly with only --model and prompt inputs.

Verification:
- just fmt
- cargo check -p codex-thread-manager-sample -p codex-app-server -p
codex-mcp-server
- git diff --check

Tests: Not run per request.
2026-04-29 11:21:06 -07:00
Andrey Mishchenko 35bc6e3d01 Delete unused ResponseItem::Message.end_turn (#19605)
This field is unused. Delete it.
2026-04-26 17:18:09 -07:00
starr-openaiandCodex 1d4cc494c9 Add turn-scoped environment selections (#18416)
## Summary
- add experimental turn/start.environments params for per-turn
environment id + cwd selections
- pass selections through core protocol ops and resolve them with
EnvironmentManager before TurnContext creation
- treat omitted selections as default behavior, empty selections as no
environment, and non-empty selections as first environment/cwd as the
turn primary

## Testing
- ran `just fmt`
- ran `just write-app-server-schema`
- not run: unit tests for this stacked PR

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-21 17:48:33 -07:00
efrazer-oai be75785504 fix: fully revert agent identity runtime wiring (#18757)
## Summary

This PR fully reverts the previously merged Agent Identity runtime
integration from the old stack:
https://github.com/openai/codex/pull/17387/changes

It removes the Codex-side task lifecycle wiring, rollout/session
persistence, feature flag plumbing, lazy `auth.json` mutation,
background task auth paths, and request callsite changes introduced by
that stack.

This leaves the repo in a clean pre-AgentIdentity integration state so
the follow-up PRs can reintroduce the pieces in smaller reviewable
layers.

## Stack

1. This PR: full revert
2. https://github.com/openai/codex/pull/18871: move Agent Identity
business logic into a crate
3. https://github.com/openai/codex/pull/18785: add explicit
AgentIdentity auth mode and startup task allocation
4. https://github.com/openai/codex/pull/18811: migrate auth callsites
through AuthProvider

## Testing

Tests: targeted Rust checks, cargo-shear, Bazel lock check, and CI.
2026-04-21 14:30:55 -07:00
guinness-oai ca3246f77a [codex] Send realtime transcript deltas on handoff (#18761)
## Summary
- Track how many realtime transcript entries have already been attached
to a background-agent handoff.
- Attach only entries added since the previous handoff as
`<transcript_delta>` instead of resending the accumulated transcript
snapshot.
- Update the realtime integration test so the second delegation carries
only the second transcript delta.

## Validation
- `just fmt`
- `cargo test -p codex-api`
- `cargo test -p codex-core
inbound_handoff_request_sends_transcript_delta_after_each_handoff`
- `cargo build -p codex-cli -p codex-app-server`

## Manual testing
Built local debug binaries at:
- `codex-rs/target/debug/codex`
- `codex-rs/target/debug/codex-app-server`
2026-04-20 16:46:15 -07:00