Commit Graph
77 Commits
Author SHA1 Message Date
jif fc916a22b5 Expose Guardian assessments in response streams (#57757)
## What changed

Decode `response.metadata` Guardian assessments into typed `GuardianAssessment` events over SSE and WebSocket, carrying `response_id`, `item_id`, and `requires_review`. Ignore assessments with missing, empty, or incorrectly typed required fields while preserving independent delivery of other metadata.

Expose the assessment type to request-scoped extension interceptors. Keep assessments out of conversation history; they do not authorize tool execution.

## Testing

Add SSE coverage for assessment ordering, malformed metadata, and mixed metadata delivery. Extend model request tests to cover SSE and WebSocket interceptor delivery and exclusion from subsequent model input.

GitOrigin-RevId: 282b8817ee97346d76b40bcb412eef023df60ff1
2026-10-28 15:04:29 +00:00
Anthony Tafoya ea819e1f4d Record skill and plugin catalog sizes on publication (#56530)
## What changed

- Add `codex.skills.catalog.entries` and `codex.plugins.catalog.entries` histograms with `cloud` or `executor` stages and `complete`, `warning`, or `partial` status. Partial results take precedence over warnings.
- Exclude cached reads and repeated observations of unchanged failed skill discovery from metric samples.
- Mark executor skill catalogs partial when discovery fails, and clear unpublished executor plugin catalogs instead of publishing an empty result.

## Testing

Extend skill integration tests to check catalog counts and statuses, fresh discovery snapshots, partial discovery, and repeated reads without duplicate samples. Update plugin state tests to distinguish unpublished catalogs from empty discovery results.

GitOrigin-RevId: e25978ba9fce54e9660853b1d9673ddab6db5061
2026-10-23 17:17:50 +00:00
Anthony Tafoya 3fd08b5405 Back off failed cloud skill and plugin catalog refreshes (#55968)
## Why

Failed cloud discovery previously retried before each model step. Apply a cooldown across steps and turns to avoid repeated discovery requests while a provider remains unavailable.

## What changed

- Share per-thread retry backoff logic between cloud skill and plugin catalogs, starting at 30 seconds and doubling to a maximum of 5 minutes.
- Scope cooldowns to authentication and MCP resource generations so account changes and reconnects permit immediate recovery.
- Clear backoff after successful discovery or configuration resets, while allowing cancelled refreshes to retry immediately.

## Testing

Update lifecycle and concurrency tests to cover shared cooldowns, reconnect recovery, and cancellation. Use paused time to verify exponential delays, the 5-minute cap, and backoff across turns.

GitOrigin-RevId: 30dab5ceba51e8ad64c0794c1729719e99f577ce
2026-10-21 19:22:57 +00:00
Anthony Tafoya 9e12b14891 Refresh cloud plugin and skill catalogs after mid-turn auth changes (#55957)
## Why

Authentication can change between model steps. Refresh cloud catalogs before the next step so plugin acceptance and skill instructions reflect the current auth scope, including plugins that are no longer available.

## What changed

- Add a `refresh_catalog_for_step` lifecycle hook and rebuild MCP when plugin catalogs change.
- Reuse successful discovery within a turn and auth scope, serialize concurrent refreshes, and allow retries after failures or cancellation. Limit cloud skill discovery warnings to once per turn.
- Skip cloud discovery during prewarm and other context-only captures, and check hosted plugins even when no executor roots are selected.

## Testing

Add regression coverage for mid-turn auth rotation and plugin removal, serialized refreshes and retries, stale discovery results, and prewarm boundaries.

GitOrigin-RevId: 355681e84dc765e8dc1a04608779d95c706c2188
2026-10-21 18:37:30 +00:00
Ruslan Nigmatullin 66d0de9983 Add lifecycle hooks for inter-agent messages (#55657)
## What changed

Add `MessageLifecycleContributor` hooks to capture extension state when local agent control publishes a message and notify contributors when the recipient commits it to history, before sampling.

Carry shared delivery state through submissions, input queues, and mailbox eviction with `PendingAgentMessage`. Notify consumption at most once per delivery, release captured state when consumed or abandoned, and drop pending mail outside queue locks. Preserve the serialized message format without republishing restored history.

## Testing

Extend the mailbox eviction test to verify that publication state survives eviction and retained messages are consumed before the first resumed model sample.

GitOrigin-RevId: 9a1f6832bd48ec646a3fd179485c095e8dcc72cc
2026-10-20 19:39:43 +00:00
Ruslan Nigmatullin 87f3c3284e Track code-mode cell lifecycle and result buffering time (#55653)
## What changed

- Add `CodeModeCellTiming` notifications for yielded executions, terminal waits, and unavailable cells, with thread, call, and cell identifiers.
- Measure how long completed results remain buffered before retrieval and carry `result_buffered_for` through the runtime, stdio protocol, and gRPC response metadata. Immediate delivery reports zero; waits without a completed result report no buffering measurement.
- Default missing buffering data to zero for compatibility with older hosts.

## Testing

Extend runtime tests to verify buffering duration with a paused clock and retrieval through termination. Add gRPC conversion tests for nanosecond precision, optional metadata, and the distinction between immediate delivery and no completed result.

GitOrigin-RevId: 60c0c5a3affa69ac3779bf1812fca50f5748af76
2026-10-20 18:53:06 +00:00
Anthony Tafoya 9b865ab31e Prepare skill catalogs before building step tools (#55357)
## Why

Skill tools depended on World State rendering to initialize their catalogs and could return `skill catalog is not ready for this step` before rendering completed.

## What changed

- Add an asynchronous `ToolContributor::prepare_for_step` hook and await all contributors before constructing tools.
- Prepare immutable skill catalogs, aliases, plugin policy, and configuration for each step. Tools, invocation detection, and World State rendering consume the prepared state without relying on rendering to perform discovery.
- Apply configuration reloads to subsequent steps while preserving live authorization checks for skill reads.

## Testing

Add coverage for preparation completing before tool construction and World State rendering, skill tools working before rendering, catalogs remaining stable across steps, and configuration reloads during discovery.

GitOrigin-RevId: 1fb95c58c412488353f3bd4403824d6d1476d3d0
2026-10-19 19:33:11 +00:00
pakrym-oai ce0323f2f2 Support typed content in contextual prompt fragments (#54776)
## Why

Contextual fragments and extension-owned world-state sections currently return strings, limiting them to text content.

## What changed

- Return `ContentItem` from fragment bodies and rendering, preserving classification and attribution. Apply text markers only to `InputText`; pass other content through unchanged.
- Allow extension prompt and world-state contributions to carry typed content, and preserve media in context-window hints.
- Hash non-text world-state fragments by their serialized content and role while retaining the existing text hashing behavior.
- Add shared content-to-tool-output conversion that preserves image references, image detail, and audio.

## Testing

Add coverage for typed world-state hashing and preservation of image content and attribution. Expand code-mode output tests to cover input text, output text, file-backed and inline images, and audio.

GitOrigin-RevId: 2ed00d466a3f169b151202f3eef71e667ea64be1
2026-10-17 04:02:21 +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
sayan-oai e8098eb406 Separate selected plugin identities from MCP contributions (#47939)
## Why

Plugin identity and skill ownership need to be available independently of MCP data, including for plugins without servers or connectors. Hosted plugins have no executor root and should not own executor skills.

## What changed

- Add `McpServerContributor::selected_plugins` to declare executor plugin identities with deferred MCP data. Let the host assign server attribution and precedence across contributors.
- Represent hosted connectors with `HostedPluginConnectors` and make `SelectedPluginIdentity::selected_root_id` optional instead of assigning synthetic roots to hosted plugins.
- Resolve executor contributions before reading hosted connectors, and clear stale hosted state on account changes before executor loading can wait.
- Preserve connector declarations from disabled plugins so Apps can hide those connectors.

## Testing

Add coverage for account changes while executor loading is pending. Update tests to verify hosted identities have no executor root and disabled plugins hide their connectors even when plugin IDs differ from root IDs.

GitOrigin-RevId: e7f511264c5874c1b56d5f3e4a46820724046db0
2026-09-24 21:03:50 +00:00
Ruslan Nigmatullin 8de2d336b8 Add extension hooks for model requests and response streams (#47679)
## What changed

Add `ModelRequestContributor` and `ModelResponseInterceptor` to the extension API. Contributors can add filtered `client_metadata` without overwriting existing or reserved fields and create interceptors for individual requests.

Wire contributors into HTTP and WebSocket requests, distinguishing generation from warmup. Apply response interceptors in registration order before tracing and response bookkeeping so transformed output is recorded consistently. Interceptors can inspect, buffer, or transform events, with stream ownership carrying request state and cancellation.

## Testing

Add tests for metadata protection, incremental event transformation, interceptor ordering, upstream cancellation, and consistency between delivered output, traces, and WebSocket bookkeeping. Integration tests cover output gating and interruption over HTTP and WebSocket, including a contributor that bypasses gating for warmup requests.

GitOrigin-RevId: d4bc1745d2cacf8636728dbc0a58ab9f250e9392
2026-09-23 22:10:04 +00:00
Ruslan Nigmatullin a79a18cd0e Expose tool dispatch and timing observations to extensions (#47662)
## Why

Tool lifecycle observers need visibility into calls rejected before execution starts and timing that remains available on cancellation, independently of tracing settings.

## What changed

- Add `on_tool_dispatch` and `on_tool_timing` callbacks to `ToolLifecycleContributor`, with thread, turn, and call IDs for correlation.
- Report direct calls before readiness, dispatch waiting, and hooks. Report handler duration when dispatch completes or is dropped, excluding readiness and gate waiting and returning zero if the call never passes the gate.
- Expose code-mode host durations as a separate `HostOperation` timing boundary. Exclude nested code-mode calls from dispatch and handler timing observations to avoid double counting.

## Testing

Add tests for callback ordering on completed and rejected calls, timing on cancellation, zero handler duration before gate admission without tracing, and code-mode host timing without nested dispatch or handler timing observations.

GitOrigin-RevId: 97998b5094564c13cb2cfad089bb0a9d6615eb5c
2026-09-23 20:49:48 +00:00
felixxia-oai ebc05da3bd Decouple tool restrictions from session identity with ToolPolicy (#46999)
## Why

Tool allowlists alone cannot express the reviewer's sandbox and shell restrictions, which previously depended on session identity. Threads need to supply these restrictions explicitly at startup.

## What changed

- Replace `AllowedTools` with `ToolPolicy`, combining an optional allowlist with managed-sandbox requirements, unified-exec requirements, and control over additional-permission arguments.
- Capture the policy once at startup and apply it during tool registration and construction, including hosted tool filtering. Later extension-state changes cannot relax it.
- Supply the reviewer policy explicitly while retaining the fallback for reviewer sessions without a supplied policy. Explicit policies take precedence over session identity; ordinary defaults preserve existing tool setup.

## Testing

Update tool-planning tests to use explicit policies and add startup coverage for additional-permission schemas, ordinary defaults, reviewer fallbacks, explicit-policy precedence, and policy capture despite later extension-state changes.

GitOrigin-RevId: 71e561d76ea24d961f5b29c7c619bdb1356c216a
2026-09-21 10:40:40 +00:00
Anthony Tafoya 394dadb93d Add turn-start cloud plugin discovery to the MCP extension (#46572)
## What changed

- Support an optional cloud provider alongside executor plugins, refreshing its thread-scoped catalog at each regular turn when plugins are enabled.
- Use cloud connector metadata for app attribution without starting cloud-declared MCP servers.
- Scope cached catalogs to authentication and Apps availability. Retain the previous catalog on discovery failure within the same scope, clear stale catalogs on auth changes, and reject results completed under outdated credentials.
- Add a cancellable regular-task startup phase that reconciles MCP before discovery and reapplies contributor state afterward without invalidating resource caches.

## Testing

Add regression coverage for per-turn refresh, empty catalogs, discovery failures, plugin disabling, auth changes during discovery, MCP reconciliation and cancellation, and cloud app attribution alongside executor MCP tools.

GitOrigin-RevId: 8469eb109ea316e21cbc4122c52ad8000caeef03
2026-09-19 02:07:58 +00:00
papayo-oai b244e9bafe Add a command-start callback for tool lifecycle extensions (#46539)
## What changed

Add `ToolLifecycleContributor::on_command_start` with `CommandStartInput` carrying the resolved command, working directory, selected executor's filesystem, and lifecycle context. Await contributors after command hooks and environment resolution so they can prepare the filesystem before `exec_command` runs, including calls from code mode.

Reserve process IDs only after preparation completes so cancelled preparation does not consume an ID. Keep deterministic process IDs from being reused after removal.

## Testing

Add tests for direct and code-mode calls that verify callbacks receive hook-rewritten commands and the executor's working directory, filesystem preparation completes before execution, and interrupted preparation prevents execution without consuming a process ID. Add a regression test for deterministic process ID reuse after removal.

GitOrigin-RevId: d10bcafcc583a6e3e8b5924d004806727e3763bb
2026-09-19 00:46:06 +00:00
jif 2fdcdeaf0e Add startup tool allowlists for threads (#45711)
## What changed

- Add `AllowedTools` to the extension API, captured once at thread startup to restrict which tools can be advertised or executed. An empty list disables all tools; an absent value preserves ordinary tool setup. Callers must supply the list again when resuming a thread.
- Filter tool registration and hosted tool specifications before Code Mode and discovery. Match names with their namespaces and require generated tools such as `exec` and `wait` to be explicitly allowed.
- Move Guardian reviewer tool selection into the allowlist while retaining feature and sandbox restrictions, with a fallback for older reviewer sessions.

## Testing

Add coverage for selected, empty, and absent allowlists across tool sources and Code Mode. Add managed-thread tests verifying advertised tools, rejection of excluded calls, and that replacing extension state after startup cannot change the captured allowlist.

GitOrigin-RevId: 33c1722c4241f368963d8385fa0415112e16a72d
2026-09-15 14:45:35 +00:00
felixxia-oai 1fd392f6b2 Retire the unused Guardian extension prototype API (#45679)
## What changed

- Mark `guardian_ext` as a removed compatibility flag.
- Remove `InternalSessionSpawner`, `InternalSessionSpawnFuture`, `ApprovalReviewInput`, and `ApprovalReviewError` from the extension API, along with the spawner test.
- Remove `NodeReplReviewEvidence::review_inputs` and make the core re-exports of `NodeReplReviewEvidenceMode` crate-private.

GitOrigin-RevId: 1c532bc57264644cf521ef8077285a9b8ed67391
2026-09-15 11:39:20 +00:00
felixxia-oai f2d9bccbde Remove Guardian subagent-spawner plumbing (#45491)
## What changed

- Remove `AgentSpawner` and `AgentSpawnFuture` from the extension API, along with the Guardian wrapper, thread lifecycle context, and app-server injection plumbing.
- Define `InternalSessionSpawnFuture` directly as a boxed future instead of aliasing `AgentSpawnFuture`.
- Raise the workspace `rustls` minimum version to `0.23.45`.

GitOrigin-RevId: b7319dee41bfb869479afeb7555a6f050c4d00a5
2026-09-14 18:56:43 +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
thomas 6baa076eb6 Allow extensions to select MCP protocol mode per HTTP server (#44571)
## Why

Extension-owned HTTP MCP servers previously inherited the default protocol mode. Extensions need to select a mode for their own server independently of other HTTP servers.

## What changed

- Add `McpServerContribution::SetWithProtocolMode` and re-export `McpProtocolMode` through the extension API.
- Carry the winning registration's protocol override through catalog resolution and materialization, and apply it to Streamable HTTP connections.
- Preserve existing defaults when no override is present. Selecting a protocol mode does not grant host-owned Apps cache access or environment authority.

## Testing

Add coverage for registration precedence and materialization, and extend cache isolation tests to cover explicit protocol selection. Add an integration test verifying that extension servers can select either the legacy or newer protocol while other HTTP servers retain the default mode.

GitOrigin-RevId: 606cecc03094a93258ffc433849f575020b81473
2026-09-10 16:02:59 +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
Eric Traut 7c098d8741 Gate new turn submissions on host shutdown admission (#43943)
## Why

Hosts need to stop new turn-input work during shutdown without consuming pending input or preventing already-running delegated work from finishing.

## What changed

- Add an optional `TurnStartAdmission` extension gate, checked before reserving or starting a new turn. Hosts without a gate retain existing behavior.
- Return `NotSubmittedReason::ServerDraining` for refused starts and surface an app-server error instructing clients to reconnect and retry.
- Keep steering, parent-delegated subagent input, and memory-only mailbox wakeups available during drain, while gating automatic starts.
- Close realtime conversations with an ordered handoff, error, and close event sequence when a handoff is refused during drain.

## Testing

Add regression coverage for rejected input staying out of subsequent requests, persisted queue items remaining available for later starts, delegated agent and review work completing during drain, mailbox wakeups, and realtime handoff error ordering.

GitOrigin-RevId: 03dbdcd71eab200e597c0649e6eb39bd92dbc82f
2026-09-08 23:45:10 +00:00
jif db0568dbbb Remove legacy Guardian approval review paths (#43462)
## What changed

- Remove the `fast_decision` and `full_review` extension hooks and `ApprovalAssessment`, leaving `ApprovalReviewContributor::decide` as the approval decision interface.
- Remove the duplicate Guardian V2 fast-approval implementation and `StrictReviewReason` state.
- Require an explicit `GuardianReviewReason` for synchronous reviews.

## Testing

Migrate Guardian reviewer tests to the production `decide_approval` path and cached-score tests to the registry's decision interface.

GitOrigin-RevId: 1f9092c0ff5bb1eed0c63fa557fb3807e2e71564
2026-09-07 13:02:46 +00:00
jif 0ae02915bd Add request-scoped Guardian approval decisions (#42807)
## What changed

- Extend `ApprovalReviewContributor` with a `decide` hook that can allow an
  action, return a synchronous review result, or hand the request to the user.
- Pass contributors the request's approval state and a callback bound to the
  existing synchronous reviewer. Review results satisfy the review gate while
  the host continues to enforce permissions.
- Add structured reasons for requesting a fresh Guardian review and select the
  first contributor decision in registration order.

GitOrigin-RevId: ec84474b3fcbcf1027c8502aa1c2947c10149f9d
2026-09-04 17:38:39 +00:00
jif 86b7d12742 Add Guardian V2 analytics events (#42144)
## What changed

- Emit `codex_guardian_v2_classification` events with the outcome, risk
  level, duration, model, and thread attribution.
- Emit `codex_guardian_v2_fast_decision` events when Guardian V2 approves an
  action without a full review.
- Add `guardian_v2_enabled` to turn analytics, accounting for review scope
  and model requirements.

## Testing

- Extend the Guardian V2 app-server coverage to verify event payloads,
  attribution, enablement state, and scoped event emission.

GitOrigin-RevId: 0805975f8e8f9d954aa1058ea8c60545a090ae74
2026-09-01 22:02:42 +00:00
Evan Fannin 5bf0ba3dd6 Let extensions process MCP tool results (#41202)
## What changed

- Add `ToolLifecycleContributor::on_mcp_tool_result` with access to the
  executed MCP tool context, rewritten arguments, extension data stores, and
  mutable server result.
- Run contributors before publishing MCP completion and before preparing the
  result for the model, so extensions can inspect or replace successful and
  error results.

## Testing

- Cover unchanged, replaced, and error results for direct MCP calls, plus
  replaced and error results through Code Mode.
- Verify completion waits for result processing and the processed result flows
  to both completion events and subsequent model input.

GitOrigin-RevId: ece7acfe9c5eed4778cb78a29c3ffd06a74e1bcf
2026-08-27 20:39:39 +00:00
felixxia-oai 21ff2e802c Expose MCP provenance to tool lifecycle extensions (#40976)
## What changed

- Add optional `McpToolContext` metadata to `ToolStartInput`, exposing the
  model-visible MCP tool details and its source classification without exposing
  the executable client.
- Classify MCP calls as connectors, configured servers, plugin servers,
  executor-selected plugins, or other registrations based on the prepared call.
- Prepare each MCP call before notifying tool lifecycle contributors and reuse
  that same call for execution so the callback describes the call that runs.

## Testing

- Cover host-owned connector calls and extension-owned Apps server calls,
  including their distinct provenance and executed tool names.

GitOrigin-RevId: efd23f511b1045ffdd96349d621ad62365569b2b
2026-08-26 21:30:23 +00:00
vkg-oai 5ca4175295 Rename host instruction payload to Instructions (#40709)
## What changed

Rename the `UserInstructions` type to `Instructions` across the extension API,
its core API re-export, and all consumers. This keeps loading behavior and the
`LoadedUserInstructions` provider interface unchanged.

GitOrigin-RevId: 1ac236b34c31718e7aa38ff5eae5e9b179aeedd8
2026-08-25 21:20:51 +00:00
Won Park 333beecd41 Add structured full approval reviews to extensions (#40472)
## What changed

- Split the approval review contributor into a `fast_decision` path for existing evidence and a `full_review` path for structured reviews.
- Add host-owned full-review inputs with action evidence, conversation history, thread and turn identifiers, approval context, and extension data.
- Add structured assessment and error types, and resolve full reviews using the first contributor that claims the request.

## Testing

- Cover full-review input propagation, first-claim ordering, and short-circuit behavior in the extension registry tests.

GitOrigin-RevId: 6f763d874af8c0b66a0d760b7b7c7dfe32251c9e
2026-08-24 20:25:26 +00:00
Tamir Duberstein e3609f2d02 Expose invocation sources to extension tools (#40382)
## What changed

- Add `ToolCallSource` to extension `ToolCall`s and propagate direct or Code Mode
  invocation metadata, including the runtime cell and nested tool-call IDs.
- Add `ToolCall::response_byte_budget` so extension tools can bound direct-call
  responses by the host truncation policy while allowing Code Mode responses up
  to the tool's own limit.
- Share the skills extension's response-size limit between its `list` and `read`
  tools.

## Testing

- Verify that Code Mode source metadata is preserved when core constructs an
  extension tool call.

GitOrigin-RevId: b10aef01be30d35b67bee3af24a1a4175c9ee112
2026-08-24 11:02:14 +00:00
pakrym-oai 546eed94ac Require content kinds for extension prompt fragments (#40177)
## What changed

- Require each `PromptFragment` to include a producer-owned `ContentItemKind`.
- Re-export `ContentItemKind` from `codex_extension_api` and assign stable kinds to skills, memories, examples, and test contributors.
- Limit prompt slots to developer policy and developer capabilities, and combine contributed fragments into a single developer update.

## Testing

- Update extension registry tests to verify fragment ordering with the new content-kind metadata.

GitOrigin-RevId: ef8624a9b4ae9dce025bca9c0954d91dd8075e85
2026-08-23 03:12:58 +00:00
Won Park 56012fafb8 Add Guardian internal session support (#39994)
## What changed

- Add an extension API for spawning host-owned internal sessions and a
  `ThreadReadyInput` lifecycle callback that runs after thread registration.
- Add Guardian reviewer session scaffolding that records the parent thread and
  effective model, plus the under-development `guardian_ext` feature flag.
- Start internal sessions with fresh history while preserving parent lineage,
  shared session controls, and internal-thread visibility rules.
- Scope internal-session prompt cache keys to their source and parent thread,
  and expose `guardian` as an internal session source.

## Testing

- Cover internal-session spawning, parent metadata, history isolation, prompt
  cache keys, and extension spawner argument forwarding.

GitOrigin-RevId: 682dae80397d62bb36247796b447042e760ca364
2026-08-21 19:11:05 +00:00
rphilizaire-openai 280d56b1d8 Attribute executor skill invocations to plugins (#39309)
## What changed

- Carry selected plugin identities from MCP discovery into per-turn extension data, limited to capability roots that are ready for the turn.
- Annotate executor skill catalog entries with the matching plugin ID and `user` scope.
- Include that attribution in `skill_invocation` analytics for both explicit and implicit executor skill invocations.

## Testing

- Extend the executor skills app-server test to verify plugin ID, skill scope, and invocation type for explicit and implicit analytics events.

GitOrigin-RevId: 9345600ae29bcb8eb894fffd2d6f7b05f22ebf74
2026-08-18 22:53:31 +00:00
jif 23094236ac Let extensions resolve approval reviews before Guardian (#38592)
## What changed

- Give approval review contributors the first opportunity to resolve an action when automatic review is not required for the model.
- Return an extension's decision directly and fall back to Guardian when no extension claims the review.
- Update Guardian V2 to approve actions below its risk threshold through the review contributor API, and remove the extension approval-policy API.

## Testing

- Verify that an extension approval bypasses both the Guardian model call and the user approval prompt.
- Cover Guardian V2 review decisions for low-risk, high-risk, and disabled threads.

GitOrigin-RevId: 5be56941143aff6f358b75b5f8101b7c047147ae
2026-08-14 15:24:10 +00:00
jif 1c4f42863c Require automatic review for high-risk Guardian v2 actions (#38569)
## What changed

- Add a thread-scoped extension API for requesting automatic review, resolving
  multiple contributors to the strongest requirement.
- Have Guardian v2 request automatic review when it is enabled and the latest
  `action_risk` score is at least `0.8`.
- Honor extension review requirements across tool approvals, MCP elicitation,
  and remote execution while preserving host configuration and managed-policy
  constraints.

## Testing

- Cover contributor registration and requirement resolution.
- Verify Guardian v2 requests review at the threshold, returns to the default
  below it, and does not affect threads where the extension is disabled.
- Exercise extension-requested strict review with a remote model override.

GitOrigin-RevId: 6329fc23585d5cc7173c39bb9952c3109ec3884b
2026-08-14 12:37:13 +00:00
felixxia-oai a70211249a Expose conversation history to tool lifecycle extensions (#38403)
## What changed

- Add a shared, read-only `ConversationHistorySnapshot` capability to the extension API.
- Include the snapshot in `ToolStartInput`, preserving conversation order while excluding contextual user messages.
- Avoid acquiring a history snapshot when no tool lifecycle contributors are registered.

## Testing

- Verify snapshots share existing response items, remain stable as history changes, and filter contextual user messages.
- Verify tool-start callbacks receive the history available for successive tool calls.

GitOrigin-RevId: 822cae33781dd876ea628f104be08d8a449a4900
2026-08-13 16:43:23 +00:00
jif 72fa74fbc9 Persist security risk scores in rollout history (#38363)
## What changed

- Add a `SecurityRiskScore` rollout item containing a category and numeric score.
- Persist the item in both thread history modes while excluding it from model context, user-visible thread history, search text, forks, and reconstructed conversation history.
- Re-export the score type from the extension API.

## Testing

- Cover serialization, persistence and loading, thread history projection, session reconstruction, append planning, and memory filtering.

GitOrigin-RevId: 1926fe366aeaa75052708a6da589f45a38eefb52
2026-08-13 12:04:29 +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
felixxia-oai d6ea5991e7 Add metrics for extension-rendered skill catalogs (#35597)
## What changed

- Add an optional `ExtensionMetrics` capability to thread, turn-input, and world-state contributors, backed by session telemetry in the host.
- Record skill counts, omissions, and truncated description characters for extension-rendered catalogs, tagged by the catalog surface.
- Preserve host session attribution on extension metrics, including the effective model for each turn, and prevent extension tags from overriding host metadata.
- Avoid duplicate host-catalog samples by recording world-state metrics only when the section is published or changes.

## Testing

- Cover metric values and surface tags, session metadata preservation, turn-level model changes, and host world-state publication behavior.

GitOrigin-RevId: 9059e521943a8f81df25a38b03692eddbc1d990d
2026-07-27 11:04:02 +00:00
felixxia-oai 5dd992acd3 Route extension warnings to app-server threads (#35168)
## Why

Extension warnings need a stable thread target even when they are emitted outside an active turn.

## What changed

- Add `ExtensionWarning` and a dedicated `ExtensionEventSink::emit_warning` path with an explicit thread ID and optional turn ID.
- Deliver extension warnings as thread-scoped app-server `warning` notifications, preserving listener ordering and waiting briefly for a subscriber when no listener is active.
- Move skills warnings to the new path, limiting provider catalog warnings to four messages of 256 bytes each.

## Testing

- Cover warning routing, ordering, UTF-8-safe truncation, subscriber fallback, and invalid thread IDs.
- Verify skills warning bounds and app-server delivery of executor catalog budget warnings.

GitOrigin-RevId: 4dcb1ba7f17c0edb1a9d548f9568e0c734bffc15
2026-07-24 12:28:29 +00:00
charleschen-oai 78ba047bda Forward thread originators from standalone extensions (#33677)
## Why

Standalone web search and image requests need to preserve the trusted,
thread-scoped originator used for billing attribution.

## What changed

- Seed extension data with the resolved thread originator and recognize
  `codex_work_cca` and `chatgpt_cca` service names as originators.
- Forward non-default originators from the web search and image generation
  extensions with the shared originator-header helper.

## Testing

- Cover originator resolution, header validation, and forwarding for web
  search, image generation, and image editing.

GitOrigin-RevId: 165dace8e4d24e4bd92f234bff5ec77a21a7ff6e
2026-07-16 19:31:26 +00:00
jif 2b9c050460 Add a skill invocation extension contributor (#32200)
## What changed

- Add `SkillInvocationContributor` and registration support to the extension API.
- Provide invocation callbacks with session-, thread-, and turn-scoped extension data, the turn ID, skill resource, and explicit or implicit invocation kind.
- Notify registered contributors when Codex observes a deduplicated implicit skill invocation.

## Testing

- Extend the extension registry round-trip test to cover skill invocation contributors.

GitOrigin-RevId: f428336728889d9bf4fba41a7dd8d3a6f9b9728c
2026-07-10 15:52:04 +00:00
jif c9e6d9783d Let extensions contribute World State sections (#30100)
## Why

#29856 already owns the durable thread intent and exact environment
binding. This PR adds only the small missing extension boundary: an
extension can contribute one named World State section, while core still
owns persistence, diffing, and model-visible fragment types.

This lets skills stay in the skills extension instead of moving their
runtime into core.

## Shape

```text
extension-owned state
        |
        | contribute section id + JSON snapshot + renderer
        v
core World State
        |
        | compare with the previous snapshot
        v
no message, or one incremental model-visible update
```

The extension API is deliberately small:

```rust
fn contribute_world_state(...) -> Vec<WorldStateSectionContribution>
```

Core adapts the rendered result to `ContextualUserFragment`, records the
snapshot, and keeps the existing compaction/resume behavior.

## What changes

- Adds extension-owned World State section contributions.
- Calls those contributors from the existing per-step World State
builder.
- Restores durable selected capability roots into extension thread state
on resume.
- Keeps the actual model-context fragment and rollout machinery in core.

## What does not change

- No skill or MCP implementation moves out of its extension.
- No new file watcher, generation, or RPC.
- No generic migration of existing World State sections.
- No change to the stable environment-ID assumption from #29856.

## Example

```text
step 1 snapshot: skills = []
step 2 snapshot: skills = [executor-demo:deploy]

core asks the skills extension to render only that change.
```

## Stack

1. **This PR:** let extensions contribute World State sections.
2. Project executor skills through the skills extension.
3. Pin one MCP runtime to each model step.
4. Project selected MCP/app/connector metadata by environment
availability.
5. One end-to-end integration scenario.
2026-06-25 22:23:51 +01:00
jif 9684ec25be Add turn-scoped context contributions (#28911)
## Summary
- keep context injection on a single ContextContributor trait
- split context injection into thread-scoped and turn-scoped
contribution methods
- wire turn-scoped fragments into initial context assembly so extensions
can contribute context from turn-local state
2026-06-18 19:40:28 +02:00
jif 693082f3c4 Make MCP server contributions thread-scoped (#27670)
## Why

`selectedCapabilityRoots` belongs to one thread, but MCP contributors
previously received only the global Codex config. That left no clean way
for a selected executor capability to contribute MCP servers to its own
thread.

## What this PR does

- Gives MCP contributors a small context containing the config and, for
a running thread, its frozen host-seeded inputs.
- Uses the same thread inputs during startup, status queries, refreshes,
and skill dependency checks.
- Keeps threadless MCP operations and the existing hosted Apps behavior
unchanged.
- Adds coverage showing that two threads resolve independent
registrations and that later lifecycle mutations do not change the
frozen MCP inputs.

This PR does not discover plugin manifests, add MCP servers, or launch
anything new. It only establishes the thread-scoped registration
boundary.

## Follow-ups

- Resolve selected executor plugin roots through their owning
environment filesystem.
- Convert their stdio MCP declarations into environment-bound
registrations and add an executor MCP end-to-end test.

## Verification

- `just fmt`
- `cargo check --tests -p codex-protocol -p codex-extension-api -p
codex-mcp-extension -p codex-core -p codex-app-server`

Tests and Clippy were not run.
2026-06-12 11:20:34 +02:00
Won Park 19ce6394af Route image extension reads through turn environments v2 (#27498)
## Why

Image generation used `std::fs::read` for referenced image paths, which
did not support environment-backed filesystems or their sandbox context.

## What changed

- Expose optional turn environments to extension tool calls.
- Include each environment’s ID, working directory, filesystem, and
sandbox context.
- Read referenced images through the selected environment filesystem.
- Keep sandbox usage at the extension call site so extensions can choose
the appropriate access mode.
- Consolidate image request construction into one async function.
- Add coverage for successful environment reads and read failures.

## Validation

- `cargo check -p codex-image-generation-extension --tests`
- `just fmt`
- `just bazel-lock-update`
- `just bazel-lock-check`

`just test -p codex-image-generation-extension` could not complete
because the build exhausted available disk space.
2026-06-11 16:32:52 -07:00
Adam Perry @ OpenAI 236b50125d [codex] Load user instructions through an injected provider (#27101)
## Why

We want to remove implicit use of `$CODEX_HOME` from `codex-core` and
make embedders responsible for supplying user-level instructions. This
also ensures user instructions load when no primary environment is
selected.

## What changed

Stacked on #27415, which makes `codex exec` surface thread-scoped
runtime warnings.

- Added `UserInstructionsProvider` to `codex-extension-api`, with
absolute source attribution and recoverable loading warnings.
- Added `codex-home` with the filesystem-backed provider for
`AGENTS.override.md` and `AGENTS.md`, preserving precedence, fallback,
trimming, lossy UTF-8 handling, and the existing uncapped global
instruction size.
- Removed global instruction loading from `Config` and require
`ThreadManager` callers to inject a provider.
- Load provider instructions once for each fresh root runtime, including
runtimes without a primary environment. Running sessions retain their
snapshot, while child agents inherit the parent snapshot without
invoking the provider.
- Keep provider instructions separate while loading project `AGENTS.md`,
then assemble the model-visible instructions with the existing ordering,
source attribution, warning, and turn-context behavior.
- Wired the Codex home provider through the CLI, app server, MCP server,
core facade, and thread-manager sample.

## Validation

- `just test -p codex-home -p codex-extension-api`
- `just test -p codex-core agents_md`
- `just test -p codex-core guardian`
- `just test -p codex-app-server
thread_start_without_selected_environment_includes_only_global_instruction_source`
- `just test -p codex-exec warning`
- `just bazel-lock-check`
2026-06-11 19:28:47 +00:00
Adam Perry @ OpenAI 2704ecea9a [codex] Remove async_trait from ToolExecutor (#27304)
## Why

We're now [discouraging use of
`async_trait`](https://github.com/openai/codex/pull/20242).

Removing use of `async_trait` from `ToolExecutor` yields a `codex_core`
debug test build speedup of ~78% (from 227.5s to 50.3s) on my machine.

Stacked on #27299, this PR applies the trait change after the handler
bodies have been outlined.

## What

Changed `ToolExecutor::handle` to return an explicit boxed
`ToolExecutorFuture` instead of using `async_trait`.

Updated ToolExecutor implementors to return `Box::pin(...)`, reexported
the future alias through `codex-tools` and `codex-extension-api`, and
removed `codex-tools` direct `async-trait` dependency.
2026-06-10 10:26:53 -07:00
jif d2f6d23c6c Remove async-trait from extension contributors (#27383)
## Why

Extension contributors are registered behind `dyn Trait` objects, so
native `async fn`/RPITIT methods would make these traits
non-object-safe. Spell out the boxed, `Send` future contract directly so
`extension-api` no longer needs `async-trait` while retaining the
existing runtime model.

## What changed

- add a shared `ExtensionFuture` alias and use it for asynchronous
contributor methods
- migrate production and test implementations to return `Box::pin(async
move { ... })`
- remove `async-trait` dependencies where they are no longer used,
keeping it dev-only where unrelated test executors still require it

## Behavior

No behavior change is intended. Contributor futures remain boxed,
`Send`, dynamically dispatched, and lazily executed; cancellation and
callback ordering stay unchanged.

## Testing

- `just test -p codex-extension-api` (11 passed)
- affected extension crates (64 passed)
- targeted `codex-core` contributor tests (14 passed)
- `just fmt`
- `just bazel-lock-update`
- `just bazel-lock-check`

A broad local `codex-core` run compiled successfully but encountered
unrelated sandbox and missing test-binary fixture failures; CI will run
the full checks.
2026-06-10 14:31:09 +02:00
jif 4ec3b8eeea Route hosted Apps MCP through extensions (#27191)
## Stack

- Base: #27184
- This PR is the second vertical and should be reviewed against
`jif/external-plugins-1`, not `main`.

## Why

CCA is moving toward a split runtime where the orchestrator may have no
filesystem or executor, but it still needs to activate remotely hosted
plugin components. HTTP MCP servers are the simplest complete example:
they need configuration and host authentication, but they do not need an
executor process.

The Apps MCP endpoint is currently synthesized by a special-purpose
loader inside the MCP runtime. That works locally, but it leaves hosted
MCP activation outside the extension model being established in #27184.
It also makes the Apps path a poor foundation for plugins whose skills,
MCP servers, connectors, and hooks may come from different sources or
execute in different places.

This PR moves that one behavior behind an extension-owned contribution
while preserving the existing local fallback. It deliberately does not
introduce a generic plugin activation framework.

## What changed

### MCP extension contribution

`codex-extension-api` gains an ordered `McpServerContributor` contract.
A contributor returns typed `Set` or `Remove` overlays for MCP server
configuration; later contributors win for the names they own.

The contract stays at the existing MCP configuration boundary.
Extensions do not create a second connection manager or transport
abstraction.

### Hosted Apps MCP extension

A new `codex-mcp-extension` contributes the reserved `codex_apps` server
from the existing Apps feature, ChatGPT base URL, path override, and
product SKU configuration.

When `apps_mcp_path_override` is enabled for `https://chatgpt.com`, the
resulting streamable HTTP endpoint is
`https://chatgpt.com/backend-api/ps/mcp`. The existing ChatGPT-auth gate
remains authoritative, so this server can run in an orchestrator-only
process without being exposed for API-key sessions.

### One resolved runtime view

`McpManager` now distinguishes three views:

- **configured:** config- and plugin-backed servers before extension
overlays;
- **runtime:** configured servers plus host-installed extension
contributions;
- **effective:** runtime servers after auth gating and compatibility
built-ins.

App-server installs the hosted MCP extension and uses the runtime view
for thread startup, refresh, status, threadless resource reads,
connector discovery, and MCP OAuth lookup. This keeps
`mcpServer/oauth/login` consistent with the servers exposed by the other
MCP APIs. The hosted Apps server itself continues to use existing
ChatGPT host authentication rather than MCP OAuth.

## Compatibility

Hosts that do not install the MCP extension retain the existing Apps MCP
synthesis path. This preserves current local-only, CLI, and
standalone-host behavior while app-server exercises the extension path.

Disabling Apps removes the reserved `codex_apps` entry, and losing
ChatGPT auth removes it from the effective runtime view. Executor
availability is not consulted for this HTTP transport.

## Follow-ups

The next vertical will resolve a manifest-declared stdio MCP server from
an executor-selected plugin root and execute it in the environment that
owns that root. Later verticals can add backend-owned skills, connector
metadata, hooks, durable selection semantics, and incremental local
convergence without changing the component-specific runtime boundaries
introduced here.

## Verification

Focused coverage was added for:

- contributing the hosted Apps MCP at `/backend-api/ps/mcp` without an
executor;
- requiring ChatGPT auth in the effective runtime view;
- removing a reserved configured Apps server when the Apps feature is
disabled.

`cargo check -p codex-app-server -p codex-mcp-extension -p
codex-extension-api -p codex-mcp` passed. Tests and Clippy were not run
locally under the current development instruction; CI provides the full
validation pass.
2026-06-09 22:44:16 +02:00