Add --resume <session-id> flag for explicit session resumption
- Add --resume CLI flag that conflicts with --new-session - Add load_continuation_by_id() to load sessions by full or partial ID - Support loading from latest.json or falling back to session.json - Handle --resume in both normal and agent modes - Agent mode validates session belongs to correct agent
This commit is contained in:
@@ -44,6 +44,25 @@ pub async fn run_agent_mode(
|
||||
// Skip session resume entirely when in chat mode (--agent --chat)
|
||||
let resuming_session = if chat {
|
||||
None // Chat mode always starts fresh
|
||||
} else if let Some(ref session_id) = flags.resume {
|
||||
// Explicit --resume flag takes precedence
|
||||
match g3_core::load_continuation_by_id(session_id) {
|
||||
Ok(continuation) => {
|
||||
// Verify the session matches this agent (or allow any if agent name matches)
|
||||
if continuation.agent_name.as_deref() != Some(agent_name) {
|
||||
eprintln!("Error: Session '{}' belongs to agent '{}', not '{}'",
|
||||
session_id,
|
||||
continuation.agent_name.as_deref().unwrap_or("(none)"),
|
||||
agent_name);
|
||||
std::process::exit(1);
|
||||
}
|
||||
Some(continuation)
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Error: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
} else if flags.new_session {
|
||||
if !chat {
|
||||
output.print("\n🆕 Starting new session (--new-session flag set)");
|
||||
|
||||
@@ -30,6 +30,8 @@ pub struct CommonFlags {
|
||||
pub acd: bool,
|
||||
/// Load a project from the given path at startup
|
||||
pub project: Option<PathBuf>,
|
||||
/// Resume a specific session by ID
|
||||
pub resume: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Parser, Clone)]
|
||||
@@ -136,6 +138,10 @@ pub struct Cli {
|
||||
#[arg(long)]
|
||||
pub new_session: bool,
|
||||
|
||||
/// Resume a specific session by ID (full or partial prefix)
|
||||
#[arg(long, value_name = "SESSION_ID", conflicts_with = "new_session")]
|
||||
pub resume: Option<String>,
|
||||
|
||||
/// Automatically remind LLM to call remember tool after turns with tool calls
|
||||
#[arg(long)]
|
||||
pub auto_memory: bool,
|
||||
@@ -172,6 +178,7 @@ impl Cli {
|
||||
no_auto_memory: self.no_auto_memory,
|
||||
acd: self.acd,
|
||||
project: self.project.clone(),
|
||||
resume: self.resume.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,13 +246,38 @@ async fn run_console_mode(
|
||||
agent.save_session_continuation(Some(result.response.clone()));
|
||||
Ok(())
|
||||
} else {
|
||||
// Handle --resume flag: load and restore specific session
|
||||
if let Some(ref session_id) = cli.resume {
|
||||
use crate::g3_status::{G3Status, Status};
|
||||
|
||||
match g3_core::load_continuation_by_id(session_id) {
|
||||
Ok(continuation) => {
|
||||
match agent.restore_from_continuation(&continuation) {
|
||||
Ok(true) => {
|
||||
G3Status::resuming(&continuation.session_id, Status::Done);
|
||||
}
|
||||
Ok(false) => {
|
||||
G3Status::resuming_summary(&continuation.session_id);
|
||||
}
|
||||
Err(e) => {
|
||||
G3Status::resuming(&continuation.session_id, Status::Error(e.to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Error: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
run_interactive(
|
||||
agent,
|
||||
cli.show_prompt,
|
||||
cli.show_code,
|
||||
combined_content,
|
||||
project.workspace(),
|
||||
cli.new_session,
|
||||
cli.new_session || cli.resume.is_some(), // Skip auto-resume prompt if --resume was used
|
||||
None, // agent_name (not in agent mode)
|
||||
initial_project,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user