Commit Graph
104 Commits
Author SHA1 Message Date
sayan-oai 0a6616f4cf Mark the primary environment in model context (#35874)
## Why

When a turn uses multiple environments, the environment context lists each one but did not identify which environment is primary.

## What changed

- Add a `primary` attribute to each environment in multi-environment model context.
- Persist primary selection in world-state snapshots and emit updates when the primary environment changes.
- Restate environments when transitioning between single- and multi-environment context, while preserving the existing single-environment format.

## Testing

- Cover primary-environment changes, single/multi-environment transitions, legacy snapshot compatibility, and deferred-executor promotion after environment startup.

GitOrigin-RevId: 73a1d794a227edef6e9b7844e7f947b7f598dc80
2026-07-29 03:02:32 +00:00
jif 03edf16f0b Support plaintext collaboration tool messages (#35845)
## What changed

- Preserve `encrypted_function_args` on function calls so an empty list can mark plaintext collaboration arguments across request replay.
- Deliver `spawn_agent`, `send_message`, and `followup_task` payloads as structured plaintext agent messages when that marker is present; retain encrypted delivery otherwise.
- Redact plaintext collaboration arguments from tool and communication logs, and omit the metadata when sending requests to non-OpenAI providers.

## Testing

- Cover serialization of empty encrypted-argument metadata and plaintext versus encrypted subagent message delivery.
- Verify plaintext tool arguments are redacted and provider-specific metadata is removed from non-OpenAI requests.

GitOrigin-RevId: 64db98ff0b61a3af2f04ed609292363f2e2362a8
2026-07-28 23:49:37 +00:00
jif 8495963ac6 Place host skills before permission instructions (#35661)
## What changed

- Insert the `host_skills` world-state section before the permissions section
  when permissions are present.
- Verify that skill metadata appears before `<permissions instructions>` in the
  rendered developer message.

GitOrigin-RevId: e9fc62f498c384e841fc34ef679850557645f989
2026-07-27 19:01:53 +00:00
rka-oai fbe65995bb Support model-owned token budget defaults (#35608)
## What changed

- Add token-budget settings to model catalog messages and apply them when the
  feature is enabled without explicit token-budget configuration.
- Keep explicit user settings authoritative, reject invalid catalog defaults,
  and preserve resolved defaults in exported config locks.
- Manage context-window guidance through world state so it updates once when
  the active model changes while retaining prior conversation history.

## Testing

- Cover catalog defaults, explicit overrides, disabled features, invalid
  values, config-lock replay, and model switching.

GitOrigin-RevId: 54544fefaa14b09f5ef5bad9967a13c52b87b0fe
2026-07-27 12:52:37 +00:00
sayan-oai 18f50c9e62 Track model and personality in world state (#35530)
## What changed

- Add model and personality sections to the persisted world-state snapshot.
- Generate model-switch and personality instructions through world-state diffs, including when prior state must be inferred during replay.
- Keep those instruction fragments in standalone developer messages instead of merging them with adjacent context updates.

## Testing

- Cover initial, unchanged, and changed model and personality states.
- Verify that model changes are recorded in rollout world-state items.

GitOrigin-RevId: 497e29cf38cac08e992e546df900f6f8b01120f9
2026-07-26 23:36:33 +00:00
Ahmed Ibrahim 1d4b58f32d Track deferred tool namespaces in world state (#35063)
## What changed

- Add the disabled-by-default `deferred_tool_world_state` feature, which exposes deferred tool namespaces and their descriptions to the model in a `<tools>` world-state section.
- Emit added and removed namespace updates as tool availability changes, bound the rendered context size, and persist nonempty state across thread resumes.
- Omit empty tool state while retaining deferred tool discovery through `tool_search`.

## Testing

- Cover initial, unchanged, removed, recovered, empty, and resumed namespace state, along with description truncation and rendered-size limits.

GitOrigin-RevId: 867e599666dc3569eb0789ba78aaa40254253a6f
2026-07-24 01:20:04 +00:00
sayan-oai 0da13c6c99 Track multi-agent mode in world state (#34845)
## Why

Multi-agent mode instructions are durable model context and need to survive
history changes without re-emitting unrelated setup hints.

## What changed

- Add a `multi_agent_mode` world-state section that diffs, retains, and restores
  the effective mode instructions.
- Persist mode changes in world-state snapshots while keeping the legacy
  `TurnContextItem.multi_agent_mode` field for reading older rollouts.
- Keep initial mode instructions after the root-agent usage hint so the active
  mode takes precedence, and bound custom mode text before snapshotting it.

## Testing

- Add snapshot coverage for mode transitions, retained history, and custom-text
  truncation.
- Verify live mode changes preserve instruction ordering, avoid duplicating the
  usage hint, and record both modes in world state.

GitOrigin-RevId: 96b9964d6e5299b07a011c559b68e3d948a49226
2026-07-22 23:57:24 +00:00
iceweasel-oai 87f71e35b8 Skip missing paths in filesystem sandbox entries (#34598)
## Why

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

## What changed

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

## Testing

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

GitOrigin-RevId: 6df13dadacdd131c44aab9f15a967c81051355c1
2026-07-21 19:17:18 +00:00
rhan-oai 2be7d3bcd9 Support catalog messages for non-request approval policies (#34434)
## What changed

- Add model-catalog approval message variants for `never` and `unless_trusted`.
- Select the catalog message that matches the active approval policy, while retaining the existing built-in text when that variant is absent.
- Treat an explicitly empty variant as an instruction to suppress the built-in approval text, consistent with `on_request` messages.

## Testing

- Cover variant selection, fallback and empty-message behavior, catalog deserialization, and the initial permissions message sent to the model.

GitOrigin-RevId: a0f8d41a08645f39b80093be53f200eeee18ca25
2026-07-21 00:22:31 +00:00
Won Park 7e51abbbd1 Avoid rendering generated images twice (#34378)
## What changed

- Tell the model that generated images are already displayed to the user and should not be repeated as Markdown images or file links.
- Keep generated-image artifact paths and output hints owned by the image generation extension.
- Centralize the availability check for the image generation tool across feature, provider, namespace-tool, model modality, and authentication requirements.

## Testing

- Verify artifact paths sanitize session and call identifiers.
- Verify the model-facing output hint reports that the generated image is already displayed.

GitOrigin-RevId: 6c865b6a96d6a71bb2c33246d1518a00e7c8b840
2026-07-20 16:47:03 +00:00
pakrym-oai 82b294c73c Track permission instructions in world state (#33944)
## What changed

- Model permission instructions as a world-state section keyed by a stable hash of their rendered developer message.
- Re-emit permission context when its model-visible contents change or the retained fragment is missing, while avoiding duplicates when matching instructions already exist in history, including bundled developer messages.
- Normalize CRLF line endings when hashing world-state fragments so equivalent content produces the same snapshot.

## Testing

- Add snapshot coverage for unchanged, changed, absent, and unknown permission state.
- Cover bundled retained permissions and restored world-state baselines during rollout reconstruction.

GitOrigin-RevId: 7d8d212460c1690ca617859f66dcd825987f1e23
2026-07-18 02:45:55 +00:00
pakrym-oai b9680065b0 Track realtime conversation state in world state (#33893)
## What changed

- Represent whether realtime is active as a persisted world-state section.
- Emit start and end instructions from world-state transitions, including when
  reconstructing context after resume.
- Retain existing realtime start fragments and avoid emitting another start when
  custom instructions change while realtime remains active.

## Testing

- Add snapshot coverage for absent, unknown, active, and inactive realtime state
  transitions.
- Cover realtime start and end updates plus resuming with changed custom start
  instructions.

GitOrigin-RevId: ec670b8132b0f1c9317738bfdeb272069927d91d
2026-07-17 19:33:52 +00:00
pakrym-oai cf4c8cab7c Track collaboration mode instructions in world state (#33876)
## What changed

- Model collaboration mode as a world-state section whose persisted snapshot is
  the active mode.
- Emit collaboration instructions when the mode changes, while ignoring
  instruction text changes within the same mode.
- Restore persisted collaboration instructions when they are missing from
  retained history, including after a fork.

## Testing

- Add snapshot coverage for initial, unchanged, changed, and unknown mode state.
- Cover retained-history restoration and same-mode instruction changes.

GitOrigin-RevId: ffd1683499f09acef6516b0bfcb5bcb4d3f28df4
2026-07-17 17:22:39 +00:00
Shijie Rao 20465d30ae Suppress empty multi-agent mode messages (#33862)
## What changed

- Treat an empty custom `multi_agent_mode_hint_text` as having no instructions to emit.
- Avoid adding an empty multi-agent mode message both on the initial turn and when the configured hint changes after resuming a session.

## Testing

- Update the empty-hint integration test to assert that no mode message is sent.
- Add resume coverage that verifies changing a custom hint to an empty string emits no update.

GitOrigin-RevId: 8033292115936fac2cf22f85141278595804ee61
2026-07-17 16:10:50 +00:00
guinness-oai 22f413bdbf Tag realtime transcript tail flush delegations (#33855)
## What changed

- Add `<source>transcript_tail_flush</source>` to realtime delegation payloads
  emitted when a session flushes its remaining transcript tail.
- Keep explicit realtime handoff payloads unchanged.
- Render both delegation variants through a shared contextual user fragment.

## Testing

- Update realtime conversation tests to cover tagged transcript-tail flushes and
  preserve the existing handoff format and XML escaping behavior.

GitOrigin-RevId: 33f70d16cf45b3af8068565c4cf2b1785be3f1d9
2026-07-17 15:50:13 +00:00
sayan-oai c4ce0493dc Keep active-turn environments stable across settings updates (#33658)
## Why

With deferred execution enabled, rebuilding a step context from the latest
thread environment snapshot could apply a settings update to a turn that was
already in progress.

## What changed

- Preserve each turn's captured environment selections when creating later
  step contexts.
- Refresh only the readiness of environments that were already starting, while
  retaining their original selection order.
- Apply updated environment selections to the next turn.

## Testing

Add coverage for changing the selected workspace while a turn is paused,
verifying that the active turn keeps its original working directory and the
next turn uses the new one.

GitOrigin-RevId: c6f4388c843384ef045b7abdbc303dcfca11d230
2026-07-16 18:23:43 +00:00
sayan-oai aff7c69659 Clarify when to wait for starting environments (#33636)
## Why

An execution environment marked `starting` is not yet usable, but unrelated work can continue while it becomes ready.

## What changed

- Add developer guidance that explains execution-environment isolation and the resources that become available after startup.
- Tell the model to wait only when the current task needs the starting environment.
- Retain the guidance across world-state updates without duplicating it in request history.

## Testing

- Cover world-state transitions, history retention, rollback handling, and deferred-environment request deduplication.

GitOrigin-RevId: f12f9204d4cbddce50a70eb0998beb6b66cd2fa9
2026-07-16 16:27:22 +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
iceweasel-oai 4bc2c723ef Select the elevated Windows sandbox for network proxies (#33445)
## Why

Windows firewall enforcement is tied to the logon-user sandbox identities. Proxy-enforced commands therefore need the elevated backend even when the configured sandbox mode is the default restricted-token mode.

## What changed

- Select the elevated Windows sandbox backend whenever a command uses the managed network proxy.
- Remove configuration and startup checks that required users or managed requirements to select the elevated sandbox explicitly.
- Start and expose managed network proxy state consistently on Windows.

## Testing

- Verify that proxy enforcement selects the elevated backend for the restricted-token sandbox mode.

GitOrigin-RevId: e01ac052587721c468a8fbcf4e2c7c5a185a3e05
2026-07-15 23:19:00 +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
pakrym-oai 8530440b91 Refactor world-state rendering tests into snapshots (#33412)
## What changed

- Add a shared test helper that renders before-and-after section states alongside the resulting role and content.
- Convert the agents, environment, apps, and plugins world-state tests to snapshot tables covering absent, unknown, unchanged, changed, and removed states.

GitOrigin-RevId: 03372a5f925d2019f37bf5a5a2f060261899026c
2026-07-15 20:01:33 +00:00
rka-oai 768330dd6c Add a fallback phase before automatic context rollover (#33255)
## Why

Token-budget sessions need a final opportunity to preserve important state before the current context is compacted.

## What changed

- When `auto_compact_fallback_prompt` is configured, reserve `auto_compact_fallback_buffer_tokens` beyond the base auto-compaction limit.
- At the base limit, inject the fallback prompt once as a developer message while keeping the normal tool surface available. Continue reporting zero base-window tokens during this reserve.
- Roll over when the reserve or full model context is exhausted, and skip the fallback when a new context was already requested.

## Testing

Added coverage for using the fallback reserve, rolling over after it is exhausted, and bypassing the fallback for an explicit `new_context` request.

GitOrigin-RevId: 32983ecadc5cb4927e15ecd7b1e896cb52a9ad3b
2026-07-15 05:45:43 +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
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
Matthew Zeng b019a5577c Tighten recommended plugin install suggestions (#32949)
## What changed

- Limit `request_plugin_install` guidance to explicitly requested plugins after tool search has been exhausted.
- Exclude adjacent capabilities, broad recommendations, and plugins that only seem potentially useful.
- Clarify that `plugin_id` is the parenthesized ID from `<recommended_plugins>` and prohibit parallel tool calls.
- Keep the recommendation context focused on listing available plugins while the tool specification owns the installation criteria.

## Testing

- Update tool specification tests to verify the stricter eligibility and serialization guidance.

GitOrigin-RevId: 6ebfdd864a76316ab59a0624dc4d7d3abda39a98
2026-07-14 04:29:57 +00:00
iceweasel-oai abbb8c569c Require the elevated Windows sandbox for network proxies (#32857)
## Why

Network proxy enforcement on Windows requires the elevated sandbox backend. Silently selecting that backend for an unelevated configuration makes the effective sandbox differ from the configured mode.

## What changed

- Reject enabled network proxy configurations on Windows unless managed requirements allow only the elevated sandbox and `windows.sandbox` resolves to `"elevated"`.
- Preserve the configured sandbox backend during execution and validate proxy compatibility at config loading, sandbox setup, and process launch boundaries.
- Defer this validation during cloud-config bootstrap so authoritative managed requirements can be loaded first.
- Do not start or expose disabled Windows proxies, and render transitions to disabled networking as `<network enabled="false"></network>`.

## Testing

- Cover Windows requirement and sandbox compatibility matrices, bootstrap behavior, backend selection, disabled proxy handling, and environment-context updates.

GitOrigin-RevId: bfa1dda98594e0db61883f8e7f65bd560e3453e6
2026-07-13 19:04:22 +00:00
jif 4ebc61c0f8 Make explicit multi-agent mode override proactive delegation (#32822)
## Why

After switching from proactive delegation to explicit-request-only mode, an
earlier proactive instruction can remain in the conversation context. The new
mode must clearly supersede that instruction.

## What changed

Update the explicit-request-only developer message to cancel earlier proactive
delegation instructions before requiring delegation to be explicitly requested
by the user, `AGENTS.md`, or a skill.

## Testing

Update the multi-agent mode integration test expectation for the explicit-mode
instruction emitted after a cold resume.

GitOrigin-RevId: 0a6d18f38ef82d29cf4f3bfcfd4ac84738a39598
2026-07-13 15:39:24 +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
Won Park a7c72aee8b Use the image generation extension by default (#31596) 2026-07-09 12:25:19 +09:00
Dylan Hurd 358575465c Use model catalog approval messages (#31312)
## Why

Approval guidance is currently assembled entirely by the client. Model
Messages V2 needs model catalogs to provide model-specific `on_request`
guidance for both user-reviewed and auto-reviewed approval flows while
retaining the existing generated prompt as a compatibility fallback.

## What changed

- add nullable `on_request` and `on_request_auto_review` catalog
messages
- select the message matching the active approvals reviewer for
`on_request` policies
- replace the complete legacy approval section when the selected catalog
value exists, including support for an empty string that suppresses the
section
- retain legacy rendering when the object or selected key is absent, and
for non-`on_request` policies
- preserve approval messages when base-instruction or personality
overrides clear instruction templates
- refresh permissions instructions when the active model changes
- pass catalog messages through initial and incremental permissions
construction

## Relationship to reviewer persistence

PR #31309 independently persists the approvals reviewer in turn context
and refreshes permissions when that reviewer changes. This PR is based
directly on `main` and does not duplicate that rollout migration; once
both land, reviewer switches will also select and append the new catalog
variant.

## Testing

- `just test -p codex-protocol`
- `just test -p codex-prompts`
- `just test -p codex-models-manager`
- `just test -p codex-core permissions_messages`
2026-07-07 10:52:38 -07:00
sayan-oai 3c2bfe7c5d Make Apps guidance react to MCP availability (#30226)
## Why

Generic Apps guidance is emitted only while building static initial
context. If the Apps MCP is unavailable then and recovers later in the
same turn, its tools can become usable without the model receiving the
guidance for using them.

## What

- move generic Apps guidance into a persisted `apps_instructions` World
State section
- derive availability from the request's MCP runtime while preserving
the existing feature, auth, orchestrator-MCP, and config gates
- recognize legacy and retained Apps fragments so resume and compaction
do not duplicate guidance
- register Apps guidance as rollback-trimmable context
- remove the old static injection path and its now-unused connector
helper
- keep tool construction on its existing independent `list_all_tools()`
read rather than adding a request-wide cache; a reconnect between the
two reads can differ for one request and reconciles on the next request

Apps and plugin guidance now render after the remaining static
host-skills block, with Apps before Plugins.

## Testing

- `just fmt`
- `just test -p codex-core apps_instructions`
- `just test -p codex-core
apps_guidance_appears_after_background_recovery_within_a_turn`
- `just test -p codex-core
drop_last_n_user_turns_trims_context_updates_above_rolled_back_turn`
2026-07-06 14:29:19 -07:00
sayan-oai 9c5be7e1d5 Make plugin guidance react to environment readiness (#30223)
## Why

Generic plugin guidance is currently emitted only with initial context
from host plugin state. An executor-selected plugin can become available
later in the same turn, making its skills and tools usable without ever
telling the model how plugin capabilities should be used.

## What

- project every ready selected plugin package, including skill-only
plugins
- carry plugin availability with the exact MCP runtime projection while
preserving MCP manager reuse when servers and connectors are unchanged
- move generic plugin guidance from the static initial-context path into
persisted World State
- recognize legacy and retained plugin fragments so resume and
compaction do not duplicate guidance

## Testing

- `just test -p codex-mcp-extension`
- `just test -p codex-core plugins_instructions`
- `just test -p codex-core
plugin_availability_change_reuses_the_mcp_manager`
- `just test -p codex-app-server --test all selected_capabilit`
2026-07-06 07:05:40 -07:00
Shijie Rao da4c8ca57d [codex] Add configurable multi-agent mode hint text (#30493)
## Why

Multi-agent V2 normally derives its mode instructions from reasoning
effort: Ultra enables proactive delegation, while other efforts require
an explicit request. Some deployments need to provide one configured
delegation policy that replaces those built-ins and remains stable when
reasoning effort changes.

## What changed

- Add `features.multi_agent_v2.multi_agent_mode_hint_text` alongside the
existing root and subagent hint settings.
- Treat any configured value, including an empty string, as
`MultiAgentMode::Custom(hint_text)`, so the configured text replaces the
built-in explicit-only and proactive policies.
- Persist the full custom variant and hint text in the turn-context
snapshot, so the durable comparison baseline detects both
reasoning-effort changes and configured policy-text changes.
- Preserve the existing explicit-only/proactive behavior when the
setting is absent.
- Replace the ambiguous `MultiAgentMode::None` variant with
`MultiAgentMode::Custom(String)` in new rollouts and API schemas. A
compatibility wire type maps legacy serialized `none` values to
`Custom("")` when resuming existing rollouts.
- Regenerate the config and app-server schemas.

## Configuration examples

The distinction is whether `multi_agent_mode_hint_text` is present. An
empty string is still a configured value and intentionally suppresses
the built-in mode instructions.

### Unset: preserve existing effort-derived behavior

```toml
[features.multi_agent_v2]
enabled = true
# multi_agent_mode_hint_text is omitted
```

- Ultra reasoning uses the built-in proactive delegation instructions.
- Other reasoning efforts use the built-in explicit-request-only
instructions.

### Empty: suppress all mode hint text

```toml
[features.multi_agent_v2]
enabled = true
multi_agent_mode_hint_text = ""
```

This selects effective mode `custom` at every reasoning effort and
injects an empty mode body, suppressing both built-in policies.

### Set: always use the configured text

```toml
[features.multi_agent_v2]
enabled = true
multi_agent_mode_hint_text = "Delegate to subagents when it will materially improve the result."
```

This selects effective mode `custom` at every reasoning effort and
injects the configured text verbatim instead of either built-in policy.

## Verification

- `just test -p codex-core multi_agent_mode`
- Covers a configured hint across High and Ultra reasoning efforts and
verifies the full custom hint is recorded for both turns.
- Covers an empty-string override suppressing both built-in instruction
bodies.
- `just test -p codex-protocol -p codex-app-server-protocol`
- Covers legacy `none` turn-context deserialization as `Custom("")` and
verifies the regenerated schemas.
2026-07-02 18:44:34 -07:00
ani-oai 6b5f5743b3 [codex] Use model metadata for skills usage instructions (#29740)
## Summary

- add a false-by-default `include_skills_usage_instructions` model
metadata field
- enable the field for the bundled `gpt-5.5` model metadata
- consume the metadata in both core and extension skill rendering
- remove hardcoded legacy-model matching and its marker plumbing
2026-06-29 09:44:36 +09:00
Charles Du 79a8ffdbf7 [codex] allow AGENTS.md and skills to authorize delegation (#30274)
Prompt update of MAv2 to include agents.md and skills more explicitly

should mimic: https://github.com/openai/codex/pull/27919
2026-06-26 12:17:26 -07:00
jif 723b23efd0 Reinject missing World State fragments on resume (#30152)
## Why

World State restores its structured snapshot on resume so unchanged
sections do not have to be rendered again. That is safe only when the
model-visible fragment represented by the snapshot is still present in
retained history.

For selected executor skills, the failing selected-capability scenario
exposed this state:

```text
persisted World State: selected skill catalog is known
retained model history: selected skill catalog message is missing
next diff: unchanged, so emit nothing
```

The model resumes without being told about the selected skill catalog.

## What changed

World State contributions may now optionally describe the concrete
model-visible fragment that must remain in retained history.

When a persisted snapshot is present:

```text
matching retained fragment exists -> trust snapshot, emit nothing
matching retained fragment missing -> treat section as absent, render current state once
```

The skills extension uses this for non-empty selected-environment
catalogs by matching its exact rendered catalog body. Empty or hidden
catalogs do not require a fragment.

## Scope

This does not clear or rebuild the whole World State baseline. It does
not change skill discovery, cache invalidation, environment
availability, or MCP runtime behavior. It only keeps a persisted section
snapshot and its retained model context consistent across resume/history
reconstruction.

## Coverage

A focused World State regression test verifies both sides:

- a missing retained fragment is rendered again
- a matching retained fragment avoids duplicate injection
2026-06-26 02:18:00 +01:00
jif c9e6d9783d Let extensions contribute World State sections (#30100)
## Why

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

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

## Shape

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

The extension API is deliberately small:

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

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

## What changes

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

## What does not change

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

## Example

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

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

## Stack

1. **This PR:** let extensions contribute World State sections.
2. Project executor skills through the skills extension.
3. Pin one MCP runtime to each model step.
4. Project selected MCP/app/connector metadata by environment
availability.
5. One end-to-end integration scenario.
2026-06-25 22:23:51 +01:00
sayan-oai ab80d4d484 core: reconcile legacy WorldState sections (#29997)
## Why

Older rollouts can retain model-visible context for a WorldState section
without having a persisted snapshot for that section. Treating the
missing snapshot as definitely absent can duplicate old context or fail
to tell the model that it was replaced or removed.

This provides a generic migration path for sections moving into
WorldState, beginning with AGENTS.md.

Builds on #29810.

## What changed

- distinguish section state that is absent, known from a persisted
snapshot, or unknown because matching legacy context remains in history
- let WorldState sections identify their own legacy fragments while
`ContextManager` owns history reconciliation and baseline persistence
- make AGENTS.md emit one conservative replacement or removal update for
legacy history, then deduplicate from the newly persisted baseline
- preserve existing environment rendering when persisted section data is
missing or malformed

## Testing

- `just test -p codex-core world_state`
- `just test -p codex-core
cold_resume_invalidates_deleted_legacy_agents_md_once -- --exact`
2026-06-25 07:03:52 +00:00
sayan-oai f2f80ef442 core: make AGENTS.md react to environment changes (#29810)
## Why

With deferred executors, a turn can begin before a remote environment
attaches. AGENTS.md discovery previously ran only during session setup,
so instructions from a later environment never reached the model or the
session instruction sources.

WorldState persistence has now landed, so this uses the durable
model-visible baseline directly instead of carrying a temporary
resume/fork compatibility path.

## What

- Add an `AgentsMdManager` in `SessionServices` to own host
instructions, loaded state, and refresh caching.
- When `DeferredExecutor` is enabled, refresh AGENTS.md when attached
environment selections change and freeze the result in the corresponding
`StepContext`.
- Represent AGENTS.md as a persisted WorldState section for every
session, with bounded initial, replacement, and removal updates.
- Remove duplicate AGENTS.md state and rendering from
`SessionConfiguration` and `TurnContext`.
- Build initial context, per-request updates, and compaction context
from the same step-scoped value.
- On resume and fork, compare current instructions with the restored
WorldState baseline and inject a replacement exactly once when they
differ.

Builds on #29833, #29835, and #29837.

## Tests

- Covers a remote environment becoming ready mid-turn, with AGENTS.md
appearing on the next request exactly once and updating canonical
instruction sources.
- Covers full, unchanged, replaced, and removed AGENTS.md WorldState
rendering.
- Covers changed instructions across cold resume and fork without
duplicate reinjection.
- Covers remote-v2 compaction retaining creation-time instructions in
the live session and cold resume appending one replacement when the
source changed.
- Ran focused `codex-core` AGENTS.md, WorldState, and context-update
test suites.
2026-06-24 22:57:42 -07:00
sayan-oai a74771340d [3/3] core: replay persisted world state (#29837)
## Why

Persisting `WorldState` snapshots and patches is only useful if resume
and fork restore that exact comparison baseline. Rebuilding it from
`TurnContextItem` loses section state and can either repeat or suppress
model-visible updates.

This is the third PR in the WorldState persistence stack, built on
#29835.

## What

- Replay full WorldState snapshots and RFC 7386 patches through the
existing rollout reconstruction segments.
- Discard state from rolled-back turns and treat compaction as a
baseline reset.
- Hydrate `ContextManager` from the reconstructed snapshot on resume and
fork.
- Remove the synthetic `TurnContextItem` to WorldState conversion path.
- Leave legacy or malformed rollouts without a baseline so the next
update safely emits a full snapshot.

## Testing

- `just test -p codex-core world_state`
- `just test -p codex-core rollout_reconstruction_tests`
- `just fix -p codex-core`
- `just test -p codex-core` *(the changed tests passed; the full run
also hit unrelated existing/test-environment failures, primarily a
missing `test_stdio_server` binary)*
2026-06-25 03:32:08 +00:00
sayan-oai fa036d39aa [2/3] core: persist world state in rollouts (#29835)
## Why

`WorldState` currently remembers its model-visible diff baseline only in
memory. That leaves no durable source for restoring the exact baseline
after resume, fork, rollback, or compaction.

This is the second PR in the WorldState persistence stack, built on
#29833 and following #29249. It records durable state transitions; the
next PR will replay them during rollout reconstruction.

## What

- Add a `world_state` rollout item containing either a full snapshot or
an RFC 7386 JSON Merge Patch.
- Persist a full snapshot after initial context and after compaction
establishes a new context window.
- Persist non-empty patches when later sampling steps or turns advance
the WorldState baseline.
- Write model-visible history before its matching WorldState record, so
an interrupted write can only cause a safe repeated update on replay.
- Preserve WorldState records for full-history forks while excluding
them from thread previews, metadata, and app-server history
materialization.

Older binaries read rollout lines independently, so they skip the
unknown `world_state` records while retaining the rest of the thread.

## Testing

- `just test -p codex-core
snapshot_merge_patch_changes_and_removes_nested_values`
- `just test -p codex-core
world_state_baseline_deduplicates_until_history_is_replaced`
- `just test -p codex-core
deferred_executor_compaction_preserves_then_updates_environment_once`
- `just test -p codex-protocol`
- `just test -p codex-rollout`
- `just test -p codex-state`
- `just test -p codex-thread-store`
- `just test -p codex-app-server-protocol`
2026-06-24 20:13:49 -07:00
sayan-oai 3e51b46eba [1/3] core: make world state snapshots serializable (#29833)
## Why

`WorldState` currently keeps its diff baseline as live Rust objects
keyed by process-local `TypeId`. That baseline cannot be written to a
rollout or restored after resume, so Codex reconstructs an approximation
from `TurnContextItem`.

This is the first change in the WorldState persistence stack. It gives
every section a stable persisted identity and a compact serializable
comparison snapshot without changing rollout behavior yet.

## What changed

- Require each `WorldStateSection` to define a stable ID and
serializable snapshot type.
- Reject duplicate section IDs when constructing `WorldState`.
- Persist a dedicated environment comparison snapshot using
model-visible strings instead of runtime path types.
- Store only `WorldStateSnapshot` in `ContextManager`, removing the
parallel live-object baseline.
- Render diffs by restoring each section's typed snapshot; invalid
snapshots fall back to a full section render.
- Omit null object fields for future RFC 7386 patches while preserving
null values inside arrays.

Follow-up PRs will record full snapshots and merge patches, then restore
the baseline during resume, fork, and rollback.

## Test plan

- WorldState snapshot tests cover stable IDs, duplicate rejection, null
omission, and array preservation.
- Environment tests cover persistence-safe snapshot values and existing
diff rendering.
- ContextManager baseline deduplication and session context-update
persistence tests.

Related: #29249
2026-06-24 19:26:55 -07:00
Michael Bolin f15df624a6 core: add configurable <context_window_guidance> message (#29936)
## Why

This PR adds a configurable `<context_window_guidance>` developer
section immediately after `<context_window>`. Harness integrations need
this section to give the model deployment-specific instructions for
preparing for context-window transitions.

## What changed

- Add an optional `features.token_budget.guidance_message` config with a
1,000-byte runtime cap and generated schema support.
- Render configured guidance as a developer `ContextualUserFragment`
wrapped in `<context_window_guidance>` immediately after
`<context_window>`.
- Omit the section when guidance is unset, empty, or whitespace-only.
- Preserve the resolved value in config locks and classify persisted
guidance as contextual developer content.
- Add integration coverage for rendered content and ordering.
2026-06-24 18:03:44 -07:00
Adam Perry @ OpenAI e639e8c4bd connectors: own app metadata types (#29723)
## Why

Connector metadata is consumed by connector discovery, ChatGPT
integration, core, and TUI code. Treating app-server's wire DTO as the
shared domain model reverses the intended dependency direction.

## What changed

- Added connector-owned app branding, review, screenshot, metadata, and
info types.
- Added explicit conversions in app-server and TUI while preserving
app-server's wire payloads.
- Removed production app-server-protocol dependencies from connectors
and ChatGPT connector code.

## Stack

This is PR 4 of 6, stacked on [PR
#29722](https://github.com/openai/codex/pull/29722). Review only the
delta from `codex/split-config-layer-types`. Next: [PR
#29724](https://github.com/openai/codex/pull/29724).

## Validation

- Connector and tools coverage passed.
- App-server app-list coverage passed: 13 tests.
2026-06-23 22:08:23 -07:00
sayan-oai d1d11cac05 core: use turn-owned world state for inline compaction (#29527)
## Why

Follow-up to #29249 and its [compaction review
thread](https://github.com/openai/codex/pull/29249#discussion_r3455055101).

During a turn, environment readiness can change between sampling
requests. Inline compaction must render the same model-visible
`WorldState` used by the request it follows. Rebuilding that state
during compaction can observe a newer environment, make replacement
history disagree with what the model saw, and suppress the next
environment update.

## What changed

- Make `run_turn` own the current `Arc<WorldState>` and replace it only
between sampling requests.
- Build each state from an explicitly chosen environment snapshot, diff
deferred-executor steps against the turn-owned state, and retain the
latest state in `ContextManager` only for cross-turn and resume
tracking.
- Pass the exact turn-owned state into inline compaction and explicit
new-context-window replacement.
- Carry that state with
`InitialContextInjection::BeforeLastUserMessage`, so replacement context
and its stored baseline cannot come from different snapshots.
- Remove obsolete state-recapture helpers and ambiguous TurnContext-only
WorldState builders.
- Add an integration test that moves an environment from starting to
ready during a paused turn, triggers compaction, and verifies the next
request receives the readiness update exactly once.

## Test plan

- `just test -p codex-core
deferred_executor_compaction_preserves_then_updates_environment_once`
- `just test -p codex-core process_compacted_history`
- `just test -p codex-core mid_turn_continuation_compaction`
- `just test -p codex-core build_initial_context`
- `just test -p codex-core
ignores_session_prefix_messages_when_truncating`
2026-06-23 10:33:19 -07:00
Celia Chen 97dc6abb11 fix: world state response item test (#29504)
seems to be a merge conflict on main:

> pakrym-oai introduced the stale initializer in commit 3b32d861c5, PR
#29249.
> Context: Owen Lin renamed metadata to
internal_chat_message_metadata_passthrough in PR #28968. PR #29249 then
landed afterward with the old field name, causing the compile/Clippy
failure.
2026-06-23 00:19:03 +00:00
Michael Bolin f1945de3b7 core: wrap token budget window context (#29494)
Token-budget initial context carries thread and context-window lineage
that the model should treat as one structured context-window block.
Wrapping it in `<context_window>` makes that boundary explicit while
preserving the existing window id content.

Before this change, the window identifiers were injected as an untagged
developer text fragment:

```text
Thread id <THREAD_ID>.
First context window id: <FIRST_WINDOW_ID>
Current context window id: <WINDOW_ID>
Previous context window id: <PREVIOUS_WINDOW_ID>
```

After this change, the same payload is wrapped as a context-window
block:

```text
<context_window>
Thread id: <THREAD_ID>
First context window id: <FIRST_WINDOW_ID>
Current context window id: <WINDOW_ID>
Previous context window id: <PREVIOUS_WINDOW_ID>
</context_window>
```

This adds shared `CONTEXT_WINDOW_*_TAG` protocol constants, updates
`TokenBudgetContext` to render with those markers, treats the new
wrapper as contextual developer content when mapping history, and
refreshes the token-budget request-shape assertions and snapshot.

Verification:
- `just test -p codex-core token_budget`
- `just test -p codex-core
recognizes_context_window_as_contextual_developer_content`
2026-06-22 23:37:49 +00:00
pakrym-oai 3b32d861c5 [codex] migrate environment context to model world state (#29249)
## Why

Environment context is model-visible state, but it is currently
assembled from transient turn values and diffed through
environment-specific paths. That makes initial injection, turn-to-turn
updates, and changes that happen within a turn use different baselines.

This PR introduces the smallest useful model world-state slice:
environments only, with one in-memory baseline and one renderer for full
state and diffs.

## What changed

- Add a typed `WorldState` container whose sections render fragments
relative to an optional previous value. Full rendering uses the same
diff path with no previous state.
- Replace the parallel `EnvironmentContext` representation with an
`EnvironmentsState` section keyed by environment ID and rendered in
deterministic order.
- Preserve the legacy single-environment output while supporting
multiple environments, starting environments, unavailable tombstones,
and changes to persisted turn-context values.
- Store the latest complete `WorldState` on `ContextManager` and use it
for both turn-boundary and mid-turn environment diffs.
- Build initial and post-compaction context from the same world-state
builder, then retain the rendered state as the next baseline.
- Seed the in-memory baseline from the latest `TurnContextItem` when
resuming an existing rollout; the world state itself is not serialized.
- Keep non-world settings updates on their existing path and merge
rendered world-state fragments at the session consumer.

## Known limitation

A legacy `TurnContextItem` only reconstructs the primary environment as
`local`; it cannot faithfully recover a remote-primary environment ID
after resume. Live state uses the exact environment IDs once a complete
baseline is established.

## Test plan

- `just test -p codex-core world_state`
- `just test -p codex-core record_context_updates`
- `just test -p codex-core deferred_executor_`
- `just test -p codex-core build_initial_context`
- `just test -p codex-core rollout_reconstruction`
- `just test -p codex-core
process_compacted_history_reinjects_full_initial_context`
2026-06-22 16:07:27 -07:00
sayan-oai 22886f21de core: refresh environment context before sampling (#29073)
## Why

Nonblocking environment snapshots allow a turn to reach the model while
a remote environment is still starting. The initial context can describe
that environment as still loading, but nothing currently refreshes the
model-visible environment context when startup finishes during the same
turn.

This adds the first request-scoped reconciliation slice on top of
#28683. It is gated by `DeferredExecutor` and intentionally updates only
model-visible environment context; tools and other environment-derived
state will migrate separately.

## What

- Add a minimal `StepContext` containing the environment snapshot
captured before each sampling request.
- Render attached environments with their resolved shell and starting
environments with `still loading`.
- Track the latest environment state recorded in model history and
append a bounded update only when it changes.
- Seed that baseline from full initial context so ready-at-start
environments are not duplicated.
- Clear the in-memory baseline when history is rewritten so replacement
history can be refreshed safely.

## Testing

- `just test -p codex-core deferred_executor`
- `just test -p codex-core
environment_context_baseline_deduplicates_until_history_is_replaced`

The integration coverage verifies that a pending environment reaches the
first request, the ready state reaches the next request, later requests
do not duplicate it, and ready-at-start environments remain
single-injected.

<details>
<summary>Live verification</summary>

- Connected to a real remote executor with startup deliberately delayed
and forced three sampling requests in one turn.
- Inspected the raw model inputs: request 1 showed the remote
environment as `still loading`, request 2 appended its ready shell and
cwd, and request 3 contained no duplicate ready update.
- With the feature disabled, startup waited for the delayed executor and
the first request contained only the ready environment.
- With a synchronously ready environment and the feature enabled, the
first request contained one environment context with no duplicate.
- Executed `pwd` and read a marker file through the remote process
runner; the command exited successfully and returned the remote cwd and
marker contents.

</details>
2026-06-22 08:47:43 -07:00
jif c03742ca0a Simplify multi-agent mode controls (#29324)
## Why

Multi-agent delegation policy was split across `multiAgentMode`,
`features.multi_agent_mode`, and `usage_hint_enabled`. These controls
could disagree: a requested mode could be downgraded by the feature
flag, and disabling usage hints also disabled mode instructions.

Some clients also need multi-agent tools without adding
delegation-policy text to model context. The previous two-mode API could
not express that directly.

## What changed

`multiAgentMode` is now the only live delegation-policy control:

| Mode | Behavior |
| --- | --- |
| `none` | Keep multi-agent tools available without adding mode
instructions. |
| `explicitRequestOnly` | Only delegate after an explicit user request.
|
| `proactive` | Delegate when parallel work materially improves speed or
quality. |

- new threads default to `explicitRequestOnly`; omitting the mode on
later turns keeps the current value
- thread start, resume, fork, and settings responses always report the
concrete current mode instead of `null`
- mode selection remains sticky across turns and resume
- usage-hint text no longer controls whether mode instructions apply
- `features.multi_agent_mode` and `usage_hint_enabled` remain accepted
as ignored compatibility settings so existing configs continue to load
- app-server documentation and generated schemas describe the three-mode
API

## Tests

- `just test -p codex-core multi_agent_mode`
- `just test -p codex-core multi_agent_v2_config_from_feature_table`
- `just test -p codex-core spawn_agent_description`
- `just test -p codex-features`
- `just test -p codex-app-server-protocol`
- `just test -p codex-app-server multi_agent_mode`
2026-06-22 10:05:36 +02:00