Commit Graph
115 Commits
Author SHA1 Message Date
Abhinav 85fc4def35 Add MCP tool handler support to the hooks engine (#38705)
## What changed

- Discover synchronous `mcp_tool` hook handlers and invoke their configured MCP server and tool through a supplied executor.
- Expand nested hook-event placeholders in MCP tool inputs while preserving JSON types, and process tool output through the existing hook output contract.
- Represent hook details as handler-specific metadata in `hooks/list`, including MCP server and tool fields, and show those details in the TUI hooks browser.
- Skip unsupported `SessionEnd` MCP hooks and runtimes without MCP invocation support with startup warnings.

## Testing

- Cover argument expansion, missing placeholders, MCP invocation and hook decisions, discovery warnings, `hooks/list` metadata, and TUI rendering.

GitOrigin-RevId: 295b845471fe92bd7ad7cd272fbcd2c3713912e0
2026-08-15 05:53:54 +00:00
joeytrasatti-openai 1549756b78 Add appearance metadata to thread sections (#37898)
## What changed

- Add optional `icon` and `color` appearance fields to custom thread sections and expose them through the app-server protocol.
- Persist appearance metadata in SQLite and include it when listing sections or returning threads.
- Let `threadSection/update` preserve an omitted appearance, clear it with `null`, or replace it with a new value.
- Reject appearance fields larger than 64 bytes.

## Testing

- Cover protocol compatibility, persistence across restart, update and clear behavior, and field-length validation.

GitOrigin-RevId: 8f55ce4f42f8bd17aa5416848a85845f681953df
2026-08-10 23:32:42 +00:00
victor-openai 78d3665d15 Expose plugin ownership in MCP server status (#37850)
## What changed

- Add `pluginId` to each `mcpServerStatus/list` result.
- Populate it for MCP servers contributed by installed or selected plugins, and
  return `null` for servers from other sources.
- Update the generated protocol schemas, TypeScript bindings, and app-server
  documentation.

## Testing

- Cover plugin-owned servers in plugin installation and executor flows.
- Verify non-plugin servers and protocol serialization return a null
  `pluginId`.

GitOrigin-RevId: 0e4b912252cf51be56dcb63e0c1c7365a5e870ee
2026-08-10 17:14:51 +00:00
kylepatel-oai 89a335ed50 Forward install attempt IDs for remote plugins (#37773)
## Why

Clients need to correlate a remote plugin installation request with a specific
installation attempt.

## What changed

- Add the optional `installAttemptId` field to `PluginInstallParams`.
- Forward the value as `install_attempt_id` in the remote plugin install POST
  body.
- Preserve the existing empty request body when the field is omitted.

## Testing

- Cover protocol serialization and remote install request bodies with and
  without an attempt ID.

GitOrigin-RevId: ffdceff4f9329b650848e6428a9ba39646c242c3
2026-08-10 03:28:19 +00:00
viyatb-oai 208f05b233 Enforce automatic review for managed models (#37511)
## What changed

- Add the managed `auto_review.required_on_models` requirement, unioning model slugs across requirement layers and exposing the result through `configRequirements/read`.
- Force listed models to use `on-request` approvals with the `auto_review` reviewer. Downgrade Full Access to workspace-write when starting a protected session, and reject incompatible runtime overrides or use when automatic review is disabled.
- Preserve these protections across thread starts, resumes, forks, model changes, turn overrides, MCP approvals, and TUI session attachment.

## Testing

- Add coverage for layered model requirements and exact provider-alias matching.
- Add app-server tests for protected thread lifecycle operations, unsafe setting overrides, legacy thread upgrades, disabled automatic review, and requirements API output.

GitOrigin-RevId: c4b1d52c3b5b75e86880725412b8f0812e0dfcd9
2026-08-07 23:43:14 +00:00
Alec Barber fcf636a41d Redact secrets from app-server command execution items (#36893)
## Why

Client-facing command execution items can include recognizable secrets in the
rendered command or parsed command actions.

## What changed

- Redact secrets in `commandExecution.command` and `commandActions` for live
  items, completed items, and replayed thread history.
- Keep command approval requests backed by the original executable command and
  parsed actions while using the redacted representation for display items.
- Document that execution item commands are redacted display values rather than
  executable commands.

## Testing

- Cover redaction for command conversion, parsed search actions, legacy replay,
  approval flows, completion notifications, and rejected commands.

GitOrigin-RevId: 2ad056f21882bf5166182ad1a4ff0bf6471d9c0e
2026-08-04 13:16:58 +00:00
jiayuhuang-openai 6751b54cae Add a realtime delegation acknowledgement control (#36413)
## What changed

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

## Testing

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

GitOrigin-RevId: 9fe8efd14e42738c3e86e3e9a8af81d0f4521244
2026-08-01 01:17:26 +00:00
Shijie Rao e2c0837923 Make user input blocking behavior explicit (#36410)
## Why

Clients need to know whether a `request_user_input` request must wait for an
explicit response or may auto-resolve. Using `autoResolutionMs` as that signal
conflated the blocking decision with timeout policy.

## What changed

- Add required `isBlocking` fields to user input protocol and app-server
  request payloads. Plan-mode requests are blocking, while requests from other
  enabled modes are non-blocking.
- Drive the TUI's auto-resolution behavior from `isBlocking` and remove
  `autoResolutionMs` from the model-facing tool schema.
- Deprecate `autoResolutionMs` while retaining it for compatibility, and treat
  legacy payloads without `isBlocking` as blocking.

## Testing

- Cover mode-derived blocking behavior, legacy deserialization, app-server
  forwarding, delegated requests, and TUI auto-resolution.

GitOrigin-RevId: 29aade657ef743065ec264376ba567a9b353d7d7
2026-08-01 00:38:10 +00:00
charlesgong-openai e6cfd40c3f Expose connector candidates in external agent detection (#36218)
## What changed

- Add a `connectors` array to `ExternalAgentConfigDetectResponse` with each candidate's normalized name, detected session count, and detection source.
- Define detection sources for remote MCP server configuration and session tool use, and export the corresponding JSON Schema and TypeScript types.
- Default `connectors` to an empty array when deserializing responses from older servers.

## Testing

- Add a protocol test covering deserialization when `connectors` is omitted.

GitOrigin-RevId: b65d76791099385226ed54411f4c1ef902be43d8
2026-07-30 20:58:06 +00:00
bear-oai 406dc92394 Expose MCP read-only hints in tool call items (#36055)
## What changed

- Propagate MCP tool `readOnlyHint` annotations through tool-call start and
  completion events.
- Include the optional hint in persisted thread history and app-server
  `mcpToolCall` items, preserving compatibility when the annotation is absent.
- Document that the hint describes tool capability, not the outcome of a
  particular invocation.

## Testing

- Cover read-only and write-capable tools in live events and persisted rollout
  data.
- Verify the hint survives thread reads and resumes for both in-progress and
  completed MCP calls.

GitOrigin-RevId: dddfe905146075e5137a1094da485b86b99807f0
2026-07-30 01:37:41 +00:00
jif 7ec480dda5 Distinguish unknown MCP authentication status (#36045)
## Why

OAuth discovery failures do not establish that an MCP server lacks OAuth
support. Reporting those failures as `unsupported` conflates an inconclusive
check with a confirmed result.

## What changed

- Add an `unknown` MCP authentication status across the protocol, app server,
  CLI, and TUI.
- Preserve OAuth discovery errors so callers can report `unknown`, while
  retaining `unsupported` for servers known not to support OAuth.
- Document the distinction in the app server API.

## Testing

- Verify transient HTTP discovery errors are preserved.
- Verify `codex mcp list --json` reports `unknown` when discovery is rate
  limited.

GitOrigin-RevId: e4562985971606740538e542ec7eeee502111964
2026-07-29 23:24:43 +00:00
joeytrasatti-openai ad6fc66b6d Add persisted manual ordering for thread sections (#36007)
## What changed

- Add `thread/section/move` to atomically move a thread into, within, or out of a section. Threads can be inserted before an existing member or appended, and moves within a section preserve `sectionEnteredAt`.
- Add `section_position` sorting to `thread/list`, with ascending order as its default, and expose `sectionEnteredAt` in thread responses.
- Persist section positions and entry times in SQLite, including migration of existing section members into recency order. Section membership is no longer updated through `thread/metadata/update`.

## Testing

- Cover section moves, reordering, pagination, persistence across restarts and rollout reconciliation, concurrent updates, and rank renumbering.

GitOrigin-RevId: aec6d7ddedca5277029b5caf5c074975397e956c
2026-07-29 18:37:22 +00:00
Eric Ning 28f3f1f9ef Expose plugin installation timestamps in app-server summaries (#35859)
## What changed

- Add nullable `installedAt` metadata to `PluginSummary` and its generated schemas, expressed as a Unix timestamp in seconds.
- Preserve the backend installation time for remote plugins across plugin list, installed, read, and share-list responses. Return `null` when the timestamp is unavailable, including for local or uninstalled plugins and older backend responses.

## Testing

- Cover timestamp conversion in the remote plugin list integration test and the field's serialization and backward-compatible default in protocol tests.

GitOrigin-RevId: 8a1640320adb298874e1074e9891d1017ad06937
2026-07-29 01:16:29 +00:00
iceweasel-oai 101d6b8cb2 Preserve foreign paths in background terminal listings (#35850)
## Why

Background terminal working directories can use a path convention from a
different platform than the app-server host. Converting them to host-native
absolute paths can reject otherwise valid terminal entries and fail the list
request.

## What changed

- Represent `ThreadBackgroundTerminal.cwd` with `LegacyAppPathString` at the
  protocol boundary.
- Convert terminal `PathUri` values directly to their inferred native path
  strings instead of validating them against the host platform.

## Testing

Add protocol round-trip coverage for POSIX, Windows drive, and Windows UNC
working directories.

GitOrigin-RevId: d766d54bdc191e75955fb419bec6e60c65f52298
2026-07-29 00:09:15 +00:00
Eric Ning 12b961d4c5 Expose plugin eligibility metadata in app-server summaries (#35837)
## What changed

- Add nullable `disabledReason` and `eligiblePlanTypes` fields to v2
  `PluginSummary` responses and generated schemas.
- Preserve the remote catalog values across discovered, installed, and cached
  plugin summary paths while returning `null` for local plugins and older
  remote responses.
- Treat unrecognized disabled reasons as `unknown` for forward compatibility.

## Testing

- Cover protocol round trips, remote summary propagation, unknown disabled
  reasons, and app-server responses for admin-disabled and plan-ineligible
  plugins.

GitOrigin-RevId: 657a7ea6f838a6ff8bd1769ebcca0f3432684437
2026-07-28 22:28:08 +00:00
joeytrasatti-openai 85c6da1c79 Add persisted sections for organizing threads (#35722)
## What changed

- Replace the `isPinned` thread metadata and filters with an optional persisted
  `section` and `sectionId`.
- Add the paginated `threadSection/list` app-server method so clients can
  discover sections even when they contain no threads.
- Seed a stable `Pinned` section, validate section assignments, and support
  filtering for a specific section or for unsectioned threads.

## Testing

- Cover section protocol serialization, listing and pagination, metadata
  updates, filtering, persistence, migration compatibility, and operation
  without SQLite state.

GitOrigin-RevId: 7972b5471d29317b9387bfd90aa9f573f691ad4c
2026-07-28 05:26:16 +00:00
thomas 61de0d8fe8 Upgrade rmcp to 3.0.0-beta.3 (#35720)
## What changed

- Update the `rmcp` model and transport integrations for `3.0.0-beta.3`.
- Preserve legacy `elicitation/create` form requests, schema defaults, metadata, and wire-format compatibility while adopting the new elicitation types.
- Harden OAuth discovery by using GET-first discovery without starting an MCP session, preventing cross-origin header redirects, validating authorization-server and callback issuers, and retaining compatibility with metadata that omits an issuer.
- Keep stored OAuth credentials readable and avoid requiring reauthorization after transient refresh failures.

## Testing

- Add coverage for legacy elicitation round trips, OAuth discovery variants, callback issuer validation, credential migration, and refresh failures.

GitOrigin-RevId: 756197d26f3fd347c28c400228f6b3d06ed493b7
2026-07-28 05:17:25 +00:00
thomas 32329b289d Expose workspace plugin publish capability (#35254)
## What changed

- Add nullable `canPublishToWorkspace` metadata to plugin share contexts and `plugin/share/save` responses.
- Preserve the remote capability through catalog parsing and app-server responses so clients can decide whether to offer workspace-directory publishing.
- Document that clients should fail closed when the capability is unavailable.

## Testing

- Cover remote catalog parsing, share-save response propagation, and protocol serialization.

GitOrigin-RevId: b0346b3b330169838f800dfdf21dfa5db1a47f4d
2026-07-24 22:14:12 +00:00
rafael-oai 41775559ca Expose Browser Use requirements through the app server (#35033)
## What changed

- Parse the `browser_use.disable_auto_review` setting from layered
  `requirements.toml` configuration.
- Return the setting as `browserUse.disableAutoReview` from
  `configRequirements/read` and publish it in the generated JSON and TypeScript
  schemas.

## Testing

- Add an app-server RPC test covering the Browser Use requirement.

GitOrigin-RevId: 5749d5bc17bcc5b582bf7ed59b8e5b72d6c8f7fc
2026-07-23 23:21:33 +00:00
Kyle Brown 84fa68b429 Attribute command executions to trusted plugin scripts (#35020)
## What changed

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

## Testing

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

GitOrigin-RevId: 02fac3a233284ccfc6642fa502a95f1881dba83d
2026-07-23 22:31:53 +00:00
joeytrasatti-openai 400ee190c3 Add persisted thread pinning to the app server (#34840)
## What changed

- Add `isPinned` to thread responses and allow `thread/metadata/update` to pin or unpin stored threads.
- Add an `isPinned` filter to `thread/list`, including cursor-based pagination and combinations with relationship filters.
- Persist pin state in SQLite without modifying rollout files, default existing threads to unpinned, and preserve pins through reconciliation and archive transitions.

## Testing

- Cover protocol serialization, database migration and indexing, pin updates, filtered pagination, rollout reconciliation, and archive/unarchive behavior.

GitOrigin-RevId: c2eacabd6dae465e2ae6ce8a169e00740960cdb7
2026-07-22 22:54:28 +00:00
jiayuhuang-openai 4ebd976312 Support configurable realtime BEM channel prefixes (#34816)
## What changed

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

## Testing

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

GitOrigin-RevId: d0aef50aa71362a5beef2c6f6d28b8633da4e529
2026-07-22 19:43:35 +00:00
iceweasel-oai 87f71e35b8 Skip missing paths in filesystem sandbox entries (#34598)
## Why

Default read-only protections for project metadata should apply when paths such
as `.git`, `.agents`, and `.codex` exist, without causing sandbox setup to
materialize missing paths as ACL targets.

## What changed

- Add an optional `missing_path_behavior` to filesystem sandbox entries and
  mark default project-metadata protections with `skip`.
- Preserve the behavior through permission transforms and exec/MCP protocol
  serialization while keeping existing path wire variants stable.
- Ignore skip-missing entries when projecting configuration or Windows sandbox
  overrides, while retaining explicit metadata carveouts.

## Testing

- Cover protocol round trips for path and special-path entries.
- Verify default metadata protections and Windows explicit carveout handling.

GitOrigin-RevId: 6df13dadacdd131c44aab9f15a967c81051355c1
2026-07-21 19:17:18 +00:00
Abhinav ee71c4a90f Enforce exact values from managed config requirements (#34597)
## What changed

- Apply managed values for `sqlite_home`, `log_dir`, `model_catalog_json`,
  `check_for_update_on_startup`, `allow_login_shell`, the report-submission
  opt-in, and `windows.sandbox_private_desktop` to the runtime configuration,
  with source-aware warnings when they override configured values.
- Expose these values through `configRequirements/read`, return them from
  `config/read`, include them in session config locks, and show their sources in
  the TUI config debug view.
- Reject app-server writes that overlap an exact managed requirement with
  `configRequirementReadonly` while leaving unrelated sibling keys writable.

## Testing

- Cover runtime overrides, requirement API mapping, config reads and writes,
  session lock serialization, cross-platform path URIs, and debug output.

GitOrigin-RevId: d4e23b6fd7775c1a6dfe2eab313cdcee50b07081
2026-07-21 19:08:58 +00:00
brisebois-oai 6ac68be6fe Accept forceRefetch in plugin list requests (#34573)
## What changed

- Add the optional `forceRefetch` boolean to `PluginListParams` and generated schemas.
- Accept both omitted and enabled values without changing `plugin/list` behavior yet.
- Cover deserialization of the enabled value in the protocol tests.

GitOrigin-RevId: fd4145161e9779638bc0bf18118d5ab5b8478745
2026-07-21 16:30:17 +00:00
charlesgong-openai a30aee8d90 Attribute external agent imports by provider (#34451)
## What changed

- Add an optional opaque `providerId` to `externalAgentConfig/import` for analytics attribution, independently of the `migrationSource` selector.
- Include the provider ID in completed-import and import-failure analytics events.
- Have TUI imports identify their selected migration source as the provider.

## Testing

- Cover provider attribution in app-server import completion and failure tests and analytics serialization tests.

GitOrigin-RevId: 0ee7313a43652e5305939c526bf6b903a79334ad
2026-07-21 02:59:22 +00:00
nhamidi-oai 643de86a19 Add audio output support to dynamic tools and code mode (#34080)
## What changed

- Add `inputAudio` content items to dynamic tool responses, app-server events, thread history, and generated protocol schemas.
- Add an `audio()` code-mode helper that accepts inline data URLs, audio URL objects, and MCP audio blocks.
- Convert MCP audio blocks into model input when audio is supported, and replace unsupported audio with an explanatory text item.
- Reject non-data audio URLs and track audio item counts in dynamic tool analytics.

## Testing

- Cover audio serialization, protocol round trips, thread-history conversion, MCP modality filtering, code-mode helper inputs, and invalid URL handling.

GitOrigin-RevId: 1ed52a8f9c62d4840fb71c5ec736b4a3566243d6
2026-07-18 23:22:13 +00:00
jiayuhuang-openai 312caf176a Seed realtime V3 sessions with initial text items (#34067)
## What changed

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

## Testing

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

GitOrigin-RevId: 09af367f9a07543e3f8d59b7fa5387f932dc5a6a
2026-07-18 20:59:57 +00:00
nhamidi-oai 97dbd01a3d Add audio variants to user input protocols (#33923)
## What changed

- Add remote and local audio variants to core and app-server user inputs, including generated JSON and TypeScript schemas.
- Preserve audio fields when converting app-server inputs and response content into thread items.
- Keep unsupported audio out of model requests, TUI rendering, text extraction, and truncated tool output, using explicit text placeholders where audio is submitted as a model input.

## Testing

- Cover app-server media conversion, unsupported-input placeholders, TUI omission, and tool-output truncation.

GitOrigin-RevId: 16152bf3af674575ce569764a8b472e032e7569d
2026-07-17 23:14:37 +00:00
brisebois-oai bc5c9161b4 Expose plugin installation interstitial requirements (#33896)
## What changed

- Add nullable `mustShowInstallationInterstitial` metadata to app-server
  `PluginSummary` responses.
- Preserve the remote service value through catalog, installed-plugin cache,
  list, read, and share-list paths.
- Return `null` for local plugins and remote responses that omit the field so
  clients can fail closed when the policy is unavailable.

## Testing

- Cover `true`, `false`, and missing values across remote summary paths and
  app-server plugin endpoints.

GitOrigin-RevId: db79702ee2bfa800a9910d64d933bcabecb3ce70
2026-07-17 20:02:51 +00:00
Felipe Coury 3f0669dbd6 Make parent-owned sub-agent threads read-only in the TUI (#33841)
## Why

Multi-agent V2 spawned threads are controlled by their parent and reject direct
app-server input. The TUI should expose that ownership instead of presenting an
input flow that the server will reject.

## What changed

- Add the experimental `Thread.canAcceptDirectInput` capability for loaded
  threads and populate it from the same policy used to validate `turn/start`
  and `turn/steer`. Stored, unloaded threads report `null`.
- Carry the capability through TUI thread discovery, selection, startup, and
  resume flows, with a compatibility fallback for older app servers.
- Present parent-owned threads as view-only, preserve drafts and queued input,
  block agent-directed commands and settings shortcuts, and keep local
  navigation and inspection commands available.

## Testing

- Cover V1 writable and V2 view-only spawned threads through selection and
  resume.
- Cover composer submission paths, queued and initial input preservation,
  allowed navigation commands, settings shortcuts, and the view-only UI.

GitOrigin-RevId: 495ad051249e5577fb0b0c1cc8c40a0998d04918
2026-07-17 15:14:47 +00:00
Martin Au-Yeung 800715d201 Remove template IDs from MCP tool call metadata (#33467)
## What changed

- Remove `template_id` from MCP tool call items and lifecycle events.
- Remove `templateId` from app-server `McpToolCallAppContext` responses and generated schemas.
- Update protocol conversions, documentation, and existing test expectations for the revised metadata shape.

GitOrigin-RevId: f2b1304eadff661eec3966673ea71206b1542b98
2026-07-16 01:23:52 +00:00
charlesgong-openai 1c4af96394 Add Cursor support to setup import (#33426)
## What changed

- Detect and import supported Cursor settings, sandbox permissions, MCP servers,
  project instructions, hooks, agents, commands, plugins, and recent chat
  sessions.
- Update the `/import` flow to check Claude Code and Cursor, prompting for a
  source when both have importable data.
- Add `migrationSource` to the app-server detect and import requests so each
  operation uses the selected adapter, while retaining `source` for import
  attribution and backwards compatibility.

## Testing

- Add coverage for Cursor config conversion, hooks, plugins, session discovery
  and conversion, app-server imports, and TUI source selection.

GitOrigin-RevId: a65a1511b6c1c2f9e3e0cfe4f816bb435807282e
2026-07-15 21:03:49 +00:00
Owen Lin da61f7d8e1 Enable paginated thread history in app-server (#33364)
## What changed

- Allow `thread/start` to select experimental `historyMode: "paginated"` when the thread store supports turn and item pagination.
- Resume paginated threads with bounded model context and require `excludeTurns: true` instead of loading full history.
- Return `turnsBackwardsCursor` and `itemsBackwardsCursor` from `thread/resume` so clients can hydrate durable history through `thread/turns/list` and `thread/items/list` while newer records arrive through live notifications.
- Reject operations that still require full history, including `initialTurnsPage`, `thread/read` with `includeTurns: true`, `thread/rollback`, and detached review.
- Make item cursors independent of the optional `turnId` filter.

## Testing

- Cover paginated thread start, cold and live resume, backwards cursor hydration, metadata reads, unsupported operations, and stores without pagination support.

GitOrigin-RevId: c42f9b268e29d049843330f474fa3ecde12f5b8a
2026-07-15 15:29:13 +00:00
Owen Lin e0a3641e6c Support paginated thread history in app-server list APIs (#33152)
## Why

Clients could discover threads with paginated history, but could not page their
turns through `thread/turns/list`.

## What changed

- Route `thread/turns/list` for paginated threads through the thread store,
  preserving cursors, sort direction, turn status, timing, errors, and the
  requested `summary` or `notLoaded` item view.
- Reject the `full` turn item view for paginated threads and direct clients to
  `thread/items/list` for complete item pagination.
- Return each item page entry with both its containing `turnId` and `item`, so
  clients can regroup thread-wide pages into turns.
- Expose local thread-store turn and item pagination through the `ThreadStore`
  implementation.

## Testing

Added app-server coverage for paging projected turns and items, item views,
cursors, turn metadata, and rejection of the unsupported `full` view.

GitOrigin-RevId: 9c4a127a9b4fa91313f0e87494c62fe2e3a06f19
2026-07-14 20:48:05 +00:00
pakrym-oai 393f64565a Scope runtime workspace roots to execution environments (#32952)
## Why

Multi-environment turns can run against different filesystems, so a single
thread-wide workspace-root list cannot accurately describe every selected
environment.

## What changed

- Add optional `runtimeWorkspaceRoots` to each app-server environment selection.
  Omitted roots default to that environment's `cwd`, while an empty list selects
  no roots.
- Carry environment-native roots through turn selection, model-visible context,
  permission materialization, and tool sandboxing.
- Keep the top-level `runtimeWorkspaceRoots` field as a compatibility input when
  constructing default environment selections; explicit selections use their
  own roots.

## Testing

- Cover thread and turn API defaults, overrides, empty roots, and schema
  round-tripping.
- Verify foreign roots remain model-visible and remote execution applies the
  target environment's roots before sandbox selection.

GitOrigin-RevId: c6e7a62883c45c676c153055f46a55ee15a323a4
2026-07-14 04:41:08 +00:00
briansong-oai 2ca20d5224 Expose structured standalone web search results (#32898)
## Why

Standalone web search can return structured result DTOs separately from its
model-facing text output. App-server clients need access to that data without
coupling Codex to every result type or field.

## What changed

- Preserve the optional `results` array from `/v1/alpha/search` as opaque JSON
  through web-search completion events, thread history, and app-server
  `webSearch` items.
- Keep responses from older endpoints compatible when `results` is absent, and
  allow clients to ignore result types and fields they do not understand.
- Regenerate the protocol schemas and TypeScript definitions for the optional
  field.

## Testing

- Cover responses with missing, empty, and forward-compatible result payloads.
- Verify standalone web-search results round-trip through app-server item
  notifications and thread-item conversion.

GitOrigin-RevId: 739ef5694ece5733f7b8749ec41d6bfa3f33c8c5
2026-07-13 23:37:35 +00:00
Owen Lin a219b6fdb4 core: migrate standalone web search to extension-owned turn items (#31525)
## Description

This PR migrates standalone web search onto the extension-owned
turn-item path introduced in #31283.

Standalone web search now emits `ExtensionItem::WebSearch` through
generic `TurnItem::Extension`, while app-server still exposes the
existing typed `ThreadItem::WebSearch` JSON shape. Hosted Responses API
web search stays on core-owned `TurnItem::WebSearch`.

## What changed

- Added `web_search::WebSearchItem` and `WebSearchAction` to
`codex-extension-items` under the stable `web.search` kind.
- Collapsed `ExtensionTurnItem` to generic `{ item, legacy_events }` now
that no typed extension special cases remain.
- Kept the existing `WebSearchBegin` / `WebSearchEnd` compatibility
events and canonical-first ordering.
- Updated app-server projection/history and generated TypeScript; the
app-server JSON schema is unchanged.
2026-07-08 09:40:00 -07:00
Eric Ning c71895f63b [codex] app-server: expose plugin install policy source (#31293)
## Summary

- Add `PluginInstallPolicySource` to the app-server v2 `PluginSummary`
payload.
- Propagate remote `installation_policy_source` through plugin
summaries, details, installed-plugin caching, and app-server responses.
- Preserve the supported source values and map unrecognized backend
values to `null`.
- Return `null` for local plugins and expose the field in generated JSON
and TypeScript schemas.
- Update app-server API documentation and plugin list/read coverage.

## Testing

- `just test -p codex-app-server-protocol` (251 passed)
- Targeted `codex-app-server` plugin list, installed, and read tests (4
passed)
- Targeted `codex-core-plugins` known and unknown policy source tests (2
passed)
- `just fmt`
- `git diff --check`
2026-07-06 17:12:39 -07:00
Eric Ning d206a5d68f [codex] expose remote plugin versions (#30981) 2026-07-03 17:14:49 -06:00
Owen Lin a107b84967 feat(protocol): define missing rollout turn items (#30282)
## Description

This PR adds canonical core `TurnItem` shapes for command execution,
dynamic tool calls, collab agent tool calls, and sub-agent activity, to
be stored in the rollout file soon.

It also teaches app-server protocol / `ThreadHistoryBuilder` how to
render those items, and adds the small legacy fanout helpers needed for
existing event-based consumers. No core producer or rollout persistence
behavior changes here, that will be done in a followup.

## Making ThreadHistoryBuilder stateless

This is the first PR in a stack to make `ThreadHistoryBuilder` stateless
enough that we can materialize app-server `ThreadItem`s from only a
given slice of `RolloutItem` history, without ever needing to replay the
whole thread from the beginning.

The persisted legacy `RolloutItem::EventMsg` records are mostly shaped
like live UI events, not like materialized `ThreadItem`s. They work if
we replay the full rollout in order, but they often do not contain
enough stable identity or complete item state to project an arbitrary
suffix on its own.

A few examples:

- `UserMessageEvent` and `AgentMessageEvent` have content, but
historically do not carry the persisted app-server item ID that should
become the SQLite primary key.
- `AgentReasoningEvent` and `AgentReasoningRawContentEvent` are
fragments. `ThreadHistoryBuilder` currently merges them into the last
reasoning item, which means a slice starting in the middle of reasoning
cannot know whether to append to an earlier item or create a new one.
- `WebSearchEndEvent`, `McpToolCallEndEvent`, collab end events, and
similar legacy events can often render a final-looking item, but they
usually rely on prior replay state to know which turn owns the item.
- Begin/end legacy events are partial views of one logical item. The
builder correlates them by `call_id` and mutates prior state to
synthesize the final `ThreadItem`.

That is the problem this direction fixes. A persisted canonical
lifecycle record looks much closer to the read model we actually want
later:

```rust
ItemCompletedEvent {
    turn_id,
    item: TurnItem { id, ...full snapshot... },
    completed_at_ms,
}
```

Once rollout has explicit `turn_id`, stable `item.id`, and a canonical
completed item snapshot, the future SQLite projector can reduce only the
new rollout suffix and upsert the affected `thread_items` rows. It no
longer needs to synthesize `item-N`, infer item ownership from the
active turn, or replay earlier events just to reconstruct the current
item snapshot.

## What changed

- Added core `TurnItem` variants and item structs for command execution,
dynamic tool calls, collab agent tool calls, and sub-agent activity.
- Added conversions from those canonical items back into the legacy
event shapes where current consumers still need them.
- Added app-server v2 `ThreadItem` conversion for the new core item
variants.
- Taught `ThreadHistoryBuilder` and rollout persistence metrics to
recognize the new item variants.

## Follow-up

The next PR https://github.com/openai/codex/pull/30283 switches the live
core producers for these item families onto canonical `ItemStarted` /
`ItemCompleted` events.
2026-06-26 16:44:34 -07:00
charlesgong-openai 6509f3148a [codex] Support npm marketplace plugin sources (#29375)
## Why

Marketplace source deserialization treated `{"source":"npm", ...}` as
unsupported. The loader logged and skipped the entry, so npm-backed
plugins never appeared in `plugin list --available` and `plugin add`
returned "plugin not found".

Codex plugins are installed from a plugin root, not from an npm
dependency tree. For npm-backed marketplace entries, Codex should fetch
the published package contents without running package scripts or
installing unrelated dependencies.

## What changed

- Add `npm` marketplace plugin sources with `package`, optional semver
`version` or version range, and optional HTTPS `registry`.
- Reject unsafe npm source fields before materialization, including
invalid package names, non-semver version selectors, plaintext or
credential-bearing registry URLs, and registry query/fragment data.
- Materialize npm plugins with `npm pack --ignore-scripts`, then unpack
the resulting tarball through the existing hardened plugin bundle
extractor.
- Enforce npm archive and extracted-size limits, require the standard
npm `package/` archive root, and verify the extracted `package.json`
name matches the requested package before installing.
- Keep plugin listings, install-source descriptions, CLI JSON/human
output, app-server v2 `PluginSource`, TUI source summaries, regenerated
schema fixtures, and app-server documentation in sync.

## Impact

Marketplaces can distribute Codex plugins from public or configured
private HTTPS npm registries using the same install flow as existing
materialized plugin sources. `npm` must be available on `PATH` when an
npm-backed plugin is installed.

Fixes #27831

## Validation

- `just write-app-server-schema`
- `just test -p codex-core-plugins -p codex-app-server-protocol -p
codex-app-server -p codex-cli`
  - npm/schema/core-plugin coverage passed in the run.
- The full focused command finished with `1739 passed`, `11 failed`, and
`6 timed out`; the failures were unrelated local app-server environment
failures from `sandbox-exec: sandbox_apply: Operation not permitted`
plus one missing `test_stdio_server` helper binary.
- Installed an npm-published Codex plugin package through a throwaway
local marketplace and throwaway `CODEX_HOME` to exercise the real npm
materialization path end to end.
2026-06-26 17:24:46 -04:00
Owen Lin f72976a5f1 feat(app-server): add optional turn_id to thread/fork (#30277)
## Description

This adds stable optional `turnId` support to `thread/fork`. When
supplied, the fork copies persisted history through that terminal turn,
inclusive, and drops later turns from the new thread.

Omitting or passing `null` preserves the existing full-history fork
behavior, including the interruption marker when the stored source
history ends mid-turn.

## Why

We're deprecating `thread/rollback` and this will help certain UX use
cases work around it by using `thread/fork` + `turn_id` instead.
2026-06-26 19:35:54 +00:00
hefuc-oai d9cf931d0e [codex] Add managed new-thread model settings (#29683)
## Why

Admins need persistent defaults for the model, reasoning effort, and
service tier shown when the Desktop App creates a new thread. These are
initialization defaults rather than runtime constraints: the App should
use them to initialize its draft while still allowing a user to make an
explicit selection.

The app-server therefore needs to expose the managed values before
thread creation without changing `thread/start` behavior for other
clients.

## What changed

- Parse `model`, `model_reasoning_effort`, and `service_tier` from
`[models.new_thread]` in `requirements.toml`.
- Compose the `models` requirements through the existing
requirements-layer precedence rules.
- Expose the resolved values through `configRequirements/read` as
`requirements.models.newThread`.
- Add the corresponding app-server protocol types and regenerate the
JSON and TypeScript schema fixtures.
- Document the new `configRequirements/read` fields in the app-server
README.

## Scope

This PR is data plumbing only. It does not apply these values during
`thread/start` and does not change thread creation for existing
app-server clients, resumed or forked sessions, internal or subagent
sessions, `codex exec`, or the TUI. A companion Desktop App change owns
draft initialization, sends the effective settings for ordinary and
prewarmed starts, and preserves explicit user changes.

## Validation

- Requirements deserialization coverage for `[models.new_thread]`
- Requirements-layer precedence coverage
- App-server API mapping coverage
- `configRequirements/read` integration coverage
- Regenerated app-server JSON and TypeScript schema fixtures
2026-06-26 18:37:40 +00:00
Owen Lin 5267e805fb feat(app-server): add history_mode to thread (#29927)
## Description

This PR adds a new `historyMode = "legacy" | "paginated"` to `Thread`.
This will be stored in `SessionMeta` in the JSONL rollout file and as a
new column in the SQLite thread_metadata table, and exposed on
`thread/start` and on the `Thread` object in app-server.

## What changed

- Added canonical `ThreadHistoryMode` with `legacy` and `paginated`,
defaulting old and new SessionMeta to `legacy`.
- Carried `history_mode` through core session config, ThreadStore stored
metadata, local/in-memory stores, rollout metadata extraction, and the
existing SQLite `threads` table.
- Added experimental `historyMode` to app-server v2 `Thread` and
`thread/start`.
- Made paginated stored threads metadata-discoverable but unsupported
for legacy full-history reads, `load_history`, live resume, and create
paths.
- Regenerated app-server schema fixtures and added
protocol/state/thread-store/app-server coverage for persistence and
fail-closed behavior.

## Compatibility floor
Because users may be running various versions of Codex binaries on the
same machine (TUI, Codex App, etc.), we will need to establish a
compatibility floor for upcoming paginated threads, which will change
how thread storage reads and writes work.

The overall plan here:
```
Release N:
- Add historyMode to SessionMeta / Thread / SQLite metadata.
- Teach binaries to understand paginated threads.
- If a binary sees `historyMode="paginated"` but does not support the paginated contract, it refuses to resume/mutate the thread.
- Default remains `"legacy"`.

Release N+1:
- First-party clients start opting into paginated threads where appropriate.
- Internal dogfood / staged rollout.
- Measure old-client usage and paginated-thread unsupported errors.

Release N+2:
- Only after Release N+ is overwhelmingly deployed, make paginated the default.
- Accept that a small tail of N-1-or-older binaries may not understand paginated threads.
```

The important behavior change is fail-closed handling for a binary that
encounters a persisted `paginated` thread before it knows how to fully
support paginated history. In app-server, if a thread is `paginated`, we
will:

- allow metadata-only discovery paths like `thread/list` and
`thread/read(includeTurns=false)`, so clients can still see the thread
and inspect its `historyMode`
- reject legacy full-history/live-thread paths like
`thread/read(includeTurns=true)` and `thread/resume` with an unsupported
JSON-RPC error
- avoid silently treating an unknown or future `historyMode` as `legacy`

Under the hood, the ThreadStore layer also rejects legacy operations
that would need to load or replay the full thread history for a
paginated thread. That gives us the behavior we want for Release N:
future paginated threads are visible, but this binary fails closed
instead of trying to operate on them as if they were legacy threads.
2026-06-26 09:12:42 -07:00
Martin Au-YeungandMartin Au-Yeung ec300bc7bd Expose MCP app identity in app context (#29934)
## Why

MCP tool-call events need to expose trusted app identity and action
metadata directly so v2 clients do not have to infer it from tool names
or resource URIs.

## What changed

- Add optional `appName`, `templateId`, and `actionName` fields to MCP
tool-call `appContext`.
- Populate `appName` and `templateId` from trusted Codex Apps metadata,
and derive `actionName` from the trusted app resource metadata.
- Preserve all three fields through core events, legacy protocol events,
persisted thread history, resume redaction, and app-server v2 responses.
- Document the public `appContext` fields in
`codex-rs/app-server/README.md`.
- Regenerate app-server JSON and TypeScript schemas and add coverage for
serialization, persistence, redaction, and metadata propagation.

## Validation

- `just test -p codex-app-server-protocol mcp_tool_call`
- `just test -p codex-core
mcp_tool_call_item_metadata_only_trusts_codex_apps_identity
mcp_tool_call_item_includes_app_identity`
- `just write-app-server-schema`

---------

Co-authored-by: Martin Au-Yeung <280153141+martinauyeung-oai@users.noreply.github.com>
2026-06-25 18:31:10 -07:00
felixxia-oai a6d20ed297 [codex] Surface MCP reauthentication-required startup failures (#29877)
## Summary

- distinguish expired, non-refreshable stored MCP OAuth credentials from
first-time missing credentials
- carry a typed `failureReason: "reauthenticationRequired"` on the
existing `mcpServer/startupStatus/updated` notification only when user
action is required
- keep the public MCP auth-status API unchanged and regenerate the
app-server protocol schemas and documentation

## Why

An MCP server with an expired access token and no usable refresh token
currently fails startup without giving clients a reliable, typed
recovery signal.

The existing startup-status notification is the natural place to carry
this state. Its nullable `failureReason` keeps the recovery reason
attached to the failed startup transition without adding a one-off
notification. Internally, Codex distinguishes first-time login from
reauthentication and emits the reason only when the startup error itself
requires authentication.

## User impact

App clients can prompt an existing user to reconnect an MCP server when
automatic recovery is impossible by handling a failed
`mcpServer/startupStatus/updated` notification whose `failureReason` is
`reauthenticationRequired`. Starting, ready, cancelled, unrelated
failures, and first-time setup carry no reauthentication reason.

## Companion app PR

- openai/openai#1069582

## Validation

- `just test -p codex-app-server-protocol` — 248 passed; schema fixture
tests passed
- `cargo check -p codex-app-server -p codex-tui`
- `just test -p codex-rmcp-client -p codex-mcp` — 184 passed, 2 skipped
- `just test -p codex-protocol -p codex-app-server-protocol -p
codex-mcp` — 579 passed
- `just write-app-server-schema`
- `just fmt`
2026-06-25 21:50:36 +00:00
Owen Lin 1882719b30 feat(app-server): thread/turns/items/list -> thread/items/list (#29705)
## Description

Rename the experimental app-server item pagination API from
`thread/turns/items/list` to `thread/items/list` and make `turnId`
optional. Clients can now page persisted items across a thread, or still
filter to one turn when needed.

## What changed

- Rename the request/response protocol types and JSON-RPC method to
`ThreadItemsList*` / `thread/items/list`.
- Pass optional `turnId` through to `ThreadStore::list_items`.
- Update app-server docs and focused protocol/app-server tests.

## Validation

- `just test -p codex-app-server-protocol thread_items_list_round_trips`
- `just test -p codex-app-server thread_items_list_returns_unsupported`
2026-06-23 13:57:08 -07:00
Adam Perry @ OpenAI 510bce9927 core: resolve view_image paths in selected environment (#29526)
## Why

view_image needs to support foreign OS remote executors.

## What

- resolve image paths against the selected environment as `PathUri` and
read them through that environment's filesystem
- keep app-server's public path field wire-compatible as
`LegacyAppPathString`, with purpose-specific UI rendering
- cover relative and absolute target-native paths in the core
integration test and run the full `view_image` suite under wine-exec
without skips
2026-06-23 19:52:37 +00:00
Boyang Niu 354807920e core: add extra metadata field to Thread struct (#29675)
# Summary

Adds a field Thread.extras that can be used to hold arbitrary metadata
specific to a given thread.
2026-06-23 19:15:59 +00:00