Commit Graph

3336 Commits

Author SHA1 Message Date
Eric Traut
0a2c9aa9d9 Simplify thread settings core helpers 2026-05-18 17:42:36 -07:00
Eric Traut
5dc813bd16 Fix thread settings op kind test 2026-05-18 17:15:15 -07:00
Eric Traut
a14199fbb6 Merge branch 'etraut/next-turn-state-remove-override-context' into etraut/next-turn-state-core 2026-05-18 16:31:20 -07:00
Eric Traut
d6ae36fd8d Merge branch 'etraut/next-turn-state-input-op-consolidation' into etraut/next-turn-state-remove-override-context 2026-05-18 16:30:45 -07:00
Eric Traut
4939645c44 Simplify thread settings test overrides 2026-05-18 16:30:08 -07:00
Eric Traut
2836662ea4 Fix thread settings field rename 2026-05-18 16:17:01 -07:00
Eric Traut
b7d18d7606 Merge branch 'etraut/next-turn-state-remove-override-context' into etraut/next-turn-state-core
# Conflicts:
#	codex-rs/core/src/session/handlers.rs
2026-05-18 16:09:13 -07:00
Eric Traut
76447889f2 Merge branch 'etraut/next-turn-state-input-op-consolidation' into etraut/next-turn-state-remove-override-context 2026-05-18 16:08:16 -07:00
Eric Traut
dea732b035 Merge branch 'etraut/next-turn-state-remove-user-input-with-context' into etraut/next-turn-state-input-op-consolidation 2026-05-18 16:07:57 -07:00
Eric Traut
d3052c6136 Merge branch 'etraut/next-turn-state-user-input-context' into etraut/next-turn-state-remove-user-input-with-context 2026-05-18 16:07:45 -07:00
Eric Traut
9ad7f64d9d Clarify thread settings model updates 2026-05-18 16:06:51 -07:00
Eric Traut
de38d2a98b Merge branch 'etraut/next-turn-state-remove-override-context' into etraut/next-turn-state-core
# Conflicts:
#	codex-rs/core/src/codex_thread.rs
#	codex-rs/core/src/session/handlers.rs
#	codex-rs/core/tests/suite/collaboration_instructions.rs
#	codex-rs/core/tests/suite/compact.rs
#	codex-rs/core/tests/suite/compact_remote.rs
#	codex-rs/core/tests/suite/compact_resume_fork.rs
#	codex-rs/core/tests/suite/model_overrides.rs
#	codex-rs/core/tests/suite/model_switching.rs
#	codex-rs/core/tests/suite/model_visible_layout.rs
#	codex-rs/core/tests/suite/override_updates.rs
#	codex-rs/core/tests/suite/permissions_messages.rs
#	codex-rs/core/tests/suite/personality.rs
#	codex-rs/core/tests/suite/prompt_caching.rs
#	codex-rs/core/tests/suite/remote_models.rs
#	codex-rs/core/tests/suite/resume.rs
#	codex-rs/core/tests/suite/review.rs
#	codex-rs/memories/write/src/startup_tests.rs
#	codex-rs/protocol/src/protocol.rs
2026-05-18 15:36:21 -07:00
Eric Traut
a940c8db7b Merge branch 'etraut/next-turn-state-input-op-consolidation' into etraut/next-turn-state-remove-override-context
# Conflicts:
#	codex-rs/core/src/codex_thread.rs
#	codex-rs/core/src/session/tests.rs
#	codex-rs/protocol/src/protocol.rs
2026-05-18 15:29:58 -07:00
Eric Traut
50435559f4 Merge branch 'etraut/next-turn-state-remove-user-input-with-context' into etraut/next-turn-state-input-op-consolidation 2026-05-18 15:28:14 -07:00
Eric Traut
5946878f8e Merge branch 'etraut/next-turn-state-user-input-context' into etraut/next-turn-state-remove-user-input-with-context
# Conflicts:
#	codex-rs/app-server/src/request_processors/turn_processor.rs
#	codex-rs/core/src/session/handlers.rs
#	codex-rs/protocol/src/protocol.rs
2026-05-18 15:28:05 -07:00
Eric Traut
14284fe5a7 Rename input settings override terminology 2026-05-18 15:27:06 -07:00
Eric Traut
0f483dd5d4 Use queued turn context op in tests 2026-05-18 15:20:43 -07:00
Eric Traut
98c38ee9bf Simplify turn context handler 2026-05-16 18:05:35 -07:00
Eric Traut
529c16f268 Merge branch 'etraut/next-turn-state-remove-override-context' into etraut/next-turn-state-core 2026-05-16 17:58:11 -07:00
Eric Traut
5b41df2613 Simplify turn context update cleanup 2026-05-16 17:57:42 -07:00
Eric Traut
91e427f9f4 Merge branch 'etraut/next-turn-state-remove-override-context' into etraut/next-turn-state-core 2026-05-16 17:42:54 -07:00
Eric Traut
a5f2e7f68f Merge branch 'etraut/next-turn-state-input-op-consolidation' into etraut/next-turn-state-remove-override-context 2026-05-16 17:39:28 -07:00
Eric Traut
9d5a0e2b5d Trim redundant turn context defaults 2026-05-16 17:39:09 -07:00
Eric Traut
c6fe81d803 Simplify turn context update handling 2026-05-16 17:23:39 -07:00
Eric Traut
5b47db287d Fix OverrideTurnContext removal split 2026-05-16 16:00:11 -07:00
Eric Traut
9393c2647b Add queued core turn context op 2026-05-16 15:49:05 -07:00
Eric Traut
875b846721 Remove core OverrideTurnContext op 2026-05-16 15:47:40 -07:00
Eric Traut
1c10a91853 Merge branch 'etraut/next-turn-state-remove-user-input-with-context' into etraut/next-turn-state-input-op-consolidation
# Conflicts:
#	codex-rs/app-server/src/request_processors/turn_processor.rs
#	codex-rs/core/src/session/handlers.rs
#	codex-rs/protocol/src/protocol.rs
2026-05-16 14:21:06 -07:00
Eric Traut
cb528adace Remove UserInputWithTurnContext op 2026-05-16 14:20:00 -07:00
Eric Traut
3b1b54ace7 Add turn context to UserInput 2026-05-16 14:16:20 -07:00
Eric Traut
e1b60da6fc Fix clippy field shorthand in core tests 2026-05-16 13:51:13 -07:00
sayan-oai
061a614d85 multiagent: trim model-visible description, cap to 5 models (#23069)
## Why

The `spawn_agent` model override guidance is uncapped and bloating
context. We need to trim down each entry and cap total entries.

picked 5 as cap, we can change

## What changed

- Cap the model override summaries shown in `spawn_agent` to the first 5
picker-visible models, preserving the existing priority ordering from
the models manager.
- Condense each rendered entry to the actionable pieces the model needs:
  - use the model slug as the label
  - render compact reasoning effort lists with the default marked inline
- render only service tier IDs, and omit the clause when no tiers are
available
- Update coverage so the compact formatter shape and the top-5 cap are
exercised, and keep the end-to-end request assertion aligned with real
model metadata.

## Example

Before:

`- gpt-5.4 ('gpt-5.4\'): Strong model for everyday coding. Default
reasoning effort: medium. Supported reasoning efforts: low (Fast
responses with lighter reasoning), medium (Balances speed and reasoning
depth for everyday tasks), high (Greater reasoning depth for complex
problems), xhigh (Extra high reasoning depth for complex problems).
Supported service tiers: priority (Fast: 1.5x speed, increased usage).`

After:

`- 'gpt-5.4': Strong model for everyday coding. Reasoning efforts: low,
medium (default), high, xhigh. Service tiers: priority.`
2026-05-16 13:43:30 -07:00
Eric Traut
30f6ab2372 Consolidate core input ops 2026-05-16 13:19:04 -07:00
Michael Bolin
d91bc15618 test: construct permission profiles directly (#23030)
## Why

`SandboxPolicy` is now a legacy compatibility shape, but several tests
still built a `SandboxPolicy` only to immediately convert it into
`PermissionProfile` for APIs that already accept canonical runtime
permissions. Those detours make it harder to audit where legacy sandbox
policy is still required, because boundary-only usages are mixed
together with ordinary test setup.

## What Changed

- Updated tests in `codex-core`, `codex-exec`, `codex-analytics`, and
`codex-config` to construct `PermissionProfile` values directly when the
code under test takes a permission profile.
- Changed exec-policy, request-permissions, session, and sandbox test
helpers to pass `PermissionProfile` through instead of converting from
`SandboxPolicy` internally.
- Left `SandboxPolicy` in place where tests are explicitly exercising
legacy compatibility or request/response boundaries.

## Test Plan

- `cargo test -p codex-analytics -p codex-config`
- `cargo test -p codex-core --lib safety::tests`
- `cargo test -p codex-core --lib exec_policy::tests::`
- `cargo test -p codex-core --lib exec::tests`
- `cargo test -p codex-core --lib guardian_review_session_config`
- `cargo test -p codex-core --lib tools::network_approval::tests`
- `cargo test -p codex-core --lib
tools::runtimes::shell::unix_escalation::tests`
- `cargo test -p codex-core --lib managed_network`
- `cargo test -p codex-core --test all request_permissions::`
- `cargo test -p codex-exec sandbox`


---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/23030).
* #23036
* __->__ #23030
2026-05-16 12:12:37 -07:00
Eric Traut
941e7f825e Improve goal completion usage reporting (#22907)
## Why

Goal completion follow-up turns currently receive a preformatted English
usage sentence such as `time used: 2586 seconds`. That nudges the model
to echo an awkward raw seconds count in the final reply, even though the
tool result already exposes structured usage fields like
`goal.timeUsedSeconds`, `goal.tokensUsed`, and `goal.tokenBudget`.

## What changed

- Replace the preformatted completion usage sentence with guidance to
read the structured goal fields from the tool result.
- Preserve token-budget reporting while allowing the model to phrase
elapsed time in a concise, human-friendly way that fits the response
language.
- Update core coverage for both the generated completion guidance and
the session flow that forwards it back to the model.

## Verification

Previously, it would have output a final message indicating that it
"worked for 303 seconds". Now it shows the following:

<img width="286" height="35" alt="image"
src="https://github.com/user-attachments/assets/d7011880-9449-46a7-856f-4e50ae00eb45"
/>
2026-05-16 11:49:40 -07:00
Michael Bolin
108234b5eb core: set permission profiles from snapshots (#22920)
## Why

#22891 moved the TUI turn-command path to pass `ActivePermissionProfile`
instead of the full `PermissionProfile`, but the remaining
config/session bridge still accepted the concrete `PermissionProfile`
and active profile id as separate arguments. That shape made it too easy
for future callers to update the concrete profile and active profile id
out of sync.

This PR makes the trusted session snapshot path pass one coherent value
into `Permissions`, while keeping `requirements.toml` enforcement owned
by the existing constrained permission state.

## What Changed

- Added `PermissionProfileSnapshot` as the public snapshot value for
trusted session/config synchronization.
- Changed `Permissions::set_permission_profile_from_session_snapshot()`
and `replace_permission_profile_from_session_snapshot()` to take a
`PermissionProfileSnapshot`.
- Updated the replacement path to derive its constrained
`PermissionProfile` from the snapshot, so callers cannot pass a separate
profile that disagrees with the snapshot.
- Removed the internal tuple-style
`PermissionProfileState::set_active_permission_profile()` mutation path.
- Updated core session projection and TUI call sites to construct
explicit legacy or active snapshots.
- Documented the snapshot constructors so legacy use and id/profile
mismatch hazards are called out at the API boundary.
- Added a focused config test that verifies snapshot updates still
respect existing permission constraints.

## How To Review

1. Start with `codex-rs/core/src/config/resolved_permission_profile.rs`;
`PermissionProfileSnapshot` is the public wrapper, while
`ResolvedPermissionProfile` stays internal.
2. Check `codex-rs/core/src/config/mod.rs` to confirm both
session-snapshot setters validate through `PermissionProfileState` and
no longer accept loose profile/id pairs.
3. Skim `codex-rs/core/src/session/session.rs` for the session
projection path; it now builds the snapshot before installing it.
4. Skim the TUI changes as call-site migration from loose argument pairs
to explicit snapshot construction.

## Verification

- `cargo test -p codex-core
permission_snapshot_setter_preserves_permission_constraints`
- `cargo test -p codex-tui status_permissions_`
- `cargo test -p codex-tui
session_configured_preserves_profile_workspace_roots`
- `just fix -p codex-core -p codex-tui`
2026-05-16 07:26:18 -07:00
Curtis 'Fjord' Hawthorne
8543e39885 Preserve image detail in app-server inputs (#20693)
## Summary

- Add optional image detail to user image inputs across core, app-server
v2, thread history/event mapping, and the generated app-server
schemas/types.
- Preserve requested detail when serializing Responses image inputs:
omitted detail stays on the existing `high` default, while explicit
`original` keeps local images on the original-resolution path.
- Support `high`/`original` consistently for tool image outputs,
including MCP `codex/imageDetail`, code-mode image helpers, and
`view_image`.
2026-05-15 15:04:04 -07:00
Michael Bolin
8df2d96860 core: construct test permission profiles directly (#22795)
## Why

The core migration is trying to make `PermissionProfile` the shape tests
and runtime code reason about, leaving `SandboxPolicy` only where legacy
behavior is explicitly under test. The local
`permission_profile_for_sandbox_policy()` test helpers kept new
permission-profile tests mentally tied to the old sandbox model even
when the equivalent profile is straightforward.

## What Changed

- Removed the `permission_profile_for_sandbox_policy()` helper from the
network proxy spec tests and session tests.
- Replaced legacy conversions for read-only, workspace-write, and
full-access cases with `PermissionProfile::read_only()`,
`PermissionProfile::workspace_write()`, and
`PermissionProfile::Disabled`.
- Constructed the external-sandbox session test's
`PermissionProfile::External` directly, while preserving the legacy
`SandboxPolicy` only where the test still exercises legacy config update
behavior.

## How To Review

This PR is intentionally test-only. Review the two touched files and
check that each replacement preserves the old legacy mapping:

- `SandboxPolicy::new_read_only_policy()` ->
`PermissionProfile::read_only()`
- `SandboxPolicy::new_workspace_write_policy()` ->
`PermissionProfile::workspace_write()`
- `SandboxPolicy::DangerFullAccess` -> `PermissionProfile::Disabled`
- `SandboxPolicy::ExternalSandbox { network_access: Restricted }` ->
`PermissionProfile::External { network: Restricted }`

## Verification

- `cargo test -p codex-core
requirements_allowed_domains_are_a_baseline_for_user_allowlist`
- `cargo test -p codex-core
start_managed_network_proxy_applies_execpolicy_network_rules`
- `cargo test -p codex-core
session_configured_reports_permission_profile_for_external_sandbox`
- `cargo test -p codex-core
managed_network_proxy_decider_survives_full_access_start`
- `just fix -p codex-core`








---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/22795).
* #22891
* __->__ #22795
2026-05-15 13:09:25 -07:00
Boyang Niu
c15613f2b6 Forward apps MCP product SKU from Codex config (#22872)
This adds `apps_mcp_product_sku` as a toplevel config.toml key. We pass
the given value as a header when listing MCPs for the client, allowing
connectors to be filtered per product entry point.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-05-15 11:52:14 -07:00
Michael Bolin
4c80435eba telemetry: tag sandboxes from permission profiles (#22791)
## Why

Sandbox telemetry tags should be derived from the active permission
profile, not from a legacy `SandboxPolicy`, so the tagging code stays
aligned with the permissions migration and does not preserve a
policy-shaped production helper only for tests.

## What Changed

- Removed the production `sandbox_tag(&SandboxPolicy, ...)` helper.
- Updated sandbox tag tests to construct the relevant
`PermissionProfile` values directly.
- Kept the platform-specific sandbox tag behavior under the existing
`permission_profile_sandbox_tag` path.

## How To Review

The production change is in `codex-rs/core/src/sandbox_tags.rs`. Most of
the diff is test cleanup that replaces legacy policy setup with
permission profiles, so review the expected tag assertions rather than
the old helper mechanics.

## Verification

- `cargo test -p codex-core sandbox_tag`









---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/22791).
* #22795
* #22792
* __->__ #22791
2026-05-15 10:58:50 -07:00
Michael Bolin
aeca1cba6f context: remove legacy permissions instructions helper (#22790)
## Why

The permissions instruction builder should consume the new permissions
model directly. Keeping a `SandboxPolicy` conversion helper in this path
encourages new code to route through legacy sandbox policy values even
when the caller already has a `PermissionProfile`.

## What Changed

- Removed `PermissionsInstructions::from_policy`.
- Removed the test that exercised that legacy helper.
- Left the existing profile-based instruction coverage in place.

## How To Review

Review `codex-rs/core/src/context/permissions_instructions.rs` first.
This PR is intentionally narrow: the production behavior should be
unchanged for profile callers, and the deleted surface was only a
convenience adapter from `SandboxPolicy`.

## Verification

- `cargo test -p codex-core builds_permissions_from_profile`








---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/22790).
* #22795
* #22792
* #22791
* __->__ #22790
2026-05-15 10:11:16 -07:00
Chris Bookholt
9facdccb37 Ignore configured hooks in git helpers (#22843)
## What
- Internal Git helper commands now ignore configured hook directories
during repository bookkeeping.

## Why
- These helper flows should stay consistent even when a repository has
hook-directory configuration of its own.

## How
- Pass a command-local `core.hooksPath` override in the shared helper
path and the Git-info helper path.
- Add regressions for the baseline index rewrite flow and the metadata
status flow.

## Validation
- `cargo fmt --manifest-path
/Users/bookholt/code/codex/codex-rs/Cargo.toml --all --check`
- `cargo test --manifest-path
/Users/bookholt/code/codex/codex-rs/Cargo.toml -p codex-git-utils`
- `cargo test --manifest-path
/Users/bookholt/code/codex/codex-rs/Cargo.toml -p codex-core
test_get_has_changes_`
2026-05-15 10:07:54 -07:00
Michael Bolin
68ccfdc905 guardian: use permission profile for review sandbox (#22789)
## Why

`SandboxPolicy` is being pushed back toward legacy config loading and
compatibility boundaries. Guardian review sessions already want the
built-in read-only permission behavior; carrying that as an active
`PermissionProfile` makes the review sandbox follow the new permissions
path instead of configuring the child session through the legacy policy
API.

## What Changed

- Configure the guardian review session with
`PermissionProfile::read_only()`.
- Send the read-only profile through the guardian child `Op::UserTurn`.
- Keep the legacy `sandbox_policy` field populated with
`SandboxPolicy::new_read_only_policy()` declared next to the profile so
the two remain visibly in sync until the compatibility field goes away.

## How To Review

Start in `codex-rs/core/src/guardian/review_session.rs`. The important
check is that both the guardian config and the child turn now use the
read-only permission profile, while the remaining
`SandboxPolicy::ReadOnly` assignment is only the compatibility field
required by the current turn protocol.

## Verification

- `cargo test -p codex-core
guardian_review_session_config_clears_parent_developer_instructions`





---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/22789).
* #22795
* #22792
* #22791
* #22790
* __->__ #22789
2026-05-15 08:59:31 -07:00
jif-oai
cccde930ce Move memory prompt injection to app-server extension (#22841)
## Why

Memory prompt injection should be owned by the extension path that
app-server composes at runtime, not by an inlined special case inside
`codex-core`. This keeps `codex-core` focused on session orchestration
while allowing the memories extension to own its app-server prompt
behavior.

## What Changed

- Registers `codex-memories-extension` in the app-server extension
registry.
- Moves the memory developer-instruction injection out of
`core/src/session/mod.rs` and into the memories extension prompt
contributor.
- Adds config-change handling so the extension keeps its per-thread
memory settings in sync after startup.
- Leaves memories read/retrieval tools unregistered for now so this PR
only changes prompt injection.
- Removes the stale `cargo-shear` ignore now that app-server depends on
the extension crate.

## Validation

Not run locally; validation is left to CI.
2026-05-15 16:19:34 +02:00
jif-oai
5d30764fe9 Run compact hooks for remote compaction v2 (#22828)
## Why

Remote compaction v2 is the `/responses` implementation of
session-history compaction, but it still needs to preserve the
observable contract of the legacy `/responses/compact` path. In
particular, users and integrations that rely on `PreCompact` and
`PostCompact` hooks should not see different behavior when
`remote_compaction_v2` is enabled.

## What Changed

- Runs `PreCompact` before issuing the remote compaction v2 request,
including `Interrupted` analytics when a pre-hook stops execution.
- Runs `PostCompact` after a successful v2 compaction and aborts the
turn if the post-hook stops execution.
- Adds `compact_remote_parity` coverage that compares legacy and v2
compaction across manual transcript shapes, automatic pre-turn
compaction, automatic mid-turn compaction, hook payloads, replacement
history, follow-up request payloads, and API-key `service_tier=fast`
behavior.
- Registers the new parity suite under `core/tests/suite`.

Relevant code:

-
[`compact_remote_v2.rs`](af63745cb5/codex-rs/core/src/compact_remote_v2.rs)
-
[`compact_remote_parity.rs`](af63745cb5/codex-rs/core/tests/suite/compact_remote_parity.rs)

## Verification

- Added `core/tests/suite/compact_remote_parity.rs` to assert parity
between legacy remote compaction and remote compaction v2 for the
affected request, hook, rollout-history, and follow-up paths.
- Existing `compact_remote_v2` unit coverage still exercises v2
replacement-history retention and compaction-output collection.
2026-05-15 15:26:21 +02:00
jif-oai
c03cea4ca2 Remove zombie tools spec module (#22820)
## Summary

- move tool_user_shell_type out of the old tools::spec module and call
it from tools directly
- attach the remaining spec planning model tests under spec_plan
- delete core/src/tools/spec.rs

## Tests

- just fmt
- cargo test -p codex-core tools::spec_plan

Note: a broader cargo test -p codex-core run on the earlier PR-head
worktree still hit the pre-existing stack overflow in
agent::control::tests::spawn_agent_fork_last_n_turns_keeps_only_recent_turns.
2026-05-15 13:44:58 +02:00
jif-oai
6f1a01fbdd Simplify tool executor and registry plumbing (#22636)
## Why

The tool runtime path still had a typed output associated type on
`ToolExecutor`, plus a core-only `RegisteredTool` adapter and
extension-only executor aliases. That made every new shared tool runtime
carry extra adapter plumbing before it could participate in core
dispatch, extension tools, hook payloads, telemetry, and model-visible
spec generation.

This PR moves output erasure to the shared executor boundary so core and
extension tools can use the same execution contract directly.

## What Changed

- Changed `codex_tools::ToolExecutor` to return `Box<dyn ToolOutput>`
instead of an associated `Output` type.
- Removed the extension-specific `ExtensionToolExecutor` /
`ExtensionToolOutput` aliases and exposed `ToolExecutor<ToolCall>` plus
`ToolOutput` through `codex-extension-api`.
- Reworked core tool registration around `CoreToolRuntime` and
`ToolRegistry::from_tools`, removing the extra `RegisteredTool` /
`ToolRegistryBuilder` layer.
- Consolidated model-visible spec planning and registry construction in
`core/src/tools/spec_plan.rs`, including deferred tool search and
code-mode-only filtering.
- Added `ToolOutput` helpers for post-tool-use hook ids and inputs so
MCP, unified exec, extension, and other boxed outputs preserve the same
hook payload behavior.
- Updated core handlers, memories tools, and the related
registry/spec/router tests to use the simplified contract.

## Test Coverage

- Updated coverage for tool spec planning, registry lookup, deferred
tool search registration, extension tool routing, post-tool-use hook
payloads, dispatch tracing, guardian output extraction, and memories
extension tool execution.
2026-05-15 11:47:54 +02:00
jif-oai
0322ac3df8 [codex] Use compaction_trigger item for remote compaction v2 (#22809)
## Why

Remote compaction v2 was still using `context_compaction` as both the
request trigger and the compacted output shape. The Responses API now
has the landed contract for this flow: Codex sends a dedicated `{
"type": "compaction_trigger" }` input item, and the backend returns the
standard `compaction` output item with encrypted content.

This aligns the v2 path with that wire contract while preserving the
existing local compacted-history post-processing behavior.

## What changed

- Add `ResponseItem::CompactionTrigger` and regenerate the app-server
protocol schema fixtures.
- Send `compaction_trigger` from `remote_compaction_v2` instead of a
payload-less `context_compaction`.
- Collect exactly one backend `compaction` output item, then reuse the
existing compacted-history rebuilding path.
- Treat the trigger item as a transient request marker rather than model
output or persisted rollout/memory content.

## Verification

- `cargo test -p codex-protocol compaction_trigger`
- `cargo test -p codex-core remote_compact_v2`
- `cargo test -p codex-core compact_remote_v2`
- `cargo test -p codex-core
responses_websocket_sends_response_processed_after_remote_compaction_v2`
- `just write-app-server-schema`
- `cargo test -p codex-app-server-protocol schema_fixtures`
2026-05-15 11:40:35 +02:00
Michael Bolin
8a5306ff88 app-server: use permission ids and runtime workspace roots (#22611)
## Why

This PR builds on [#22610](https://github.com/openai/codex/pull/22610)
and is the app-server side of the migration from mutable per-turn
`SandboxPolicy` replacement toward selecting immutable permission
profiles by id plus mutable runtime workspace roots.

Once permission profiles can carry their own immutable
`workspace_roots`, app-server no longer needs to mutate the selected
`PermissionProfile` just to represent thread-specific filesystem
context. The mutable part now lives on the thread as explicit
`runtimeWorkspaceRoots`, while `:workspace_roots` remains symbolic until
the sandbox is realized for a turn.

## What Changed

- Replaced the v2 permission-selection wrapper surface with plain
profile ids for `thread/start`, `thread/resume`, `thread/fork`, and
`turn/start`.
- Removed the API surface for profile modifications
(`PermissionProfileSelectionParams`,
`PermissionProfileModificationParams`,
`ActivePermissionProfileModification`).
- Added experimental `runtimeWorkspaceRoots` fields to the thread
lifecycle and turn-start APIs.
- Threaded runtime workspace roots through core session/thread
snapshots, turn overrides, app-server request handling, and command
execution permission resolution.
- Kept session permission state symbolic so later runtime root updates
and cwd-only implicit-root retargeting rebind `:workspace_roots`
correctly.
- Updated the embedded clients just enough to send and restore the new
thread state.
- Refreshed the generated schema/TypeScript artifacts and the app-server
README to match the new contract.

## Verification

Targeted coverage for this layer lives in:

- `codex-rs/app-server-protocol/src/protocol/v2/tests.rs`
- `codex-rs/app-server/tests/suite/v2/thread_start.rs`
- `codex-rs/app-server/tests/suite/v2/thread_resume.rs`
- `codex-rs/app-server/tests/suite/v2/turn_start.rs`
- `codex-rs/core/src/session/tests.rs`

The key regression checks exercise that:

- `runtimeWorkspaceRoots` resolve against the effective cwd on thread
start.
- Profile-declared workspace roots are excluded from the runtime
workspace roots returned by app-server.
- A turn-level runtime workspace-root update persists onto the thread
and is returned by `thread/resume`.
- A named permission profile selected on one turn remains symbolic so a
later runtime-root-only turn update changes the actual sandbox writes.
- A cwd-only turn update retargets the implicit runtime cwd root while
preserving additional runtime roots.
- The protocol fixtures and generated client artifacts stay in sync with
the string-based permission selection contract.











---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/22611).
* #22612
* __->__ #22611
2026-05-14 23:00:05 -07:00
guinness-oai
4f2918dd7f [codex] Add opaque desktop config namespace (#22584)
## Summary
- reserve an explicit opaque `desktop` namespace in `ConfigToml`
- expose `desktop` directly in the app-server v2 `config/read` response
- keep `config/value/write` and `config/batchWrite` as the only mutation
seam for paths like `desktop.someKey`
- regenerate the config/app-server schema outputs and document the new
contract

## Why
The desktop settings work wants one durable, user-editable home for
app-owned preferences in `~/.codex/config.toml`, without forcing Rust to
model every individual desktop setting key.

This PR is only the enabling Rust/app-server layer. It gives the
Electron app a first-class config namespace it can read and write
through the existing config APIs, while leaving the actual desktop
migration to the app PR.

## Behavior and design notes
- **Opaque but explicit:** `desktop` is first-class at the typed config
root, while its children remain app-owned and open-ended.
- **Strict validation still works:** arbitrary nested `desktop.*` keys
are accepted instead of being rejected as unknown config.
- **Existing config APIs stay the seam:** `config/read` returns the bag,
and dotted writes such as `desktop.someKey` continue to flow through
`config/value/write` / `config/batchWrite` rather than a bespoke RPC.
- **No new consumer behavior:** Core/TUI do not start depending on
desktop preferences. This only preserves and exposes the namespace for
callers that intentionally use it.
- **Same persistence machinery:** hand-edited `config.toml` keeps using
the existing TOML edit/write path; this PR does not introduce a second
serializer or side channel.
- **TOML-friendly values:** the namespace is intended for ordinary
JSON-shaped setting values that map cleanly into TOML: strings, numbers,
booleans, arrays, and nested object/table values. This PR does not add
special handling for TOML-only edge cases such as datetimes.

## Layering semantics
Reads keep using the ordinary effective config pipeline, so `desktop`
participates in the same layered `config/read` behavior as the rest of
`ConfigToml`. Writes still target user config through the existing
config service.

## Why this is the shape
The alternative would be teaching Rust about each desktop setting as it
is added. That would make ordinary app preferences into a cross-repo
change, which is exactly the coupling we want to avoid.

This keeps the contract small:
1. Rust owns one opaque `desktop` namespace in `config.toml`.
2. The desktop app owns the schema and meaning of individual keys inside
it.
3. The existing config APIs remain the transport and mutation surface.

That is the piece the desktop settings PR needs in order to move forward
cleanly.

## Verification
- `cargo test -p codex-config strict_config_accepts_opaque_desktop_keys`
- `cargo test -p codex-core
desktop_toml_round_trips_opaque_nested_values`
- `cargo test -p codex-core config_schema_matches_fixture`
- `cargo test -p codex-app-server-protocol`
- `cargo test -p codex-app-server --test all desktop_settings`
2026-05-15 02:34:21 +00:00