## Why
Clients starting delegated work need to attribute descendant turns to the original turn and retain that attribution through completion and history reads.
## What changed
- Accept optional `parentTurnId` and `rootTurnId` in `turn/start`, and expose `rootTurnId` on returned turns and lifecycle notifications.
- Default new turns to their own root when none is supplied. Preserve the active turn's root when steering, ignoring incoming lineage fields.
- Carry root IDs through completion, interruption, recovery, and fork boundaries, and persist them for paginated history reads. Leave unknown roots null in older history.
- Update protocol schemas and generated TypeScript and Python bindings.
## Testing
Extend coverage for default and explicit roots, steering without changing lineage, interrupted and recovered turns, history reads after restart in both history modes, nested fork pagination, and compatibility with older database writers.
GitOrigin-RevId: f1a570a12bd11742929fd2e8b017e5d35aa07dcb
## Why
Recovering an interrupted turn replaced its original trigger with `retry` and restored only its root lineage from model context. Turns suspended before that context was written could lose their attribution entirely.
## What changed
- Persist regular-turn attribution in `TurnStartedEvent` and compaction resume metadata, including the trigger, parent and root turn IDs, and initiating agent path.
- Restore matching attribution during recovery, keep unknown triggers absent, and retain the model-context root fallback for older records.
- Reconstruct attribution from surviving turns across rollback and late completion or abort events, and clear inherited attribution when spawning a forked agent.
## Testing
Add coverage for repeated cold recovery, suspension before context persistence, legacy rollouts, fresh attribution on subsequent turns, compaction checkpoints, rollback, and late terminal events.
GitOrigin-RevId: 85b5763e8fbd48a1ea2c07cfda8196e63c2cd33a
## Why
When `flush_transcript_tail_on_session_end` is enabled, remaining speech must be available in thread history as soon as realtime closure is reported, even while a model response is still running. Saving that transcript should not trigger another model request.
## What changed
Record the transcript tail directly in model and client history, attaching it to the active turn or creating a completed history turn when idle. Flush persistence before emitting `RealtimeConversationClosed`, and keep realtime context active until recording finishes so the return to text instructions follow the transcript.
## Testing
Extend core and app-server tests to cover immediate history visibility in paginated and legacy modes, idle and active turns, closure without extra inference, transcript reuse in subsequent text turns, and interruption after closure.
GitOrigin-RevId: ae323b711f22aa88db1432e24ad4bb3eb3f08f6b
## 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
## 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
## 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
## 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
## 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