- Introduce websearch end to complement the begin
- Moves the logic of adding the sebsearch tool to
create_tools_json_for_responses_api
- Making it the client responsibility to toggle the tool on or off
- Other misc in #2371 post commit feedback
- Show the query:
<img width="1392" height="151" alt="image"
src="https://github.com/user-attachments/assets/8457f1a6-f851-44cf-bcca-0d4fe460ce89"
/>
Adds custom `/prompts` to `~/.codex/prompts/<command>.md`.
<img width="239" height="107" alt="Screenshot 2025-08-25 at 6 22 42 PM"
src="https://github.com/user-attachments/assets/fe6ebbaa-1bf6-49d3-95f9-fdc53b752679"
/>
---
Details:
1. Adds `Op::ListCustomPrompts` to core.
2. Returns `ListCustomPromptsResponse` with list of `CustomPrompt`
(name, content).
3. TUI calls the operation on load, and populates the custom prompts
(excluding prompts that collide with builtins).
4. Selecting the custom prompt automatically sends the prompt to the
agent.
## What
Make slash commands (/init, /status, /approvals, /model) bold and white
in the welcome message for better visibility.
<img width="990" height="286" alt="image"
src="https://github.com/user-attachments/assets/13f90e96-b84a-4659-aab4-576d84a31af7"
/>
## Why
The current welcome message displays all text in a dimmed style, making
the slash commands less prominent. Users need to quickly identify
available commands when starting Codex.
## How
Modified `tui/src/history_cell.rs` in the `new_session_info` function
to:
- Split each command line into separate spans
- Apply bold white styling to command text (`/init`, `/status`, etc.)
- Keep descriptions dimmed for visual contrast
- Maintain existing layout and spacing
## Test plan
- [ ] Run the TUI and verify commands appear bold in the welcome message
- [ ] Ensure descriptions remain dimmed for readability
- [ ] Confirm all existing tests pass
This PR fixes two edge cases in managing burst paste (mainly on power
shell).
Bugs:
- Needs an event key after paste to render the pasted items
> ChatComposer::flush_paste_burst_if_due() flushes on timeout. Called:
> - Pre-render in App on TuiEvent::Draw.
> - Via a delayed frame
>
BottomPane::request_redraw_in(ChatComposer::recommended_paste_flush_delay()).
- Parses two key events separately before starting parsing burst paste
> When threshold is crossed, pull preceding burst chars out of the
textarea and prepend to paste_burst_buffer, then keep buffering.
- Integrates with #2567 to bring image pasting to windows.
This was supposed to be fixed by #2569, but I think the actual fix got
lost in the refactoring.
Intended behavior: pressing ^Z moves the cursor below the viewport
before suspending.
This was mostly written by codex under heavy guidance via test cases
drawn from logged session data and fuzzing. It also uncovered some bugs
in tui_markdown, which will in some cases split a list marker from the
list item content. We're not addressing those bugs for now.
Prevented panics when deleting placeholders near multibyte characters by
clamping the cursor to a valid boundary and using get-based slicing
Added a regression test to ensure backspacing after multibyte text
leaves placeholders intact without crashing
---------
Co-authored-by: Ahmed Ibrahim <aibrahim@openai.com>
This fixes a bug where if you ran /diff while at turn was running,
transcript lines would be added to the end of the diff view. Also,
refactor to make this kind of issue less likely in future.
This pr addresses the fix for
https://github.com/openai/codex/issues/2713
### Changes:
- Added key handler for `Alt+Ctrl+H` → `delete_backward_word()`
- Added test coverage in `delete_backward_word_alt_keys()` that verifies
both:
- Standard `Alt+Backspace` binding continues to work
- New `Alt+Ctrl+H` binding works correctly for backward word deletion
### Testing:
The test ensures both key combinations produce identical behavior:
- Delete the previous word from "hello world" → "hello "
- Cursor positioned correctly after deletion
### Backward Compatibility:
This change is backward compatible - existing `Alt+Backspace`
functionality remains unchanged while adding support for the
terminal-specific `Alt+Ctrl+H` variant
Use emoji variation selector (VS16) for the keyboard icon so it
consistently renders as emoji (⌨️) rather than text (⌨) across
terminals.
Touches TUI command rendering for unknown parsed commands. No behavior
change beyond display.
Esc and Ctrl+C while a task is running should do the same thing. There
were some cases where pressing Esc would leave a "stuck" widget in the
history; this fixes that and cleans up the logic so there's just one
path for interrupting the task. Also clean up some subtly mishandled key
events (e.g. Ctrl+D would quit the app while an approval modal was
showing if the textarea was empty).
---------
Co-authored-by: Ahmed Ibrahim <aibrahim@openai.com>
In this PR:
- [x] Add support for dragging / copying image files into chat.
- [x] Don't remove image placeholders when submitting.
- [x] Add tests.
Works for:
- Image Files
- Dragging MacOS Screenshots (Terminal, iTerm)
Todos:
- [ ] In some terminals (VSCode, WIndows Powershell, and remote
SSH-ing), copy-pasting a file streams the escaped filepath as individual
key events rather than a single Paste event. We'll need to have a
function (in a separate PR) for detecting these paste events.
Esc should have other functionalities when it's not used in a
backtracking situation. i.e. to cancel pop up menu when selecting
model/approvals or to interrupt an active turn.
I noticed that when running `/status` on Windows, I saw something like:
```
Path: ~/src\codex
```
so now it should be:
```
Path: ~\src\codex
```
Admittedly, `~` is understood by PowerShell but not on Windows, in
general, but it's much less verbose than `%USERPROFILE%`.
this dramatically improves time to run `cargo test -p codex-core` (~25x
speedup).
before:
```
cargo test -p codex-core 35.96s user 68.63s system 19% cpu 8:49.80 total
```
after:
```
cargo test -p codex-core 5.51s user 8.16s system 63% cpu 21.407 total
```
both tests measured "hot", i.e. on a 2nd run with no filesystem changes,
to exclude compile times.
approach inspired by [Delete Cargo Integration
Tests](https://matklad.github.io/2021/02/27/delete-cargo-integration-tests.html),
we move all test cases in tests/ into a single suite in order to have a
single binary, as there is significant overhead for each test binary
executed, and because test execution is only parallelized with a single
binary.
Adds web_search tool, enabling the model to use Responses API web_search
tool.
- Disabled by default, enabled by --search flag
- When --search is passed, exposes web_search_request function tool to
the model, which triggers user approval. When approved, the model can
use the web_search tool for the remainder of the turn
<img width="1033" height="294" alt="image"
src="https://github.com/user-attachments/assets/62ac6563-b946-465c-ba5d-9325af28b28f"
/>
---------
Co-authored-by: easong-openai <easong@openai.com>
We want to send an aggregated output of stderr and stdout so we don't
have to aggregate it stderr+stdout as we lose order sometimes.
---------
Co-authored-by: Gabriel Peal <gpeal@users.noreply.github.com>
This can be the underlying logic in order to start a conversation from a
previous message. will need some love in the UI.
Base for building this: #2588
before:
```
$ time cargo test -p codex-tui -q
[...]
cargo test -p codex-tui -q 39.89s user 10.77s system 98% cpu 51.328 total
```
after:
```
$ time cargo test -p codex-tui -q
[...]
cargo test -p codex-tui -q 1.37s user 0.64s system 29% cpu 6.699 total
```
the major offenders were the textarea fuzz test and the custom_terminal
doctests. (i think the doctests were being recompiled every time which
made them extra slow?)
## Summary
When resolving our current directory as a project, we want to be a
little bit more clever:
1. If we're in a sub-directory of a git repo, resolve our project
against the root of the git repo
2. If we're in a git worktree, resolve the project against the root of
the git repo
## Testing
- [x] Added unit tests
- [x] Confirmed locally with a git worktree (the one i was using for
this feature)
This PR adds a central `AuthManager` struct that manages the auth
information used across conversations and the MCP server. Prior to this,
each conversation and the MCP server got their own private snapshots of
the auth information, and changes to one (such as a logout or token
refresh) were not seen by others.
This is especially problematic when multiple instances of the CLI are
run. For example, consider the case where you start CLI 1 and log in to
ChatGPT account X and then start CLI 2 and log out and then log in to
ChatGPT account Y. The conversation in CLI 1 is still using account X,
but if you create a new conversation, it will suddenly (and
unexpectedly) switch to account Y.
With the `AuthManager`, auth information is read from disk at the time
the `ConversationManager` is constructed, and it is cached in memory.
All new conversations use this same auth information, as do any token
refreshes.
The `AuthManager` is also used by the MCP server's GetAuthStatus
command, which now returns the auth method currently used by the MCP
server.
This PR also includes an enhancement to the GetAuthStatus command. It
now accepts two new (optional) input parameters: `include_token` and
`refresh_token`. Callers can use this to request the in-use auth token
and can optionally request to refresh the token.
The PR also adds tests for the login and auth APIs that I recently added
to the MCP server.
Introduce a minimal paste-burst heuristic in the chat composer so Enter
is treated as a newline during paste-like bursts (plain chars arriving
in very short intervals), avoiding premature submit after the first line
on Windows consoles that lack bracketed paste.
- Detect tight sequences of plain Char events; open a short window where
Enter inserts a newline instead of submitting.
- Extend the window on newline to handle blank lines in pasted content.
- No behavior change for terminals that already emit Event::Paste; no
OS/env toggles added.
allow ctrl+v in TUI for images + @file that are images are appended as
raw files (and read by the model) rather than pasted as a path that
cannot be read by the model.
Re-used components and same interface we're using for copying pasted
content in
72504f1d9c.
@aibrahim-oai as you've implemented this, mind having a look at this
one?
https://github.com/user-attachments/assets/c6c1153b-6b32-4558-b9a2-f8c57d2be710
---------
Co-authored-by: easong-openai <easong@openai.com>
Co-authored-by: Daniel Edrisian <dedrisian@openai.com>
Co-authored-by: Michael Bolin <mbolin@openai.com>
This is a somewhat roundabout way to fix the issue that pressing ^Z
would put the shell prompt in the wrong place (overwriting some of the
status area below the composer). While I'm at it, clean up the suspend
logic and fix some suspend-while-in-alt-screen behavior too.
moves TranscriptApp to be an "overlay", and continue to pump AppEvents
while the transcript is active, but forward all tui handling to the
transcript screen.