Commit Graph

750 Commits

Author SHA1 Message Date
thomas
3a06748458 Allow publishing plugins through share updates (#33908)
## What changed

- Accept `LISTED` discoverability in `plugin/share/updateTargets` and forward it to the remote plugin sharing API.
- Update the generated JSON schemas and TypeScript type with the new enum value.

## Testing

- Add an app-server integration test that publishes a workspace plugin and verifies the `LISTED` request and response.

GitOrigin-RevId: 978f4b94b318e772bf80347e58dd5b1d2819a653
2026-07-17 21:29:51 +00:00
Owen Lin
c1862b8db4 Add occurrence search for paginated threads (#33907)
## What changed

- Add the experimental `thread/searchOccurrences` app-server method for case-insensitive literal search across visible user messages and final assistant messages without replaying the thread.
- Return paginated snippets with UTF-16 match ranges and `thread/turns/list` cursors for navigating to each matching turn.
- Index persisted item types to efficiently select searchable messages from paginated thread history.

## Testing

- Add an app-server integration test covering pagination, steering messages, final-answer selection, Markdown normalization, and UTF-16 offsets.

GitOrigin-RevId: e80160e0f83eb4e5db8de862307085093bee362b
2026-07-17 21:24:26 +00:00
jiayuhuang-openai
025db22058 Route realtime V3 handoffs by response channel (#33903)
## What changed

- Add `codexResponseHandoffMode` to `thread/realtime/start` for V3 sessions, with `thinking` as the default and `commentary` and `bemTags` routing modes.
- Map BEM `analysis` and `commentary` output to the commentary channel and `final` output to the speakable channel, while preserving the original BEM envelope. Unrecognized output falls back to speakable.
- Mark explicit speech appends as speakable and stop adding the legacy `"Agent Final Message"` prefix to V3 handoffs. V1 and V2 continue to ignore the new setting.

## Testing

- Cover channel selection for every routing mode, streamed BEM header parsing, fallback behavior, explicit speech, and V1 compatibility.

GitOrigin-RevId: 1974578257488f2914b252c9c1990ba38831c96b
2026-07-17 21:12:40 +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
Abhinav
7bd44085e1 Add SessionEnd hooks for thread teardown (#33895)
## What changed

- Add the `SessionEnd` hook event to hook configuration, protocol schemas, analytics, and the hooks browser.
- Run matching hooks for root threads during shutdown, including app-server archive, delete, idle unload, and graceful shutdown. Flush the transcript first and provide the session ID, transcript path, working directory, and `reason: "other"`.
- Keep teardown bounded: hook output is advisory, the default timeout is one second, configured timeouts are capped at three seconds, and async hooks run synchronously with a warning.

## Testing

- Cover transcript availability, matcher selection, timeout normalization, ignored control output, subagent exclusion, archive/delete ordering, and graceful shutdown of multiple loaded threads.

GitOrigin-RevId: 5d19a658677a137caf836ed5042dcb43f5eb6d1a
2026-07-17 19:58:56 +00:00
jiayuhuang-openai
b03545b5b8 Stream realtime V3 Codex handoff output (#33856)
## What changed

- Stream V3 agent message deltas to `delegation.context.append` at 200 ms intervals instead of waiting for each completed message.
- Send commentary without a prefix and label final or phase-less V1/V3 output with `"Agent Final Message":`.
- Bound streamed output while preserving both its beginning and final tail when truncation is required.
- Remove `codexResponseHandoffPrefix` from `thread/realtime/start`; unknown fields from older clients remain ignored.

## Testing

- Cover incremental V3 commentary and final output, Unicode-safe truncation, V1/V3 phase labeling, and legacy request compatibility.

GitOrigin-RevId: 633c18b5eb9a4f5756a264b63b7bfc185b073951
2026-07-17 15:54:33 +00:00
Matthew Zeng
a238b753af Add an API for reading installed app runtime state (#33843)
## What changed

- Add `app/installed` to return each connector observed in the committed runtime tool snapshot, including its runtime name and effective `enabled` and `callable` state.
- Support evaluating thread-specific configuration with `threadId` and refreshing the hosted connector tool snapshot with `forceRefresh`.
- Preserve observed connector identities as disabled when global or workspace policy disables Apps, and retain the previous snapshot when a refresh fails.

## Testing

- Cover cached and forced reads, policy and configuration filtering, thread-specific configuration, snapshot refresh failures, and protocol serialization.

GitOrigin-RevId: f697b6fb501b7d329a169e947a1c1607806222fe
2026-07-17 15:23:35 +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
Celia Chen
315195492c Support custom transports for Amazon Bedrock (#33695)
## What changed

- Allow the built-in `amazon-bedrock` provider to override `base_url`, `auth`,
  and `http_headers` in addition to its AWS profile and region.
- Use command-based bearer authentication and configured endpoints without
  applying AWS request signing, while retaining regional endpoint resolution
  for the default Bedrock configuration.
- Replace the Bedrock account `credentialSource` enum with the
  `usesCodexManagedCredentials` boolean so command-authenticated and other
  externally managed configurations are reported consistently.

## Testing

- Cover configuration merging and validation, command-authenticated proxy
  requests with custom headers, and account reporting for managed and external
  credentials.

GitOrigin-RevId: d1acbe602060470583b5e12f8d304bee5be46f4c
2026-07-16 21:41:00 +00:00
stevenlee-oai
726b6378d2 Add an app-server API for reading app metadata (#33651)
## What changed

- Add the experimental `app/read` request for fetching metadata for up to 100
  app IDs, with optional display-only tool summaries.
- Preserve first-request order while deduplicating IDs, and report unknown or
  unauthorized apps as partial misses.
- Cache metadata by backend and ChatGPT account/workspace identity, refetch
  metadata-only entries when tools are requested, and preserve cached records
  when a backend request fails.

## Testing

- Cover request serialization, ordering, deduplication, partial misses, caching,
  tool-summary refetches, backend failures, cache isolation, and the ID limit.

GitOrigin-RevId: 55fc3281d99291e76d6c4a581e8d11569d3cb1ac
2026-07-16 17:46:36 +00:00
pakrym-oai
5a85351dfe Remove generated-default filesystem path variants (#33632)
## What changed

- Represent built-in filesystem policy entries with the same `Path` and
  `Special` variants used by other entries.
- Remove generated-default filtering from Windows sandbox policy resolution and
  simplify elevated deny-write handling to rely on direct-runtime enforcement
  and the legacy policy projection.
- Update protocol conversions, policy transforms, and profile expectations for
  the reduced filesystem path model.

GitOrigin-RevId: a65793e6855a03d52a575e82cb3d4b9b2e32db5c
2026-07-16 16:13:53 +00:00
Adam Perry @ OpenAI
1d941253e9 Add cache-write tokens to the raw response schema (#33500)
## What changed

Add `cacheWriteInputTokens` to the usage breakdown in the
`rawResponse/completed` JSON schema, defaulting it to zero. Update the
compaction and turn-start notification expectations for the expanded usage
breakdown.

GitOrigin-RevId: d9232b724d646b803c7f5a64c5daa311f77ad408
2026-07-16 04:45:05 +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
Eric Traut
2edad72de3 Track prompt cache write token usage (#33454)
## What changed

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

## Testing

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

GitOrigin-RevId: 634e4fbe3086a8923c0ee13b622573e7d9d221bd
2026-07-16 00:22:53 +00:00
charlesgong-openai
7d1218a997 Add external agent memory migration (#33444)
## What changed

- Add a feature-gated `MEMORY` migration item to the app-server protocol and TUI.
- Discover project memory Markdown files, preserve their project scope, and copy selected projects into the Codex memory extension workspace.
- Detect changed, renamed, and removed source projects, report per-project import failures, and enqueue memory consolidation after workspace changes.

## Testing

- Cover memory discovery, selection, synchronization, scope validation, feature gating, protocol results, and TUI rendering.

GitOrigin-RevId: 9b17b2e9a639a064dba8aaffbec6345ae419018e
2026-07-15 22:49:52 +00:00
iceweasel-oai
cb79b3cdf9 Avoid creating metadata paths in the Windows sandbox (#33430)
## Why

Elevated Windows sandbox setup could turn the built-in read-only protections
for workspace metadata into deny-write paths, creating metadata directories
that did not already exist.

## What changed

- Track whether filesystem permission entries come from a built-in profile or
  were explicitly configured.
- Exclude generated metadata defaults from direct Windows deny-write overrides
  while continuing to enforce explicit read-only carveouts for the same paths.
- Preserve the distinction while materializing and normalizing permission
  paths, without exposing generated defaults as user configuration.

## Testing

Added Windows coverage confirming that elevated sandbox setup leaves missing
workspace metadata absent and still produces overrides for explicit metadata
carveouts.

GitOrigin-RevId: 701bcb229f631b18ab5ced22f3edf6f303d932f3
2026-07-15 21:19:14 +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
charlesgong-openai
58e4ed17a0 Expose connector candidates from imported sessions (#33414)
## What changed

- Correlate MCP server attribution in imported session records with connector
  metadata, and persist normalized connector names in the session import ledger.
- Extend `externalAgentConfig/import/readHistories` with connector candidates,
  including each connector's display name, imported-session count, and detection
  source.

## Testing

- Cover connector detection through the session import and history-read flow.
- Verify candidate aggregation uses the latest import for each source session.

GitOrigin-RevId: 7f1f7f596925b2e6efcd17afd4490148e1ac9ff1
2026-07-15 20:06:16 +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
jiayuhuang-openai
2e1607ee2f Add Frameless Bidi support for realtime conversations (#33261)
## What changed

- Add realtime conversation version `v3`, which preserves the V1 Codex Voice behavior while using Frameless Bidi `delegation.*` events.
- Translate audio, transcripts, handoffs, session context, and lifecycle events between the app server and the Frameless Bidi wire protocol.
- Support `v3` over WebSocket and WebRTC, including the Frameless `/live` endpoint, session configuration, headers, and default model selection.
- Update the app-server protocol schemas and documentation for the new version.

## Testing

- Add unit coverage for Frameless event parsing, outbound messages, context chunking, URL construction, and call creation.
- Add app-server end-to-end coverage for WebSocket delegation and WebRTC session startup.

GitOrigin-RevId: 79a3307bc209e1a54582ebd2febc07c909fca016
2026-07-15 05:59:37 +00:00
sayan-oai
3afbd8dd45 Report selected environment connection transitions (#33251)
## What changed

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

## Testing

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

GitOrigin-RevId: 5dd767372363c4a2a8319fc16164be117d5bd20c
2026-07-15 05:21:13 +00:00
Felipe Coury
d88db19144 Preserve thread context when retrying or editing turns (#33211)
## What changed

- Add experimental `beforeTurnId` support to `thread/fork` for copying history strictly before a turn, including an in-progress turn.
- Use before-turn forks for TUI backtracking and safety retries so the replacement prompt retains thread context instead of recreating the branch from the preceding turn or a new thread.
- Add experimental `deferGoalContinuation` support so safety-retry forks can inherit an active goal while waiting for the replacement turn before automatic continuation resumes.
- Hide duplicated nested-review prompts when replaying history or selecting a prompt to edit.

## Testing

- Cover before-turn truncation, fork validation, active-goal inheritance, TUI safety retries, backtracking, and nested-review replay.

GitOrigin-RevId: 4915d85ae1929a0b8c40f3ed7dca29c7a5bdcdf3
2026-07-15 02:35:49 +00:00
Adam Perry @ OpenAI
72b41c55fb Separate exec permission paths from core models (#33200)
## Why

Core filesystem permission models operate on native absolute paths, while exec
sandbox contexts must serialize paths as portable URIs.

## What changed

- Make the core filesystem permission and profile types concrete over
  `AbsolutePathBuf` instead of generic over their path representation.
- Add exec-specific permission types that convert native permission paths to
  `PathUri` values at the sandbox protocol boundary.
- Replace the legacy read/write-roots tuple with a named
  `LegacyReadWriteRoots` struct.

## Testing

- Add coverage that exec sandbox permission paths serialize as URIs and round
  trip through the filesystem protocol.

GitOrigin-RevId: a0ef5f8aba9bbfdf00a00fcc4f199314836bc85d
2026-07-15 01:31:40 +00:00
stefanstokic-oai
4df8027a97 Honor workspace spend controls in rate-limit handling (#33187)
## Why

Sparse and out-of-order rate-limit updates can omit account metadata or let an
older full read overwrite a newer workspace hard stop. Credit availability also
does not always include a displayable balance.

## What changed

- Propagate the backend's `spendControlReached` state through rate-limit
  snapshots and the app-server protocol, preserving it across sparse updates.
- Keep workspace hard-stop classifications for error routing and ignore stale
  full-read results after a newer hard-stop notification.
- Base TUI warnings and model-switch prompts on credit availability and hard-stop
  state, and show `Credits: Available` when a finite balance is hidden.

## Testing

Added coverage for spend-control mapping, snapshot merging, out-of-order reads,
workspace error routing, warning and prompt behavior, and credit status display.

GitOrigin-RevId: 18b09d493d5a620a7c079fb721ec50b38dd5b04c
2026-07-14 22:43:26 +00:00
charlesgong-openai
3fae30dd85 Preserve plugin install failure subtypes during imports (#33182)
## What changed

- Add `subErrorType` to external agent config import failures and carry it through progress and completion notifications, persisted import histories, and analytics.
- Expose plugin store failure subtypes from `PluginInstallError` so manual installs and imported plugins report details such as `failed_to_copy_plugin_file` while failures without a subtype remain `null`.
- Keep existing persisted import records compatible by defaulting the new field when it is absent.

## Testing

- Cover store I/O subtype extraction, analytics serialization, persisted import histories, and migration notification fixtures.

GitOrigin-RevId: ec1a85623fc826cbd7cfe9f55c2dd2bc86665937
2026-07-14 22:21:27 +00:00
pakrym-oai
5d325ba223 Move sleep items to the extension-owned lifecycle path (#33159)
## What changed

- Define `SleepItem` in `codex-extension-items` and carry `clock.sleep` events through `TurnItem::Extension`.
- Preserve sleep persistence, thread-history reconstruction, and the app-server's `type: "sleep"` schema while reusing the extension-owned type.

## Testing

- Add serialization coverage for the `clock.sleep` extension wire shape and its protocol wrapper.
- Update sleep lifecycle and thread-history tests to exercise the extension-owned item.

GitOrigin-RevId: 34bb33ed9b90a09bf4744aafdb56e019c717a168
2026-07-14 21:01:54 +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
Adam Perry @ OpenAI
0396f99cf1 Preserve special filesystem subpaths as wire strings (#33107)
## Why

Special filesystem subpaths can contain relative or foreign-platform path
spellings. Treating this wire text as a host-native path can reinterpret it.

## What changed

- Store special filesystem subpaths as strings in the core permissions model.
- Represent app-server subpaths as `LegacyAppPathString` and convert them at
  the protocol boundary without changing their spelling.
- Add `LegacyAppPathString::from_string` for callers that already own legacy
  app-server path text.

GitOrigin-RevId: 2214f03aa997fd0e6eb2ab60d425304bb4bd6132
2026-07-14 16:40:13 +00:00
jif
271136e00c Include raw response completions in TypeScript envelopes (#33026)
## What changed

Add `rawResponse/completed` and its `RawResponseCompletedNotification` payload
to the generated `ServerNotificationEnvelope` union, keeping the envelope type
aligned with the supported server notifications.

GitOrigin-RevId: 25a8b5e05a146a66ea65928eb6f0c3bd7b80f082
2026-07-14 10:11:51 +00:00
Dylan Hurd
1c9f890c05 Expose exact per-response usage in raw app-server events (#32985)
## Why

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

## What changed

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

## Testing

- Cover exact token breakdowns for turn and compaction completions.

GitOrigin-RevId: 49040a060bf1784c1ff1dd62112efb4a778428c4
2026-07-14 06:39:42 +00:00
pakrym-oai
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
Adam Perry @ OpenAI
f96cf4d1c3 Expose environment status through app-server (#32920)
## What changed

- Add the experimental `environment/status` request for inspecting a configured environment without starting or reconnecting it.
- Report `ready`, `pending`, `disconnected`, or `unknown`, including error details for disconnected and unknown environments.
- Probe ready remote environments over their existing exec-server connection.

## Testing

- Add an app-server integration test covering local and remote ready, pending, disconnected, and unknown environments.

GitOrigin-RevId: 397bba603aa9e0b59008ee6cb7cbde46e357652c
2026-07-14 01:49:16 +00:00
Owen Lin
c39520f3d1 Timestamp app-server notifications at emission (#32905)
## What changed

- Add an optional `emittedAtMs` field to server notification envelopes and expose the envelope in the generated JSON and TypeScript schemas.
- Populate the Unix timestamp when app-server emits a notification, before transport routing, so every connection in a fan-out receives the same value.
- Keep the field optional for clients decoding notifications from older app-server versions.

## Testing

- Verify notification serialization includes `emittedAtMs`.
- Verify targeted fan-out reuses one timestamp across connections.

GitOrigin-RevId: b379cb11e8e91c558bcd3d46ce459311a6e81e54
2026-07-14 00:38:04 +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
charlesgong-openai
bc8222b8d9 Prepare external agent migration for source adapters (#32884)
## What changed

- Add an optional `source` selector to `externalAgentConfig/detect`, while preserving the existing behavior for omitted, `null`, and unrecognized values.
- Pass `claude-code` as the source for TUI detection and import requests.
- Move source-specific migration behavior behind an adapter boundary and consolidate session migration into `codex-external-agent-migration`.

## Testing

- Cover explicit, omitted, and unknown detection source values with app-server protocol tests.
- Add unit coverage for the extracted migration and hook helpers.

GitOrigin-RevId: 63bd3dcb485f3ad7bd996022db4e351506aeea77
2026-07-13 22:15:55 +00:00
Owen Lin
5c19155cbd Add ordinals to paginated rollout records (#32332)
## Why

Paginated thread history needs durable ordering so consumers can process a rollout suffix without rebuilding all earlier history.

## What changed

- Add optional, zero-based ordinals to `RolloutLine` records in paginated rollouts while leaving legacy rollout serialization unchanged.
- Continue ordinals from the last valid record when appending or resuming, including after gaps or an incomplete tail, and reject overflow without appending.
- Add a stateless `project_rollout_line` helper that maps canonical turn lifecycle and completed-item records into thread-history change sets.

## Testing

- Cover ordinal assignment, legacy compatibility, resume and tail recovery, overflow handling, and thread-history projection for completed, failed, and interrupted turns.

GitOrigin-RevId: 3a9bb6cd2a1f674a9f154342e96e9aa3d8330781
2026-07-11 04:15:42 +00:00
pakrym-oai
c9d52de5ca Require prefixes for outbound response item IDs (#32312)
## What changed

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

## Testing

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

GitOrigin-RevId: 0209fe430c826d0ae88bc4648652c4ebf390c4a4
2026-07-11 02:29:14 +00:00
Owen Lin
c4318c386d Include terminal errors in turn completion events (#32280)
## What changed

- Add an optional `error` payload to `TurnCompleteEvent` and omit it when a turn completes without an error.
- Preserve the full terminal `ErrorEvent` through the turn lifecycle so the completion event includes the same error details emitted separately by `EventMsg::Error`.

## Testing

- Extend the stream-error integration test to verify that `TurnCompleteEvent` contains the emitted error and that the next turn can still proceed.

GitOrigin-RevId: 8d32942a44132763076130102d8b89ab356d59d0
2026-07-10 22:04:03 +00:00
Abhinav
431ad23be4 Expose scheduled tasks in plugin details (#32272)
## What changed

- Add optional `scheduledTasks` metadata to `plugin/read` responses for remote
  plugins, including hourly, daily, weekday, and weekly schedules.
- Preserve the distinction between unavailable metadata (`null`) and a catalog
  response containing no scheduled tasks (`[]`). Local plugin details return
  `null`.
- Export the corresponding Rust, JSON Schema, and TypeScript protocol types.

## Testing

- Cover scheduled-task deserialization and propagation through `plugin/read`.
- Verify missing and empty remote metadata remain distinct.

GitOrigin-RevId: 7af223ed0a1bf6d8f054293084a73f34c6d0332d
2026-07-10 21:13:38 +00:00
Owen Lin
bca577d69a Include start times in terminal turn events (#32263)
## What changed

- Add an optional `started_at` Unix timestamp to `TurnCompleteEvent` and
  `TurnAbortedEvent`.
- Populate the timestamp from turn timing state when a turn completes or is
  aborted.
- Preserve the timestamp when synthesizing interrupted fork history and when
  importing external sessions.

## Testing

- Verify that interrupting a turn emits a `TurnAbortedEvent` with a start
  timestamp.

GitOrigin-RevId: 75b3911b95c060e5fc1843a5e293d8fe47377186
2026-07-10 20:25:03 +00:00
Celia Chen
b45fef0774 feat: add managed Bedrock login API (#31327)
## Why

App-server clients can report whether Amazon Bedrock is using
AWS-managed credentials or a Codex-managed API key, but they do not have
a matching API for creating the managed login. This PR defines that
experimental wire contract independently from its implementation.

Managed Bedrock API keys are already a primary `CodexAuth` mode. The API
therefore describes a normal Codex login that replaces the current
stored auth rather than introducing provider-scoped credential storage.

## What changed

- Add the experimental `amazonBedrock` variant to `account/login/start`.
- Accept an API key and AWS region and return a matching discriminated
response.
- Gate the request behind the app-server `experimentalApi` capability.
- Regenerate the JSON and TypeScript protocol schemas.
- Document the login contract, notifications, primary-auth replacement
semantics, restart boundary, and non-transactional durable writes.

## Impact

This PR defines the API shape but does not implement login behavior. The
next PR adds validation, persistence through the existing Codex auth
lifecycle, provider selection, and notifications.

## Validation

- `just test -p codex-app-server-protocol`

## Stack

1. **#31327 Managed Bedrock experimental API** — base: `main`
2. #31326 Managed Bedrock login — base: `codex/managed-bedrock-api`
3. #31325 Managed Bedrock logout — base:
`codex/managed-bedrock-login-v2`
2026-07-09 17:05:37 -07:00
Owen Lin
ba5dd1fd3a feat(core): emit canonical hook prompt items (#31630)
## Description

This PR moves hook prompts onto the canonical `TurnItem` lifecycle in
core.

Stop hooks now record their `ResponseItem` through the existing
lifecycle path, which emits `ItemStarted` and `ItemCompleted`.
App-server consumes those events directly instead of deriving a hook
prompt from `RawResponseItem`.

## Why

Hook prompts were the only `ThreadItem` app-server synthesized from
`RawResponseItem`. This brings them in line with other core-owned turn
items while preserving legacy rollout replay.

## What changed

- Route stop-hook prompts through
`record_response_item_and_emit_turn_item`.
- Materialize canonical hook prompts in `ThreadHistoryBuilder`.
- Remove `RawResponseItem` to `ThreadItem` synthesis while preserving
legacy rollout replay.
- Add focused coverage for lifecycle emission and canonical and legacy
history materialization.
2026-07-08 13:42:06 -07:00
Owen Lin
23aac925e7 feat(core): emit canonical review mode items (#31473)
## Description

This PR moves review-mode markers onto canonical `TurnItem` lifecycle:

- `TurnItem::EnteredReviewMode`
- `TurnItem::ExitedReviewMode`

Core now emits `ItemStarted` / `ItemCompleted` for both. The completed
items map back into the existing `EnteredReviewMode` /
`ExitedReviewMode` events, so raw core event consumers and legacy
rollout persistence keep seeing the old events.

This is the compatibility layer needed before paginated rollouts persist
review markers as `ItemCompleted(TurnItem)`.

## Why

Review markers were one of the remaining app-server thread items created
directly from legacy events. Giving them canonical items lets paginated
history persist stable turn/item IDs without changing legacy rollouts.

## What changed

- Added canonical review-mode `TurnItem`s and switched review flow to
emit their lifecycle.
- Added completed-item → legacy review event mappings with stable
turn/item IDs.
- Switched app-server live notifications to the generic canonical item
path and kept legacy replay compatible with old payloads.
- Updated `ThreadHistoryBuilder` to replay canonical review items even
though review turns still do not emit `TurnStarted`.
2026-07-08 09:59:50 -07: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
Owen Lin
f1affbac5e core: support extension-owned turn items (#31283)
## Description

This PR adds a `codex-extension-items` crate for extension-owned
`TurnItem` schemas, and updates standalone image generation to start
using it via `TurnItem::Extension`.

This gives us a way to prevent Core from having to be aware of all
extension items. App-server still exposes the existing public
`ThreadItem::ImageGeneration` shape, now by wrapping the same shared
`image_generation::ImageGenerationItem` type.

The new `codex-extension-items` crate is necessary because the image gen
extension item is used by:
- `codex-image-generation-extension`, which produces it.
- `codex-tools / core`, which carry it generically.
- `codex-protocol`, which serializes it into lifecycle events and
rollouts.
- `app-server protocol`, which wraps it in public
`ThreadItem::ImageGeneration`

```
extension implementation
        ↓
codex-extension-items
        ↓
protocol / tools / app-server
```

We keep the hosted Responses API image generation as
`TurnItem::ImageGeneration` because core still owns its persistence and
legacy fanout.

### Before

Standalone image generation is implemented as an extension, but its item
representation previously lived in the core protocol. This sets the
precedent that core is aware of all extension items, which would be good
to avoid.

```
image-gen extension
→ constructs codex_protocol::ImageGenerationItem
→ emits ExtensionTurnItem::ImageGeneration
→ core matches ImageGeneration specially
→ protocol stores TurnItem::ImageGeneration
```

### After
```
image-gen extension
→ constructs extension-owned ImageGenerationItem
→ emits generic ExtensionItem
→ core transports/persists it generically
→ app-server wraps ImageGenerationItem as ThreadItem::ImageGeneration
```

Future extension items can have typed app-server APIs without adding a
new `TurnItem` variant, `ExtensionTurnItem` variant, or core emitter
match arm.

## What changed

- Added `codex-extension-items` with the closed `ExtensionItem` enum and
shared `image_generation::ImageGenerationItem` schema.
- Added generic `TurnItem::Extension(ExtensionItem)` and
`ExtensionTurnItem::Extension { item, legacy_events }` paths.
- Updated standalone image generation to emit a typed extension item and
provide its existing legacy `ImageGenerationBegin` /
`ImageGenerationEnd` events explicitly.
- Kept canonical lifecycle ordering: core emits `ItemStarted` /
`ItemCompleted` before extension-provided legacy events.

## Follow-up

Standalone web search still uses its typed special-case path. Migrating
it later would let `ExtensionTurnItem` collapse into a single
extension-item struct.
2026-07-08 03:55:13 +00:00
lt-oai
8784de445e [codex] Add externally provided Codex auth (#31274)
## Summary

Add an in-memory externally provided Codex auth snapshot with explicit
runtime capabilities, installed through the existing `ExternalAuth`
provider path.

## Testing

- `just fmt-check`
- `cargo test -p codex-login --lib externally_provided_auth`
- `cargo test -p codex-core --lib
external_auth_snapshot_is_installed_from_runtime_config`
- `cargo test -p codex-model-provider --lib external_auth`
- `cargo test -p codex-mcp-extension --test hosted_apps_mcp
hosted_apps_mcp_accepts_external_provided_codex_auth`
- `cargo check -p codex-app-server -p codex-core-api -p
codex-thread-manager-sample`

---------

Co-authored-by: pakrym-oai <pakrym@openai.com>
2026-07-07 17:43:19 -07:00
rafael-jac
1fd0858e86 [login] support hosted success redirects (#28745)
## What

Adds an optional hosted login-success redirect path for app-server login
requests.

- Keeps the existing localhost success page as the default.
- Lets app-server callers opt into a hosted success page with an
optional protocol field.
- Persists credentials before redirecting to the hosted success page.
- Keeps org setup and existing CLI/device-code login flows on the local
success page.
- Accepts an optional typed `appBrand` value and forwards it to the
hosted page as `app_brand` so web can select the correct asset.
- Generates the app-server protocol schema updates for the new optional
fields.

## Why

This supports the hosted Codex login success page rollout without
changing existing login behavior by default. The Codex Apps frontend can
gate the opt-in with Statsig after the hosted web page.

## Rollout safety

- Old callers omit the new field and continue using localhost.
- New callers talking to old app-server builds remain safe because the
Codex Apps side treats the field as optional and defaults the flag off.
- Missing brand values default to Codex.
- The hosted redirect always uses the app-login source so the hosted
page can reopen Codex; the existing streamlined-login visual flag
remains separate.

## Validation

- `just fmt`
- `just fix -p codex-login -p codex-app-server-protocol -p
codex-app-server -p codex-app-server-test-client -p codex-tui`
- `just test -p codex-login`
- `just test -p codex-app-server-protocol`
- `just write-app-server-schema`
- `git diff HEAD --check`

The focused login and protocol run passed all 380 tests.

I also started the broader `just test -p codex-app-server`; it compiled
successfully, then many tests failed on this machine because spawned
test servers tried to use the ambient `/Users/rafaelj/.codex/sqlite`
state DB, which is read-only in this sandbox. I stopped that run after
confirming the failures shared that environment issue.
2026-07-07 19:48:05 +00:00
Alex Zamoshchin
f6e251c3ac [codex-rs] Add writes app approval mode (#30482)
## Summary

- Adds `writes` to `AppToolApproval` and exposes it through config and
app-server schemas, including
`[apps._default].default_tools_approval_mode`.
- In `writes`, tools with `readOnlyHint = true` skip approval; all other
tools prompt, including non-destructive writes and tools without
annotations.
- Prevents session or persistent approval choices in this mode so later
writes still prompt.

## Why

`auto` only prompts for risk-hinted actions, while `prompt` also
interrupts reads. Apps need a middle mode that gates writes without
prompting for declared read-only actions.

## Validation

- `just write-config-schema`
- `just write-app-server-schema`
- `just fmt`
- `just test -p codex-core mcp_turn_metadata` (4 passed)
- `just test -p codex-core writes_mode` (2 passed)
- `just test -p codex-app-server config_read_includes_apps` (1 passed)
- `just test -p codex-app-server-protocol` (251 passed)
- `just test -p codex-config` (200 passed)
- `just test -p codex-cli` (300 passed)
- `just fix -p codex-core -p codex-config -p codex-app-server-protocol
-p codex-app-server -p codex-cli`
2026-07-07 13:13:59 -04: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
guinness-oai
c976741124 [codex] Flush trailing realtime transcript tail (#29918)
## Why

A realtime session can end after more transcript has accumulated than
was included in its last handoff. That tail already lives in core's
active transcript state, but the stop path aborted the realtime
input/fanout tasks before routing it, so the final bit of the
conversation could disappear before `thread/realtime/closed`.

This behavior is still being evaluated, so clients must opt in per
realtime session. Omitted or false leaves shutdown behavior unchanged.

## What changed

- Add optional `flushTranscriptTailOnSessionEnd` to
`thread/realtime/start`, defaulting to false in app-server.
- Expose an idempotent `take_transcript_tail()` from the existing active
transcript state using `last_handoff_entry_count`.
- When enabled, let shutdown cancel the input owner cleanly and publish
at most one final existing `<realtime_delegation>` with the remaining
text in `<transcript_delta>`.
- Have the existing fanout drain already-parsed events before routing
that final delegation, so a queued handoff wins first and is not
duplicated in the tail.
- Flush realtime shutdown before ordinary session task abort during core
cleanup.

## Validation

- `just test -p codex-app-server-protocol`
- `just test -p codex-app-server
realtime_conversation_stop_emits_closed_notification`
- `just test -p codex-core conversation_transport_close_`
- `just test -p codex-core
conversation_close_routes_only_remaining_transcript_tail_once`
- scoped `just fix` for `codex-app-server-protocol`, `codex-app-server`,
`codex-protocol`, and `codex-core`
- `just fmt`
2026-07-06 14:12:54 -07:00