mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
46b0c4acbbbd2631aeadd2e72e28fd4e5afe3bc2
5 Commits
-
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.Owen Lin ·
2026-01-09 08:17:13 -08:00 -
feat: change ConfigLayerName into a disjoint union rather than a simple enum (#8095)
This attempts to tighten up the types related to "config layers." Currently, `ConfigLayerEntry` is defined as follows: https://github.com/openai/codex/blob/bef36f4ae765f471d7cd69372fcf1b92c8f0367a/codex-rs/core/src/config_loader/state.rs#L19-L25 but the `source` field is a bit of a lie, as: - for `ConfigLayerName::Mdm`, it is `"com.openai.codex/config_toml_base64"` - for `ConfigLayerName::SessionFlags`, it is `"--config"` - for `ConfigLayerName::User`, it is `"config.toml"` (just the file name, not the path to the `config.toml` on disk that was read) - for `ConfigLayerName::System`, it seems like it is usually `/etc/codex/managed_config.toml` in practice, though on Windows, it is `%CODEX_HOME%/managed_config.toml`: https://github.com/openai/codex/blob/bef36f4ae765f471d7cd69372fcf1b92c8f0367a/codex-rs/core/src/config_loader/layer_io.rs#L84-L101 All that is to say, in three out of the four `ConfigLayerName`, `source` is a `PathBuf` that is not an absolute path (or even a true path). This PR tries to uplevel things by eliminating `source` from `ConfigLayerEntry` and turning `ConfigLayerName` into a disjoint union named `ConfigLayerSource` that has the appropriate metadata for each variant, favoring the use of `AbsolutePathBuf` where appropriate: ```rust pub enum ConfigLayerSource { /// Managed preferences layer delivered by MDM (macOS only). #[serde(rename_all = "camelCase")] #[ts(rename_all = "camelCase")] Mdm { domain: String, key: String }, /// Managed config layer from a file (usually `managed_config.toml`). #[serde(rename_all = "camelCase")] #[ts(rename_all = "camelCase")] System { file: AbsolutePathBuf }, /// Session-layer overrides supplied via `-c`/`--config`. SessionFlags, /// User config layer from a file (usually `config.toml`). #[serde(rename_all = "camelCase")] #[ts(rename_all = "camelCase")] User { file: AbsolutePathBuf }, } ```
Michael Bolin ·
2025-12-17 08:13:59 -08:00 -
chore: use anyhow::Result for all app-server integration tests (#5836)
There's a lot of visual noise in app-server's integration tests due to the number of `.expect("<some_msg>")` lines which are largely redundant / not very useful. Clean them up by using `anyhow::Result` + `?` consistently. Replaces the existing pattern of: ``` let codex_home = TempDir::new().expect("create temp dir"); create_config_toml(codex_home.path()).expect("write config.toml"); let mut mcp = McpProcess::new(codex_home.path()) .await .expect("spawn mcp process"); timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()) .await .expect("initialize timeout") .expect("initialize request"); ``` With: ``` let codex_home = TempDir::new()?; create_config_toml(codex_home.path())?; let mut mcp = McpProcess::new(codex_home.path()).await?; timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??; ```Owen Lin ·
2025-10-28 08:10:23 -07:00 -
fix: remove mcp-types from app server protocol (#4537)
We continue the separation between `codex app-server` and `codex mcp-server`. In particular, we introduce a new crate, `codex-app-server-protocol`, and migrate `codex-rs/protocol/src/mcp_protocol.rs` into it, renaming it `codex-rs/app-server-protocol/src/protocol.rs`. Because `ConversationId` was defined in `mcp_protocol.rs`, we move it into its own file, `codex-rs/protocol/src/conversation_id.rs`, and because it is referenced in a ton of places, we have to touch a lot of files as part of this PR. We also decide to get away from proper JSON-RPC 2.0 semantics, so we also introduce `codex-rs/app-server-protocol/src/jsonrpc_lite.rs`, which is basically the same `JSONRPCMessage` type defined in `mcp-types` except with all of the `"jsonrpc": "2.0"` removed. Getting rid of `"jsonrpc": "2.0"` makes our serialization logic considerably simpler, as we can lean heavier on serde to serialize directly into the wire format that we use now.
Michael Bolin ·
2025-10-01 02:16:26 +00:00 -
fix: separate
codex mcpintocodex mcp-serverandcodex app-server(#4471)This is a very large PR with some non-backwards-compatible changes. Historically, `codex mcp` (or `codex mcp serve`) started a JSON-RPC-ish server that had two overlapping responsibilities: - Running an MCP server, providing some basic tool calls. - Running the app server used to power experiences such as the VS Code extension. This PR aims to separate these into distinct concepts: - `codex mcp-server` for the MCP server - `codex app-server` for the "application server" Note `codex mcp` still exists because it already has its own subcommands for MCP management (`list`, `add`, etc.) The MCP logic continues to live in `codex-rs/mcp-server` whereas the refactored app server logic is in the new `codex-rs/app-server` folder. Note that most of the existing integration tests in `codex-rs/mcp-server/tests/suite` were actually for the app server, so all the tests have been moved with the exception of `codex-rs/mcp-server/tests/suite/mod.rs`. Because this is already a large diff, I tried not to change more than I had to, so `codex-rs/app-server/tests/common/mcp_process.rs` still uses the name `McpProcess` for now, but I will do some mechanical renamings to things like `AppServer` in subsequent PRs. While `mcp-server` and `app-server` share some overlapping functionality (like reading streams of JSONL and dispatching based on message types) and some differences (completely different message types), I ended up doing a bit of copypasta between the two crates, as both have somewhat similar `message_processor.rs` and `outgoing_message.rs` files for now, though I expect them to diverge more in the near future. One material change is that of the initialize handshake for `codex app-server`, as we no longer use the MCP types for that handshake. Instead, we update `codex-rs/protocol/src/mcp_protocol.rs` to add an `Initialize` variant to `ClientRequest`, which takes the `ClientInfo` object we need to update the `USER_AGENT_SUFFIX` in `codex-rs/app-server/src/message_processor.rs`. One other material change is in `codex-rs/app-server/src/codex_message_processor.rs` where I eliminated a use of the `send_event_as_notification()` method I am generally trying to deprecate (because it blindly maps an `EventMsg` into a `JSONNotification`) in favor of `send_server_notification()`, which takes a `ServerNotification`, as that is intended to be a custom enum of all notification types supported by the app server. So to make this update, I had to introduce a new variant of `ServerNotification`, `SessionConfigured`, which is a non-backwards compatible change with the old `codex mcp`, and clients will have to be updated after the next release that contains this PR. Note that `codex-rs/app-server/tests/suite/list_resume.rs` also had to be update to reflect this change. I introduced `codex-rs/utils/json-to-toml/src/lib.rs` as a small utility crate to avoid some of the copying between `mcp-server` and `app-server`.
Michael Bolin ·
2025-09-30 07:06:18 +00:00