Commit Graph
239 Commits
Author SHA1 Message Date
Eric Traut 7c9bfb910e Restore thread-owned permissions on cold resume (#53150)
## Why

Cold resume can replace saved unnamed permissions with current configuration defaults or recover an executor's permissions from turn context. A first-turn context can also predate an acknowledged settings update.

## What changed

- Restore eligible unnamed permission profiles from settings snapshots owned by the resumed thread, honoring explicit caller overrides and current managed requirements.
- Use owned snapshots as the authority for named permission profiles and reapply workspace permissions for the resumed workspace roots.
- Persist a thread-owned settings checkpoint after the first turn's context, serialized with settings updates so older checkpoints cannot supersede newer settings.

## Testing

Extend regression coverage for cold resume with changed defaults, managed permission restrictions, workspace-root overrides, foreign snapshots, and settings updates during first-turn processing.

GitOrigin-RevId: e411d9fd3d586a4162498c9c77c4184459071bd1
2026-10-11 15:48:35 +00:00
Channing Conger 2dc0791c7d Add opt-in gRPC over stdio for the code-mode host (#52723)
## What changed

- Add `grpc+stdio://` as a host transport and the disabled-by-default `code_mode_host_grpc` feature flag to select it.
- Share a lazy HTTP/2 channel and host process across code-mode sessions while keeping session state isolated.
- Use HTTP/2 keepalives to detect unresponsive hosts, kill and reap disconnected children, and spawn a fresh host on reconnect. Exit the host when its stdio connection closes.

## Testing

Add coverage for shared-host session isolation, host exit on stdin EOF, and recovery after an unresponsive host is reaped. Exercise nested tool calls with both legacy stdio and gRPC stdio, asserting that the feature flag selects the expected transport.

GitOrigin-RevId: 31389d8540de236b8e0571d3c24e29e117b75c4a
2026-10-09 23:26:34 +00:00
jif a06545b311 Add opt-in history prefix preservation for full agent forks (#52535)
## What changed

Add `preserve_fork_prefix` to the multi-agent v2 configuration, defaulting to `false`. When enabled, full forks retain the parent's model-visible history, including commentary and tool records, and append the child's instructions. Legacy compaction without a reusable context baseline still rebuilds the child context.

Mark copied history as inherited, complete unfinished tool calls in the fork snapshot, and exclude inherited manual approvals from authorization review while retaining them in model context.

## Testing

Add coverage for preserved request prefixes, child instructions, legacy and paginated histories, Code Mode, missing inherited tool outputs, compaction fallback, and approval isolation across checkpoint replay. Update the noisy helper failure test to read its response before starting cleanup.

GitOrigin-RevId: ce9235dfa111c88d6ce66cb93d564fb63b326489
2026-10-09 11:08:24 +00:00
Adam Perry @ OpenAI 780d7ab097 Track history initialization in Responses turn metadata (#52325)
## What changed

Add `history_initialization` to `x-codex-turn-metadata`, distinguishing `new`, `cleared`, `cold_resume`, `warm_fork`, `cold_fork`, and `supplied_history`.

Classify forks by whether the source runtime is loaded and has not shut down. Preserve the classification for the runtime's lifetime, including warm resumes and compaction. This records how history was initialized; it does not establish whether tool metadata is missing. Reserve the field against client-supplied overrides.

## Testing

Extend coverage for warm and cold forks, cold resumes, warm reconnects, supplied history, WebSocket metadata serialization, and reserved-field filtering.

GitOrigin-RevId: 468153512a84d0f4d4ea742198a29e0fa3873a72
2026-10-08 23:34:16 +00:00
Adam Perry @ OpenAI 845345b1dd Preserve subagent capabilities independently of forked history (#52241)
## Why

Subagents should retain the spawning turn's selected skills and plugin choices whether `fork_turns` is `none` or `all`. Capability selection should not depend on copied conversation metadata.

## What changed

- Use a shared child startup path for fresh and history-forked agents, inheriting selected capability roots from the spawning environment snapshot.
- Pass the spawning turn's `disabled_plugin_ids` through both spawn handlers. When omitted, inherit the parent's current choices; explicit lists, including an empty list, override them.
- Resolve the parent before startup so inherited client MCP settings apply even when only the session source identifies the parent.
- Carry plugin choices into delegates with inherited isolation and preserve saved capability roots when resuming a child.

## Testing

Add regression coverage for executor skill listing and reading, plugin MCP registration with both history modes, plugin overrides, capability-root precedence and isolation, and restoring saved child settings after parent settings change.

GitOrigin-RevId: 2a6891a9bc6372fd2d1f30add2b5611f96b60594
2026-10-08 19:21:57 +00:00
liame-oai ec8251c545 Add experimental prediction forks that inherit parent context (#51884)
## Why

Prediction forks need to preserve the parent's effective context and request settings to maximize prompt-cache reuse.

## What changed

- Add `experimentalPredictionMode` to `thread/fork` for ephemeral forks of loaded, persisted parents. Reject configuration overrides, `path`, `lastTurnId`, and `beforeTurnId` in this mode.
- Inherit the parent's effective configuration, tools, environments, collaboration settings, disabled plugins, and persisted history.
- Enable `features.reasoning_effort_override` on the fork while preserving the parent's request-effort baseline, including when overrides were disabled on the parent.
- Report the fork's effective model, service tier, and reasoning effort in the response.

## Testing

Add coverage for matching parent and fork requests and prompt-cache keys across legacy and paginated history, invalid fork parameters, and reasoning-effort inheritance. Add a context snapshot for identical parent and fork continuations.

GitOrigin-RevId: 46b41f2ac331562b441dadff1a0a9f926c94880d
2026-10-08 00:09:03 +00:00
keith thornhill 24edd7b890 Expose detailed agent tree shutdown failure reports (#51515)
## Why

Agent tree shutdown previously returned a generic error without identifying which operation or thread failed, making cleanup failures difficult to diagnose.

## What changed

- Add `AgentTreeShutdown::wait_detailed()` and public report types while preserving the existing `wait()` result and error message.
- Record operation, optional thread ID, and either an abandoned teardown guard or a failed phase with a payload-free error category across session cleanup, child spawn cleanup, and resident eviction.
- Give each tree a correlation ID, log each failure, and retain up to 64 failures with a count of additional failures omitted. Record failures before releasing tree membership so all completed waiters observe the same report.

## Testing

Add unit coverage for aborted and completed teardown, cloned guard context, concurrent and repeated waiters, omitted failure counts, and report formatting without raw error payloads. Extend integration coverage for successful tree shutdown and persistence writer failures, including compatibility with `wait()`.

GitOrigin-RevId: 68784af28b63e875b00a55d78729f0cc5b01ac15
2026-10-06 23:28:55 +00:00
Eddie Chen cfc946f4e1 Expose and persist turn lineage across the app server (#51415)
## 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
2026-10-06 16:56:39 +00:00
Adam Perry @ OpenAI 2dbcab90e2 Separate environment requests from runtime selections (#51221)
## What changed

Introduce `TurnEnvironmentRequest` for caller-supplied environment input and construct `TurnEnvironmentSelection` at session startup and app-server settings boundaries. Update thread startup, default environments, and inherited environment handoffs to use requests, with explicit conversions when reusing runtime selections.

Move the environment types into `protocol::environment` while retaining their `protocol` re-exports. Update test fixtures and existing tests to build request inputs separately from runtime selections.

GitOrigin-RevId: 12e7daaece95aae136afae8b055b4dbaebdffc75
2026-10-06 01:39:50 +00:00
Owen Lin c73775f19e Remove initial messages from session configuration events (#50360)
## What changed

Remove `initial_messages` from `SessionConfiguredEvent` and the corresponding schema. Stop attaching replay history to startup events for resumed or rejoined threads, and remove `InitialHistory::get_event_msgs`.

## Testing

Update the MCP resume test to verify persisted tool events through `load_history`, and retain coverage that resumed requests include prior conversation items.

GitOrigin-RevId: 54b72bc44423c9b1ef2051891ef392c0ede32fe5
2026-10-02 16:55:41 +00:00
ke-oai e4e33a56b0 Enable dynamic tool inheritance for fresh V2 subagents (#50082)
## Why

Subagents spawned without forked history do not receive their parent's client-defined dynamic tools, preventing them from using those tools for delegated work.

## What changed

Add the disabled-by-default `multi_agent_v2_dynamic_tools` feature flag. When enabled, fresh V2 subagents inherit the parent's dynamic tool definitions and persist them in session metadata.

## Testing

Add coverage for V1 and V2 feature gating, tool persistence, and a fresh V2 subagent calling an inherited tool and receiving its result without inheriting parent history. Update TUI assertions and a snapshot to reflect blank-line separation and question text in recovered answers.

GitOrigin-RevId: a17a16bf5570f54ce922c1521cffb883022354f2
2026-10-01 19:45:28 +00:00
sayan-oai 408f48ce0c Capture host-supplied extension data for each turn (#49846)
## What changed

Add `turn_extension_init` to thread startup and settings, and expose `WithTurnExtensionData` for turn input, recovery, and settings requests. Accept or reject data updates together with the request that supplies them.

Each new turn captures the configured data, including automatically started turns. Accepted steering updates the data for future turns while preserving the running turn's capture. Plain requests preserve the configured data; an empty initializer clears it. The data is not persisted and must be supplied again on cold resume.

Expose `current_turn_extension_data` to retrieve typed data only when the requested turn is still running and has not been cancelled.

## Testing

Add an integration test covering initial capture, accepted and rejected steering, inheritance by an automatic turn, clearing future data without changing the active capture, and rejection of lookups for an earlier turn.

GitOrigin-RevId: dd81eda3e32c7b62d783c772221858f4c0e68264
2026-10-01 03:31:48 +00:00
Owen Lin 8e44ad94b0 Add coordinated shutdown for local agent trees (#49814)
## What changed

Expose `ThreadManager::request_agent_tree_shutdown` and an `AgentTreeShutdown::wait` handle. Requests reject new starts in the shared runtime, cancel pending startup, and signal every session in that tree, including delegates outside the thread registry. Waiting covers admitted operations and session teardown, and reports cleanup or persistence writer failures. Other root trees remain unaffected; registry removal and persistence handoff remain caller responsibilities.

Retain tree membership through startup, cancelled spawn cleanup, residency eviction, and completion watchers. Release persistence resources before returning startup failures, and stop completion watchers during tree shutdown without reporting shutdown as a child result.

## Testing

Add coverage for tree isolation, children removed from the registry, delegate teardown, cancellation during required MCP initialization, aborted teardown, persistence writer failures, and successful retry after a failed resume releases its writer.

GitOrigin-RevId: a109e25adf23d20baf7595891099947050c6b6b5
2026-10-01 01:57:56 +00:00
felixxia-oai 92bc601ad6 Reuse unchanged history snapshots when resuming threads (#49600)
## Why

Resuming a thread rereads persisted history even when a preloaded snapshot is unchanged. Reusing that snapshot must still account for writes committed before writer ownership is acquired.

## What changed

- Carry optional, non-serialized revisions from stored history and model context through thread and agent resume paths.
- Validate the revision under writer ownership and reuse the shared snapshot when it matches. Reload stored history when the revision is missing or changed, while preserving explicit history overrides.
- Resolve the selected rollout before loading context, validate compressed snapshots before materialization, and enforce archived-thread restrictions on canonical paths.

## Testing

Extend coverage for snapshot reuse and late-write refresh in legacy and paginated histories, compressed rollout reuse, archived rollout symlinks, and cold child restoration that includes edits made after preloading history.

GitOrigin-RevId: e1fd7aee6ef2b30f41951e6b7e6b01c3e1420cab
2026-09-30 11:59:13 +00:00
sayan-oai 3749d1eff7 Preserve pending environments when spawning subagents (#49075)
## Why

Spawning a subagent before an environment was ready dropped the starting environment from the child's selections. The child needs to retain that environment and receive its configuration or failure when preparation finishes.

## What changed

- Pass the spawning step's environment snapshot to children, preserving ready and starting environments and configuration ownership.
- Propagate the original owner's first configuration result through descendants, applying each session's validation and leaving independently configured children unchanged.
- Preserve pending configuration waits across executor retries. Later owner updates do not overwrite the child's inherited configuration.

## Testing

Add regression coverage for fresh and forked subagents, readiness through turn-settings updates, failure propagation to children and grandchildren, child configuration precedence, and executor retries. Add a request snapshot showing a child using `wait_for_environment` before execution tools become available.

GitOrigin-RevId: a2afed740391f88d195596cfe28e418332b60d43
2026-09-28 20:42:04 +00:00
felixxia-oai 41ed72c32b Add opt-in conversation history retrieval to Guardian reviews (#49036)
## Why

The transcript supplied to Guardian may omit earlier user instructions, restrictions, or revoked permissions. History retrieval lets the reviewer check relevant authorization before approving actions with side effects.

## What changed

- Add the disabled-by-default `guardian_conversation_history_tools` feature. With Apps enabled, expose `user_message.search_messages` and `user_message.read_messages` through the parent's live Apps connection and conversation identity.
- Recheck the parent's current app and tool policy on each call, rejecting disabled tools and calls requiring approval.
- Add retrieval instructions that distinguish user authorization from assistant context and account for later revocations and incomplete results. Allow overrides through `auto_review.experimental_conversation_history_prompt`.
- Limit history responses to an estimated 4,000 tokens by default, configurable through `auto_review.conversation_history_max_output_tokens`, while preserving stricter parent and reviewer limits.
- Allow explicit extension registries for isolated sessions and prevent those sessions from inheriting the implicit Apps connection.

## Testing

Add scenarios covering history tool exposure, parent connection and identity reuse, custom prompts, output truncation, stricter reviewer budgets, and live permission changes on a reused reviewer. Extend configuration coverage for blank prompt overrides.

GitOrigin-RevId: 055a69b113c8548bd58e7d5618ea026ba6d1ffb1
2026-09-28 17:29:52 +00:00
Won Park d7748e1185 Add opt-in structured errors for Guardian circuit-breaker interruptions (#48796)
## Why

Guardian denial-limit interruptions lack a structured error identifying the cause. Make this opt-in because older clients may not recognize the new error in shared history.

## What changed

- Add `auto_review.circuit_break_action = "strict"` to attach `TooManyDenials` to the interrupted turn. The default leaves the error unset.
- Expose `turn.error.codexErrorInfo = "tooManyDenials"` in app-server notifications and saved history, and update protocol schemas and generated types.
- Preserve the warning, denial limit, and interrupted status without emitting a separate error notification.

## Testing

Add an integration test covering omitted, `default`, and `strict` settings, checking warnings, live turn errors, the absence of separate error notifications, and persisted turn errors after restart.

GitOrigin-RevId: cb5d379e64728d4d7b9daf834c13756e4a70db31
2026-09-27 22:05:19 +00:00
Owen Lin 12cb14f7b7 Default local threads to paginated history (#47900)
## What changed

- Make `LocalThreadStore` default to paginated history while retaining explicit legacy mode.
- Explicitly use paginated history for Guardian review sessions and allow in-memory stores to create paginated threads.
- Rename full-history resume, fork, and subagent helpers to identify them as legacy APIs, and document the paginated alternatives.
- Reject `thread/revert` for ephemeral threads and prevent the TUI from replaying or attaching to ephemeral agent threads.

## Testing

Add coverage for preserving the default and explicitly selected history modes and conversation context across restart, and for retaining context after rejected ephemeral reverts. Extend Guardian checkpoint coverage across both history modes and verify that saved reviews use paginated history.

GitOrigin-RevId: 870239eb3757018159ee4f230a009c97d38ac5b7
2026-09-24 18:07:37 +00:00
jif fdbe23da45 Allow hosts to provide agent controllers through ThreadManager (#47808)
## What changed

- Add `ThreadManager::with_agent_control_factory` to select a host-owned controller asynchronously using the final thread ID for new and cold-resumed threads. Keep local control as the default, reuse live controllers on warm resume, and preserve parent controllers for internal sessions.
- Fail startup on factory errors or when a provided controller's identity does not match the session identity.
- Defer root service-tier updates to host controllers until thread registration succeeds, preventing failed starts from changing settings on a shared controller.

GitOrigin-RevId: 095afbecfee5d47329038d2a97d0cc0081f181df
2026-09-24 10:39:10 +00:00
jif e1f3fafad8 Route V2 child loading through AgentControl (#47629)
## What changed

Add `AgentControl::ensure_child_loaded` and use the parent's configured agent control in `ThreadManager` to reload recorded V2 children. The local implementation delegates to the existing loader using the live parent's current configuration, preserving parent-controlled restoration without sending input.

GitOrigin-RevId: 67cadf79cbc034eb271c5ae13145f1a42722fe69
2026-09-23 19:02:47 +00:00
jif 27969c0ae9 Route session agent operations through AgentControl (#47520)
## What changed

- Store `Arc<dyn AgentControl>` in session services and route agent tools, turn admission, usage accounting, completion notifications, and shared settings through the trait.
- Add `AgentControlInit` so delegated and guardian sessions inherit the parent's controller and local runtime.
- Move local registry and context helpers to `LocalAgentRuntime`, keep resume, close, inspection, and status subscriptions on the local controller, and simplify synchronous and infallible trait methods.

GitOrigin-RevId: ad3f213eb483ac524bde56d769f20a78f20989a0
2026-09-23 09:39:30 +00:00
sayan-oai 370cd7cba8 Allow environment selection updates during an active turn (#47435)
## What changed

- Add `environments` to `TurnSettingsUpdate` to replace the selection for subsequent steps without changing future turns.
- Capture model settings and environments together so combined updates apply or reject atomically, while existing steps retain their captured selection.
- Validate environment IDs, working directories, configuration ownership, and permission requirements against the running turn's selections.
- Preserve executor startup behavior when switching environments and use the step's local working directory for tool hooks.

## Testing

Add coverage for workspace switching and restoration on the next turn, atomic model and environment updates, permission validation, executor connection waits, and replacement of pending environment selections.

GitOrigin-RevId: 02b5c57a78fd594b2aed84fc09d9e99eb97be28c
2026-09-23 03:12:33 +00:00
Owen Lin 5121aeff13 Overlap subagent spawn persistence and clean up cancelled children (#47348)
## Why

Forked subagent startup serializes history persistence and spawn-edge writes. Cancellation during startup can also leave a provisional child behind.

## What changed

- Defer copied-history durability so it can run alongside spawn-edge persistence, while still awaiting both before submitting the child's initial input.
- Commit agent and residency reservations and notify clients only after initial input is accepted.
- Guard provisional children so cancellation or startup failure removes and shuts them down, discards their stored state, and closes their spawn edge after any pending edge write finishes.

## Testing

Add coverage for cancellation at the child-history durability barrier, checking child termination, removal, and edge closure. Extend fork-context tests in legacy and paginated history modes to verify inherited context can be read from storage after spawn acknowledgment without flushing the live child first.

GitOrigin-RevId: e02dda57efc32b7237bb7af0ce5e5844922890c3
2026-09-22 19:39:18 +00:00
jif 5c07856e25 Separate local agent runtime state from controller handles (#47301)
## What changed

Extract `LocalAgentRuntime` from `LocalAgentControl` to hold the shared registry, residency state, execution limiter, rollout budget, service tier, instruction provider, and thread-manager bindings. Keep session identity on the controller handle.

Store the runtime in `SessionServices` and use it to bind controllers for child startup, resume, delegation, and guardian reviews. Route ownership checks and residency handling through the shared runtime, preserving registry identity across handles. Update existing test fixtures to keep the controller and runtime paired.

GitOrigin-RevId: 846094657cbdf736da3149f0a1c96b4e01423dfe
2026-09-22 14:48:28 +00:00
jif acc20df49f Prevent V2 agent eviction from racing with queued messages (#47240)
## Why

Accepted inter-agent messages can still be waiting in the submission queue when a worker appears idle. Evicting that worker can lose the queued work, while cancelling an eviction caller can leave shutdown unfinished and allow delivery to a closing runtime.

## What changed

- Pin V2 recipients until queued submissions are handled or dropped, and verify that delivery targets the registered runtime.
- Move `Submission` into core so it can carry the residency guard through queue handoffs.
- Give eviction exclusive access to each runtime and keep it counted against capacity until removal. Run teardown in a separate task so it completes even if its caller is cancelled, and remove registry and residency entries together.

## Testing

Add a regression test covering queued follow-up delivery, eviction refusal while mail is pending, cancelled eviction completing teardown, rejection of late delivery, and capacity reuse after removal.

GitOrigin-RevId: d6de3d68cb6b911942e9ddfc05c65b3741b796b2
2026-09-22 09:50:48 +00:00
jif 73129716c2 Delete persisted message boards with their root threads (#47029)
## Why

Permanent thread deletion needs to remove persisted agent message board data even when the message board feature has been disabled.

## What changed

- Add a cleanup hook for single and batch thread deletion, invoked after reference and writer checks but before rollout removal so cleanup failures remain retryable.
- Remove the deleted roots' channels, posts, and subscriptions regardless of the current feature setting.
- Record board tombstones and check them within write transactions to prevent delayed writes from recreating deleted data.

## Testing

Add an app-server regression test that creates a board, archives its root thread, restarts with the feature disabled, and verifies that permanent deletion removes the persisted channels, posts, and subscriptions.

GitOrigin-RevId: 4ea71559a8df0814dffda23a056a9bbaf6e0a0cb
2026-09-21 13:28:02 +00:00
vinh-gpt e24ac448b3 Allow thread instruction providers to share updates with subagents (#46577)
## Why

Subagents inherit applied instruction snapshots, so later provider updates do not reach running descendants. Hosts need an explicit way to share current thread instructions across an agent tree.

## What changed

- Add `ThreadInstructionsProvider::share_with_subagents()`, defaulting to `false`. Opted-in descendants refresh instructions at their next model-request boundary.
- Retain shared providers across root unloads and descendant reloads. Let a resumed root replace the provider for surviving descendants, or preserve their last shared instructions when it supplies a non-sharing provider.
- Keep providers scoped to their root tree and preserve snapshot-only instructions for root forks and isolated sessions, including Guardian reviews.

## Testing

Add coverage for child and grandchild instruction updates and clearing, provider replacement after root restart, lazy descendant reloads, default snapshot inheritance, and isolation between roots and Guardian sessions.

GitOrigin-RevId: 44c9fb7fe9ae1f96156bdf3c47ab6c4a81bd65e9
2026-09-19 02:15:20 +00:00
jif 7fb599de8c Rename AgentControl to LocalAgentControl (#46513)
GitOrigin-RevId: a8e8a5c818a1751c5d2667f5af87e481482fc7db
2026-09-18 23:39:30 +00:00
Charlie Marsh 17baabd01b Separate thread startup metadata from replay history (#46294)
## Why

`CodexThread` retained the full `SessionConfiguredEvent`, including initial replay messages, and cloned it even for callers that only needed thread or session IDs.

## What changed

Store `ThreadStartupMetadata` without replay history and expose it by reference through `startup_metadata()`. Update callers to read IDs from this metadata. When rejoining a running thread, rebuild the startup response using the supplied resume history for `initial_messages`.

## Testing

Extend the resume test to verify that rejoining reuses the loaded thread, preserves startup metadata, and still returns the original replay messages as a prefix.

GitOrigin-RevId: 9d656063088c28f091d29e5862e4b9d894b7642c
2026-09-17 19:55:20 +00:00
jif 821ad43f9d Tag rollout compression metrics by trigger (#46047)
## Why

Compression metrics do not distinguish startup runs from runs requested through
`rollout/compress`, making their outcomes indistinguishable by entry point.

## What changed

Pass `RolloutCompressionTrigger` from startup and RPC callers through the
compression worker. Add a `trigger` tag with `startup` or `rpc` to run, file,
scan-error, and temporary-file cleanup metrics, including durations, byte counts,
and compression ratios.

GitOrigin-RevId: f23d9da791b666a7311f2323f6bead6570067798
2026-09-16 22:33:15 +00:00
joeytrasatti-openai 19286b8819 Copy current thread attachments into non-ephemeral forks (#45579)
## What changed

Copy the source thread's current attachments when creating a non-ephemeral fork, including forks at an earlier turn. Copies receive new attachment IDs and creation timestamps while preserving resource identities and payloads. Attachment membership can then change independently on either thread; referenced resources are not copied.

Await the atomic copy before publishing the fork. If copying fails, log the error and allow the conversation fork to succeed without attachments. Resuming a fork does not copy attachments again.

Document that clients should use `forkedFromId` on `thread/started` and fetch the fork's attachments with `thread/attachment/list`; copying does not emit per-attachment updates.

## Testing

Add coverage for atomic rollback, independent attachment membership, inheritance across history cutoffs, successful conversation forks after copy failures, and resuming without restoring removed attachments.

GitOrigin-RevId: 939d2c6a3073ccfcd922380c6beda45d3deac606
2026-09-15 02:33:27 +00:00
Krish Chainani 446b771049 Add attachment upload and resolution APIs and pass stores into sessions (#45556)
## What changed

Replace `AttachmentStore::persist` with `upload` and `resolve`. Uploads return inline bytes or a file ID; resolution returns optional file metadata and a download URL only when a minimum URL lifetime is requested. Add image dimensions, digest, size, MIME type, and categorized errors to the API.

Make `InlineAttachmentStore` return the original bytes and report `NotFound` when resolving file IDs. Redact attachment bytes and file URLs in debug output.

Pass the configured image store from the thread manager into sessions and inherit it in delegated sessions. Allow `TestCodexBuilder` to accept a custom image store.

## Testing

Update unit coverage for preserving PNG and JPEG bytes, redacting bytes and URLs in debug output, and rejecting file resolution in the inline store.

GitOrigin-RevId: f313e0048925998d84394c7e5a278e0d39d86a45
2026-09-15 00:29:13 +00:00
jif 7c73903be2 Route Guardian reviewers through ThreadManager for inline parents (#45518)
## Why

Inline delegates have no entry in the thread registry, so reviewer creation cannot depend on looking up the parent or waiting for its thread-ready notification.

## What changed

- Capture parent identity, authentication, shared agent control, originator, and inherited instructions in `StartThreadOptions` so `ThreadManager` can start a child without a registered parent.
- Route Guardian reviewer creation through this path, remove the standalone fallback and readiness gate, and require a Guardian extension host.
- Install explicit reviewer hosts in unit tests and the Guardian reviewer extension in the integration test harness, using `ExtensionRegistry::to_builder()` to preserve existing contributors.

## Testing

Extend the thread-manager regression test to remove the parent from the registry before starting a child, then verify inherited lineage, originator, session identity, and authentication, and exclusion from the public thread list.

GitOrigin-RevId: 468ded6fdce7520cb39d55c1a884dcfa5aaea2d9
2026-09-14 21:23:06 +00:00
jif 08d3748cf0 Add managed thread lifetimes with cancellation-safe startup (#45502)
## Why

Callers need to tie isolated threads to an explicit lifetime and wait for cleanup even when startup is cancelled or its result is never received.

## What changed

- Add `ThreadManager::start_thread_until` to run an isolated thread until a caller-provided future completes or the thread exits, with a `TaskTracker` covering cleanup and deregistration.
- Retain persistence and session resources across interrupted startup so cleanup can release partially initialized resources or shut down a running session using normal history rules.
- Reject resumed history and startup without explicit session isolation.

## Testing

Add integration tests for cancellation during stalled required MCP initialization, dropping an unconsumed startup result, and owner cancellation that preserves history and parent usability. Also verify that failed duplicate startup leaves the existing thread's writer intact.

GitOrigin-RevId: 47251c1b0c43821ab8f950816c6d341d39cdc823
2026-09-14 19:30:11 +00:00
Matthew Zeng c62d191c4c Expose disabled plugin settings in the app-server API (#44905)
## What changed

- Accept `disabledPluginIds` in `thread/settings/update` and `turn/start`. A supplied list replaces the saved selection; omission or `null` preserves it, and `[]` clears it.
- Return the selection in thread start, resume, and fork responses and `thread/settings/updated` notifications. Update generated schemas and client types.
- Restore disabled plugin IDs from the history retained at the requested fork boundary, preserving explicit overrides.

The selection persists across resume but does not yet filter plugin capabilities.

## Testing

Add coverage for replacing, preserving, and clearing selections without inference; turn-start notifications; resume; and fork boundaries across legacy and paginated history, with loaded and restarted parents. Add a core regression test for history restoration and explicit clearing.

GitOrigin-RevId: 654a8c2a0527228d422c0dd4919228447e2663db
2026-09-11 20:27:37 +00:00
vkg-oai fc948f8c47 Add a provider for thread-scoped instructions (#44701)
## What changed

- Expose `ThreadInstructionsProvider` through `StartThreadOptions`. Load its snapshot at startup and model-request boundaries, composing it after global instructions and before repository instructions. Empty or blank output clears only the thread contribution.
- Reject thread instructions exceeding 10,000 estimated tokens independently of the repository instruction budget. Allow host-provided instructions without a filesystem source and rename the shared future type to `LoadInstructionsFuture`.
- Retain the provider across warm resumes; require hosts to supply it again for cold resumes and offline forks. Live forks and subagents inherit applied snapshots without inheriting the source thread's provider, including when the parent is unloaded during setup or reload.
- Include thread instructions in guardian reviewer inheritance and reuse decisions.

## Testing

Add coverage for composition and clearing, refresh within an active turn, size rejection before sampling, cancellation-safe refresh, fork and resume behavior, parent eviction, and reviewer reuse invalidation.

GitOrigin-RevId: 7be9a523cbbfd67704067dfd526188dad89a3c88
2026-09-11 01:57:54 +00:00
vkg-oai 935ac7710d Refresh global instructions at model-request boundaries (#44675)
## Why

Running root threads retained their startup global instructions, so edits to global `AGENTS.md` files did not take effect during an active session.

## What changed

- Reload global instructions when capturing model-request context, including after tools within the same turn. Apply changes without repeating unchanged instructions or rediscovering repository instructions when the environment and trust level are unchanged.
- Preserve the last successful global instructions on read failures, suppress recurring warnings until recovery, and clear instructions when their source is removed or blank.
- Serialize refreshes and allow cancellation without blocking subsequent requests.
- Give new subagents the parent's applied instruction snapshot and update Guardian reviewer reuse to account for refreshed instructions.

## Testing

Add regression coverage for live edits and removal, read failures and recovery, warning suppression, cancellation, subagent inheritance, and Guardian reviewer reuse. Update resume, fork, and compaction tests to verify refreshed instructions.

GitOrigin-RevId: f7e9b399740fa4f45e482c070f6e901ee7cf85cd
2026-09-10 23:46:33 +00:00
jif ed6dde9fda Decouple session isolation from subagent attribution (#44521)
## Why

Session isolation relied on Guardian source attribution. An explicit policy lets callers control inherited capabilities independently of how a session is attributed.

## What changed

- Add `SessionIsolation` with default `Inherit` and opt-in `Isolated` modes, captured at session startup through `ExtensionDataInit`.
- Use the policy to control inherited instructions, extensions, execution rules, and MCP resources. Isolated sessions retain managed execution rules and omit executor-discovered MCP servers.
- Explicitly isolate Guardian reviewers while preserving source-based fallback for older callers and saved reviewers.

## Testing

Extend delegate tests to cover isolation independently of attribution, update execution-policy coverage to supply the explicit policy, and assert that managed reviewers do not inherit the parent's configured MCP tools.

GitOrigin-RevId: f0ab42fa2f0237860ec661e72693ab191216afbf
2026-09-10 12:52:27 +00:00
andrewgu-oai ea53c8d4f7 Add opt-in model discovery for OpenAI API keys (#44392)
## What changed

Add the default-off `api_key_model_discovery` feature and expose it through app-server experimental feature enablement, respecting user configuration overrides.

When enabled, fetch OpenAI API-key model metadata from the Codex backend, honoring explicit provider base URLs. Treat remote catalogs containing visible models as authoritative. When disabled at startup, skip discovery requests and cached catalogs and retain bundled models.

## Testing

Add coverage for feature enablement and user overrides, cached catalogs across sessions, provider routing, and API-key `model/list` results. Extend coverage for remote instructions and auth-specific cache isolation.

GitOrigin-RevId: 4b189c37c615a7f808cb6ff5f0858a9a55f36ebc
2026-09-10 03:18:28 +00:00
joeytrasatti-openai 2df0b747ba Add thread attachment operations with coordinated deletion (#44350)
## Why

Attachment mutations must coordinate with thread deletion so queued requests cannot use metadata belonging to a deleted thread.

## What changed

- Add typed `ThreadStore` operations for idempotent attachment creation, paginated listing, and removal, with capability detection and unsupported defaults.
- Implement attachment operations for SQLite-backed `LocalThreadStore`, including unloaded threads, and preserve invalid-request and missing-thread errors.
- Coordinate attachment mutations with lifecycle locks and move SQLite cleanup into thread-store deletion. Remove state rows only after rollout deletion, preserving retries after cleanup failures.
- Give the in-memory store ownership of its associated SQLite cleanup and remove duplicate cleanup from the app-server.

## Testing

Add coverage for attachment pagination and idempotency, unsupported stores, error categories, lifecycle exclusion, mutations queued behind single and batch deletion, cleanup failure retries, and in-memory state cleanup. Extend the app-server descendant deletion test to verify SQLite rows are removed.

GitOrigin-RevId: f0157538c7c5c2ee1362ce40eac157101c5d4505
2026-09-10 00:30:27 +00:00
Matthew Zeng b5544d5732 Persist disabled plugin IDs in thread settings (#44332)
## What changed

- Add `disabled_plugin_ids` to thread startup options, settings overrides, snapshots, and persisted turn contexts. Omitted overrides preserve the current list; an empty list clears it.
- Restore the selection on resume and capture it before truncating history for a fork. Prefer the owning thread's latest settings snapshot, falling back only to the latest turn context so stale history cannot resurrect an older selection.
- Freeze the selection at turn admission and retain compatibility with histories that lack the new fields.

## Testing

Add coverage for owned settings, explicit clears, latest-turn fallback, and legacy snapshots. Extend settings tests to cover plugin selection during runtime restoration and compaction, and verify initial turn persistence without extra settings checkpoints in both history modes.

GitOrigin-RevId: 75ffbff5763cd93cc5ac69d73b08b237f59bc009
2026-09-09 23:23:59 +00:00
vkg-oai 283f34387b Use StartThreadOptions across thread fork APIs (#44043)
## What changed

Pass `StartThreadOptions` through rollout, loaded-history, and prepared forks instead of separate configuration and startup arguments. Replace `options.initial_history` with the fork snapshot while preserving the other supplied startup options, and update app-server and test callers.

Box the app-server's `thread_fork_inner` future to keep the large fork future out of the shared request dispatcher's stack frame.

GitOrigin-RevId: d54eb8b212dedabaf2c5d99d155637cefd7deb7a
2026-09-09 04:07:40 +00:00
jif 98a5cb46b1 Manage synchronous Guardian reviewers through the thread manager (#43570)
## What changed

- Store the shared `GuardianReviewSessionManager` in thread extension data and let the Guardian extension spawn and fork reviewers through `ThreadManager`, independently of async scorer startup.
- Preserve reviewer reuse, concurrent forks, cancellation, inherited environments, and user instructions. Gate managed reviewer startup on parent registration and remove terminated reviewers from the manager.
- Retain the `guardian` subagent identity in saved conversations. Reject resume of live Guardian reviewers and reject client archive or delete of live owner-managed workers with JSON-RPC error `-32600`; allow normal access after the owner releases them.
- Keep standalone reviewer support for inline delegates and remove duplicated extension prompt and configuration code.

## Testing

Add app-server tests covering reviewer reuse and concurrent forks, inherited instructions and prompt cache keys, live resume and removal rejection, saved reviewer discovery and resume after parent shutdown, and strict Guardian assessment inside an inline review.

GitOrigin-RevId: 4f9893c1ade151eacb4c11ffeae3d9e9ec019187
2026-09-07 19:43:10 +00:00
jif 9f70e348e0 Allow internal sessions to fork from selected history (#43495)
## What changed

Add `ThreadManager::fork_internal_session` to start an internal session from caller-selected committed history without reading an in-flight parent turn or appending an interruption marker. Preserve parent authentication and budget sharing, and propagate fork lineage. Keep `spawn_internal_session` starting with fresh history.

## Testing

Add a regression test verifying that the fork contains only the selected history, retains its parent association and authentication manager, and stays outside the public thread registry.

GitOrigin-RevId: df4260ed3adfa0abe7a07c2b6d8b8c6ef6ba3d16
2026-09-07 15:27:52 +00:00
Krish Chainani 03467026f2 Add an injectable attachment store to ThreadManager (#42634)
## What changed

- Add the `codex-attachment-store` crate with storage-neutral attachment metadata, references, errors, and an asynchronous persistence interface.
- Provide an inline implementation that preserves attachment bytes as media-typed base64 data URLs.
- Inject the store into `ThreadManager`, expose it to consumers, and retain inline storage as the default for existing entry points.

## Testing

- Verify inline storage round-trips binary, text, PNG, and JPEG data.
- Verify attachment debug output redacts URLs while retaining file IDs.

GitOrigin-RevId: 7688dcd3c89d7540ed2398f3e7c63881fbfcda97
2026-09-03 23:20:54 +00:00
Charlie Marsh 8436b749a4 Bound Git root discovery for metadata enrichment (#42132)
## Why

Git root discovery is optional metadata work, but filesystem probes can block. They should not exhaust Tokio's blocking pool, delay runtime shutdown, or prevent later turns from observing repository changes.

## What changed

- Add a shared `GitRootDiscovery` service that coalesces concurrent lookups for the same working directory and limits probes across directories.
- Run probes on detached threads, retain in-flight work across caller cancellation, and discard completed results instead of caching them.
- Use the service for turn and memory metadata enrichment, abort unused turn enrichment when its state is dropped, and limit memory metadata waits to one second.

## Testing

Add coverage for probe sharing, capacity limits, cancellation, fresh discovery, runtime shutdown, memory timeouts, and repositories restored after startup prewarming.

GitOrigin-RevId: bca46fc263e7a12a2f69146d8a0b3e7c7e0846cb
2026-09-01 20:41:32 +00:00
jif 9d0eae74cd Include shared histories in rollout compression (#42039)
## What changed

- Make `local_thread_store_compression` compress cold rollout files across shared and forked histories without a separate compression mode.
- Retire `local_thread_store_shared_compression` while continuing to accept it in strict configuration without changing compression behavior.
- Read rollout files through the compressed-rollout reader when `codex exec resume` determines the latest turn's working directory.

## Testing

- Cover compression and restoration of an archived fork chain.
- Cover cwd-based resume selection when only the compressed rollout remains.
- Cover the removed compatibility key in strict configuration.

GitOrigin-RevId: 8edebf61eccc1f79cabb8e641f8982c76f337bf1
2026-09-01 12:23:20 +00:00
Benjamin Carlsson 9d19c7426e Box the session startup future at its API boundary (#41853)
## What changed

- Make `Session::spawn` return a `BoxFuture` while preserving lazy session
  initialization.
- Prevent the startup wrapper from being inlined so callers do not expose its
  concrete future.
- Await the returned future directly at session creation call sites.

GitOrigin-RevId: 5432745aae1c934b16202716a8d49a8553de2018
2026-08-31 14:43:39 +00:00
jif 1cc81ca89a Support compression for shared rollout lineages (#41357)
## Why

Rollout compression skips files that participate in paginated fork lineages because lineage readers rely on byte offsets into the original JSONL. This prevents shared rollout history from being compressed.

## What changed

- Add a seekable rollout reader that preserves logical JSONL offsets for plain and zstd-compressed files without materializing compressed data beside the rollout.
- Use the reader for lineage validation, model-context replay, and SQLite history projection, including when compression races with a read.
- Add the opt-in `local_thread_store_shared_compression` feature. The default mode continues to leave shared lineages uncompressed for compatibility, while the new mode includes referenced sources and fork pointers.
- Record the uncompressed size in new zstd frames so common prefix-bound checks can avoid decoding the full file.

## Testing

Add coverage for seekable compressed reads, prefix validation across zstd frame shapes, compressed lineage replay and projection, concurrent forks, and compression-mode behavior.

GitOrigin-RevId: 83e519f7eabf7448977eff37c55899858cc17a07
2026-08-28 16:04:26 +00:00
faizan-oai 94967e03e5 Add per-turn cyber access program selection (#40687)
## What changed

- Add the experimental `turn/start.cyberAccessProgram` option with `standard`,
  `daybreakBlue`, and `daybreakRed` values.
- Forward the selection as `access_programs.cyber` on Responses, WebSocket,
  and remote-compaction requests made with ChatGPT authentication, while
  omitting it for API-key and custom-provider requests.
- Preserve the per-turn selection across recovery, compaction, and child-agent
  turns without making it a persistent thread setting.

## Testing

- Cover app-server forwarding, authentication boundaries, WebSocket reuse,
  turn recovery, compaction, and child-agent inheritance.

GitOrigin-RevId: d2eb468f365b2214c5099bc21741cf30f8bd2eb5
2026-08-25 19:54:52 +00:00