fix: ensure execution task result is shown (#3629)
This commit is contained in:
@@ -42,6 +42,7 @@ use crate::providers::errors::ProviderError;
|
|||||||
use crate::recipe::{Author, Recipe, Response, Settings, SubRecipe};
|
use crate::recipe::{Author, Recipe, Response, Settings, SubRecipe};
|
||||||
use crate::scheduler_trait::SchedulerTrait;
|
use crate::scheduler_trait::SchedulerTrait;
|
||||||
use crate::tool_monitor::{ToolCall, ToolMonitor};
|
use crate::tool_monitor::{ToolCall, ToolMonitor};
|
||||||
|
use crate::utils::is_token_cancelled;
|
||||||
use mcp_core::{protocol::GetPromptResult, ToolError, ToolResult};
|
use mcp_core::{protocol::GetPromptResult, ToolError, ToolResult};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rmcp::model::Tool;
|
use rmcp::model::Tool;
|
||||||
@@ -742,7 +743,7 @@ impl Agent {
|
|||||||
});
|
});
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if cancel_token.as_ref().is_some_and(|t| t.is_cancelled()) {
|
if is_token_cancelled(&cancel_token) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -778,7 +779,7 @@ impl Agent {
|
|||||||
let mut tools_updated = false;
|
let mut tools_updated = false;
|
||||||
|
|
||||||
while let Some(next) = stream.next().await {
|
while let Some(next) = stream.next().await {
|
||||||
if cancel_token.as_ref().is_some_and(|t| t.is_cancelled()) {
|
if is_token_cancelled(&cancel_token) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -950,7 +951,7 @@ impl Agent {
|
|||||||
let mut all_install_successful = true;
|
let mut all_install_successful = true;
|
||||||
|
|
||||||
while let Some((request_id, item)) = combined.next().await {
|
while let Some((request_id, item)) = combined.next().await {
|
||||||
if cancel_token.as_ref().is_some_and(|t| t.is_cancelled()) {
|
if is_token_cancelled(&cancel_token) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
match item {
|
match item {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use rmcp::object;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::{mpsc, RwLock};
|
use tokio::sync::{mpsc, RwLock};
|
||||||
use tokio::time::{Duration, Instant};
|
use tokio::time::{sleep, Duration, Instant};
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
|
|
||||||
use crate::agents::subagent_execution_tool::notification_events::{
|
use crate::agents::subagent_execution_tool::notification_events::{
|
||||||
@@ -12,6 +12,7 @@ use crate::agents::subagent_execution_tool::notification_events::{
|
|||||||
};
|
};
|
||||||
use crate::agents::subagent_execution_tool::task_types::{Task, TaskInfo, TaskResult, TaskStatus};
|
use crate::agents::subagent_execution_tool::task_types::{Task, TaskInfo, TaskResult, TaskStatus};
|
||||||
use crate::agents::subagent_execution_tool::utils::{count_by_status, get_task_name};
|
use crate::agents::subagent_execution_tool::utils::{count_by_status, get_task_name};
|
||||||
|
use crate::utils::is_token_cancelled;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::mpsc::Sender;
|
||||||
|
|
||||||
@@ -22,6 +23,7 @@ pub enum DisplayMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const THROTTLE_INTERVAL_MS: u64 = 250;
|
const THROTTLE_INTERVAL_MS: u64 = 250;
|
||||||
|
const COMPLETION_NOTIFICATION_DELAY_MS: u64 = 500;
|
||||||
|
|
||||||
fn format_task_metadata(task_info: &TaskInfo) -> String {
|
fn format_task_metadata(task_info: &TaskInfo) -> String {
|
||||||
if let Some(params) = task_info.task.get_command_parameters() {
|
if let Some(params) = task_info.task.get_command_parameters() {
|
||||||
@@ -90,9 +92,7 @@ impl TaskExecutionTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_cancelled(&self) -> bool {
|
fn is_cancelled(&self) -> bool {
|
||||||
self.cancellation_token
|
is_token_cancelled(&self.cancellation_token)
|
||||||
.as_ref()
|
|
||||||
.is_some_and(|t| t.is_cancelled())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn log_notification_error(
|
fn log_notification_error(
|
||||||
@@ -299,7 +299,8 @@ impl TaskExecutionTracker {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let event = TaskExecutionNotificationEvent::tasks_complete(stats, failed_tasks);
|
let event = TaskExecutionNotificationEvent::tasks_complete(stats, failed_tasks);
|
||||||
|
|
||||||
self.try_send_notification(event, "tasks complete");
|
self.try_send_notification(event, "tasks complete");
|
||||||
|
// Wait for the notification to be recieved and displayed before clearing the tasks
|
||||||
|
sleep(Duration::from_millis(COMPLETION_NOTIFICATION_DELAY_MS)).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use tokio_util::sync::CancellationToken;
|
||||||
|
|
||||||
/// Safely truncate a string at character boundaries, not byte boundaries
|
/// Safely truncate a string at character boundaries, not byte boundaries
|
||||||
///
|
///
|
||||||
/// This function ensures that multi-byte UTF-8 characters (like Japanese, emoji, etc.)
|
/// This function ensures that multi-byte UTF-8 characters (like Japanese, emoji, etc.)
|
||||||
@@ -18,6 +20,12 @@ pub fn safe_truncate(s: &str, max_chars: usize) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_token_cancelled(cancellation_token: &Option<CancellationToken>) -> bool {
|
||||||
|
cancellation_token
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|t| t.is_cancelled())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
Reference in New Issue
Block a user