enable-resume (#3537)
Adding the ability to resume conversations. we have one verb `resume`. Behavior: `tui`: `codex resume`: opens session picker `codex resume --last`: continue last message `codex resume <session id>`: continue conversation with `session id` `exec`: `codex resume --last`: continue last conversation `codex resume <session id>`: continue conversation with `session id` Implementation: - I added a function to find the path in `~/.codex/sessions/` with a `UUID`. This is helpful in resuming with session id. - Added the above mentioned flags - Added lots of testing
This commit is contained in:
@@ -13,35 +13,18 @@ pub struct Cli {
|
||||
#[arg(long = "image", short = 'i', value_name = "FILE", value_delimiter = ',', num_args = 1..)]
|
||||
pub images: Vec<PathBuf>,
|
||||
|
||||
/// Open an interactive picker to resume a previous session recorded on disk
|
||||
/// instead of starting a new one.
|
||||
///
|
||||
/// Notes:
|
||||
/// - Mutually exclusive with `--continue`.
|
||||
/// - The picker displays recent sessions and a preview of the first real user
|
||||
/// message to help you select the right one.
|
||||
#[arg(
|
||||
long = "resume",
|
||||
default_value_t = false,
|
||||
conflicts_with = "continue",
|
||||
hide = true
|
||||
)]
|
||||
pub resume: bool,
|
||||
// Internal controls set by the top-level `codex resume` subcommand.
|
||||
// These are not exposed as user flags on the base `codex` command.
|
||||
#[clap(skip)]
|
||||
pub resume_picker: bool,
|
||||
|
||||
/// Continue the most recent conversation without showing the picker.
|
||||
///
|
||||
/// Notes:
|
||||
/// - Mutually exclusive with `--resume`.
|
||||
/// - If no recorded sessions are found, this behaves like starting fresh.
|
||||
/// - Equivalent to picking the newest item in the resume picker.
|
||||
#[arg(
|
||||
id = "continue",
|
||||
long = "continue",
|
||||
default_value_t = false,
|
||||
conflicts_with = "resume",
|
||||
hide = true
|
||||
)]
|
||||
pub r#continue: bool,
|
||||
#[clap(skip)]
|
||||
pub resume_last: bool,
|
||||
|
||||
/// Internal: resume a specific recorded session by id (UUID). Set by the
|
||||
/// top-level `codex resume <SESSION_ID>` wrapper; not exposed as a public flag.
|
||||
#[clap(skip)]
|
||||
pub resume_session_id: Option<String>,
|
||||
|
||||
/// Model the agent should use.
|
||||
#[arg(long, short = 'm')]
|
||||
|
||||
@@ -15,6 +15,7 @@ use codex_core::config::SWIFTFOX_MEDIUM_MODEL;
|
||||
use codex_core::config::find_codex_home;
|
||||
use codex_core::config::load_config_as_toml_with_cli_overrides;
|
||||
use codex_core::config::persist_model_selection;
|
||||
use codex_core::find_conversation_path_by_id_str;
|
||||
use codex_core::protocol::AskForApproval;
|
||||
use codex_core::protocol::SandboxPolicy;
|
||||
use codex_ollama::DEFAULT_OSS_MODEL;
|
||||
@@ -343,7 +344,16 @@ async fn run_ratatui_app(
|
||||
}
|
||||
}
|
||||
|
||||
let resume_selection = if cli.r#continue {
|
||||
// Determine resume behavior: explicit id, then resume last, then picker.
|
||||
let resume_selection = if let Some(id_str) = cli.resume_session_id.as_deref() {
|
||||
match find_conversation_path_by_id_str(&config.codex_home, id_str).await? {
|
||||
Some(path) => resume_picker::ResumeSelection::Resume(path),
|
||||
None => {
|
||||
error!("Error finding conversation path: {id_str}");
|
||||
resume_picker::ResumeSelection::StartFresh
|
||||
}
|
||||
}
|
||||
} else if cli.resume_last {
|
||||
match RolloutRecorder::list_conversations(&config.codex_home, 1, None).await {
|
||||
Ok(page) => page
|
||||
.items
|
||||
@@ -352,7 +362,7 @@ async fn run_ratatui_app(
|
||||
.unwrap_or(resume_picker::ResumeSelection::StartFresh),
|
||||
Err(_) => resume_picker::ResumeSelection::StartFresh,
|
||||
}
|
||||
} else if cli.resume {
|
||||
} else if cli.resume_picker {
|
||||
match resume_picker::run_resume_picker(&mut tui, &config.codex_home).await? {
|
||||
resume_picker::ResumeSelection::Exit => {
|
||||
restore();
|
||||
|
||||
Reference in New Issue
Block a user