Commit Graph

407 Commits

  • Normalize MCP tool names to code-mode safe form (#14605)
    Code mode doesn't allow `-` in names and it's better if function names
    and code-mode names are the same.
  • Stabilize multi-agent feature flag (#14622)
    - make multi_agent stable and enabled by default
    - update feature and tool-spec coverage to match the new default
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • Rename multi-agent wait tool to wait_agent (#14631)
    - rename the multi-agent tool name the model sees to wait_agent
    - update the model-facing prompts and tool descriptions to match
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • Add code_mode_only feature (#14617)
    Summary
    - add the code_mode_only feature flag/config schema and wire its
    dependency on code_mode
    - update code mode tool descriptions to list nested tools with detailed
    headers
    - restrict available tools for prompt and exec descriptions when
    code_mode_only is enabled and test the behavior
    
    Testing
    - Not run (not requested)
  • fix: preserve zsh-fork escalation fds across unified-exec spawn paths (#13644)
    ## Why
    
    `zsh-fork` sessions launched through unified-exec need the escalation
    socket to survive the wrapper -> server -> child handoff so later
    intercepted `exec()` calls can still reach the escalation server.
    
    The inherited-fd spawn path also needs to avoid closing Rust's internal
    exec-error pipe, and the shell-escalation handoff needs to tolerate the
    receive-side case where a transferred fd is installed into the same
    stdio slot it will be mapped onto.
    
    ## What Changed
    
    - Added `SpawnLifecycle::inherited_fds()` in
    `codex-rs/core/src/unified_exec/process.rs` and threaded inherited fds
    through `codex-rs/core/src/unified_exec/process_manager.rs` so
    unified-exec can preserve required descriptors across both PTY and
    no-stdin pipe spawn paths.
    - Updated `codex-rs/core/src/tools/runtimes/shell/zsh_fork_backend.rs`
    to expose the escalation socket fd through the spawn lifecycle.
    - Added inherited-fd-aware spawn helpers in
    `codex-rs/utils/pty/src/pty.rs` and `codex-rs/utils/pty/src/pipe.rs`,
    including Unix pre-exec fd pruning that preserves requested inherited
    fds while leaving `FD_CLOEXEC` descriptors alone. The pruning helper is
    now named `close_inherited_fds_except()` to better describe that
    behavior.
    - Updated `codex-rs/shell-escalation/src/unix/escalate_client.rs` to
    duplicate local stdio before transfer and send destination stdio numbers
    in `SuperExecMessage`, so the wrapper keeps using its own
    `stdin`/`stdout`/`stderr` until the escalated child takes over.
    - Updated `codex-rs/shell-escalation/src/unix/escalate_server.rs` so the
    server accepts the overlap case where a received fd reuses the same
    stdio descriptor number that the child setup will target with `dup2`.
    - Added comments around the PTY stdio wiring and the overlap regression
    helper to make the fd handoff and controlling-terminal setup easier to
    follow.
    
    ## Verification
    
    - `cargo test -p codex-utils-pty`
    - covers preserved-fd PTY spawn behavior, PTY resize, Python REPL
    continuity, exec-failure reporting, and the no-stdin pipe path
    - `cargo test -p codex-shell-escalation`
    - covers duplicated-fd transfer on the client side and verifies the
    overlap case by passing a pipe-backed stdin payload through the
    server-side `dup2` path
    
    ---
    [//]: # (BEGIN SAPLING FOOTER)
    Stack created with [Sapling](https://sapling-scm.com). Best reviewed
    with [ReviewStack](https://reviewstack.dev/openai/codex/pull/13644).
    * #14624
    * __->__ #13644
  • Use a private desktop for Windows sandbox instead of Winsta0\Default (#14400)
    ## Summary
    - launch Windows sandboxed children on a private desktop instead of
    `Winsta0\Default`
    - make private desktop the default while keeping
    `windows.sandbox_private_desktop=false` as the escape hatch
    - centralize process launch through the shared
    `create_process_as_user(...)` path
    - scope the private desktop ACL to the launching logon SID
    
    ## Why
    Today sandboxed Windows commands run on the visible shared desktop. That
    leaves an avoidable same-desktop attack surface for window interaction,
    spoofing, and related UI/input issues. This change moves sandboxed
    commands onto a dedicated per-launch desktop by default so the sandbox
    no longer shares `Winsta0\Default` with the user session.
    
    The implementation stays conservative on security with no silent
    fallback back to `Winsta0\Default`
    
    If private-desktop setup fails on a machine, users can still opt out
    explicitly with `windows.sandbox_private_desktop=false`.
    
    ## Validation
    - `cargo build -p codex-cli`
    - elevated-path `codex exec` desktop-name probe returned
    `CodexSandboxDesktop-*`
    - elevated-path `codex exec` smoke sweep for shell commands, nested
    `pwsh`, jobs, and hidden `notepad` launch
    - unelevated-path full private-desktop compatibility sweep via `codex
    exec` with `-c windows.sandbox=unelevated`
  • code mode: single line tool declarations (#14526)
    ## Summary
    - render code mode tool declarations as single-line TypeScript snippets
    - make the JSON schema renderer emit inline object shapes for these
    declarations
    - update code mode/spec expectations to match the new inline rendering
    
    ## Testing
    - `just fmt`
    - `cargo test -p codex-core render_json_schema_to_typescript`
    - `cargo test -p codex-core code_mode_augments_`
    - `cargo test -p codex-core --test all exports_all_tools_metadata --
    --nocapture`
  • Split multi-agent handler into dedicated files (#14603)
    ## Summary
    - move the multi-agent handlers suite into its own files for spawn,
    wait, resume, send input, and close logic
    - keep the aggregated module in place while delegating each handler to
    its new file to keep things organized per handler
    
    ## Testing
    - Not run (not requested)
  • feat: support skill-scoped managed network domain overrides in skill config (#14522)
    ## Summary
    
    This lets skill loading split `permissions.network` into two distinct
    pieces:
    
    - `permissions.network.enabled` still feeds the skill
    `PermissionProfile` and remains the coarse gate for whether the skill
    can use network access at all.
    - `permissions.network.allowed_domains` and
    `permissions.network.denied_domains` are lifted into a new
    `SkillManagedNetworkOverride` so managed-network sessions can start
    per-skill scoped proxies with the right domain overrides.
    
    The change also updates `SkillMetadata` construction sites and adds
    loader tests covering YAML parsing plus normalization of the network
    gate vs. domain override fields.
    
    ## Follow-up
    A PR that uses the network_override to spin up a skill-specific proxy if
    network_override is not none.
  • code_mode: Move exec params from runtime declarations to @pragma (#14511)
    This change moves code_mode exec session settings out of the runtime API
    and into an optional first-line pragma, so instead of calling runtime
    helpers like set_yield_time() or set_max_output_tokens_per_exec_call(),
    the model can write // @exec: {"yield_time_ms": ...,
    "max_output_tokens": ...} at the top of the freeform exec source. Rust
    now parses that pragma before building the source, validates it, and
    passes the values directly in the exec start message to the code-mode
    broker, which applies them at session start without any worker-runtime
    mutation path. The @openai/code_mode module no longer exposes those
    setter functions, the docs and grammar were updated to describe the
    pragma form, and the existing code_mode tests were converted to use
    pragma-based configuration instead.
  • Add typed multi-agent tool outputs (#14536)
    ## Summary
    - return typed `ToolOutput` values from the multi-agent handlers instead
    of plain `FunctionToolOutput`
    - keep the regular function-call response shape as JSON text while
    exposing structured values to code mode
    - add output schemas for `spawn_agent`, `send_input`, `resume_agent`,
    `wait`, and `close_agent`
    
    ## Verification
    - `just fmt`
    - focused multi-agent and integration tests passed earlier in this
    branch during iteration
    - after the final edit, I only reran formatting before opening this PR
  • [js_repl] Hard-stop active js_repl execs on explicit user interrupts (#13329)
    ## Summary
    - hard-stop `js_repl` only for `TurnAbortReason::Interrupted`,
    preserving the persistent REPL across replaced turns
    - track the current top-level exec by turn and only reset when the
    interrupted turn owns submitted work or a freshly started kernel for the
    current exec attempt
    - close both interrupt races: the write-window race by marking the exec
    as submitted before async pipe writes begin, and the startup-window race
    by tracking fresh-kernel ownership until submission
    - add regression coverage for interrupted in-flight execs and the
    pending-kernel-start window
    
    ## Why
    Stopping a turn previously surfaced `aborted by user after Xs` even
    though the underlying `js_repl` kernel could continue executing. Earlier
    fixes also risked resetting the session-scoped REPL too broadly or
    missing already-dispatched work. This change keeps cleanup scoped to
    explicit stop semantics and makes the interrupt path line up with both
    submitted execs and newly started kernels.
    
    ## Testing
    - `just fmt`
    - `cargo test -p codex-core`
    - `just fix -p codex-core`
    
    `cargo test -p codex-core` passes the updated `js_repl` coverage,
    including the new startup-window regression test, but still has
    unrelated integration failures in this environment outside `js_repl`.
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • Split multi-agent handlers per tool (#14535)
    Summary
    - move the existing multi-agent handler logic into each tool-specific
    handler and inline helper implementations
    - remove the old central dispatcher now that each handler encapsulates
    its own behavior
    - adjust handler specs and tests to match the new structure without
    macros
    
    Testing
    - Not run (not requested)
  • Expose code-mode tools through globals (#14517)
    Summary
    - make all code-mode tools accessible as globals so callers only need
    `tools.<name>`
    - rename text/image helpers and key globals (store, load, ALL_TOOLS,
    etc.) to reflect the new shared namespace
    - update the JS bridge, runners, descriptions, router, and tests to
    follow the new API
    
    Testing
    - Not run (not requested)
  • Persist js_repl codex helpers across cells (#14503)
    ## Summary
    
    This changes `js_repl` so saved references to `codex.tool(...)` and
    `codex.emitImage(...)` keep working across cells.
    
    Previously, those helpers were recreated per exec and captured that
    exec's `message.id`. If a persisted object or saved closure reused an
    old helper in a later cell, the nested tool/image call could fail with
    `js_repl exec context not found`.
    
    This patch:
    - keeps stable `codex.tool` and `codex.emitImage` helper identities in
    the kernel
    - resolves the current exec dynamically at call time using
    `AsyncLocalStorage`
    - adds regression coverage for persisted helper references across cells
    - updates the js_repl docs and project-doc instructions to describe the
    new behavior and its limits
    
    ## Why
    
    We already support persistent top-level bindings across `js_repl` cells,
    so persisted objects should be able to reuse `codex` helpers in later
    active cells. The bug was that helper identity was exec-scoped, not
    kernel-scoped.
    
    Using `AsyncLocalStorage` fixes the cross-cell reuse case without
    falling back to a single global active exec that could accidentally
    attribute stale background callbacks to the wrong cell.
  • Rename exec session IDs to cell IDs (#14510)
    - Update the code-mode executor, wait handler, and protocol plumbing to
    use cell IDs instead of session IDs for node communication
    - Switch tool metadata, wait description, and suite tests to refer to
    cell IDs so user-visible messages match the new terminology
    
    **Testing**
    - Not run (not requested)
  • Fix MCP tool calling (#14491)
    Properly escape mcp tool names and make tools only available via
    imports.
  • Fix js_repl hangs on U+2028/U+2029 dynamic tool responses (#14421)
    ## Summary
    Dynamic tool responses containing literal U+2028 / U+2029 would cause
    await codex.tool(...) to hang even though the response had already
    arrived. This PR replaces the kernel’s readline-based stdin handling
    with byte-oriented JSONL framing that handles these characters properly.
    
    ## Testing
    - `cargo test -p codex-core`
    - tested the binary on a repro case and confirmed it's fixed
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • Reuse tool runtime for code mode worker (#14496)
    ## Summary
    - create the turn-scoped `ToolCallRuntime` before starting the code mode
    worker so the worker reuses the same runtime and router
    - thread the shared runtime through the code mode service/worker path
    and use it for nested tool calls
    - model aborted tool calls as a concrete `ToolOutput` so aborted
    responses still produce valid tool output shapes
    
    ## Testing
    - `just fmt`
    - `cargo test -p codex-core` (still running locally)
  • Add default code-mode yield timeout (#14484)
    Summary
    - expose the default yield timeout through code mode runtime so the
    handler, wait tool, and protocol share the same 10s value that matches
    unified exec
    - document the timeout change in the tool descriptions and propagate the
    value all the way into the runner metadata
    - adjust Cargo.lock to keep the dependency tree in sync with the added
    code mode tool dependency
    
    Testing
    - Not run (not requested)
  • Do not allow unified_exec for sandboxed scenarios on Windows (#14398)
    as reported in https://github.com/openai/codex/issues/14367 users can
    explicitly enable unified_exec which will bypass the sandbox even when
    it should be enabled.
    
    Until we support unified_exec with the Windows Sandbox, we will disallow
    it unless the sandbox is disabled
  • Cleanup code_mode tool descriptions (#14480)
    Move to separate files and clarify a bit.
  • rename spawn_csv feature flag to enable_fanout (#14475)
    ## Summary
    - rename the public feature flag for `spawn_agents_on_csv()` from
    `spawn_csv` to `enable_fanout`
    - regenerate the config schema so only `enable_fanout` is advertised
    - keep the behavior the same: enabling `enable_fanout` still pulls in
    `multi_agent`
    
    ## Notes
    - this is a hard rename with no `spawn_csv` compatibility alias
    - the internal enum remains `Feature::SpawnCsv` to keep the patch small
    
    ## Testing
    - `cd codex-rs && just fmt`
    - `cd codex-rs && cargo test -p codex-core` (running locally;
    `suite::agent_jobs::*` and rename-specific coverage passed so far)
  • Move code mode tool files under tools/code_mode and split functionality (#14476)
    - **Summary**
    - migrate the code mode handler, service, worker, process, runner, and
    bridge assets into the `tools/code_mode` module tree
    - split Execution, protocol, and handler logic into dedicated files and
    relocate the tool definition into `code_mode/spec.rs`
    - update core references and tests to stitch the new organization
    together
    - **Testing**
      - Not run (not requested)
  • Dispatch tools when code mode is not awaited directly (#14437)
    ## Summary
    - start a code mode worker once per turn and let it pump nested tool
    calls through a dedicated queue
    - simplify code mode request/response dispatch around request ids and
    generic runner-unavailable errors
    - clean up the code mode process API and runner protocol plumbing
    
    ## Testing
    - not run yet
  • fix: move inline codex-rs/core unit tests into sibling files (#14444)
    ## Why
    PR #13783 moved the `codex.rs` unit tests into `codex_tests.rs`. This
    applies the same extraction pattern across the rest of `codex-rs/core`
    so the production modules stay focused on runtime code instead of large
    inline test blocks.
    
    Keeping the tests in sibling files also makes follow-up edits easier to
    review because product changes no longer have to share a file with
    hundreds or thousands of lines of test scaffolding.
    
    ## What changed
    - replaced each inline `mod tests { ... }` in `codex-rs/core/src/**`
    with a path-based module declaration
    - moved each extracted unit test module into a sibling `*_tests.rs`
    file, using `mod_tests.rs` for `mod.rs` modules
    - preserved the existing `cfg(...)` guards and module-local structure so
    the refactor remains structural rather than behavioral
    
    ## Testing
    - `cargo test -p codex-core --lib` (`1653 passed; 0 failed; 5 ignored`)
    - `just fix -p codex-core`
    - `cargo fmt --check`
    - `cargo shear`
  • fix: follow up on linux sandbox review nits (#14440)
    ## Summary
    - address the follow-up review nits from #13996 in a separate PR
    - make the approvals test command a raw string and keep the
    managed-network path using env proxy routing
    - inline `--apply-seccomp-then-exec` in the Linux sandbox inner command
    builder
    - remove the bubblewrap-specific sandbox metric tag path and drop the
    `use_legacy_landlock` shim from `sandbox_tag`/`TurnMetadataState::new`
    - restore the `Feature` import that `origin/main` currently still needs
    in `connectors.rs`
    
    ## Testing
    - `cargo test -p codex-linux-sandbox`
    - focused `codex-core` tests were rerun/started, but the final
    verification pass was interrupted when I pushed at request
  • refactor: make bubblewrap the default Linux sandbox (#13996)
    ## Summary
    - make bubblewrap the default Linux sandbox and keep
    `use_legacy_landlock` as the only override
    - remove `use_linux_sandbox_bwrap` from feature, config, schema, and
    docs surfaces
    - update Linux sandbox selection, CLI/config plumbing, and related
    tests/docs to match the new default
    - fold in the follow-up CI fixes for request-permissions responses and
    Linux read-only sandbox error text
  • Support waiting for code_mode sessions (#14295)
    ## Summary
    - persist the code mode runner process in the session-scoped code mode
    store
    - switch the runner protocol from `init` to `start` with explicit
    session ids
    - handle runner-side session processing without the init waiter queue
    
    ## Validation
    - just fmt
    - cargo check -p codex-core
    - node --check codex-rs/core/src/tools/code_mode_runner.cjs
  • Clarify spawn agent authorization (#14432)
    - Clarify that spawn_agent requires explicit user permission for
    delegation or parallel agent work.
    - Add a regression test covering the new description text.
  • [apps] Add tool_suggest tool. (#14287)
    - [x] Add tool_suggest tool.
    - [x] Move chatgpt/src/connectors.rs and core/src/connectors.rs into a
    dedicated mod so that we have all the logic and global cache in one
    place.
    - [x] Update TUI app link view to support rendering the installation
    view for mcp elicitation.
    
    ---------
    
    Co-authored-by: Shaqayeq <shaqayeq@openai.com>
    Co-authored-by: Eric Traut <etraut@openai.com>
    Co-authored-by: pakrym-oai <pakrym@openai.com>
    Co-authored-by: Ahmed Ibrahim <aibrahim@openai.com>
    Co-authored-by: guinness-oai <guinness@openai.com>
    Co-authored-by: Eugene Brevdo <ebrevdo@users.noreply.github.com>
    Co-authored-by: Charlie Guo <cguo@openai.com>
    Co-authored-by: Fouad Matin <fouad@openai.com>
    Co-authored-by: Fouad Matin <169186268+fouad-openai@users.noreply.github.com>
    Co-authored-by: xl-openai <xl@openai.com>
    Co-authored-by: alexsong-oai <alexsong@openai.com>
    Co-authored-by: Owen Lin <owenlin0@gmail.com>
    Co-authored-by: sdcoffey <stevendcoffey@gmail.com>
    Co-authored-by: Codex <noreply@openai.com>
    Co-authored-by: Won Park <won@openai.com>
    Co-authored-by: Dylan Hurd <dylan.hurd@openai.com>
    Co-authored-by: celia-oai <celia@openai.com>
    Co-authored-by: gabec-openai <gabec@openai.com>
    Co-authored-by: joeytrasatti-openai <joey.trasatti@openai.com>
    Co-authored-by: Leo Shimonaka <leoshimo@openai.com>
    Co-authored-by: Rasmus Rygaard <rasmus@openai.com>
    Co-authored-by: maja-openai <163171781+maja-openai@users.noreply.github.com>
    Co-authored-by: pash-openai <pash@openai.com>
    Co-authored-by: Josh McKinney <joshka@openai.com>
  • feat(app-server): propagate traces across tasks and core ops (#14387)
    ## Summary
    
    This PR keeps app-server RPC request trace context alive for the full
    lifetime of the work that request kicks off (e.g. for `thread/start`,
    this is `app-server rpc handler -> tokio background task -> core op
    submissions`). Previously we lose trace lineage once the request handler
    returns or hands work off to background tasks.
    
    This approach is especially relevant for `thread/start` and other RPC
    handlers that run in a non-blocking way. In the near future we'll most
    likely want to make all app-server handlers run in a non-blocking way by
    default, and only queue operations that must operate in order (e.g.
    thread RPCs per thread?), so we want to make sure tracing in app-server
    just generally works.
    
    Depends on https://github.com/openai/codex/pull/14300
    
    **Before**
    <img width="155" height="207" alt="image"
    src="https://github.com/user-attachments/assets/c9487459-36f1-436c-beb7-fafeb40737af"
    />
    
    
    **After**
    <img width="299" height="337" alt="image"
    src="https://github.com/user-attachments/assets/727392b2-d072-4427-9dc4-0502d8652dea"
    />
    
    ## What changed
    
    - Keep request-scoped trace context around until we send the final
    response or error, or the connection closes.
    - Thread that trace context through detached `thread/start` work so
    background startup stays attached to the originating request.
    - Pass request trace context through to downstream core operations,
    including:
      - thread creation
      - resume/fork flows
      - turn submission
      - review
      - interrupt
      - realtime conversation operations
    - Add tracing tests that verify:
      - remote W3C trace context is preserved for `thread/start`
      - remote W3C trace context is preserved for `turn/start`
      - downstream core spans stay under the originating request span
      - request-scoped tracing state is cleaned up correctly
    - Clean up shutdown behavior so detached background tasks and spawned
    threads are drained before process exit.
  • Include spawn agent model metadata in app-server items (#14410)
    - add model and reasoning effort to app-server collab spawn items and
    notifications
    - regenerate app-server protocol schemas for the new fields
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • fix: align core approvals with split sandbox policies (#14171)
    ## Stack
    
       fix: fail closed for unsupported split windows sandboxing #14172
       fix: preserve split filesystem semantics in linux sandbox #14173
    -> fix: align core approvals with split sandbox policies #14171
       refactor: centralize filesystem permissions precedence #14174
    
    ## Why This PR Exists
    
    This PR is intentionally narrower than the title may suggest.
    
    Most of the original split-permissions migration already landed in the
    earlier `#13434 -> #13453` stack. In particular:
    
    - `#13439` already did the broad runtime plumbing for split filesystem
    and network policies.
    - `#13445` already moved `apply_patch` safety onto filesystem-policy
    semantics.
    - `#13448` already switched macOS Seatbelt generation to split policies.
    - `#13449` and `#13453` already handled Linux helper and bubblewrap
    enforcement.
    - `#13440` already introduced the first protocol-side helpers for
    deriving effective filesystem access.
    
    The reason this PR still exists is that after the follow-on
    `[permissions]` work and the new shared precedence helper in `#14174`, a
    few core approval paths were still deciding behavior from the legacy
    `SandboxPolicy` projection instead of the split filesystem policy that
    actually carries the carveouts.
    
    That means this PR is mostly a cleanup and alignment pass over the
    remaining core consumers, not a fresh sandbox backend migration.
    
    ## What Is Actually New Here
    
    - make unmatched-command fallback decisions consult
    `FileSystemSandboxPolicy` instead of only legacy `DangerFullAccess` /
    `ReadOnly` / `WorkspaceWrite` categories
    - thread `file_system_sandbox_policy` into the shell, unified-exec, and
    intercepted-exec approval paths so they all use the same split-policy
    semantics
    - keep `apply_patch` safety on the same effective-access rules as the
    shared protocol helper, rather than letting it drift through
    compatibility projections
    - add loader-level regression coverage proving legacy `sandbox_mode`
    config still builds split policies and round-trips back without semantic
    drift
    
    ## What This PR Does Not Do
    
    This PR does not introduce new platform backend enforcement on its own.
    
    - Linux backend parity remains in `#14173`.
    - Windows fail-closed handling remains in `#14172`.
    - The shared precedence/model changes live in `#14174`.
    
    ## Files To Focus On
    
    - `core/src/exec_policy.rs`: unmatched-command fallback and approval
    rendering now read the split filesystem policy directly
    - `core/src/tools/sandboxing.rs`: default exec-approval requirement keys
    off `FileSystemSandboxPolicy.kind`
    - `core/src/tools/handlers/shell.rs`: shell approval requests now carry
    the split filesystem policy
    - `core/src/unified_exec/process_manager.rs`: unified-exec approval
    requests now carry the split filesystem policy
    - `core/src/tools/runtimes/shell/unix_escalation.rs`: intercepted exec
    fallback now uses the same split-policy approval semantics
    - `core/src/safety.rs`: `apply_patch` safety keeps using effective
    filesystem access rather than legacy sandbox categories
    - `core/src/config/config_tests.rs`: new regression coverage for legacy
    `sandbox_mode` no-drift behavior through the split-policy loader
    
    ## Notes
    
    - `core/src/codex.rs` and `core/src/codex_tests.rs` are just small
    fallout updates for `RequestPermissionsResponse.scope`; they are not the
    point of the PR.
    - If you reviewed the earlier `#13439` / `#13445` stack, the main review
    question here is simply: “are there any remaining approval or
    patch-safety paths that still reconstruct semantics from legacy
    `SandboxPolicy` instead of consuming the split filesystem policy
    directly?”
    
    ## Testing
    - cargo test -p codex-core
    legacy_sandbox_mode_config_builds_split_policies_without_drift
    - cargo test -p codex-core request_permissions
    - cargo test -p codex-core intercepted_exec_policy
    - cargo test -p codex-core
    restricted_sandbox_requires_exec_approval_on_request
    - cargo test -p codex-core
    unmatched_on_request_uses_split_filesystem_policy_for_escalation_prompts
    - cargo test -p codex-core explicit_
    - cargo clippy -p codex-core --tests -- -D warnings
  • feat: search_tool migrate to bring you own tool of Responses API (#14274)
    ## Why
    
    to support a new bring your own search tool in Responses
    API(https://developers.openai.com/api/docs/guides/tools-tool-search#client-executed-tool-search)
    we migrating our bm25 search tool to use official way to execute search
    on client and communicate additional tools to the model.
    
    ## What
    - replace the legacy `search_tool_bm25` flow with client-executed
    `tool_search`
    - add protocol, SSE, history, and normalization support for
    `tool_search_call` and `tool_search_output`
    - return namespaced Codex Apps search results and wire namespaced
    follow-up tool calls back into MCP dispatch
  • Let models opt into original image detail (#14175)
    ## Summary
    
    This PR narrows original image detail handling to a single opt-in
    feature:
    
    - `image_detail_original` lets the model request `detail: "original"` on
    supported models
    - Omitting `detail` preserves the default resized behavior
    
    The model only sees `detail: "original"` guidance when the active model
    supports it:
    
    - JS REPL instructions include the guidance and examples only on
    supported models
    - `view_image` only exposes a `detail` parameter when the feature and
    model can use it
    
    The image detail API is intentionally narrow and consistent across both
    paths:
    
    - `view_image.detail` supports only `"original"`; otherwise omit the
    field
    - `codex.emitImage(..., detail)` supports only `"original"`; otherwise
    omit the field
    - Unsupported explicit values fail clearly at the API boundary instead
    of being silently reinterpreted
    - Unsupported explicit `detail: "original"` requests fall back to normal
    behavior when the feature is disabled or the model does not support
    original detail
  • Add js_repl cwd and homeDir helpers (#14385)
    ## Summary
    
    This PR adds two read-only path helpers to `js_repl`:
    
    - `codex.cwd`
    - `codex.homeDir`
    
    They are exposed alongside the existing `codex.tmpDir` helper so the
    REPL can reference basic host path context without reopening direct
    `process` access.
    
    ## Implementation
    
    - expose `codex.cwd` and `codex.homeDir` from the js_repl kernel
    - make `codex.homeDir` come from the kernel process environment
    - pass session dependency env through js_repl kernel startup so
    `codex.homeDir` matches the env a shell-launched process would see
    - keep existing shell `HOME` population behavior unchanged
    - update js_repl prompt/docs and add runtime/integration coverage for
    the new helpers
  • spawn prompt (#14362)
    # External (non-OpenAI) Pull Request Requirements
    
    Before opening this Pull Request, please read the dedicated
    "Contributing" markdown file or your PR may be closed:
    https://github.com/openai/codex/blob/main/docs/contributing.md
    
    If your PR conforms to our contribution guidelines, replace this text
    with a detailed and high quality description of your changes.
    
    Include a link to a bug report or enhancement request.
  • Add ALL_TOOLS export to code mode (#14294)
    So code mode can search for tools.
  • Add snippets annotated with types to tools when code mode enabled (#14284)
    Main purpose is for code mode to understand the return type.
  • Split spawn_csv from multi_agent (#14282)
    - make `spawn_csv` a standalone feature for CSV agent jobs
    - keep `spawn_csv -> multi_agent` one-way and preserve restricted
    subagent disable paths
  • Make unified exec session_id numeric (#14279)
    It's a number on the write_stdin input, make it a number on the output
    and also internally.
  • Show spawned agent model and effort in TUI (#14273)
    - include the requested sub-agent model and reasoning effort in the
    spawn begin event\n- render that metadata next to the spawned agent name
    and role in the TUI transcript
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>