diff --git a/src/gateway/ws.rs b/src/gateway/ws.rs index f421fe8..7390f64 100644 --- a/src/gateway/ws.rs +++ b/src/gateway/ws.rs @@ -27,6 +27,8 @@ use crate::command::handlers::switch_topic::SwitchTopicCommandHandler; use crate::gateway::agent_prompt_provider::AgentPromptProvider; use crate::protocol::{WsInbound, WsOutbound, MediaSummary, parse_inbound, serialize_outbound}; use crate::skills::SkillPromptProvider; +use crate::tools::task::repository::TaskRepository; +use crate::tools::task::types::TaskSessionState; use axum::extract::State; use axum::extract::ws::{Message as WsMessage, WebSocket, WebSocketUpgrade}; use axum::response::Response; @@ -482,7 +484,7 @@ async fn handle_inbound( *current_topic_id = Some(topic_id.clone()); // 加载并发送该话题的历史消息 - if let Err(e) = send_topic_history(&store, current_session_id, topic_id, sender).await { + if let Err(e) = send_topic_history(&store, current_session_id, topic_id, sender, &state.task_repository).await { tracing::warn!(error = %e, topic_id = %topic_id, "Failed to send topic history"); } } @@ -586,7 +588,7 @@ async fn handle_inbound( if let Some(first_topic) = topics.first() { let topic_id = first_topic.topic_id.clone(); *current_topic_id = Some(topic_id.clone()); - if let Err(e) = send_topic_history(&store, current_session_id, &topic_id, sender).await { + if let Err(e) = send_topic_history(&store, current_session_id, &topic_id, sender, &state.task_repository).await { tracing::warn!(error = %e, topic_id = %topic_id, "Failed to send initial topic history"); } } @@ -641,6 +643,7 @@ async fn send_topic_history( session_id: &str, topic_id: &str, sender: &mpsc::Sender, + task_repository: &Arc, ) -> Result<(), Box> { // 加载话题消息,按 session_id 过滤,避免混入子智能体消息 let messages = store.load_messages_for_topic(topic_id, Some(session_id))?; @@ -654,6 +657,35 @@ async fn send_topic_history( } } + // 查询该话题下所有运行中的子智能体任务,补发 TaskStarted 事件 + // 解决页面刷新后 navigateToTaskId 丢失的问题 + let running_tasks = match task_repository.list_tasks_for_topic(topic_id).await { + Ok(tasks) => tasks, + Err(e) => { + tracing::warn!(error = %e, topic_id = %topic_id, "Failed to list tasks for topic"); + return Ok(()); + } + }; + + for task in running_tasks { + if task.state == TaskSessionState::Running { + tracing::info!( + task_id = %task.id, + description = %task.description, + "Re-sending TaskStarted for running task after topic history load" + ); + let _ = sender + .send(WsOutbound::TaskStarted { + task_id: task.id.clone(), + description: task.description.clone(), + subagent_type: task.subagent_type.clone(), + topic_id: Some(topic_id.to_string()), + parent_task_id: None, + }) + .await; + } + } + Ok(()) }