Commit Graph

1164 Commits

Author SHA1 Message Date
Owen Lin
8e8659d4e4 fix(app-server): filter out codex-auto-* models and ensure gpt-5.2-codex is default 2026-01-13 16:07:22 -08:00
Ahmed Ibrahim
87f7226cca Assemble sandbox/approval/network prompts dynamically (#8961)
- Add a single builder for developer permissions messaging that accepts
SandboxPolicy and approval policy. This builder now drives the developer
“permissions” message that’s injected at session start and any time
sandbox/approval settings change.
- Trim EnvironmentContext to only include cwd, writable roots, and
shell; removed sandbox/approval/network duplication and adjusted XML
serialization and tests accordingly.

Follow-up: adding a config value to replace the developer permissions
message for custom sandboxes.
2026-01-12 23:12:59 +00:00
charley-oai
d7cdcfc302 Add some tests for image attachments (#9080)
Some extra tests for https://github.com/openai/codex/pull/8950
2026-01-12 13:41:50 -08:00
pakrym-oai
5dfa780f3d Remove unused conversation_id header (#9107)
It's an exact copy of session_id
2026-01-12 21:01:07 +00:00
Shijie Rao
3e91a95ce1 feat: hot reload mcp servers (#8957)
### Summary
* Added `mcpServer/refresh` command to inform app servers and active
threads to refresh mcpServer on next turn event.
* Added `pending_mcp_server_refresh_config` to codex core so that if the
value is populated, we reinitialize the mcp server manager on the thread
level.
* The config is updated on `mcpServer/refresh` command which we iterate
through threads and provide with the latest config value after last
write.
2026-01-12 11:17:50 -08:00
jif-oai
898e5f82f0 nit: add docstring (#9099)
Add docstring on `ToolHandler` trait
2026-01-12 17:40:52 +00:00
WhammyLeaf
d5562983d9 Add static mcp callback uri support (#8971)
Currently the callback URI for MCP authentication is dynamically
generated. More specifically, the callback URI is dynamic because the
port part of it is randomly chosen by the OS. This is not ideal as
callback URIs are recommended to be static and many authorization
servers do not support dynamic callback URIs.

This PR fixes that issue by exposing a new config option named
`mcp_oauth_callback_port`. When it is set, the callback URI is
constructed using this port rather than a random one chosen by the OS,
thereby making callback URI static.

Related issue: https://github.com/openai/codex/issues/8827
2026-01-12 16:57:04 +00:00
jif-oai
9659583559 feat: add close tool implementation for collab (#9090)
Pretty straight forward. A known follow-up will be to drop it from the
AgentControl
2026-01-12 13:21:46 +00:00
jif-oai
623707ab58 feat: add wait tool implementation for collab (#9088)
Add implementation for the `wait` tool.

For this we consider all status different from `PendingInit` and
`Running` as terminal. The `wait` tool call will return either after a
given timeout or when the tool reaches a non-terminal status.

A few points to note:
* The usage of a channel is preferred to prevent some races (just
looping on `get_status()` could "miss" a terminal status)
* The order of operations is very important, we need to first subscribe
and then check the last known status to prevent race conditions
* If the channel gets dropped, we return an error on purpose
2026-01-12 12:16:24 +00:00
jif-oai
86f81ca010 feat: testing harness for collab 1 (#8983) 2026-01-12 11:17:05 +00:00
charley-oai
6709ad8975 Label attached images so agent can understand in-message labels (#8950)
Agent wouldn't "see" attached images and would instead try to use the
view_file tool:
<img width="1516" height="504" alt="image"
src="https://github.com/user-attachments/assets/68a705bb-f962-4fc1-9087-e932a6859b12"
/>

In this PR, we wrap image content items in XML tags with the name of
each image (now just a numbered name like `[Image #1]`), so that the
model can understand inline image references (based on name). We also
put the image content items above the user message which the model seems
to prefer (maybe it's more used to definitions being before references).

We also tweak the view_file tool description which seemed to help a bit

Results on a simple eval set of images:

Before
<img width="980" height="310" alt="image"
src="https://github.com/user-attachments/assets/ba838651-2565-4684-a12e-81a36641bf86"
/>

After
<img width="918" height="322" alt="image"
src="https://github.com/user-attachments/assets/10a81951-7ee6-415e-a27e-e7a3fd0aee6f"
/>

```json
[
  {
    "id": "single_describe",
    "prompt": "Describe the attached image in one sentence.",
    "images": ["image_a.png"]
  },
  {
    "id": "single_color",
    "prompt": "What is the dominant color in the image? Answer with a single color word.",
    "images": ["image_b.png"]
  },
  {
    "id": "orientation_check",
    "prompt": "Is the image portrait or landscape? Answer in one sentence.",
    "images": ["image_c.png"]
  },
  {
    "id": "detail_request",
    "prompt": "Look closely at the image and call out any small details you notice.",
    "images": ["image_d.png"]
  },
  {
    "id": "two_images_compare",
    "prompt": "I attached two images. Are they the same or different? Briefly explain.",
    "images": ["image_a.png", "image_b.png"]
  },
  {
    "id": "two_images_captions",
    "prompt": "Provide a short caption for each image (Image 1, Image 2).",
    "images": ["image_c.png", "image_d.png"]
  },
  {
    "id": "multi_image_rank",
    "prompt": "Rank the attached images from most colorful to least colorful.",
    "images": ["image_a.png", "image_b.png", "image_c.png"]
  },
  {
    "id": "multi_image_choice",
    "prompt": "Which image looks more vibrant? Answer with 'Image 1' or 'Image 2'.",
    "images": ["image_b.png", "image_d.png"]
  }
]
```
2026-01-09 21:33:45 -08:00
Michael Bolin
cf515142b0 fix: include AGENTS.md as repo root marker for integration tests (#9010)
As explained in `codex-rs/core/BUILD.bazel`, including the repo's own
`AGENTS.md` is a hack to get some tests passing. We should fix this
properly, but I wanted to put stake in the ground ASAP to get `just
bazel-remote-test` working and then add a job to `bazel.yml` to ensure
it keeps working.
2026-01-09 17:09:59 -08:00
gt-oai
cc0b5e8504 Add URL to responses error messages (#8984)
Put the URL in error messages, to aid debugging Codex pointing at wrong
endpoints.

<img width="759" height="164" alt="Screenshot 2026-01-09 at 16 32 49"
src="https://github.com/user-attachments/assets/77a0622c-955d-426d-86bb-c035210a4ecc"
/>
2026-01-10 00:53:47 +00:00
Ahmed Ibrahim
af1ed2685e Refactor remote models tests to use TestCodex builder (#8940)
- add `with_model_provider` to the test codex builder
- replace the bespoke remote models harness with `TestCodex` in
`remote_models` tests
2026-01-09 15:11:56 -08:00
pakrym-oai
acfd94f625 Add hierarchical agent prompt (#8996) 2026-01-09 13:47:37 -08:00
Owen Lin
fbe883318d fix(app-server): set originator header from initialize (re-revert) (#8988)
Reapplies https://github.com/openai/codex/pull/8873 which was reverted
due to merge conflicts
2026-01-09 12:09:30 -08:00
zbarsky-openai
2a06d64bc9 feat: add support for building with Bazel (#8875)
This PR configures Codex CLI so it can be built with
[Bazel](https://bazel.build) in addition to Cargo. The `.bazelrc`
includes configuration so that remote builds can be done using
[BuildBuddy](https://www.buildbuddy.io).

If you are familiar with Bazel, things should work as you expect, e.g.,
run `bazel test //... --keep-going` to run all the tests in the repo,
but we have also added some new aliases in the `justfile` for
convenience:

- `just bazel-test` to run tests locally
- `just bazel-remote-test` to run tests remotely (currently, the remote
build is for x86_64 Linux regardless of your host platform). Note we are
currently seeing the following test failures in the remote build, so we
still need to figure out what is happening here:

```
failures:
    suite::compact::manual_compact_twice_preserves_latest_user_messages
    suite::compact_resume_fork::compact_resume_after_second_compaction_preserves_history
    suite::compact_resume_fork::compact_resume_and_fork_preserve_model_history_view
```

- `just build-for-release` to build release binaries for all
platforms/architectures remotely

To setup remote execution:
- [Create a buildbuddy account](https://app.buildbuddy.io/) (OpenAI
employees should also request org access at
https://openai.buildbuddy.io/join/ with their `@openai.com` email
address.)
- [Copy your API key](https://app.buildbuddy.io/docs/setup/) to
`~/.bazelrc` (add the line `build
--remote_header=x-buildbuddy-api-key=YOUR_KEY`)
- Use `--config=remote` in your `bazel` invocations (or add `common
--config=remote` to your `~/.bazelrc`, or use the `just` commands)

## CI

In terms of CI, this PR introduces `.github/workflows/bazel.yml`, which
uses Bazel to run the tests _locally_ on Mac and Linux GitHub runners
(we are working on supporting Windows, but that is not ready yet). Note
that the failures we are seeing in `just bazel-remote-test` do not occur
on these GitHub CI jobs, so everything in `.github/workflows/bazel.yml`
is green right now.

The `bazel.yml` uses extra config in `.github/workflows/ci.bazelrc` so
that macOS CI jobs build _remotely_ on Linux hosts (using the
`docker://docker.io/mbolin491/codex-bazel` Docker image declared in the
root `BUILD.bazel`) using cross-compilation to build the macOS
artifacts. Then these artifacts are downloaded locally to GitHub's macOS
runner so the tests can be executed natively. This is the relevant
config that enables this:

```
common:macos --config=remote
common:macos --strategy=remote
common:macos --strategy=TestRunner=darwin-sandbox,local
```

Because of the remote caching benefits we get from BuildBuddy, these new
CI jobs can be extremely fast! For example, consider these two jobs that
ran all the tests on Linux x86_64:

- Bazel 1m37s
https://github.com/openai/codex/actions/runs/20861063212/job/59940545209?pr=8875
- Cargo 9m20s
https://github.com/openai/codex/actions/runs/20861063192/job/59940559592?pr=8875

For now, we will continue to run both the Bazel and Cargo jobs for PRs,
but once we add support for Windows and running Clippy, we should be
able to cutover to using Bazel exclusively for PRs, which should still
speed things up considerably. We will probably continue to run the Cargo
jobs post-merge for commits that land on `main` as a sanity check.

Release builds will also continue to be done by Cargo for now.

Earlier attempt at this PR: https://github.com/openai/codex/pull/8832
Earlier attempt to add support for Buck2, now abandoned:
https://github.com/openai/codex/pull/8504

---------

Co-authored-by: David Zbarsky <dzbarsky@gmail.com>
Co-authored-by: Michael Bolin <mbolin@openai.com>
2026-01-09 11:09:43 -08:00
Helmut Januschka
7daaabc795 fix: add tui.alternate_screen config and --no-alt-screen CLI flag for Zellij scrollback (#8555)
Fixes #2558

Codex uses alternate screen mode (CSI 1049) which, per xterm spec,
doesn't support scrollback. Zellij follows this strictly, so users can't
scroll back through output.

**Changes:**
- Add `tui.alternate_screen` config: `auto` (default), `always`, `never`
- Add `--no-alt-screen` CLI flag
- Auto-detect Zellij and skip alt screen (uses existing `ZELLIJ` env var
detection)

**Usage:**
```bash
# CLI flag
codex --no-alt-screen

# Or in config.toml
[tui]
alternate_screen = "never"
```

With default `auto` mode, Zellij users get working scrollback without
any config changes.

---------

Co-authored-by: Josh McKinney <joshka@openai.com>
2026-01-09 18:38:26 +00:00
jif-oai
1aed01e99f renaming: task to turn (#8963) 2026-01-09 17:31:17 +00:00
jif-oai
ed64804cb5 nit: rename to analytics_enabled (#8978) 2026-01-09 17:18:42 +00:00
jif-oai
5c380d5b1e Revert "fix(app-server): set originator header from initialize JSON-RPC request" (#8986)
Reverts openai/codex#8873
2026-01-09 17:00:53 +00:00
gt-oai
5b5a5b92b5 Add config to disable /feedback (#8909)
Some enterprises do not want their users to be able to `/feedback`.

<img width="395" height="325" alt="image"
src="https://github.com/user-attachments/assets/2dae9c0b-20c3-4a15-bcd3-0187857ebbd8"
/>

Adds to `config.toml`:

```toml
[feedback]
enabled = false
```

I've deliberately decided to:
1. leave other references to `/feedback` (e.g. in the interrupt message,
tips of the day) unchanged. I think we should continue to promote the
feature even if it is not usable currently.
2. leave the `/feedback` menu item selectable and display an error
saying it's disabled, rather than remove the menu item (which I believe
would raise more questions).

but happy to discuss these.

This will be followed by a change to requirements.toml that admins can
use to force the value of feedback.enabled.
2026-01-09 16:33:48 +00:00
Owen Lin
ea56186c2b fix(app-server): set originator header from initialize JSON-RPC request (#8873)
**Motivation**
The `originator` header is important for codex-backend’s Responses API
proxy because it identifies the real end client (codex cli, codex vscode
extension, codex exec, future IDEs) and is used to categorize requests
by client for our enterprise compliance API.

Today the `originator` header is set by either:
- the `CODEX_INTERNAL_ORIGINATOR_OVERRIDE` env var (our VSCode extension
does this)
- calling `set_default_originator()` which sets a global immutable
singleton (`codex exec` does this)

For `codex app-server`, we want the `initialize` JSON-RPC request to set
that header because it is a natural place to do so. Example:
```json
{
  "method": "initialize",
  "id": 0,
  "params": {
    "clientInfo": {
      "name": "codex_vscode",
      "title": "Codex VS Code Extension",
      "version": "0.1.0"
    }
  }
}
```
and when app-server receives that request, it can call
`set_default_originator()`. This is a much more natural interface than
asking third party developers to set an env var.

One hiccup is that `originator()` reads the global singleton and locks
in the value, preventing a later `set_default_originator()` call from
setting it. This would be fine but is brittle, since any codepath that
calls `originator()` before app-server can process an `initialize`
JSON-RPC call would prevent app-server from setting it. This was
actually the case with OTEL initialization which runs on boot, but I
also saw this behavior in certain tests.

Instead, what we now do is:
- [unchanged] If `CODEX_INTERNAL_ORIGINATOR_OVERRIDE` env var is set,
`originator()` would return that value and `set_default_originator()`
with some other value does NOT override it.
- [new] If no env var is set, `originator()` would return the default
value which is `codex_cli_rs` UNTIL `set_default_originator()` is called
once, in which case it is set to the new value and becomes immutable.
Later calls to `set_default_originator()` returns
`SetOriginatorError::AlreadyInitialized`.

**Other notes**
- I updated `codex_core::otel_init::build_provider` to accepts a service
name override, and app-server sends a hardcoded `codex_app_server`
service name to distinguish it from `codex_cli_rs` used by default (e.g.
TUI).

**Next steps**
- Update VSCE to set the proper value for `clientInfo.name` on
`initialize` and drop the `CODEX_INTERNAL_ORIGINATOR_OVERRIDE` env var.
- Delete support for `CODEX_INTERNAL_ORIGINATOR_OVERRIDE` in codex-rs.
2026-01-09 08:17:13 -08:00
jif-oai
e2e3f4490e chore: add approval metric (#8970) 2026-01-09 13:10:31 +00:00
jif-oai
225614d7fb chore: add mcp call metric (#8973) 2026-01-09 13:09:21 +00:00
jif-oai
16c66c37eb chore: move otel provider outside of trace module (#8968) 2026-01-09 12:42:54 +00:00
jif-oai
e9c548c65e chore: non mutable btree when building specs (#8969) 2026-01-09 12:21:55 +00:00
jif-oai
fceae86581 nit: rename session metric (#8966) 2026-01-09 11:55:57 +00:00
jif-oai
568b938c80 feat: first pass on clb tool (#8930) 2026-01-09 11:54:05 +00:00
Matthew Zeng
24d6e0114f [device-auth] When headless environment is detected, show device login flow instead. (#8756)
When headless environment is detected, show device login flow instead.
2026-01-08 21:48:30 -08:00
Ahmed Ibrahim
81caee3400 Add 5s timeout to models list call + integration test (#8942)
- Enforce a 5s timeout around the remote models refresh to avoid hanging
/models calls.
2026-01-08 18:06:10 -08:00
Thibault Sottiaux
51dd5af807 fix: treat null MCP resource args as empty (#8917)
Handle null tool arguments in the MCP resource handler so optional
resource tools accept null without failing, preserving normal JSON
parsing for non-null payloads and improving robustness when models emit
null; this avoids spurious argument parse errors for list/read MCP
resource calls.
2026-01-08 17:47:02 -08:00
iceweasel-oai
6372ba9d5f Elevated sandbox NUX (#8789)
Elevated Sandbox NUX:

* prompt for elevated sandbox setup when agent mode is selected (via
/approvals or at startup)
* prompt for degraded sandbox if elevated setup is declined or fails
* introduce /elevate-sandbox command to upgrade from degraded
experience.
2026-01-08 16:23:06 -08:00
Michael Bolin
bdfdebcfa1 fix: increase timeout for wait_for_event() for Bazel (#8946)
This seems to be necessary to get the Bazel builds on ARM Linux to go
green on https://github.com/openai/codex/pull/8875.

I don't feel great about timeout-whack-a-mole, but we're still learning
here...
2026-01-08 15:37:46 -08:00
pakrym-oai
62a73b6d58 Attempt to reload auth as a step in 401 recovery (#8880)
When authentication fails, first attempt to reload the auth from file
and then attempt to refresh it.
2026-01-08 15:06:44 -08:00
Ahmed Ibrahim
0d3e673019 remove get_responses_requests and get_responses_request_bodies to use in-place matcher (#8858) 2026-01-08 13:57:48 -08:00
Anton Panasenko
41a317321d feat: fork conversation/thread (#8866)
## Summary
- add thread/conversation fork endpoints to the protocol (v1 + v2)
- implement fork handling in app-server using thread manager and config
overrides
- add fork coverage in app-server tests and document `thread/fork` usage
2026-01-08 12:54:20 -08:00
Michael Bolin
224c4867dd fix: increase timeout for tests that have been flaking with timeout issues (#8932)
I have seen this test flake out sometimes when running the macOS build
using Bazel in CI: https://github.com/openai/codex/pull/8875. Perhaps
Bazel runs with greater parallelism, inducing a heavier load, causing an
issue?
2026-01-08 20:31:03 +00:00
jif-oai
c9c6560685 nit: parse_arguments (#8927) 2026-01-08 19:49:17 +00:00
pakrym-oai
634764ece9 Immutable CodexAuth (#8857)
Historically we started with a CodexAuth that knew how to refresh it's
own tokens and then added AuthManager that did a different kind of
refresh (re-reading from disk).

I don't think it makes sense for both `CodexAuth` and `AuthManager` to
be mutable and contain behaviors.

Move all refresh logic into `AuthManager` and keep `CodexAuth` as a data
object.
2026-01-08 11:43:56 -08:00
gt-oai
4156060416 Add read-only when backfilling requirements from managed_config (#8913)
When a user has a managed_config which doesn't specify read-only, Codex
fails to launch.
2026-01-08 11:27:46 -08:00
Thibault Sottiaux
98122cbad0 fix: preserve core env vars on Windows (#8897)
This updates core shell environment policy handling to match Windows
case-insensitive variable names and adds a Windows-only regression test,
so Path/TEMP are no longer dropped when inherit=core.
2026-01-08 10:36:36 -08:00
github-actions[bot]
7b21b443bb Update models.json (#8792)
Automated update of models.json.

Co-authored-by: aibrahim-oai <219906144+aibrahim-oai@users.noreply.github.com>
2026-01-08 10:26:01 -08:00
jif-oai
69898e3dba clean: all history cloning (#8916) 2026-01-08 18:17:18 +00:00
Michael Bolin
59d6937550 fix: reduce duplicate include_str!() calls (#8914) 2026-01-08 17:20:41 +00:00
gt-oai
932a5a446f config requirements: improve requirement error messages (#8843)
**Before:**
```
Error loading configuration: value `Never` is not in the allowed set [OnRequest]
```

**After:**
```
Error loading configuration: invalid value for `approval_policy`: `Never` is not in the
allowed set [OnRequest] (set by MDM com.openai.codex:requirements_toml_base64)
```

Done by introducing a new struct `ConfigRequirementsWithSources` onto
which we `merge_unset_fields` now. Also introduces a pair of requirement
value and its `RequirementSource` (inspired by `ConfigLayerSource`):

```rust
pub struct Sourced<T> {
    pub value: T,
    pub source: RequirementSource,
}
```
2026-01-08 16:11:14 +00:00
jif-oai
5522663f92 feat: add a few metrics (#8910) 2026-01-08 15:39:57 +00:00
jif-oai
98e171258c nit: drop unused function call error (#8903) 2026-01-08 15:07:30 +00:00
jif-oai
da667b1f56 chore: drop useless interaction_input (#8907) 2026-01-08 15:01:07 +00:00
Michael Bolin
1e29774fce fix: leverage codex_utils_cargo_bin() in codex-rs/core/tests/suite (#8887)
This eliminates our dependency on the `escargot` crate and better
prepares us for Bazel builds: https://github.com/openai/codex/pull/8875.
2026-01-08 14:56:16 +00:00