Commit Graph

5625 Commits

Author SHA1 Message Date
rhan-oai
32d1704205 merge commit for archive created by Sapling 2026-04-10 14:40:34 -07:00
rhan-oai
2e21934e10 [codex-analytics] feature plumbing and emittance 2026-04-10 14:38:18 -07:00
rhan-oai
8af0af0000 merge commit for archive created by Sapling 2026-04-10 14:26:37 -07:00
rhan-oai
f42998d852 [codex-analytics] denormalize thread metadata onto turn events 2026-04-10 14:24:52 -07:00
rhan-oai
f00fe86b78 [codex-analytics] add steering metadata 2026-04-10 14:24:52 -07:00
rhan-oai
9323523020 [codex-analytics] add token usage metadata 2026-04-10 14:24:52 -07:00
rhan-oai
d91bd51ff9 [codex-analytics] feature plumbing and emittance 2026-04-10 14:24:52 -07:00
rhan-oai
a5a281c5a1 Merge 169d814006 into sapling-pr-archive-rhan-oai 2026-04-10 14:17:19 -07:00
rhan-oai
169d814006 [codex-analytics] denormalize thread metadata onto turn events 2026-04-10 14:15:53 -07:00
rhan-oai
6123f210f4 Merge aa2b4665c7 into sapling-pr-archive-rhan-oai 2026-04-10 14:08:59 -07:00
rhan-oai
a1405eb1d7 [codex-analytics] add steering metadata 2026-04-10 14:07:57 -07:00
rhan-oai
aa2b4665c7 [codex-analytics] denormalize thread metadata onto turn events 2026-04-10 14:07:57 -07:00
rhan-oai
e7c81347bf [codex-analytics] add token usage metadata 2026-04-10 14:07:57 -07:00
rhan-oai
8dba615a8b [codex-analytics] feature plumbing and emittance 2026-04-10 14:07:57 -07:00
rhan-oai
8005c858f9 merge commit for archive created by Sapling 2026-04-10 13:38:58 -07:00
rhan-oai
bcc8196c4f [codex-analytics] denormalize thread metadata onto turn events 2026-04-10 13:37:25 -07:00
rhan-oai
1a060ac1c9 [codex-analytics] add steering metadata 2026-04-10 13:37:25 -07:00
rhan-oai
5076c1158b [codex-analytics] add token usage metadata 2026-04-10 13:37:25 -07:00
rhan-oai
bc876c3c10 [codex-analytics] feature plumbing and emittance 2026-04-10 13:37:25 -07:00
rhan-oai
5779be314a [codex-analytics] add compaction analytics event (#17155)
- event for compaction analytics
- introduces thread-connection and thread metadata caches for data
denormalization, expected to be useful for denormalization onto core
emitted events in general
- threads analytics event client into core (mirrors approved
implementation in #16640)
- denormalizes key thread metadata: thread_source, subagent_source,
parent_thread_id, as well as app-server client and runtime metadata)
- compaction strategy defaults to memento, forward compatible with
expected prefill_compaction strategy

1. Manual standalone compact, local
`INFO | 2026-04-09 17:35:50 | codex_backend.routers.analytics_events |
analytics_events.track_analytics_events:526 | Tracked
codex_compaction_event event params={'thread_id':
'019d74d0-5cfb-70c0-bef9-165c3bf9b2df', 'turn_id':
'019d74d0-d7f6-7c81-acc6-aae2030243d6', 'product_surface': 'codex',
'app_server_client': {'product_client_id': 'CODEX_CLI', 'client_name':
'codex-tui', 'client_version': '0.0.0', 'rpc_transport': 'in_process',
'experimental_api_enabled': True}, 'runtime': {'codex_rs_version':
'0.0.0', 'runtime_os': 'macos', 'runtime_os_version': '26.4.0',
'runtime_arch': 'aarch64'}, 'trigger': 'manual', 'reason':
'user_requested', 'implementation': 'responses', 'phase':
'standalone_turn', 'strategy': 'memento', 'status': 'completed',
'active_context_tokens_before': 20170, 'active_context_tokens_after':
4830, 'started_at': 1775781337, 'completed_at': 1775781350,
'thread_source': 'user', 'subagent_source': None, 'parent_thread_id':
None, 'error': None, 'duration_ms': 13524} | `

2. Auto pre-turn compact, local
`INFO | 2026-04-09 17:37:30 | codex_backend.routers.analytics_events |
analytics_events.track_analytics_events:526 | Tracked
codex_compaction_event event params={'thread_id':
'019d74d2-45ef-71d1-9c93-23cc0c13d988', 'turn_id':
'019d74d2-7b42-7372-9f0e-c0da3f352328', 'product_surface': 'codex',
'app_server_client': {'product_client_id': 'CODEX_CLI', 'client_name':
'codex-tui', 'client_version': '0.0.0', 'rpc_transport': 'in_process',
'experimental_api_enabled': True}, 'runtime': {'codex_rs_version':
'0.0.0', 'runtime_os': 'macos', 'runtime_os_version': '26.4.0',
'runtime_arch': 'aarch64'}, 'trigger': 'auto', 'reason':
'context_limit', 'implementation': 'responses', 'phase': 'pre_turn',
'strategy': 'memento', 'status': 'completed',
'active_context_tokens_before': 20063, 'active_context_tokens_after':
4822, 'started_at': 1775781444, 'completed_at': 1775781449,
'thread_source': 'user', 'subagent_source': None, 'parent_thread_id':
None, 'error': None, 'duration_ms': 5497} | `

3. Auto mid-turn compact, local
`INFO | 2026-04-09 17:38:28 | codex_backend.routers.analytics_events |
analytics_events.track_analytics_events:526 | Tracked
codex_compaction_event event params={'thread_id':
'019d74d3-212f-7a20-8c0a-4816a978675e', 'turn_id':
'019d74d3-3ee1-7462-89f6-2ffbeefcd5e3', 'product_surface': 'codex',
'app_server_client': {'product_client_id': 'CODEX_CLI', 'client_name':
'codex-tui', 'client_version': '0.0.0', 'rpc_transport': 'in_process',
'experimental_api_enabled': True}, 'runtime': {'codex_rs_version':
'0.0.0', 'runtime_os': 'macos', 'runtime_os_version': '26.4.0',
'runtime_arch': 'aarch64'}, 'trigger': 'auto', 'reason':
'context_limit', 'implementation': 'responses', 'phase': 'mid_turn',
'strategy': 'memento', 'status': 'completed',
'active_context_tokens_before': 20325, 'active_context_tokens_after':
14641, 'started_at': 1775781500, 'completed_at': 1775781508,
'thread_source': 'user', 'subagent_source': None, 'parent_thread_id':
None, 'error': None, 'duration_ms': 7507} | `

4. Remote /responses/compact, manual standalone
`INFO | 2026-04-09 17:40:20 | codex_backend.routers.analytics_events |
analytics_events.track_analytics_events:526 | Tracked
codex_compaction_event event params={'thread_id':
'019d74d4-7a11-78a1-89f7-0535a1149416', 'turn_id':
'019d74d4-e087-7183-9c20-b1e40b7578c0', 'product_surface': 'codex',
'app_server_client': {'product_client_id': 'CODEX_CLI', 'client_name':
'codex-tui', 'client_version': '0.0.0', 'rpc_transport': 'in_process',
'experimental_api_enabled': True}, 'runtime': {'codex_rs_version':
'0.0.0', 'runtime_os': 'macos', 'runtime_os_version': '26.4.0',
'runtime_arch': 'aarch64'}, 'trigger': 'manual', 'reason':
'user_requested', 'implementation': 'responses_compact', 'phase':
'standalone_turn', 'strategy': 'memento', 'status': 'completed',
'active_context_tokens_before': 23461, 'active_context_tokens_after':
6171, 'started_at': 1775781601, 'completed_at': 1775781620,
'thread_source': 'user', 'subagent_source': None, 'parent_thread_id':
None, 'error': None, 'duration_ms': 18971} | `
2026-04-10 13:03:54 -07:00
rhan-oai
fb1e0bcd15 merge commit for archive created by Sapling 2026-04-10 12:58:40 -07:00
rhan-oai
c36ffd6555 [codex-analytics] denormalize thread metadata onto turn events 2026-04-10 12:26:37 -07:00
Ahmed Ibrahim
029fc63d13 Strengthen realtime backend delegation prompt (#17363)
Encourages realtime prompt handling to delegate user requests to the
backend agent by default when repo inspection, commands, implementation,
or validation may help.

Co-authored-by: Codex <noreply@openai.com>
2026-04-10 12:14:33 -07:00
rhan-oai
24c54673fe Merge c815dc6870 into sapling-pr-archive-rhan-oai 2026-04-10 11:49:16 -07:00
rhan-oai
c815dc6870 [codex-analytics] denormalize thread metadata onto turn events 2026-04-10 11:45:41 -07:00
rhan-oai
b940eee9ab [codex-analytics] add steering metadata 2026-04-10 11:37:58 -07:00
rhan-oai
761d713d78 merge commit for archive created by Sapling 2026-04-10 11:20:31 -07:00
rhan-oai
0294922b78 [codex-analytics] denormalize thread metadata onto turn events 2026-04-10 11:16:21 -07:00
rhan-oai
2b2db7bb97 [codex-analytics] add steering metadata 2026-04-10 11:16:21 -07:00
jif-oai
87328976f6 fix: main (#17352) 2026-04-10 18:14:42 +01:00
Ahmed Ibrahim
2e81eac004 Queue Realtime V2 response.create while active (#17306)
Builds on #17264.

- queues Realtime V2 `response.create` while an active response is open,
then flushes it after `response.done` or `response.cancelled`
- requests `response.create` after background agent final output and
steering acknowledgements
- adds app-server integration coverage for all `response.create` paths

Validation:
- `just fmt`
- `cargo check -p codex-app-server --tests`
- `git diff --check`
- CI green

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-10 09:09:13 -07:00
Owen Lin
88165e179a feat(guardian): send only transcript deltas on guardian followups (#17269)
## Description

We reuse a guardian thread for a given user thread when we can. However,
we had always sent the full transcript history every time we made a
followup review request to an existing guardian thread.

This is especially bad for long guardian threads since we keep
re-appending old transcript entries instead of just what has changed.
The fix is to just send what's new.

**Caveat**: Whenever a thread is compacted or rolled back, we fall back
to sending the full transcript to guardian again since the thread's
history has been modified. However in the happy path we get a nice
optimization.

## Before
Initial guardian review sends the full parent transcript:

```
The following is the Codex agent history whose request action you are assessing...
>>> TRANSCRIPT START
[1] user: Please check the repo visibility and push the docs fix if needed.
[2] tool gh_repo_view call: {"repo":"openai/codex"}
[3] tool gh_repo_view result: repo visibility: public
[4] assistant: The repo is public; I now need approval to push the docs fix.
>>> TRANSCRIPT END
The Codex agent has requested the following action:
>>> APPROVAL REQUEST START
...
>>> APPROVAL REQUEST END
```

And a followup to the same guardian thread would send the full
transcript again (including items 1-4 we already sent):
```
The following is the Codex agent history whose request action you are assessing...
>>> TRANSCRIPT START
[1] user: Please check the repo visibility and push the docs fix if needed.
[2] tool gh_repo_view call: {"repo":"openai/codex"}
[3] tool gh_repo_view result: repo visibility: public
[4] assistant: The repo is public; I now need approval to push the docs fix.
[5] user: Please push the second docs fix too.
[6] assistant: I need approval for the second docs fix.
>>> TRANSCRIPT END
The Codex agent has requested the following action:
>>> APPROVAL REQUEST START
...
>>> APPROVAL REQUEST END
```

## After
Initial guardian review sends the full parent transcript (this is
unchanged):

```
The following is the Codex agent history whose request action you are assessing...
>>> TRANSCRIPT START
[1] user: Please check the repo visibility and push the docs fix if needed.
[2] tool gh_repo_view call: {"repo":"openai/codex"}
[3] tool gh_repo_view result: repo visibility: public
[4] assistant: The repo is public; I now need approval to push the docs fix.
>>> TRANSCRIPT END
The Codex agent has requested the following action:
>>> APPROVAL REQUEST START
...
>>> APPROVAL REQUEST END
```

But a followup now sends:
```
The following is the Codex agent history added since your last approval assessment. Continue the same review conversation...
>>> TRANSCRIPT DELTA START
[5] user: Please push the second docs fix too.
[6] assistant: I need approval for the second docs fix.
>>> TRANSCRIPT DELTA END
The Codex agent has requested the following next action:
>>> APPROVAL REQUEST START
...
>>> APPROVAL REQUEST END
```
2026-04-10 07:48:44 -07:00
jif-oai
d39a722865 feat: description multi-agent v2 (#17338) 2026-04-10 15:31:32 +01:00
jif-oai
8d58899297 fix: MCP leaks in app-server (#17223)
The disconnect path now reuses the same teardown flow as explicit
unsubscribe, and the thread-state bookkeeping consistently reports only
threads that lost their last subscriber

https://github.com/openai/codex/issues/16895
2026-04-10 15:31:26 +01:00
jif-oai
8035cb03f1 feat: make rollout recorder reliable against errors (#17214)
The rollout writer now keeps an owned/monitored task handle, returns
real Result acks for flush/persist/shutdown, retries failed flushes by
reopening the rollout file, and keeps buffered items until they are
successfully written. Session flushes are now real durability barriers
for fork/rollback/read-after-write paths, while turn completion surfaces
a warning if the rollout still cannot be saved after recovery.
2026-04-10 14:12:33 +01:00
jif-oai
085ffb4456 feat: move exec-server ownership (#16344)
This introduces session-scoped ownership for exec-server so ws
disconnects no longer immediately kill running remote exec processes,
and it prepares the protocol for reconnect-based resume.
- add session_id / resume_session_id to the exec-server initialize
handshake
  - move process ownership under a shared session registry
- detach sessions on websocket disconnect and expire them after a TTL
instead of killing processes immediately (we will resume based on this)
- allow a new connection to resume an existing session and take over
notifications/ownership
- I use UUID to make them not predictable as we don't have auth for now
- make detached-session expiry authoritative at resume time so teardown
wins at the TTL boundary
- reject long-poll process/read calls that get resumed out from under an
older attachment

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-10 14:11:47 +01:00
Vivian Fang
7bbe3b6011 Add output_schema to code mode render (#17210)
This updates code-mode tool rendering so MCP tools can surface
structured output types from their `outputSchema`.

What changed:
- Detect MCP tool-call result wrappers from the output schema shape
instead of relying on tool-name parsing or provenance flags.
- Render shared TypeScript aliases once for MCP tool results
(`CallToolResult`, `ContentBlock`, etc.) so multiple MCP tool
declarations stay compact.
- Type `structuredContent` from the tool definition's `outputSchema`
instead of rendering it as `unknown`.
- Update the shared MCP aliases to match the MCP draft `CallToolResult`
schema more closely.

Example:
- Before: `declare const tools: { mcp__rmcp__echo(args: { env_var?:
string; message: string; }): Promise<{ _meta?: unknown; content:
Array<unknown>; isError?: boolean; structuredContent?: unknown; }>; };`
- After: `declare const tools: { mcp__rmcp__echo(args: { env_var?:
string; message: string; }): Promise<CallToolResult<{ echo: string; env:
string | null; }>>; };`
2026-04-10 11:41:44 +00:00
Ahmed Ibrahim
1de0085418 Stream Realtime V2 background agent progress (#17264)
Stream Realtime V2 background agent updates while the background agent
task is still running, then send the final tool output when it
completes. User input during an active V2 handoff is acknowledged back
to realtime as a steering update.

Stack:
- Depends on #17278 for the background_agent rename.
- Depends on #17280 for the input task handler refactor.

Coverage:
- Adds an app-server integration regression test that verifies V2
progress is sent before the final function-call output.

Validation:
- just fmt
- cargo check -p codex-core
- cargo check -p codex-app-server --tests
- git diff --check

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-10 00:06:00 -07:00
Won Park
4e910bf151 adding parent_thread_id in guardian (#17249)
## Summary

This PR adds the parent conversation/session id to the subagent-start
analytics event for Guardian subagents.

Previously, Guardian sessions were emitted as subagent
thread-initialized events, but their `parent_thread_id` was serialized
as `null`. After this change, the `codex_thread_initialized` analytics
event for a Guardian child session includes the parent user conversation
id.
2026-04-10 06:25:05 +00:00
Ahmed Ibrahim
26a28afc6d Extract realtime input task handlers (#17280)
Refactor the realtime input task select loop into named handlers for
user text, background agent output, realtime server events, and user
audio without changing the V2 behavior.

Stack:
- Depends on #17278 for the background_agent rename.

Validation:
- just fmt
- cargo check -p codex-core
- git diff --check

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-09 22:35:18 -07:00
Ahmed Ibrahim
60236e8c92 Rename Realtime V2 tool to background_agent (#17278)
Rename the Realtime V2 delegation tool and parser constant to
background_agent, and update the tool description and fixtures to match.

Validation: just fmt; cargo check -p codex-api; git diff --check

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-09 22:17:55 -07:00
richardopenai
9f2a585153 Option to Notify Workspace Owner When Usage Limit is Reached (#16969)
## Summary
- Replace the manual `/notify-owner` flow with an inline confirmation
prompt when a usage-based workspace member hits a credits-depleted
limit.
- Fetch the current workspace role from the live ChatGPT
`accounts/check/v4-2023-04-27` endpoint so owner/member behavior matches
the desktop and web clients.
- Keep owner, member, and spend-cap messaging distinct so we only offer
the owner nudge when the workspace is actually out of credits.

## What Changed
- `backend-client`
- Added a typed fetch for the current account role from
`accounts/check`.
  - Mapped backend role values into a Rust workspace-role enum.
- `app-server` and protocol
  - Added `workspaceRole` to `account/read` and `account/updated`.
- Derived `isWorkspaceOwner` from the live role, with a fallback to the
cached token claim when the role fetch is unavailable.
- `tui`
  - Removed the explicit `/notify-owner` slash command.
- When a member is blocked because the workspace is out of credits, the
error now prompts:
- `Your workspace is out of credits. Request more from your workspace
owner? [y/N]`
  - Choosing `y` sends the existing owner-notification request.
- Choosing `n`, pressing `Esc`, or accepting the default selection
dismisses the prompt without sending anything.
- Selection popups now honor explicit item shortcuts, which is how the
`y` / `n` interaction is wired.

## Reviewer Notes
- The main behavior change is scoped to usage-based workspace members
whose workspace credits are depleted.
- Spend-cap reached should not show the owner-notification prompt.
- Owners and admins should continue to see `/usage` guidance instead of
the member prompt.
- The live role fetch is best-effort; if it fails, we fall back to the
existing token-derived ownership signal.

## Testing
- Manual verification
  - Workspace owner does not see the member prompt.
- Workspace member with depleted credits sees the confirmation prompt
and can send the nudge with `y`.
- Workspace member with spend cap reached does not see the
owner-notification prompt.

### Workspace member out of usage

https://github.com/user-attachments/assets/341ac396-eff4-4a7f-bf0c-60660becbea1

### Workspace owner
<img width="1728" height="1086" alt="Screenshot 2026-04-09 at 11 48
22 AM"
src="https://github.com/user-attachments/assets/06262a45-e3fc-4cc4-8326-1cbedad46ed6"
/>
2026-04-09 21:15:17 -07:00
Eric Traut
36712d8546 Install rustls provider for remote websocket client (#17288)
Addresses #17283

Problem: `codex --remote wss://...` could panic because
app-server-client did not install rustls' process-level crypto provider
before opening TLS websocket connections.

Solution: Add the existing rustls provider utility dependency and
install it before the remote websocket connect.
2026-04-09 20:29:12 -07:00
Abhinav
f6cc2bb0cb Emit live hook prompts before raw-event filtering (#17189)
# What
Project raw Stop-hook prompt response items into typed v2 hookPrompt
item-completed notifications before applying the raw-response-event
filter. Keep ordinary raw response items filtered for normal
subscribers; only the existing hookPrompt bridge runs on the filtered
raw-item path.

# Why
Blocked Stop hooks record their continuation instruction as a raw
model-history user item. Normal v2 desktop subscribers do not opt into
raw response events, so the app-server listener filtered that raw item
before the existing hookPrompt translator could emit the typed live
item/completed notification. As a result, the hook-prompt bubble only
appeared after thread history was reloaded.
2026-04-09 19:48:21 -07:00
sayan-oai
04fc208b6d preserve search results order in tool_search_output (#17263)
we used to alpha-sort tool search results because we were using
`BTreeMap`, which threw away the actual search result ordering.

Now we use a vec to preserve it.

### Tests
Updated tests
2026-04-09 18:15:10 -07:00
viyatb-oai
b976e701a8 fix: support split carveouts in windows elevated sandbox (#14568)
## Summary
- preserve legacy Windows elevated sandbox behavior for existing
policies
- add elevated-only support for split filesystem policies that can be
represented as readable-root overrides, writable-root overrides, and
extra deny-write carveouts
- resolve those elevated filesystem overrides during sandbox transform
and thread them through setup and policy refresh
- keep failing closed for explicit unreadable (`none`) carveouts and
reopened writable descendants under read-only carveouts
- for explicit read-only-under-writable-root carveouts, materialize
missing carveout directories during elevated setup before applying the
deny-write ACL
- document the elevated vs restricted-token support split in the core
README

## Example
Given a split filesystem policy like:

```toml
":root" = "read"
":cwd" = "write"
"./docs" = "read"
"C:/scratch" = "write"
```

the elevated backend now provisions the readable-root overrides,
writable-root overrides, and extra deny-write carveouts during setup and
refresh instead of collapsing back to the legacy workspace-only shape.

If a read-only carveout under a writable root is missing at setup time,
elevated setup creates that carveout as an empty directory before
applying its deny-write ACE; otherwise the sandboxed command could
create it later and bypass the carveout. This is only for explicit
policy carveouts. Best-effort workspace protections like `.codex/` and
`.agents/` still skip missing directories.

A policy like:

```toml
"/workspace" = "write"
"/workspace/docs" = "read"
"/workspace/docs/tmp" = "write"
```

still fails closed, because the elevated backend does not reopen
writable descendants under read-only carveouts yet.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-09 17:34:52 -07:00
rhan-oai
62c5934b0e merge commit for archive created by Sapling 2026-04-09 17:26:29 -07:00
rhan-oai
af2db0f369 [codex-analytics] add token usage metadata 2026-04-09 17:24:11 -07:00
rhan-oai
3cbd03b1af [codex-analytics] denormalize thread metadata onto turn events 2026-04-09 17:24:11 -07:00
rhan-oai
dd2f563418 [codex-analytics] feature plumbing and emittance 2026-04-09 17:24:11 -07:00