mirror of
https://github.com/aaif-goose/goose.git
synced 2026-07-03 14:10:03 +02:00
fix(summon): stop MOIM from telling models to sleep while waiting for tasks (#7377)
Signed-off-by: rabi <ramishra@redhat.com>
This commit is contained in:
@@ -330,10 +330,12 @@ impl SummonClient {
|
||||
"Load knowledge into your current context or discover available sources.\n\n\
|
||||
Call with no arguments to list all available sources (subrecipes, recipes, skills, agents).\n\
|
||||
Call with a source name to load its content into your context.\n\
|
||||
For background tasks: load(source: \"task_id\", cancel: true) stops and returns output.\n\n\
|
||||
For background tasks: load(source: \"task_id\") waits for the task and returns the result.\n\
|
||||
To cancel a running task: load(source: \"task_id\", cancel: true) stops and returns output.\n\n\
|
||||
Examples:\n\
|
||||
- load() → Lists available sources\n\
|
||||
- load(source: \"rust-patterns\") → Loads the rust-patterns skill"
|
||||
- load(source: \"rust-patterns\") → Loads the rust-patterns skill\n\
|
||||
- load(source: \"20260219_1\") → Waits for background task, then returns result"
|
||||
.to_string(),
|
||||
schema.as_object().unwrap().clone(),
|
||||
)
|
||||
@@ -880,7 +882,7 @@ impl SummonClient {
|
||||
|
||||
// Wait for the running task to complete, keeping the tool call
|
||||
// alive so notifications (subagent tool calls) stream in real time.
|
||||
let task = running.remove(task_id).unwrap();
|
||||
let mut task = running.remove(task_id).unwrap();
|
||||
drop(running);
|
||||
|
||||
let buffered = {
|
||||
@@ -896,45 +898,37 @@ impl SummonClient {
|
||||
}
|
||||
}
|
||||
|
||||
let description = task.description.clone();
|
||||
let mut handle = task.handle;
|
||||
|
||||
let (output, timed_out) = tokio::select! {
|
||||
result = &mut handle => {
|
||||
let s = match result {
|
||||
tokio::select! {
|
||||
result = &mut task.handle => {
|
||||
let output = match result {
|
||||
Ok(Ok(s)) => s,
|
||||
Ok(Err(e)) => format!("Error: {}", e),
|
||||
Err(e) => format!("Task panicked: {}", e),
|
||||
};
|
||||
(s, false)
|
||||
|
||||
return Ok(vec![Content::text(format!(
|
||||
"# Background Task Result: {}\n\n\
|
||||
**Task:** {}\n\
|
||||
**Status:** ✓ Completed\n\
|
||||
**Duration:** {} ({} turns)\n\n\
|
||||
## Output\n\n{}",
|
||||
task_id,
|
||||
task.description,
|
||||
round_duration(task.started_at.elapsed()),
|
||||
task.turns.load(Ordering::Relaxed),
|
||||
output
|
||||
))]);
|
||||
}
|
||||
_ = tokio::time::sleep(Duration::from_secs(300)) => {
|
||||
handle.abort();
|
||||
("Task timed out waiting for completion (aborted after 5 min)".to_string(), true)
|
||||
self.background_tasks.lock().await.insert(task_id.to_string(), task);
|
||||
|
||||
return Err(format!(
|
||||
"Task '{task_id}' is still running after waiting 5 min. \
|
||||
Use load(source: \"{task_id}\") to wait again, or \
|
||||
load(source: \"{task_id}\", cancel: true) to stop."
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let duration = task.started_at.elapsed();
|
||||
let turns_taken = task.turns.load(Ordering::Relaxed);
|
||||
let status = if timed_out {
|
||||
"⏱ Timed out"
|
||||
} else {
|
||||
"✓ Completed"
|
||||
};
|
||||
|
||||
return Ok(vec![Content::text(format!(
|
||||
"# Background Task Result: {}\n\n\
|
||||
**Task:** {}\n\
|
||||
**Status:** {}\n\
|
||||
**Duration:** {} ({} turns)\n\n\
|
||||
## Output\n\n{}",
|
||||
task_id,
|
||||
description,
|
||||
status,
|
||||
round_duration(duration),
|
||||
turns_taken,
|
||||
output
|
||||
))]);
|
||||
}
|
||||
}
|
||||
|
||||
Err(format!("Task '{}' not found.", task_id))
|
||||
@@ -1628,7 +1622,8 @@ impl SummonClient {
|
||||
.insert(task_id.clone(), task);
|
||||
|
||||
Ok(vec![Content::text(format!(
|
||||
"Task {} started in background: \"{}\"\nUse load(source: \"{}\") to wait for the result (it will block until complete).",
|
||||
"Task {} started in background: \"{}\"\n\
|
||||
Continue with other work. When you need the result, use load(source: \"{}\").",
|
||||
task_id, description, task_id
|
||||
))])
|
||||
}
|
||||
@@ -1714,8 +1709,6 @@ impl McpClientTrait for SummonClient {
|
||||
let mut lines = vec!["Background tasks:".to_string()];
|
||||
let now = current_epoch_millis();
|
||||
|
||||
let mut shortest_elapsed_secs: Option<u64> = None;
|
||||
|
||||
let mut sorted_running: Vec<_> = running.values().collect();
|
||||
sorted_running.sort_by_key(|t| &t.id);
|
||||
|
||||
@@ -1723,10 +1716,6 @@ impl McpClientTrait for SummonClient {
|
||||
let elapsed = task.started_at.elapsed();
|
||||
let idle_ms = now.saturating_sub(task.last_activity.load(Ordering::Relaxed));
|
||||
|
||||
let elapsed_secs = elapsed.as_secs();
|
||||
shortest_elapsed_secs =
|
||||
Some(shortest_elapsed_secs.map_or(elapsed_secs, |s| s.min(elapsed_secs)));
|
||||
|
||||
lines.push(format!(
|
||||
"• {}: \"{}\" - running {}, {} turns, idle {}",
|
||||
task.id,
|
||||
@@ -1757,12 +1746,11 @@ impl McpClientTrait for SummonClient {
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(shortest) = shortest_elapsed_secs {
|
||||
let sleep_secs = 300u64.saturating_sub(shortest).max(10);
|
||||
lines.push(format!(
|
||||
"\n→ sleep {} to wait, or load(source: \"id\", cancel: true) to stop",
|
||||
sleep_secs
|
||||
));
|
||||
if !running.is_empty() {
|
||||
lines.push(
|
||||
"\n→ Use load(source: \"<id>\") to wait for a task, or load(source: \"<id>\", cancel: true) to stop it"
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
Some(lines.join("\n"))
|
||||
|
||||
Reference in New Issue
Block a user