Skip to content

Sync upstream/main (2026-01-07) - #143

Merged
ScriptedAlchemy merged 28 commits into
mainfrom
sync-upstream-main-2026-01-07
Jan 7, 2026
Merged

ScriptedAlchemy merged 28 commits into
mainfrom
sync-upstream-main-2026-01-07

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Merges latest upstream/main into our fork to stay aligned.

dylan-hurd-oai and others added 24 commits January 5, 2026 15:56
## Summary
More apply-patch scenarios

## Testing
- [x] This pr only adds tests
Trim whitespace when validating '*** Begin Patch'/'*** End Patch'
markers in codex-apply-patch so padded marker lines parse as intended,
and add regression coverage (unit + fixture scenario); this avoids
apply_patch failures when models include extra spacing. Tested with
cargo test -p codex-apply-patch.
Background
Streaming assistant prose in tui2 was being rendered with viewport-width
wrapping during streaming, then stored in history cells as already split
`Line`s. Those width-derived breaks became indistinguishable from hard
newlines, so the transcript could not "un-split" on resize. This also
degraded copy/paste, since soft wraps looked like hard breaks.

What changed
- Introduce width-agnostic `MarkdownLogicalLine` output in
`tui2/src/markdown_render.rs`, preserving markdown wrap semantics:
initial/subsequent indents, per-line style, and a preformatted flag.
- Update the streaming collector (`tui2/src/markdown_stream.rs`) to emit
logical lines (newline-gated) and remove any captured viewport width.
- Update streaming orchestration (`tui2/src/streaming/*`) to queue and
emit logical lines, producing `AgentMessageCell::new_logical(...)`.
- Make `AgentMessageCell` store logical lines and wrap at render time in
`HistoryCell::transcript_lines_with_joiners(width)`, emitting joiners so
copy/paste can join soft-wrap continuations correctly.

Overlay deferral
When an overlay is active, defer *cells* (not rendered `Vec<Line>`) and
render them at overlay close time. This avoids baking width-derived
wraps based on a stale width.

Tests + docs
- Add resize/reflow regression tests + snapshots for streamed agent
output.
- Expand module/API docs for the new logical-line streaming pipeline and
clarify joiner semantics.
- Align scrollback-related docs/comments with current tui2 behavior
(main draw loop does not flush queued "history lines" to the terminal).

More details
See `codex-rs/tui2/docs/streaming_wrapping_design.md` for the full
problem statement and solution approach, and
`codex-rs/tui2/docs/tui_viewport_and_history.md` for viewport vs printed
output behavior.
Display paths relative to the cwd before checking git roots so view
image tool calls keep project-local names in jj/no-.git workspaces.
Fixes ReadinessFlag::subscribe to avoid handing out token 0 or duplicate
tokens on i32 wrap-around, adds regression tests, and prevents readiness
gates from getting stuck waiting on an unmarkable or mis-authorized
token.
The models are outdated and sometime get used by GPT when it to try
delegate.

I have read the CLA Document and I hereby sign the CLA
Allows us to run `cargo run -p codex-app-server-test-client --
model-list` to return the list of models over app-server.
Force an announcement tooltip in the CLI. This query the gh repo on this
[file](https://raw.githubusercontent.com/openai/codex/main/announcement_tip.toml)
which contains announcements in TOML looking like this:
```
# Example announcement tips for Codex TUI.
# Each [[announcements]] entry is evaluated in order; the last matching one is shown.
# Dates are UTC, formatted as YYYY-MM-DD. The from_date is inclusive and the to_date is exclusive.
# version_regex matches against the CLI version (env!("CARGO_PKG_VERSION")); omit to apply to all versions.
# target_app specify which app should display the announcement (cli, vsce, ...).

[[announcements]]
content = "Welcome to Codex! Check out the new onboarding flow."
from_date = "2024-10-01"
to_date = "2024-10-15"
version_regex = "^0\\.0\\.0$"
target_app = "cli"
``` 

To make this efficient, the announcement is queried on a best effort
basis at the launch of the CLI (no refresh made after this).
This is done in an async way and we display the announcement (with 100%
probability) iff the announcement is available, the cache is correctly
warmed and there is a matching announcement (matching is recomputed for
each new session).
Added an agent control plane that lets sessions spawn or message other
conversations via `AgentControl`.

`AgentBus` (core/src/agent/bus.rs) keeps track of the last known status
of a conversation.

ConversationManager now holds shared state behind an Arc so AgentControl
keeps only a weak back-reference, the goal is just to avoid explicit
cycle reference.

Follow-ups:
* Build a small tool in the TUI to be able to see every agent and send
manual message to each of them
* Handle approval requests in this TUI
* Add tools to spawn/communicate between agents (see related design)
* Define agent types
### Motivation
- Fix a visual bug where transcript text could bleed through the
on-screen copy "pill" overlay.
- Ensure the copy affordance fully covers the underlying buffer so the
pill background is solid and consistent with styling.
- Document the approach in-code to make the background-clearing
rationale explicit.

### Description
- Clear the pill area before drawing by iterating `Rect::positions()`
and calling `cell.set_symbol(" ")` and `cell.set_style(base_style)` in
`render_copy_pill` in `transcript_copy_ui.rs`.
- Added an explanatory comment for why the pill background is explicitly
cleared.
- Added a unit test `copy_pill_clears_background` and committed the
corresponding snapshot file to validate the rendering behavior.

### Testing
- Ran `just fmt` (formatting completed; non-blocking environment warning
may appear).
- Ran `just fix -p codex-tui2` to apply lints/fixes (completed). 
- Ran `cargo test -p codex-tui2` and all tests passed (snapshot updated
and tests succeeded).

------
[Codex
Task](https://chatgpt.com/codex/tasks/task_i_695c9b23e9b8832997d5a457c4d83410)
Add `thread/rollback` to app-server to support IDEs undo-ing the last N
turns of a thread.

For context, an IDE partner will be supporting an "undo" capability
where the IDE (the app-server client) will be responsible for reverting
the local changes made during the last turn. To support this well, we
also need a way to drop the last turn (or more generally, the last N
turns) from the agent's context. This is what `thread/rollback` does.

**Core idea**: A Thread rollback is represented as a persisted event
message (EventMsg::ThreadRollback) in the rollout JSONL file, not by
rewriting history. On resume, both the model's context (core replay) and
the UI turn list (app-server v2's thread history builder) apply these
markers so the pruned history is consistent across live conversations
and `thread/resume`.

Implementation notes:
- Rollback only affects agent context and appends to the rollout file;
clients are responsible for reverting files on disk.
- If a thread rollback is currently in progress, subsequent
`thread/rollback` calls are rejected.
- Because we use `CodexConversation::submit` and codex core tracks
active turns, returning an error on concurrent rollbacks is communicated
via an `EventMsg::Error` with a new variant
`CodexErrorInfo::ThreadRollbackFailed`. app-server watches for that and
sends the BAD_REQUEST RPC response.

Tests cover thread rollbacks in both core and app-server, including when
`num_turns` > existing turns (which clears all turns).

**Note**: this explicitly does **not** behave like `/undo` which we just
removed from the CLI, which does the opposite of what `thread/rollback`
does. `/undo` reverts local changes via ghost commits/snapshots and does
not modify the agent's context / conversation history.
Currently we don't load config properly for app server conversations.
see:
https://linear.app/openai/issue/CODEX-3956/config-flags-not-respected-in-codex-app-server.
This PR fixes that by respecting the config passed in.

Tested by running `cargo build -p codex-cli &&
RUST_LOG=codex_app_server=debug CODEX_BIN=target/debug/codex cargo run
-p codex-app-server-test-client -- \
--config
model_providers.mock_provider.base_url=\"http://localhost:4010/v2\" \
    --config model_provider=\"mock_provider\" \
    --config model_providers.mock_provider.name="hello" \
    send-message-v2 "hello"`
and verified that the mock_provider is called instead of default
provider.

#closes
https://linear.app/openai/issue/CODEX-3956/config-flags-not-respected-in-codex-app-server

---------

Co-authored-by: Michael Bolin <mbolin@openai.com>
Add `web_search_cached` feature to config. Enables `web_search` tool
with access only to cached/indexed results (see
[docs](https://platform.openai.com/docs/guides/tools-web-search#live-internet-access)).

This takes precedence over the existing `web_search_request`, which
continues to enable `web_search` over live results as it did before.

`web_search_cached` is disabled for review mode, as `web_search_request`
is.
Use the contents of the commit message from the commit associated with
the tag (that contains the version bump) as the release notes by writing
them to a file and then specifying the file as the `body_path` of
`softprops/action-gh-release@v2`.
Fixes inscrutable multiline approval requests:
<img width="686" height="844" alt="image"
src="https://github.com/user-attachments/assets/cf9493dc-79e6-4168-8020-0ef0fe676d5e"
/>
…icker (#8802)

With `config.toml`:
```
model = "gpt-5.1-codex"
```
(where `gpt-5.1-codex` has `show_in_picker: false` in
[`model_presets.rs`](https://github.com/openai/codex/blob/main/codex-rs/core/src/models_manager/model_presets.rs);
this happens if the user hasn't used codex in a while so they didn't see
the popup before their model was changed to `show_in_picker: false`)

The upgrade picker used to not show (because `gpt-5.1-codex` was
filtered out of the model list in code). Now, the filtering is done
downstream in tui and app-server, so the model upgrade popup shows:

<img width="1503" height="227" alt="Screenshot 2026-01-06 at 5 04 37 PM"
src="https://github.com/user-attachments/assets/26144cc2-0b3f-4674-ac17-e476781ec548"
/>
@changeset-bot

changeset-bot Bot commented Jan 7, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: a2b483d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

Updated PR with a fix for just test (cargo nextest) timeouts in exec-server integration tests.

  • Root cause: exec-server tests used a fresh temp DOTSLASH_CACHE per test, forcing a cold DotSlash download/extract and exceeding nextest slow-timeout.
  • Fix: tests now use the default DotSlash cache (and on Linux can fall back to /bin/bash), so nextest no longer times out.

Re-ran:

  • just test (cargo nextest): PASS (2918 passed, 22 skipped)
  • pnpm -C sdk/native run build: PASS
  • pnpm -C sdk/native test: PASS

@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

Update: refined the nextest-timeout fix to keep upstream behavior (always use the DotSlash tests/suite/bash) while avoiding per-test cold downloads.

  • Change: stop overriding DOTSLASH_CACHE in exec-server integration tests; use DotSlash default cache.
  • Re-ran: just test PASS (2918 passed, 22 skipped); pnpm -C sdk/native run build PASS; pnpm -C sdk/native test PASS.

@ScriptedAlchemy
ScriptedAlchemy merged commit 9c582cb into main Jan 7, 2026
28 checks passed
@ScriptedAlchemy
ScriptedAlchemy deleted the sync-upstream-main-2026-01-07 branch January 7, 2026 23:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.