-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Conversation naming #8991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation naming #8991
Conversation
JaviSoto
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!!
Random suggestion I just thought of: it could be useful to give the agent a way to set the name as well via a tool call, so you can tell the agent to name the conversation as well? (you could even add something to your AGENTS.md with instructions on how you want the agent to name your sessions, or to rename them in certain cases etc)
codex-rs/cli/src/main.rs
Outdated
| #[derive(Debug, Parser)] | ||
| struct ResumeCommand { | ||
| /// Conversation/session id (UUID). When provided, resumes this session. | ||
| /// Conversation/session id (UUID) or session name. UUIDs take precedence if it parses. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
| pub struct SessionMetaUpdatedEvent { | ||
| /// Name left as session_id instead of thread_id for backwards compatibility. | ||
| pub session_id: ThreadId, | ||
| #[serde(default, skip_serializing_if = "Option::is_none")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
jif-oai
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would def go to the index file
- can we try to use
threadinstead ofsessionas much as possible
| Ok(()) | ||
| } | ||
|
|
||
| async fn rewrite_session_name( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those functions should not be needed. We should use the same mechanism as for the model used during the rollout for example
|
@jif-oai @JaviSoto moved to an index file instead of SessionMeta so we don't touch rollout files. We're reading a Implemented your comments (adding tests on resume, move to thread, thread_name or thread_id naming) |
|
I'm wondering if it won't be confusing though given the composer is still showing (we're still in the TUI) compared to when we exit (in which case we'll show codex resume anyway if a name is set). Should we keep @jif-oai ? |
|
Hi! Thanks for putting this together — it addresses the core pain point of making sessions easier to find via I’d like to contribute a small “minimal integration” improvement that stays within the existing flow:
Would appreciate maintainer guidance on whether you prefer If this approach sounds good, I’m happy to send a small follow-up PR (or base changes off your branch) with the tweaks + tests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 84324c0d41
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let line = serde_json::to_string(entry).map_err(std::io::Error::other)?; | ||
| file.write_all(line.as_bytes()).await?; | ||
| file.write_all(b"\n").await?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Write session_index entries atomically
The append path writes the JSON line and the newline as two separate write_all calls. If two Codex sessions/processes rename threads concurrently (same codex_home), the writes can interleave (e.g., json1json2\n\n), producing malformed JSONL that scan_index_from_end* will skip and making resume by name fail. Write the line plus newline in a single write (or lock the file) to keep each entry atomic under concurrent appends.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2eb7459e9b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| self.outgoing | ||
| .send_response(request_id, ThreadSetNameResponse {}) | ||
| .await; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don’t acknowledge rename before it succeeds
The handler sends a success response immediately after enqueueing Op::SetThreadName, but the core implementation can still fail later (e.g., persistence disabled or a write error when appending to the session index), in which case it emits an Error event and never sends ThreadNameUpdated (see codex-rs/core/src/codex.rs around lines 2953–2979). That means JSON-RPC clients that rely on the response will think the rename succeeded even though it didn’t persist, and resume-by-name will silently fail. Consider waiting for the ThreadNameUpdated/error event (similar to thread_rollback) or pre-checking persistence and returning an error response.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5d90138ad1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| pub fn resume_command(thread_name: Option<&str>, thread_id: Option<ThreadId>) -> Option<String> { | ||
| let resume_target = thread_name | ||
| .filter(|name| !name.is_empty()) | ||
| .map(str::to_string) | ||
| .or_else(|| thread_id.map(|thread_id| thread_id.to_string())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard resume hints against UUID-looking thread names
Because resume_command always prefers thread_name, a thread renamed to something that parses as a UUID will produce a hint like codex resume <name>. Both TUI and exec resume resolution treat UUID-looking strings as IDs (Uuid::parse_str branches in tui/src/lib.rs and exec/src/lib.rs), so that hint will resume a different thread or fail if the UUID doesn’t exist. Consider falling back to the actual thread_id when the name parses as a UUID (and doesn’t match the thread’s id), or add an explicit disambiguation flag for name-based resume.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 38b9d8bdb0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| self.personality_command_enabled, | ||
| self.windows_degraded_sandbox_active, | ||
| ) | ||
| && cmd == SlashCommand::Review | ||
| && matches!(cmd, SlashCommand::Review | SlashCommand::Rename) | ||
| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update chat composer docs for new /rename arg handling
This change expands the chat-composer command-with-args path to include /rename, which modifies the state machine behavior. Per codex-rs/tui/src/bottom_pane/AGENTS.md, any chat-composer state-machine change must be reflected in the module docs and docs/tui-chat-composer.md. Those docs were not updated here, so the documented slash-command dispatch behavior is now out of sync and will be misleading to future maintainers. Please sync the docs with the new /rename handling.
Useful? React with 👍 / 👎.
…ession-naming-clean
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 68997282f5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| self.outgoing | ||
| .send_response(request_id, ThreadSetNameResponse {}) | ||
| .await; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Return an error when rename fails in core
The thread/name/set handler sends a success response immediately after enqueueing Op::SetThreadName, but the core handler can still fail later (e.g., persistence disabled or session_index.jsonl write errors) and emits an Error event instead of a ThreadNameUpdated event (see codex-rs/core/src/codex.rs around the set_thread_name error branches). In those cases clients get {} even though the rename didn’t persist, so UIs may update state incorrectly unless they separately watch for error notifications. Consider waiting for a ThreadNameUpdated/Error event to reply, or pre-check persistence and IO failures so the RPC response accurately reflects success.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e021ed2627
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let is_uuid = Uuid::parse_str(id_str).is_ok(); | ||
| let path = if is_uuid { | ||
| find_thread_path_by_id_str(&config.codex_home, id_str).await? | ||
| } else { | ||
| find_thread_path_by_name_str(&config.codex_home, id_str).await? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid UUID-like thread names breaking name resume
Because resume selection treats any argument that parses as a UUID as an ID (Uuid::parse_str branch here), a user can rename a thread to a UUID-like string and then be unable to resume it by name (the lookup never reaches find_thread_path_by_name_str, and the printed codex resume <name> hint will resolve by ID instead). This only shows up when the chosen name parses as a UUID, but it makes the new rename feature unreliable in that case and can even resume the wrong thread if that UUID exists. Consider rejecting UUID-like names on rename or falling back to name lookup when the UUID path isn’t found.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e7abfec081
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| self.outgoing | ||
| .send_response(request_id, ThreadSetNameResponse {}) | ||
| .await; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don’t acknowledge rename before it succeeds
The app-server replies success immediately after enqueuing Op::SetThreadName, but the actual rename can still fail later (e.g., session persistence disabled or I/O error appending the session index in codex-rs/core/src/codex.rs around the set_thread_name handler). In those cases the client will already have received {} as a success response even though an Error event is emitted and the name is not updated, which can leave the UI/state inconsistent. Consider deferring the response until a ThreadNameUpdated event arrives for this request, or translating the failure Error into a request error response.
Useful? React with 👍 / 👎.
| pub fn resume_command(thread_name: Option<&str>, thread_id: Option<ThreadId>) -> Option<String> { | ||
| let resume_target = thread_name | ||
| .filter(|name| !name.is_empty()) | ||
| .map(str::to_string) | ||
| .or_else(|| thread_id.map(|thread_id| thread_id.to_string())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid suggesting resume-by-name for UUID-like names
resume_command always prefers thread_name over thread_id, but the CLI/TUI resume logic treats any UUID-parsing string as an ID (Uuid::parse_str in codex-rs/tui/src/lib.rs around the resume/fork path selection). If a user renames a thread to a UUID-looking string, the resume hint will suggest codex resume <name>, but the CLI will interpret it as an ID and either resume the wrong session or fail if that ID doesn’t exist. You may want to detect UUID-looking names and fall back to the actual thread_id (or disallow such names) so the hint matches the real resume behavior.
Useful? React with 👍 / 👎.

Session renaming:
/rename my_session/renamewithout arg and passing an argument incustomViewPromptCODEX_HOME/sessions.jsonlSession resuming:
CODEX_HOME/sessions.jsonlfirst entry matching the name and resumes the session