Commit Graph
81 Commits
Author SHA1 Message Date
ioanbudea-OAI 400a1e1e82 Use native permission profiles for diagnostics and sandbox checks (#61369)
## What changed

- Derive sampling diagnostic and rollout trace labels directly from permission profiles instead of constructing legacy sandbox policies. Rename the trace metadata field from `sandbox_policy` to `permissions_profile`.
- Extract `with_workspace_write_cwd` to share default workspace metadata protections between legacy policy conversion and the TUI's sandbox-mode compatibility check. Build the check's workspace-write profile from filesystem and network permissions directly.

## Testing

Add a regression test confirming that the sandbox-mode compatibility check accepts standard workspace metadata protections and rejects a profile with an additional writable `.git` root.

GitOrigin-RevId: f20d23afd80dff6347865df3d6a94d6f5e90e1e0
2026-11-13 20:22:45 +00:00
tongzhou wang 9d12d007b2 Record host-confirmed Code Mode wait targets in rollout traces (#61338)
## Why

Inferring wait targets from request arguments can abort trace replay on malformed arguments and link waits to cells the host never resolved.

## What changed

Record an explicit `CodeCellWaitTargetResolved` event when the host confirms a live cell, and expose its runtime handle as `resolved_wait_runtime_cell_id` on the tool call. Build cell wait links from these observations, preserving links while cell source is pending and preventing late confirmations from linking to recycled handles after thread resume.

Older traces no longer infer wait links from request arguments, so an empty `wait_tool_call_ids` list does not establish that nobody waited on a cell.

## Testing

Extend dispatch and replay tests to cover live, missing, and invalid wait targets, pending cell source, legacy traces, and runtime handle reuse across threads and resume.

GitOrigin-RevId: 0f13b291c197c5487258b6ce36276cf1f19e2b6d
2026-11-13 18:43:21 +00:00
cassirer-openai b8dde1eb40 Move rollout trace recording to a background worker (#61253)
## Why

Recording inference starts synchronously serializes prompts and writes trace payloads before model work can proceed. Defer that work so inference dispatch can continue while the trace is recorded.

## What changed

- Use one worker per trace bundle to write events in submission order, with up to eight pending jobs.
- Share prepared prompts and encoded requests with the worker, and build remote compaction snapshots there. Write payloads before publishing events that reference them.
- Add `TraceWriter::flush` and `ThreadTraceContext::flush` for live reads. Drain accepted jobs and seal the bundle on shutdown; suppress the closing marker after a recording failure.

## Testing

Add tests for deferred prompt serialization, ordered start and completion events, shutdown draining, and serialization failures that preserve earlier evidence without publishing a closing marker. Verify compaction snapshots are built on the worker and skipped when tracing is disabled.

GitOrigin-RevId: 32fd787bb1d281f1814df2f08c73b667628f8add
2026-11-13 04:36:03 +00:00
cassirer-openai e73744b3f4 Store rollout trace payloads in compressed shards (#61222)
## What changed

- Replace individual JSON payload files with numbered Zstandard shards in trace schema v3. Add `PayloadReader` to resolve payload references, cache decoded shards, and validate payloads during replay.
- Capture exact outgoing HTTP bodies and WebSocket messages alongside prepared prompts. Preserve full formatted context for continuations from unrecorded WebSocket warmups while retaining the actual incremental request.
- Flush payload records before publishing references and seal the final shard before recording completion. Replace `recording_complete` with `recording_status` to distinguish unclosed recordings, closed recordings with partial payloads, and complete recordings.

Reduce trace bundles with the binary that recorded them.

## Testing

Add coverage for shard rotation, oversized records, live reads, cache eviction, and malformed or corrupt payloads. Extend HTTP and WebSocket integration assertions to verify captured requests and prepared prompts, including warmup continuations.

GitOrigin-RevId: 40ce3c11383f48e08f52e7120b706c61a449df9c
2026-11-13 01:22:19 +00:00
cassirer-openai 94fc729602 Align rollout trace replay with the same-binary contract (#61199)
## Why

Raw trace events and payloads are implementation details of the recording executable. Matching release or schema versions do not establish compatibility with another binary.

## What changed

- Document that bundles must be reduced by the exact executable that recorded them, with `state.json` as the consumer API and `manifest.json` for discovery and identity.
- Require explicit thread IDs on code-cell runtime events and use structured agent-message metadata instead of parsing legacy assistant-message JSON.
- Include expected schema versions and guidance to use the recording executable in schema mismatch errors.
- Update agent-delivery test fixtures to use structured `agent_message` inputs and check manifest schema rejection directly.

GitOrigin-RevId: 67206fa554f1ba9c1bf9bfdad54840b5d86c5a77
2026-11-12 22:43:46 +00:00
ioanbudea-OAI a7aab624ab Use permission profiles in sandbox tests and documentation (#61133)
## What changed

- Build and assert `PermissionProfile` values directly in memory consolidation tests using filesystem and network permissions.
- Remove the `SandboxPolicy` dependency from rollout trace test fixtures while preserving their `DangerFullAccess` value.
- Update sandbox documentation to describe legacy `sandbox_mode` conversion to `PermissionProfile` and nested filesystem rules, and reference `SandboxMode` in the CLI documentation.

GitOrigin-RevId: ac1be62625b1bfd98dde5f762b379eb840f9186b
2026-11-12 14:22:20 +00:00
cassirer-openai d4b19eca27 Preserve agent message deliveries in rollout traces (#60673)
## Why

An accepted agent message may never appear in a later inference request or compaction snapshot. Rollout traces need to retain the delivery and its interaction edge even when the receiving agent makes no further request.

## What changed

Capture agent message payloads in `HistoryItemAccepted` events and create conversation items when those receipts are replayed. Reuse each item's ID when it later appears in a request or checkpoint, updating its body to the model-visible representation. Repeated receipts preserve that representation without duplicating the item.

## Testing

Extend the spawn-edge regression test to cover delivery before any child inference, stable item IDs across a later request, and preservation of trimmed content after a repeated receipt.

GitOrigin-RevId: c193d691e8240645800ce004c11f21e3f1c82915
2026-11-10 22:22:35 +00:00
tongzhou wang 57a808a392 Preserve code mode dispatch errors in rollout traces (#60122)
## Why

Code mode requests can fail before a `CodeCellStarted` event. Suppressing their dispatch traces loses the caller-facing error in that case.

## What changed

Record dispatch lifecycles for code mode custom payloads, preserving their results independently of code cell events.

## Testing

Update the incompatible-payload regression test to use the code mode tool name and verify that replay retains the failed tool call and result payload even when no code cells were recorded.

GitOrigin-RevId: 687a36cd7ba55665ed7abc88c36732597e7fb025
2026-11-07 12:41:14 +00:00
tongzhou wang 43b4274f3f Buffer payload JSON reads during rollout trace replay (#60118)
GitOrigin-RevId: b0fbc478e19ceda1874d98ea50a39252a2951ed7
2026-11-07 12:32:02 +00:00
tongzhou wang 6103cf6c78 Expose acceptance metadata and code-cell links in rollout traces (#59778)
## What changed

- Add `accepted_at_unix_ms` and `accepted_seq` to conversation items, recording the first local `HistoryItemAccepted` event in trace order. Inherited context alone does not count as local acceptance.
- Add `started_code_cell_id` to model-requested `exec` tool calls when a matching code cell exists in the same thread and, when known, turn. Resolve links after replay so deferred cell starts can be matched.
- Default the new optional fields to absent when deserializing older traces and omit them from serialized output when unset.

## Testing

Extend reducer tests to cover duplicate acceptance events with out-of-order clock readings, inherited items without local acceptance, and `exec` calls with and without matching code cells.

GitOrigin-RevId: dfb594630f77d7c899398aa181c88a681587b1df
2026-11-06 01:20:54 +00:00
Charlie Marsh 4969675f01 Resolve network approval prompts when their requests end (#58350)
## Why

A network request can disappear while its approval prompt is still pending. Leaving that prompt active allows a late cancellation to interrupt the turn even though the request no longer needs approval.

## What changed

- Track network prompt lifetimes in core and notify the app server when a prompt is resolved or withdrawn.
- Cancel the corresponding server request, emit `serverRequest/resolved`, and release its permission guard. Resolve outstanding network prompts during thread shutdown as well.
- Claim a live pending approval and validate its originating turn before applying a decision, so stale responses cannot interrupt a turn or persist policy changes.
- Distinguish network approvals that require the originating turn from proxy approvals that can be serviced by a later active turn.

## Testing

Extend regression coverage for disconnected network requests, late cancellation responses, turn completion during review, shutdown cleanup, mismatched turn IDs, and command approvals from background code running during a later turn.

GitOrigin-RevId: 78f656d92607ec21ddd0c5d781ed0947588cb2eb
2026-10-30 14:40:32 +00:00
cassirer-openai e9854c0aa5 Validate trace completion records and payload UTF-8 during replay (#58172)
## Why

A completion marker missing its final newline can make an incomplete trace appear complete. Opaque JSON payload validation can also miss invalid UTF-8 inside strings.

## What changed

Require a newline-terminated `RecordingCompleted` record before setting `recording_complete`. Read raw payloads as UTF-8 text before validating their JSON structure.

## Testing

Extend the lifecycle replay test to cover a completion marker missing its final newline and an opaque payload containing invalid UTF-8.

GitOrigin-RevId: a0007ff449cdefeb44065ed9165ef60bf720dad9
2026-10-29 20:44:09 +00:00
cassirer-openai 297f5e33a5 Make rollout recording failures and completion explicit (#58166)
## Why

Enabled rollout tracing could silently fail to initialize, and a terminal task status did not establish whether all recording had finished. Trace consumers need to distinguish a complete recording from a partial bundle, including when a task is interrupted.

## What changed

- Fail thread startup or resume if an enabled recorder cannot initialize, while cleaning up session resources.
- Stop recording after the first write or serialization failure and preserve that failure across shared producers.
- Append a closing record when the last writer handle is released without recording errors. Expose `recording_complete` in `state.json` independently of task success, and mark submission-channel closure as an aborted rollout.
- Reject replay logs with missing or reordered events, mismatched rollout IDs, events after completion, or missing or invalid JSON payloads. Valid prefixes remain replayable with `recording_complete` set to `false`.

## Testing

Add coverage for startup failure and recovery, shared-writer failures, finalization after child handles close, incomplete logs, and missing or malformed payloads. Extend session and CLI tests to check recording completion after shutdown, interruption, stream failure, and submission-channel closure.

GitOrigin-RevId: 30d62fa95912fb0442ad1199776d110884066c30
2026-10-29 19:56:26 +00:00
cassirer-openai 68b67f0ff4 Preserve rollout tracing across sub-agent reloads (#57615)
## Why

Reloading an evicted sub-agent disabled its rollout tracing, leaving later turns out of the trace. Replacement Code Mode sessions could also reuse cell IDs from earlier sessions.

## What changed

- Reattach reloaded children to the root rollout trace and emit `ThreadResumed` without duplicating `ThreadStarted`.
- Reopen existing threads during replay, preserving their identity and history while clearing stale runtime cell and terminal process mappings.
- Allocate Code Mode cell generations across sessions for both gRPC and stdio hosts to prevent ID reuse after reload.
- Record an aborted trace when session startup fails before the session loop begins.

## Testing

Add regression coverage for child eviction and reload, including a failed reload, continued inference tracing, distinct cell IDs, and preserved mail and follow-up context. Extend replay tests for history preservation and reused runtime handles, and host tests for cell IDs across session replacement and reconnection.

GitOrigin-RevId: 6c146c04b5cda9295afb7d973c0d5474b363a822
2026-10-28 01:29:34 +00:00
Brent Traut d93071fae8 Avoid retaining unneeded output items in HTTP response streams (#57563)
## Why

HTTP response streams retained copies of completed output items even when inference tracing was disabled, keeping their payloads alive until the response completed.

## What changed

Collect completed output items only when inference tracing or WebSocket last-response bookkeeping needs them. Make the last-response sender optional and create its channel only for WebSocket requests.

## Testing

Add a regression test that verifies an untraced HTTP stream releases a completed item's shared payload after delivery, while the response remains open. Update existing tracing and WebSocket bookkeeping tests for the optional sender.

GitOrigin-RevId: 7695534c6d00f3002005324c43c23bf733f01804
2026-10-27 20:42:47 +00:00
cassirer-openai e977cb394d Preserve tool output versions and history order in rollout traces (#57311)
## Why

Tool calls can emit multiple outputs, and compaction can trim output content while retaining the same call and item IDs. The trace reducer rejected these versions as conflicting content. Late tool and code-cell events could also link outputs in map-key order instead of conversation order.

## What changed

- Preserve distinct tool output versions while retaining consistency checks for tool invocations.
- Link tool and code-cell outputs in thread history order, and resolve pending code cells after the entire event has been reduced.
- Prevent snapshot reconciliation from reusing the same conversation item twice when identical items move within history.

## Testing

Extend reducer regression tests for trimmed outputs, changed images and metadata, reordered identical messages, and late tool and code-cell events spanning the item-ID ordering boundary.

GitOrigin-RevId: eb4242d6a2d32d61c3caab9d3cc3cf6b374ce799
2026-10-26 23:55:28 +00:00
cassirer-openai f2df3e3b56 Preserve full MCP results in rollout traces (#57280)
## Why

MCP completion events can truncate large results and omit content removed for model consumption. Rollout traces need the original response, including content and metadata, as well as results for calls denied before reaching the backend.

## What changed

- Record MCP runtime results before callbacks, content filtering, and UI truncation, and record skipped calls as failures.
- Stop deriving MCP runtime completion records from protocol events to avoid duplicate records.
- Treat MCP runtime payloads as opaque results when reducing agent interactions.
- Buffer JSON trace writes and explicitly flush them.

## Testing

Extend app-server tests to verify that traces retain oversized MCP text, audio, structured content, and metadata while UI results remain truncated, and that denied calls produce exactly one failed runtime result with the denial reason.

GitOrigin-RevId: 57880770545eb5869420d7dc6fa4a15e481cae9d
2026-10-26 21:56:23 +00:00
cassirer-openai 36021e1ad5 Truncate rollout JSON summaries at UTF-8 character boundaries (#57199)
## Why

Truncating a JSON summary at the 240-byte limit can panic when the cutoff falls inside a multibyte UTF-8 character.

## What changed

Truncate at the nearest preceding character boundary before appending `...`.

## Testing

Extend the JSON tool-call reuse test with multibyte arguments and assert the truncated summary and original payload reference.

GitOrigin-RevId: e4b2af17eb6e3abaeb042772944305c6e1744bdf
2026-10-26 19:11:53 +00:00
cassirer-openai b6a4378862 Classify rollout tool calls by their runtime handler (#57194)
## Why

Tool interception and MCP aliases can route a requested callable to a different handler. Rollout traces need to reflect the handler that actually executes, including when an `exec_command` invocation is intercepted as `apply_patch`.

## What changed

Carry an explicit `ToolCallKind` in runtime-start events and use it to update the tool call's execution classification. This replaces MCP-specific payload inspection while preserving the original callable summary and invocation for intercepted patch and aliased MCP calls.

## Testing

Add a regression test verifying that an intercepted `exec_command` is recorded as `ApplyPatch`, retains its original summary and invocation, completes successfully, and creates no terminal operations or sessions.

GitOrigin-RevId: 0e72f3ef55cda2796e779efd16241e4a0dbf0c5b
2026-10-26 19:04:02 +00:00
cassirer-openai cfc11bfab3 Preserve failed write_stdin calls in rollout trace replay (#57193)
## Why

Invalid model arguments to `write_stdin` represent a tool failure, but parsing them could fail rollout trace replay.

## What changed

Skip terminal operation creation when dispatched `write_stdin` arguments cannot be parsed or lack a usable `session_id`. Preserve the generic tool call and its error, including the original arguments, so replay can continue.

## Testing

Add a regression test covering malformed JSON and missing or null `session_id` values. Verify that replay retains the failed call's arguments and error without creating terminal operations or sessions.

GitOrigin-RevId: 967e975a88072c169eb3e391d5c62e807d608fbf
2026-10-26 19:03:36 +00:00
cassirer-openai e5ea2ed50b Match rollout trace image content across request snapshots (#56342)
## Why

Repeated image outputs in different request payloads could fail replay with a call ID reuse error even when their content was unchanged.

## What changed

- Hash canonical JSON for non-text content parts and compare their `content_sha256` values independently of payload location.
- Preserve empty content arrays as empty bodies so they also match across snapshots.

## Testing

Add a regression test verifying that repeated image and empty tool outputs reuse conversation items, while changed image content with the same call and item IDs still fails replay.

GitOrigin-RevId: 07699312675764079f679fd2c12ba6679332d709
2026-10-23 03:39:48 +00:00
cassirer-openai 5b792948f9 Track accepted conversation history in rollout traces (#56312)
## Why

Model output alone does not establish that an item entered conversation history. Treating every response item as accepted can include discarded attempts, while relying on a later request misses accepted final output when a turn ends or is interrupted.

## What changed

- Record `HistoryItemAccepted` events and retain Responses item IDs, generating missing IDs consistently across item events.
- Build thread conversation history from request inputs, compaction checkpoints, and explicit acceptance. Keep unaccepted output accessible through its inference call.
- Preserve inference provenance across retries and late response records without overwriting newer request or compaction snapshots.
- Mark turns with errors as failed. Bump trace schemas to version 2 and reject incompatible bundles and event schemas during replay.

## Testing

Add reducer coverage for discarded attempts with identical text, late responses, compaction, inherited context, and legacy bundle rejection. Add CLI integration tests that run `debug trace-reduce` after success, stream failure, and interruption followed by shutdown, including responses without provider item IDs.

GitOrigin-RevId: 8e387a91d9b3f704df82847d630e6f0b08f998b3
2026-10-23 00:45:20 +00:00
jif 07316174c6 Forward Guardian reviewer events to parent raw-event subscribers (#56124)
## What changed

Add the disabled-by-default `guardian_recorded_items` feature to forward recorded reviewer items and interruptions through the parent's raw-event subscription, preserving reviewer thread and turn IDs without modifying the parent's history or completing its turn.

Emit reviewer items as `rawResponseItem/completed` notifications and interruptions as interrupted `turn/completed` notifications. Mark opted-in reviewer requests with `guardian_recorded_items` metadata.

## Testing

Extend Guardian integration tests to cover reviewer identity, recorded-item metadata replay, concurrent reviewer interruptions, independent parent completion, and behavior without the feature enabled.

GitOrigin-RevId: beb4dbf6c6f2a800a2fbf3cfd11ae174a1382386
2026-10-22 09:20:00 +00:00
cassirer-openai deede7201d Keep rollout trace terminal sessions distinct when process IDs are reused (#56011)
## Why

Runtime process handles are recyclable and thread-local. Using them as terminal session identities can merge separate commands or associate `write_stdin` operations with the wrong exec.

## What changed

- Give each exec a distinct terminal session and track the latest session for each thread-local process handle.
- Record the exec selected by `write_stdin` at runtime and use it to correct session membership during replay, including when dispatch is delayed until a handle is reused.
- Fall back to the latest session for the thread and handle when replaying older traces without runtime target events.

## Testing

Extend reducer coverage for process ID reuse across threads and successive execs, stdin session membership, and delayed runtime target resolution.

GitOrigin-RevId: 330c6fd26a4eebdef03ae600a030dc76920e0dd9
2026-10-21 23:13:31 +00:00
cassirer-openai d571eaf1f6 Preserve code cell response metadata in rollout traces (#55725)
## Why

Reducing code cell lifecycle events discarded their response payload references and lost the initial response status when the runtime status changed.

## What changed

Store the initial response status and separate raw payload IDs for the initial response and final result on `CodeCell`. Carry payload references through queued lifecycle events so they survive replay when the source item arrives later.

## Testing

Extend lifecycle tests to verify distinct initial and final payload IDs and the preserved initial status for yielded cells that complete and failed cells whose lifecycle events precede their source item.

GitOrigin-RevId: 8f49a3174ea487a5d91ebc2a6c97133aacaabfd2
2026-10-21 02:02:49 +00:00
cassirer-openai 3f31c0a040 Resolve MCP backend identity from runtime events in rollout traces (#55710)
## Why

MCP callable namespaces and tool names can differ from their backend identities or match built-in tool names. Classifying calls by name can misidentify MCP calls and incorrectly parse namespaced `write_stdin` calls as terminal operations.

## What changed

Resolve `ToolCallKind::Mcp` from the runtime invocation's server and tool as soon as the runtime starts, before MCP correlation assignment. Preserve the caller-facing summary and raw invocation, and skip built-in runtime handling for MCP calls.

Only create dispatch-based `write_stdin` terminal operations for calls without a namespace.

## Testing

Add replay regression coverage for prefixed and unprefixed MCP aliases, names that match built-in tools, and `write_stdin` arguments with and without a session ID. Verify backend classification, preserved callable identity and dispatch lifecycle, and the absence of terminal operations and sessions.

GitOrigin-RevId: 71f31335c1eb36b6b7e1a34383d10fc500bd2c4f
2026-10-21 00:53:48 +00:00
Nick Steele a6baf8867c Signal abandonment of unanswered MCP elicitations (#51611)
## Why

Published MCP elicitation requests could lose their response waiter without notifying the event consumer that the request was no longer answerable.

## What changed

- Add `ElicitationAbandoned` with the original server name and response token for requests published through unbounded event channels.
- Emit abandonment exactly once when a waiter is dropped, response delivery fails, or the MCP runtime shuts down.
- Close the elicitation router during shutdown, reject new requests on unbounded sources, and wait for terminal deliveries before shutdown completes. Preserve bounded sources' request-only behavior and backpressure.

## Testing

Add router tests for ordered, exactly-once abandonment, closed receivers, failed response delivery, shutdown coordination, and bounded-channel backpressure. Add a core integration scenario verifying that a pending form's abandonment precedes `ShutdownComplete`.

GitOrigin-RevId: 53fe9f4a8b32f7324be180288aa492f31f4d2057
2026-10-07 07:57:14 +00:00
Steve Coffey b0a6b8d86f Record resolved model and reasoning effort in sub-agent activity (#51463)
## What changed

Add `model` and `reasoningEffort` to `subAgentActivity` items for multi-agent v2 spawns. Capture startup settings before the child begins its turn and resolve the reported effort against model metadata, including model defaults, while preserving the child's configured effort.

Carry these fields through live notifications, persisted activity, thread history, and legacy rollout migration. Update the JSON schemas and generated TypeScript and Python types. Older records and other activity kinds retain null values.

## Testing

Add coverage for resolved spawn settings matching the child's request across legacy and paginated history, preserving configured effort, forwarding metadata through events and history, and reading and migrating older records without the new fields.

GitOrigin-RevId: a9e4241ae21bb8db1ead293f78ffba8257cca0ae
2026-10-06 19:29:40 +00:00
rb-oai 822e58cc3d Handle partial answers in realtime routing and thread search (#51260)
## Why

Messages with the `partial_answer` phase contain answer text without declaring a terminal answer. They should remain searchable and speakable without being treated as final messages.

## What changed

- Preserve explicit `partial_answer` phases in streamed and completed realtime handoffs, bypassing legacy channel-prefix parsing and routing them to the `speakable` channel.
- Treat partial answers as nonterminal in V1 handoffs and omit the final-message prefix.
- Include partial answers in thread occurrence searches and normalize them to the final conversation channel in rollout traces.

## Testing

Extend coverage for realtime phase routing, streamed and completed handoffs, partial-answer search results, and rollout normalization. Verify that turn summaries still exclude nonterminal messages.

GitOrigin-RevId: aa183da783f6e7e0b78ddd51073cba533297e121
2026-10-06 03:58:55 +00:00
Owen Lin c5d242fa79 Consolidate command execution output into aggregated_output (#50402)
## What changed

- Remove `stdout`, `stderr`, and `formatted_output` from `CommandExecutionItem` and `ExecCommandEndEvent`, retaining `aggregated_output` as the output field.
- Update command event producers, legacy conversion, rollout traces, and the precomputed schema. Use aggregated output for terminal trace results.
- Clear `interaction_input` in emitted and migrated command completion items.

## Testing

Update command execution and trace tests to use aggregated output, and assert that legacy rollout migration preserves `aggregatedOutput`.

GitOrigin-RevId: ed59827d4a5ec9a767084ee4feac72c2042440f2
2026-10-02 18:48:49 +00:00
alexsong-oai 41d3dc56a0 Surface model provider authentication recovery progress (#41239)
## What changed

- Emit turn-scoped authentication recovery started and completed events when a model provider refreshes expired credentials.
- Add stable `modelProvider/authRecoveryStarted` and `modelProvider/authRecoveryCompleted` app-server notifications with the thread, turn, provider, and user-facing message.
- Show recovery progress in the TUI and `codex exec`, including Amazon Bedrock session reauthentication.

## Testing

- Cover provider recovery success and failure events, app-server routing, client rendering, and Amazon Bedrock credential refresh.

GitOrigin-RevId: 3010c38d0676f18bced27761cf86dd38344d09f9
2026-08-28 01:14:02 +00:00
jif b705b6b076 Report completed sub-agent activity on parent turns (#40437)
## Why

A Multi-Agent V2 child can finish after the parent turn that spawned it, so its
successful completion needs to remain associated with that parent turn in
notifications and history.

## What changed

- Add `completed` to `SubAgentActivityKind` and emit the corresponding started
  and completed item events on the spawning parent turn when a child succeeds.
- Persist completed activity as a canonical turn item in both legacy and
  paginated history, and expose it through app-server history and schemas.
- Render completed activity as terminal in the TUI without counting it as a
  separate tool call or tool-runtime event.

## Testing

- Cover successful completion in legacy and paginated history, late updates to
  completed parent turns, TUI rendering, analytics, and rollout tracing.
- Verify that terminal child errors do not emit completed activity.

GitOrigin-RevId: 6c71eb8b10e7327611c6af84f70e294e27d94d02
2026-08-24 17:07:21 +00:00
efrazer-oai bc8b25ea02 Add durable user-message queue dispatch (#37204)
## What changed

- Add a storage-neutral queue extension for listing, adding, editing, reordering, deleting, and explicitly starting queued user messages.
- Dispatch queued messages in FIFO order when a thread becomes idle after a completed turn, while leaving them queued after interruptions or failures.
- Wait for user input to be persisted before removing its queue item, and report hook rejection, task termination, and persistence failures distinctly.
- Snapshot local image and audio attachments into validated data URLs before storing them, enforce input limits, and emit `ThreadQueueChanged` events after mutations.

## Testing

- Cover queue mutations, automatic and explicit dispatch, interruption and failure behavior, hook rejection, invalid records, input limits, and local attachment snapshotting.

GitOrigin-RevId: 14f39d7c8cbaccb767a6da84b82cced0edfcb4b9
2026-08-06 03:11:42 +00:00
mandal-OAI 745603a5a1 Ignore passthrough metadata when reconciling rollout items (#36221)
## What changed

- Remove top-level `internal_chat_message_metadata_passthrough` from model items before rollout-trace normalization so replayed tool calls and outputs reuse their existing conversation items.
- Keep nested metadata model-visible and continue rejecting call ID reuse when that content changes.

## Testing

- Add reducer coverage for replayed tool search calls and tool outputs with top-level passthrough metadata, plus conflicting nested metadata.

GitOrigin-RevId: db81b9957770a2226f77db1d9df87e75572fc6de
2026-07-30 21:09:15 +00:00
Kyle Brown 9fc4e5a7aa Preserve plugin attribution across command approvals (#35029)
## What changed

- Add optional `plugin_id` and `script_path` fields to execution approval and guardian assessment events.
- Propagate validated plugin attribution through delegated approvals, guardian-reviewed command items, app-server notifications, thread history, and rollout traces.
- Preserve attribution on both started and completed command items, including declined commands.

## Testing

- Extend core, app-server, thread-history, and rollout-trace tests to cover plugin attribution propagation and serialization.

GitOrigin-RevId: 723684d010cab04142918d7a95e06ed95d008da1
2026-07-23 23:13:59 +00:00
Kyle Brown 84fa68b429 Attribute command executions to trusted plugin scripts (#35020)
## What changed

- Resolve shell and unified-exec commands against the trusted plugin roots loaded for each turn.
- Add optional `pluginId` and safe plugin-relative `scriptPath` fields to command execution items and legacy execution events, and propagate them through app-server notifications.
- Include the attribution in command execution analytics while rejecting absolute, unsafe, and unattributed script paths.

## Testing

- Cover attribution for cached curated and remote plugin scripts from command execution through core and app-server events.
- Verify analytics serialization and unsafe-path filtering.

GitOrigin-RevId: 02fac3a233284ccfc6642fa502a95f1881dba83d
2026-07-23 22:31:53 +00:00
Charlie Marsh fd3c1dc13d Optimize remote compaction history handling (#34431)
## Why

Remote compaction can process large histories. Repeatedly estimating and replacing the full history, and cloning it when tracing is disabled, adds avoidable CPU and memory overhead.

## What changed

- Estimate each history item's token count once, update the total as trailing tool outputs are rewritten, and replace history only after all rewrites are selected.
- Preserve unclamped token totals while calculating removed tokens so saturated estimates do not hide overflow.
- Snapshot compaction input history only when rollout tracing is enabled.
- Reuse the v2 request input instead of cloning it before adding the compaction trigger.

## Testing

- Cover enabled and disabled compaction trace contexts through `is_enabled()` assertions.

GitOrigin-RevId: 8de9c9704ba29532fba05430eb204bbae2e8bf83
2026-07-20 23:30:30 +00:00
Eric Traut 2edad72de3 Track prompt cache write token usage (#33454)
## What changed

- Parse `cache_write_tokens` from response input token details and carry it through token usage aggregation.
- Expose `cache_write_input_tokens` in protocol, app-server, exec, and TypeScript SDK usage events, defaulting it to zero for compatibility with older payloads.
- Report cache-write usage in analytics, metrics, traces, and rollout data alongside existing cache-read usage.

## Testing

- Add coverage for response parsing, usage event output, aggregation, analytics, metrics, and telemetry fields.

GitOrigin-RevId: 634e4fbe3086a8923c0ee13b622573e7d9d221bd
2026-07-16 00:22:53 +00:00
sayan-oai 3afbd8dd45 Report selected environment connection transitions (#33251)
## What changed

- Track connected and disconnected states across initial remote exec-server connections and reconnection attempts.
- Emit experimental `thread/environment/connected` and `thread/environment/disconnected` app-server notifications for each thread selecting the environment. Each payload identifies the thread and environment; current state is not replayed when a thread starts.
- Stop forwarding connection events when an environment selection is removed or replaced.

## Testing

- Cover connection, disconnection, reconnection, shared-environment notifications, and replacement of a selected environment.

GitOrigin-RevId: 5dd767372363c4a2a8319fc16164be117d5bd20c
2026-07-15 05:21:13 +00:00
Dylan Hurd 1c9f890c05 Expose exact per-response usage in raw app-server events (#32985)
## Why

Clients that account for individual upstream Responses API calls need the exact
usage for each completion rather than accumulated or estimated thread usage.

## What changed

- Add the opt-in `rawResponse/completed` app-server notification with the
  `threadId`, `turnId`, `responseId`, and upstream `usage` payload.
- Emit the transient event for normal turns and compaction requests when
  `experimentalRawEvents` is enabled. The event is not persisted or replayed,
  and `usage` is `null` when the upstream response omits it.
- Export the notification in the app-server schemas and document its behavior.

## Testing

- Cover exact token breakdowns for turn and compaction completions.

GitOrigin-RevId: 49040a060bf1784c1ff1dd62112efb4a778428c4
2026-07-14 06:39:42 +00:00
pakrym-oai c9d52de5ca Require prefixes for outbound response item IDs (#32312)
## What changed

- Add a `ResponseItemId` type that generates item-specific prefixes with UUIDv7 suffixes and use it across response items.
- Keep deserialization permissive for legacy histories, but omit empty or unprefixed item IDs from HTTP and WebSocket requests.
- Export the new type in the generated TypeScript protocol schema.

## Testing

- Cover prefixed ID generation, legacy deserialization, prefix recognition, and outbound request filtering.

GitOrigin-RevId: 0209fe430c826d0ae88bc4648652c4ebf390c4a4
2026-07-11 02:29:14 +00:00
Won Park a7c72aee8b Use the image generation extension by default (#31596) 2026-07-09 12:25:19 +09:00
Celia Chen 172ab264bd fix: retry rejected previous-model compaction with selected model (#30319)
## Why

Pre-sampling compaction intentionally uses the previous turn's model
when the compaction compatibility hash changes or when switching to a
model with a smaller context window. This keeps compaction aligned with
the settings that produced the history, but it can block the next turn
when a resumed ChatGPT thread still references a model slug that has
since been retired. The Codex backend rejects that compaction request
before the user's currently selected model gets a chance to sample.

This PR lets those threads recover without changing previous-model
compaction behavior for API-key authentication or custom providers. It
is stacked on #31316, which is a behavior-preserving extraction of the
individual remote compaction attempts; this PR contains the fallback
behavior.

## What changed

- For automatic previous-model compaction, capture the selected model's
request context when using ChatGPT authentication with the OpenAI
provider and the selected model differs from the previous model.
- If the previous-model attempt returns an `InvalidRequest`, retry
compaction once with the selected model for both `/responses/compact`
and Responses Compaction V2.
- Complete history processing, lifecycle events, and token accounting
with the context of the model that successfully compacted the thread.
- If the fallback also fails, return the original previous-model error
so the retry does not change the user-visible failure.
- Record fallback attempts with reason, implementation, and outcome
telemetry.
- Leave API-key authentication, custom providers, same-model turns, and
non-`InvalidRequest` failures on their existing paths.

## Testing

- `just test -p codex-core -E 'test(pre_sampling_compact) |
test(model_unavailable_error)'` (10 tests)
- Added integration coverage for a resumed thread whose model was
renamed, a model downshift using Responses Compaction V2, and API-key
authentication with a custom provider.
2026-07-07 14:26:03 -07:00
rka-oai 33cc928d33 [codex] Use input items for Responses Lite tools (#27946)
When using Responses Lite, we should all use `additional_tools` and a
developer item instead of the top level tools array & instructions
field. This keeps things 1-to-1.

Forced namespacing for _all_ tools will land in a following PR after
some coordination & fixes in Responses API (around collisions & return
items).

The goal is to eventually expand the scope of this to _all_ requests
from codex, but that will require larger coordination across providers &
slower rollout.
2026-06-22 23:56:16 -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
Francis Chalissery 566f7bf631 Propagate safety buffering events to app-server clients (#29371)
Responses API safety buffering metadata currently stops at the transport
boundary, so app-server clients cannot render the in-progress safety
review state.

This change:
- decodes and deduplicates `safety_buffering` metadata from Responses
API SSE and WebSocket events without suppressing the original response
event
- emits a typed core event containing the requested model plus backend
use cases and reasons
- forwards that event as `turn/safetyBuffering/updated` through
app-server v2 and updates generated protocol schemas
- keeps the side-channel event out of persisted rollouts and turn timing

This supports the Codex Apps buffering UX and depends on the Responses
API backend work in https://github.com/openai/openai/pull/1044569 and
https://github.com/openai/openai/pull/1044571.

Validation:
- focused `codex-core` safety-buffering integration test passes
- `cargo check -p codex-core -p codex-app-server -p
codex-app-server-protocol`
- `just fix -p codex-api -p codex-protocol -p codex-core -p
codex-app-server-protocol -p codex-app-server -p codex-rollout -p
codex-rollout-trace -p codex-otel`
- `just fmt`
- broad package test run: 4,430/4,492 passed; 62 unrelated
local-environment/concurrency failures involved unavailable test
binaries, MCP subprocess setup, and app-server timeouts
2026-06-22 03:39:14 +00:00
pakrym-oai f00f93d8c0 [codex] Assign response item IDs when recording history (#28814)
## Why

Client-created response items enter history without IDs, so their
identity is lost across rollout persistence and resume. IDs should be
assigned once at the history-recording boundary, while IDs returned by
the server must remain unchanged.

The Responses API validates item IDs using type-specific prefixes.
Locally generated IDs therefore use the matching prefix plus a
hyphenated UUIDv7, keeping them valid while distinguishable from
server-generated IDs. Because this changes persisted history and
provider request shapes, the behavior is opt-in behind the
under-development `item_ids` feature. Compaction triggers remain request
controls whose API shape does not accept an ID.

## What changed

- Register the disabled-by-default `item_ids` feature and expose it in
`config.schema.json`.
- Make supported optional `ResponseItem` IDs serializable and expose
them in the generated app-server schemas.
- When `item_ids` is enabled, assign an ID during conversation-history
preparation if an item has no ID.
- Generate type-prefixed, hyphenated UUIDv7 IDs using the Responses API
item conventions.
- Preserve existing server IDs without rewriting them.
- Persist assigned IDs in rollouts and include them in subsequent
Responses requests.
- Remove the unsupported ID field from `CompactionTrigger` and document
why it has no ID.
- Add integration coverage for enabled ID persistence, preservation of
server IDs, and omission of generated IDs while the feature is disabled.

`prepare_conversation_items_for_history` is the single response-item ID
allocation boundary.

## Test plan

- `just test -p codex-features`
- `just test -p codex-core
response_item_ids_persist_across_resume_and_preserve_server_ids`
- `just test -p codex-core
non_openai_responses_requests_omit_item_turn_metadata`
- `just test -p codex-core
resize_all_images_prepares_failures_before_history_insertion`
- `just test -p codex-protocol`
- `just test -p codex-app-server-protocol`
- `just test -p codex-api azure_default_store_attaches_ids_and_headers`
2026-06-18 17:30:55 -07:00
Adam Perry @ OpenAI 3931bc2bde unified-exec: retain PathUri in command events (#28780)
## Why

App-server must report command events containing foreign-platform paths
without changing existing client or rollout path-string formats.

## What changed

- retain `PathUri` through exec command begin/end events
- convert cwd values to `LegacyAppPathString` at the app-server
compatibility boundary
- drop command actions with foreign paths and log them
- serialize rollout-trace cwd values using their inferred native path
representation
- restore Wine coverage for retained Windows cwd values and successful
completion
2026-06-18 05:00:04 +00:00
pakrym-oai dbd2857f4b [codex] Add optional IDs to response items (#28812)
## Why

`ResponseItem` variants do not have a consistent internal ID shape: some
variants carry required IDs, some carry optional IDs, and some cannot
represent an ID at all. The existing fields also use inconsistent serde,
TypeScript, and JSON-schema annotations. A single enum-level access path
is needed before history recording can assign and retain IDs.

This PR establishes that internal model only. It intentionally does not
generate or serialize IDs; allocation and wire persistence are isolated
in the stacked follow-up.

## What changed

- Give every concrete `ResponseItem` variant an `Option<String>` ID
field.
- Apply the same internal-only annotations to every ID field:
`#[serde(default, skip_serializing)]`, `#[ts(skip)]`, and
`#[schemars(skip)]`.
- Add `ResponseItem::id()` and `ResponseItem::set_id()` as the shared
accessors.
- Preserve IDs when history items are rewritten for truncation.
- Adapt consumers that previously assumed reasoning and image-generation
IDs were required.
- Regenerate app-server schemas so the hidden fields are represented
consistently.

The serde catch-all `ResponseItem::Other` remains ID-less because it
must remain a unit variant.

## Test plan

- `cargo check --tests -p codex-core -p codex-api -p codex-rollout-trace
-p codex-image-generation-extension`
- `just test -p codex-protocol`
- `just test -p codex-app-server-protocol`
- `just test -p codex-api -p codex-rollout-trace -p
codex-image-generation-extension`
- `just test -p codex-core event_mapping`
2026-06-17 18:27:43 -07:00
jif 5b22a8e5b1 feat: render typed envelopes for multi-agent v2 messages (#28368)
## Why

Multi-agent v2 messages need a consistent, model-visible envelope that
identifies what kind of interaction occurred, who sent it, and which
agent it targets. Previously, encrypted deliveries exposed only
`encrypted_content`, while child completion used the legacy
`<subagent_notification>` shape. That meant the client could not
consistently present `NEW_TASK`, `MESSAGE`, and `FINAL_ANSWER` using the
same format.

This change adds the routing envelope as plaintext while keeping task
and message payloads encrypted. No new Responses API field is required:
an encrypted delivery is represented as an `input_text` header
immediately followed by its existing `encrypted_content` item.

Every envelope now follows this shape:

```text
Message Type: <NEW_TASK | MESSAGE | FINAL_ANSWER>
Task name: <recipient agent path>
Sender: <author agent path>
Payload:
<message payload>
```

## Message types

### `NEW_TASK`

`NEW_TASK` is used when the recipient should begin a new turn, including
an initial `spawn_agent` task and a later `followup_task`.

For a root agent spawning `/root/worker`, the request contains a
plaintext envelope followed by the encrypted task:

```json
{
  "type": "agent_message",
  "author": "/root",
  "recipient": "/root/worker",
  "content": [
    {
      "type": "input_text",
      "text": "Message Type: NEW_TASK\nTask name: /root/worker\nSender: /root\nPayload:\n"
    },
    {
      "type": "encrypted_content",
      "encrypted_content": "<encrypted task payload>"
    }
  ]
}
```

Conceptually, the model receives:

```text
Message Type: NEW_TASK
Task name: /root/worker
Sender: /root
Payload:
Review the authentication changes and report any regressions.
```

### `MESSAGE`

`MESSAGE` is used for a queued `send_message` delivery. It communicates
with an existing agent without starting a new turn.

For `/root/worker` reporting progress to the root agent, the request
contains:

```json
{
  "type": "agent_message",
  "author": "/root/worker",
  "recipient": "/root",
  "content": [
    {
      "type": "input_text",
      "text": "Message Type: MESSAGE\nTask name: /root\nSender: /root/worker\nPayload:\n"
    },
    {
      "type": "encrypted_content",
      "encrypted_content": "<encrypted message payload>"
    }
  ]
}
```

Conceptually, the model receives:

```text
Message Type: MESSAGE
Task name: /root
Sender: /root/worker
Payload:
The protocol tests pass; I am checking the resume path now.
```

### `FINAL_ANSWER`

`FINAL_ANSWER` is emitted when a child agent reaches a terminal state
and reports its result to its parent. Completion payloads are already
available locally, so the complete envelope is represented as plaintext
rather than as a plaintext header plus encrypted content.

For `/root/worker` completing work for the root agent, the request
contains:

```json
{
  "type": "agent_message",
  "author": "/root/worker",
  "recipient": "/root",
  "content": [
    {
      "type": "input_text",
      "text": "Message Type: FINAL_ANSWER\nTask name: /root\nSender: /root/worker\nPayload:\nNo regressions found."
    }
  ]
}
```

The model-visible form is:

```text
Message Type: FINAL_ANSWER
Task name: /root
Sender: /root/worker
Payload:
No regressions found.
```

Errored, shut down, and missing agents also use `FINAL_ANSWER`, with a
terminal-status description in the payload.

## What changed

- Render `NEW_TASK` or `MESSAGE` in
`InterAgentCommunication::to_model_input_item`, based on whether the
encrypted delivery starts a turn.
- Replace the multi-agent v2 `<subagent_notification>` completion
payload with a model-visible `FINAL_ANSWER` envelope.
- Document `Task name`, `Sender`, and `Payload` consistently in the
multi-agent developer instructions.
- Prevent local-only history projections from treating an encrypted
message's plaintext header as the complete assistant message.
- Preserve rollout-trace interaction edges when an agent message
contains both plaintext and encrypted content.

Legacy multi-agent behavior remains unchanged.

## Verification

- `just test -p codex-protocol`
- `just test -p codex-rollout-trace`
- `just test -p codex-web-search-extension`
- `just test -p codex-core
encrypted_multi_agent_v2_spawn_sends_agent_message_to_child`
- `just test -p codex-core
plaintext_multi_agent_v2_completion_sends_agent_message`
- `just test -p codex-core
multi_agent_v2_followup_task_completion_notifies_parent_on_every_turn`
- `just test -p codex-core
multi_agent_v2_completion_queues_message_for_direct_parent`
2026-06-16 11:46:59 +02:00