mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
1d5eba0090d61444029fea1b44eae76238dcdd67
12 Commits
-
feat: retain NetworkProxy, when appropriate (#11207)
As of this PR, `SessionServices` retains a `Option<StartedNetworkProxy>`, if appropriate. Now the `network` field on `Config` is `Option<NetworkProxySpec>` instead of `Option<NetworkProxy>`. Over in `Session::new()`, we invoke `NetworkProxySpec::start_proxy()` to create the `StartedNetworkProxy`, which is a new struct that retains the `NetworkProxy` as well as the `NetworkProxyHandle`. (Note that `Drop` is implemented for `NetworkProxyHandle` to ensure the proxies are shutdown when it is dropped.) The `NetworkProxy` from the `StartedNetworkProxy` is threaded through to the appropriate places. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/11207). * #11285 * __->__ #11207
Michael Bolin ·
2026-02-10 02:09:23 -08:00 -
fix(tui): keep unified exec summary on working line (#10962)
## Problem When unified-exec background sessions appear while the status indicator is visible, the bottom pane can grow by one row to show a dedicated footer line. That row insertion/removal makes the composer jump vertically and produces visible jitter/flicker during streaming turns. ## Mental model The bottom pane should expose one canonical background-exec summary string, but it should surface that string in only one place at a time: - if the status indicator row is visible, show the summary inline on that row; - if the status indicator row is hidden, show the summary as the standalone unified-exec footer row. This keeps status information visible while preserving a stable pane height. ## Non-goals This change does not alter unified-exec lifecycle, process tracking, or `/ps` behavior. It does not redesign status text copy, spinner timing, or interrupt handling semantics. ## Tradeoffs Inlining the summary preserves layout stability and keeps interrupt affordances in a fixed location, but it reduces horizontal space for long status/detail text in narrow terminals. We accept that truncation risk in exchange for removing vertical jitter and keeping the composer anchored. ## Architecture `UnifiedExecFooter` remains the source of truth for background-process summary copy via `summary_text()`. `BottomPane` mirrors that text into `StatusIndicatorWidget::update_inline_message()` whenever process state changes or a status widget is created. Rendering enforces single-surface output: the standalone footer row is skipped while status is present, and the status row appends the summary after the elapsed/interrupt segment. ## Documentation pass Added non-functional docs/comments that make the new invariant explicit: - status row owns inline summary when present; - unified-exec footer row renders only when status row is absent; - summary ordering keeps elapsed/interrupt affordance in a stable position. ## Observability No new telemetry or logs are introduced. The behavior is traceable through: - `BottomPane::set_unified_exec_processes()` for state updates, - `BottomPane::sync_status_inline_message()` for status-row synchronization, - `StatusIndicatorWidget::render()` for final inline ordering. ## Tests - Added `bottom_pane::tests::unified_exec_summary_does_not_increase_height_when_status_visible` to lock the no-height-growth invariant. - Updated the unified-exec status restoration snapshot to match inline rendering order. - Validated with: - `just fmt` - `cargo test -p codex-tui --lib` --------- Co-authored-by: Sayan Sisodiya <sayan@openai.com>
Josh McKinney ·
2026-02-09 14:25:32 -08:00 -
Add resume_agent collab tool (#10903)
Summary - add the new resume_agent collab tool path through core, protocol, and the app server API, including the resume events - update the schema/TypeScript definitions plus docs so resume_agent appears in generated artifacts and README - note that resumed agents rehydrate rollout history without overwriting their base instructions Testing - Not run (not requested)
jif-oai ·
2026-02-07 17:31:45 +01:00 -
fix(tui): conditionally restore status indicator using message phase (#10947)
TLDR: use new message phase field emitted by preamble-supported models to determine whether an AgentMessage is mid-turn commentary. if so, restore the status indicator afterwards to indicate the turn has not completed. ### Problem `commit_tick` hides the status indicator while streaming assistant text. For preamble-capable models, that text can be commentary mid-turn, so hiding was correct during streaming but restore timing mattered: - restoring too aggressively caused jitter/flashing - not restoring caused indicator to stay hidden before subsequent work (tool calls, web search, etc.) ### Fix - Add optional `phase` to `AgentMessageItem` and propagate it from `ResponseItem::Message` - Keep indicator hidden during streamed commit ticks, restore only when: - assistant item completes as `phase=commentary`, and - stream queues are idle + task is still running. - Treat `phase=None` as final-answer behavior (no restore) to keep existing behavior for non-preamble models ### Tests Add/update tests for: - no idle-tick restore without commentary completion - commentary completion restoring status before tool begin - snapshot coverage for preamble/status behavior --------- Co-authored-by: Josh McKinney <joshka@openai.com>
sayan-oai ·
2026-02-07 02:39:52 +00:00 -
feat(app-server, core): allow text + image content items for dynamic tool outputs (#10567)
Took over the work that @aaronl-openai started here: https://github.com/openai/codex/pull/10397 Now that app-server clients are able to set up custom tools (called `dynamic_tools` in app-server), we should expose a way for clients to pass in not just text, but also image outputs. This is something the Responses API already supports for function call outputs, where you can pass in either a string or an array of content outputs (text, image, file): https://platform.openai.com/docs/api-reference/responses/create#responses_create-input-input_item_list-item-function_tool_call_output-output-array-input_image So let's just plumb it through in Codex (with the caveat that we only support text and image for now). This is implemented end-to-end across app-server v2 protocol types and core tool handling. ## Breaking API change NOTE: This introduces a breaking change with dynamic tools, but I think it's ok since this concept was only recently introduced (https://github.com/openai/codex/pull/9539) and it's better to get the API contract correct. I don't think there are any real consumers of this yet (not even the Codex App). Old shape: `{ "output": "dynamic-ok", "success": true }` New shape: ``` { "contentItems": [ { "type": "inputText", "text": "dynamic-ok" }, { "type": "inputImage", "imageUrl": "data:image/png;base64,AAA" } ] "success": true } ```
Owen Lin ·
2026-02-04 16:12:47 -08:00 -
feat: add APIs to list and download public remote skills (#10448)
Add API to list / download from remote public skills
xl-openai ·
2026-02-03 14:09:37 -08:00 -
Cleanup collaboration mode variants (#10404)
## Summary This PR simplifies collaboration modes to the visible set `default | plan`, while preserving backward compatibility for older partners that may still send legacy mode names. Specifically: - Renames the old Code behavior to **Default**. - Keeps **Plan** as-is. - Removes **Custom** mode behavior (fallbacks now resolve to Default). - Keeps `PairProgramming` and `Execute` internally for compatibility plumbing, while removing them from schema/API and UI visibility. - Adds legacy input aliasing so older clients can still send old mode names. ## What Changed 1. Mode enum and compatibility - `ModeKind` now uses `Plan` + `Default` as active/public modes. - `ModeKind::Default` deserialization accepts legacy values: - `code` - `pair_programming` - `execute` - `custom` - `PairProgramming` and `Execute` variants remain in code but are hidden from protocol/schema generation. - `Custom` variant is removed; previous custom fallbacks now map to `Default`. 2. Collaboration presets and templates - Built-in presets now return only: - `Plan` - `Default` - Template rename: - `core/templates/collaboration_mode/code.md` -> `default.md` - `execute.md` and `pair_programming.md` remain on disk but are not surfaced in visible preset lists. 3. TUI updates - Updated user-facing naming and prompts from “Code” to “Default”. - Updated mode-cycle and indicator behavior to reflect only visible `Plan` and `Default`. - Updated corresponding tests and snapshots. 4. request_user_input behavior - `request_user_input` remains allowed only in `Plan` mode. - Rejection messaging now consistently treats non-plan modes as `Default`. 5. Schemas - Regenerated config and app-server schemas. - Public schema types now advertise mode values as: - `plan` - `default` ## Backward Compatibility Notes - Incoming legacy mode names (`code`, `pair_programming`, `execute`, `custom`) are accepted and coerced to `default`. - Outgoing/public schema surfaces intentionally expose only `plan | default`. - This allows tolerant ingestion of older partner payloads while standardizing new integrations on the reduced mode set. ## Codex author `codex fork 019c1fae-693b-7840-b16e-9ad38ea0bd00`
Charley Cunningham ·
2026-02-03 09:23:53 -08:00 -
jif-oai ·
2026-02-03 11:31:57 +00:00 -
chore: add phase to message responseitem (#10455)
### What add wiring for `phase` field on `ResponseItem::Message` to lay groundwork for differentiating model preambles and final messages. currently optional. follows pattern in #9698. updated schemas with `just write-app-server-schema` so we can see type changes. ### Tests Updated existing tests for SSE parsing and hydrating from history
sayan-oai ·
2026-02-03 02:52:26 +00:00 -
feat: replace custom mcp-types crate with equivalents from rmcp (#10349)
We started working with MCP in Codex before https://crates.io/crates/rmcp was mature, so we had our own crate for MCP types that was generated from the MCP schema: https://github.com/openai/codex/blob/8b95d3e082376f4cb23e92641705a22afb28a9da/codex-rs/mcp-types/README.md Now that `rmcp` is more mature, it makes more sense to use their MCP types in Rust, as they handle details (like the `_meta` field) that our custom version ignored. Though one advantage that our custom types had is that our generated types implemented `JsonSchema` and `ts_rs::TS`, whereas the types in `rmcp` do not. As such, part of the work of this PR is leveraging the adapters between `rmcp` types and the serializable types that are API for us (app server and MCP) introduced in #10356. Note this PR results in a number of changes to `codex-rs/app-server-protocol/schema`, which merit special attention during review. We must ensure that these changes are still backwards-compatible, which is possible because we have: ```diff - export type CallToolResult = { content: Array<ContentBlock>, isError?: boolean, structuredContent?: JsonValue, }; + export type CallToolResult = { content: Array<JsonValue>, structuredContent?: JsonValue, isError?: boolean, _meta?: JsonValue, }; ``` so `ContentBlock` has been replaced with the more general `JsonValue`. Note that `ContentBlock` was defined as: ```typescript export type ContentBlock = TextContent | ImageContent | AudioContent | ResourceLink | EmbeddedResource; ``` so the deletion of those individual variants should not be a cause of great concern. Similarly, we have the following change in `codex-rs/app-server-protocol/schema/typescript/Tool.ts`: ``` - export type Tool = { annotations?: ToolAnnotations, description?: string, inputSchema: ToolInputSchema, name: string, outputSchema?: ToolOutputSchema, title?: string, }; + export type Tool = { name: string, title?: string, description?: string, inputSchema: JsonValue, outputSchema?: JsonValue, annotations?: JsonValue, icons?: Array<JsonValue>, _meta?: JsonValue, }; ``` so: - `annotations?: ToolAnnotations` ➡️ `JsonValue` - `inputSchema: ToolInputSchema` ➡️ `JsonValue` - `outputSchema?: ToolOutputSchema` ➡️ `JsonValue` and two new fields: `icons?: Array<JsonValue>, _meta?: JsonValue` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/10349). * #10357 * __->__ #10349 * #10356
Michael Bolin ·
2026-02-02 17:41:55 -08:00 -
feat: experimental flags (#10231)
## Problem being solved - We need a single, reliable way to mark app-server API surface as experimental so that: 1. the runtime can reject experimental usage unless the client opts in 2. generated TS/JSON schemas can exclude experimental methods/fields for stable clients. Right now that’s easy to drift or miss when done ad-hoc. ## How to declare experimental methods and fields - **Experimental method**: add `#[experimental("method/name")]` to the `ClientRequest` variant in `client_request_definitions!`. - **Experimental field**: on the params struct, derive `ExperimentalApi` and annotate the field with `#[experimental("method/name.field")]` + set `inspect_params: true` for the method variant so `ClientRequest::experimental_reason()` inspects params for experimental fields. ## How the macro solves it - The new derive macro lives in `codex-rs/codex-experimental-api-macros/src/lib.rs` and is used via `#[derive(ExperimentalApi)]` plus `#[experimental("reason")]` attributes. - **Structs**: - Generates `ExperimentalApi::experimental_reason(&self)` that checks only annotated fields. - The “presence” check is type-aware: - `Option<T>`: `is_some_and(...)` recursively checks inner. - `Vec`/`HashMap`/`BTreeMap`: must be non-empty. - `bool`: must be `true`. - Other types: considered present (returns `true`). - Registers each experimental field in an `inventory` with `(type_name, serialized field name, reason)` and exposes `EXPERIMENTAL_FIELDS` for that type. Field names are converted from `snake_case` to `camelCase` for schema/TS filtering. - **Enums**: - Generates an exhaustive `match` returning `Some(reason)` for annotated variants and `None` otherwise (no wildcard arm). - **Wiring**: - Runtime gating uses `ExperimentalApi::experimental_reason()` in `codex-rs/app-server/src/message_processor.rs` to reject requests unless `InitializeParams.capabilities.experimental_api == true`. - Schema/TS export filters use the inventory list and `EXPERIMENTAL_CLIENT_METHODS` from `client_request_definitions!` to strip experimental methods/fields when `experimental_api` is false.jif-oai ·
2026-02-02 11:06:50 +00:00 -
feat: vendor app-server protocol schema fixtures (#10371)
Similar to what @sayan-oai did in openai/codex#8956 for `config.schema.json`, this PR updates the repo so that it includes the output of `codex app-server generate-json-schema` and `codex app-server generate-ts` and adds a test to verify it is in sync with the current code. Motivation: - This makes any schema changes introduced by a PR transparent during code review. - In particular, this should help us catch PRs that would introduce a non-backwards-compatible change to the app schema (eventually, this should also be enforced by tooling). - Once https://github.com/openai/codex/pull/10231 is in to formalize the notion of "experimental" fields, we can work on ensuring the non-experimental bits are backwards-compatible. `codex-rs/app-server-protocol/tests/schema_fixtures.rs` was added as the test and `just write-app-server-schema` can be use to generate the vendored schema files. Incidentally, when I run: ``` rg _ codex-rs/app-server-protocol/schema/typescript/v2 ``` I see a number of `snake_case` names that should be `camelCase`.
Michael Bolin ·
2026-02-01 23:38:43 -08:00