Mnovich/temporal foreground tasks (#2895)
Co-authored-by: Carlos M. Lopez <carlopez@squareup.com>
This commit is contained in:
@@ -28,6 +28,7 @@ tokio = { version = "1.43", features = ["full"] }
|
||||
futures = "0.3"
|
||||
serde = { version = "1.0", features = ["derive"] } # For serialization
|
||||
serde_yaml = "0.9"
|
||||
tempfile = "3"
|
||||
etcetera = "0.8.0"
|
||||
reqwest = { version = "0.12.9", features = [
|
||||
"rustls-tls-native-roots",
|
||||
|
||||
@@ -509,6 +509,16 @@ enum Command {
|
||||
help = "Quiet mode. Suppress non-response output, printing only the model response to stdout"
|
||||
)]
|
||||
quiet: bool,
|
||||
|
||||
/// Scheduled job ID (used internally for scheduled executions)
|
||||
#[arg(
|
||||
long = "scheduled-job-id",
|
||||
value_name = "ID",
|
||||
help = "ID of the scheduled job that triggered this execution (internal use)",
|
||||
long_help = "Internal parameter used when this run command is executed by a scheduled job. This associates the session with the schedule for tracking purposes.",
|
||||
hide = true
|
||||
)]
|
||||
scheduled_job_id: Option<String>,
|
||||
},
|
||||
|
||||
/// Recipe utilities for validation and deeplinking
|
||||
@@ -662,6 +672,7 @@ pub async fn cli() -> Result<()> {
|
||||
settings: None,
|
||||
debug,
|
||||
max_tool_repetitions,
|
||||
scheduled_job_id: None,
|
||||
interactive: true,
|
||||
quiet: false,
|
||||
})
|
||||
@@ -709,6 +720,7 @@ pub async fn cli() -> Result<()> {
|
||||
params,
|
||||
explain,
|
||||
render_recipe,
|
||||
scheduled_job_id,
|
||||
quiet,
|
||||
}) => {
|
||||
let (input_config, session_settings) = match (
|
||||
@@ -808,6 +820,7 @@ pub async fn cli() -> Result<()> {
|
||||
settings: session_settings,
|
||||
debug,
|
||||
max_tool_repetitions,
|
||||
scheduled_job_id,
|
||||
interactive, // Use the interactive flag from the Run command
|
||||
quiet,
|
||||
})
|
||||
@@ -925,6 +938,7 @@ pub async fn cli() -> Result<()> {
|
||||
settings: None::<SessionSettings>,
|
||||
debug: false,
|
||||
max_tool_repetitions: None,
|
||||
scheduled_job_id: None,
|
||||
interactive: true, // Default case is always interactive
|
||||
quiet: false,
|
||||
})
|
||||
|
||||
@@ -44,6 +44,7 @@ pub async fn agent_generator(
|
||||
debug: false,
|
||||
max_tool_repetitions: None,
|
||||
interactive: false, // Benchmarking is non-interactive
|
||||
scheduled_job_id: None,
|
||||
quiet: false,
|
||||
})
|
||||
.await;
|
||||
|
||||
@@ -99,6 +99,7 @@ pub async fn handle_schedule_add(
|
||||
paused: false,
|
||||
current_session_id: None,
|
||||
process_start_time: None,
|
||||
execution_mode: Some("background".to_string()), // Default to background for CLI
|
||||
};
|
||||
|
||||
let scheduler_storage_path =
|
||||
|
||||
@@ -464,6 +464,7 @@ async fn process_message_streaming(
|
||||
id: session::Identifier::Path(session_file.clone()),
|
||||
working_dir: std::env::current_dir()?,
|
||||
schedule_id: None,
|
||||
execution_mode: None,
|
||||
};
|
||||
|
||||
// Get response from agent
|
||||
|
||||
@@ -40,6 +40,8 @@ pub struct SessionBuilderConfig {
|
||||
pub debug: bool,
|
||||
/// Maximum number of consecutive identical tool calls allowed
|
||||
pub max_tool_repetitions: Option<u32>,
|
||||
/// ID of the scheduled job that triggered this session (if any)
|
||||
pub scheduled_job_id: Option<String>,
|
||||
/// Whether this session will be used interactively (affects debugging prompts)
|
||||
pub interactive: bool,
|
||||
/// Quiet mode - suppress non-response output
|
||||
@@ -115,7 +117,7 @@ async fn offer_extension_debugging_help(
|
||||
std::env::temp_dir().join(format!("goose_debug_extension_{}.jsonl", extension_name));
|
||||
|
||||
// Create the debugging session
|
||||
let mut debug_session = Session::new(debug_agent, temp_session_file.clone(), false);
|
||||
let mut debug_session = Session::new(debug_agent, temp_session_file.clone(), false, None);
|
||||
|
||||
// Process the debugging request
|
||||
println!("{}", style("Analyzing the extension failure...").yellow());
|
||||
@@ -341,7 +343,12 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> Session {
|
||||
}
|
||||
|
||||
// Create new session
|
||||
let mut session = Session::new(agent, session_file.clone(), session_config.debug);
|
||||
let mut session = Session::new(
|
||||
agent,
|
||||
session_file.clone(),
|
||||
session_config.debug,
|
||||
session_config.scheduled_job_id.clone(),
|
||||
);
|
||||
|
||||
// Add extensions if provided
|
||||
for extension_str in session_config.extensions {
|
||||
@@ -490,6 +497,7 @@ mod tests {
|
||||
settings: None,
|
||||
debug: true,
|
||||
max_tool_repetitions: Some(5),
|
||||
scheduled_job_id: None,
|
||||
interactive: true,
|
||||
quiet: false,
|
||||
};
|
||||
@@ -499,6 +507,7 @@ mod tests {
|
||||
assert_eq!(config.builtins.len(), 1);
|
||||
assert!(config.debug);
|
||||
assert_eq!(config.max_tool_repetitions, Some(5));
|
||||
assert!(config.scheduled_job_id.is_none());
|
||||
assert!(config.interactive);
|
||||
assert!(!config.quiet);
|
||||
}
|
||||
@@ -517,6 +526,7 @@ mod tests {
|
||||
assert!(config.additional_system_prompt.is_none());
|
||||
assert!(!config.debug);
|
||||
assert!(config.max_tool_repetitions.is_none());
|
||||
assert!(config.scheduled_job_id.is_none());
|
||||
assert!(!config.interactive);
|
||||
assert!(!config.quiet);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ pub struct Session {
|
||||
completion_cache: Arc<std::sync::RwLock<CompletionCache>>,
|
||||
debug: bool, // New field for debug mode
|
||||
run_mode: RunMode,
|
||||
scheduled_job_id: Option<String>, // ID of the scheduled job that triggered this session
|
||||
}
|
||||
|
||||
// Cache structure for completion data
|
||||
@@ -107,7 +108,12 @@ pub async fn classify_planner_response(
|
||||
}
|
||||
|
||||
impl Session {
|
||||
pub fn new(agent: Agent, session_file: PathBuf, debug: bool) -> Self {
|
||||
pub fn new(
|
||||
agent: Agent,
|
||||
session_file: PathBuf,
|
||||
debug: bool,
|
||||
scheduled_job_id: Option<String>,
|
||||
) -> Self {
|
||||
let messages = match session::read_messages(&session_file) {
|
||||
Ok(msgs) => msgs,
|
||||
Err(e) => {
|
||||
@@ -123,6 +129,7 @@ impl Session {
|
||||
completion_cache: Arc::new(std::sync::RwLock::new(CompletionCache::new())),
|
||||
debug,
|
||||
run_mode: RunMode::Normal,
|
||||
scheduled_job_id,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,7 +314,13 @@ impl Session {
|
||||
let provider = self.agent.provider().await?;
|
||||
|
||||
// Persist messages with provider for automatic description generation
|
||||
session::persist_messages(&self.session_file, &self.messages, Some(provider)).await?;
|
||||
session::persist_messages_with_schedule_id(
|
||||
&self.session_file,
|
||||
&self.messages,
|
||||
Some(provider),
|
||||
self.scheduled_job_id.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Track the current directory and last instruction in projects.json
|
||||
let session_id = self
|
||||
@@ -413,10 +426,11 @@ impl Session {
|
||||
let provider = self.agent.provider().await?;
|
||||
|
||||
// Persist messages with provider for automatic description generation
|
||||
session::persist_messages(
|
||||
session::persist_messages_with_schedule_id(
|
||||
&self.session_file,
|
||||
&self.messages,
|
||||
Some(provider),
|
||||
self.scheduled_job_id.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -600,10 +614,11 @@ impl Session {
|
||||
self.messages = summarized_messages;
|
||||
|
||||
// Persist the summarized messages
|
||||
session::persist_messages(
|
||||
session::persist_messages_with_schedule_id(
|
||||
&self.session_file,
|
||||
&self.messages,
|
||||
Some(provider),
|
||||
self.scheduled_job_id.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -727,7 +742,8 @@ impl Session {
|
||||
id: session_id.clone(),
|
||||
working_dir: std::env::current_dir()
|
||||
.expect("failed to get current session working directory"),
|
||||
schedule_id: None,
|
||||
schedule_id: self.scheduled_job_id.clone(),
|
||||
execution_mode: None,
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
@@ -776,7 +792,7 @@ impl Session {
|
||||
Err(ToolError::ExecutionError("Tool call cancelled by user".to_string()))
|
||||
));
|
||||
self.messages.push(response_message);
|
||||
session::persist_messages(&self.session_file, &self.messages, None).await?;
|
||||
session::persist_messages_with_schedule_id(&self.session_file, &self.messages, None, self.scheduled_job_id.clone()).await?;
|
||||
|
||||
drop(stream);
|
||||
break;
|
||||
@@ -862,7 +878,8 @@ impl Session {
|
||||
id: session_id.clone(),
|
||||
working_dir: std::env::current_dir()
|
||||
.expect("failed to get current session working directory"),
|
||||
schedule_id: None,
|
||||
schedule_id: self.scheduled_job_id.clone(),
|
||||
execution_mode: None,
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
@@ -872,7 +889,7 @@ impl Session {
|
||||
self.messages.push(message.clone());
|
||||
|
||||
// No need to update description on assistant messages
|
||||
session::persist_messages(&self.session_file, &self.messages, None).await?;
|
||||
session::persist_messages_with_schedule_id(&self.session_file, &self.messages, None, self.scheduled_job_id.clone()).await?;
|
||||
|
||||
if interactive {output::hide_thinking()};
|
||||
let _ = progress_bars.hide();
|
||||
@@ -1006,7 +1023,13 @@ impl Session {
|
||||
self.messages.push(response_message);
|
||||
|
||||
// No need for description update here
|
||||
session::persist_messages(&self.session_file, &self.messages, None).await?;
|
||||
session::persist_messages_with_schedule_id(
|
||||
&self.session_file,
|
||||
&self.messages,
|
||||
None,
|
||||
self.scheduled_job_id.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let prompt = format!(
|
||||
"The existing call to {} was interrupted. How would you like to proceed?",
|
||||
@@ -1015,7 +1038,13 @@ impl Session {
|
||||
self.messages.push(Message::assistant().with_text(&prompt));
|
||||
|
||||
// No need for description update here
|
||||
session::persist_messages(&self.session_file, &self.messages, None).await?;
|
||||
session::persist_messages_with_schedule_id(
|
||||
&self.session_file,
|
||||
&self.messages,
|
||||
None,
|
||||
self.scheduled_job_id.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
output::render_message(&Message::assistant().with_text(&prompt), self.debug);
|
||||
} else {
|
||||
@@ -1029,8 +1058,13 @@ impl Session {
|
||||
self.messages.push(Message::assistant().with_text(prompt));
|
||||
|
||||
// No need for description update here
|
||||
session::persist_messages(&self.session_file, &self.messages, None)
|
||||
.await?;
|
||||
session::persist_messages_with_schedule_id(
|
||||
&self.session_file,
|
||||
&self.messages,
|
||||
None,
|
||||
self.scheduled_job_id.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
output::render_message(
|
||||
&Message::assistant().with_text(prompt),
|
||||
|
||||
Reference in New Issue
Block a user