diff --git a/src/command/handlers/load_task_messages.rs b/src/command/handlers/load_task_messages.rs index 7115b0d..f44a2f2 100644 --- a/src/command/handlers/load_task_messages.rs +++ b/src/command/handlers/load_task_messages.rs @@ -158,6 +158,8 @@ fn reconstruct_task_from_db( parent_channel_name: record.channel_name.clone(), description, subagent_type, + // TODO: DB 重建时无法可靠推断 task 状态,暂硬编码为 Completed。 + // 实际 failed/timeout 的子智能体会被错误显示为 completed,需独立跟进。 state: TaskSessionState::Completed, created_at: record.created_at, updated_at: now, diff --git a/src/tools/task/runtime.rs b/src/tools/task/runtime.rs index 2e9109b..8580937 100644 --- a/src/tools/task/runtime.rs +++ b/src/tools/task/runtime.rs @@ -279,6 +279,63 @@ impl SubAgentEmitter { } } +/// 构建子智能体事件的基础 metadata,与 SubAgentEmitter 注入的字段保持一致。 +fn build_subagent_event_metadata(session: &TaskSession) -> HashMap { + let mut metadata = HashMap::new(); + metadata.insert("subagent_task_id".to_string(), session.id.clone()); + metadata.insert("is_subagent_event".to_string(), "true".to_string()); + metadata.insert( + "topic_id".to_string(), + session.parent_topic_id.clone().unwrap_or_default(), + ); + metadata +} + +/// 发布子智能体执行完成事件(ExecutionCompleted),metadata 含 subagent_task_id。 +async fn publish_subagent_completion( + bus: &Option>, + session: &TaskSession, +) { + if let Some(bus) = bus { + let metadata = build_subagent_event_metadata(session); + if let Err(e) = bus + .publish_outbound(OutboundMessage::execution_completed( + session.parent_channel_name.clone(), + session.parent_chat_id.clone(), + Some(session.parent_session_id.clone()), + metadata, + )) + .await + { + tracing::warn!(error = %e, task_id = %session.id, "Failed to publish subagent execution_completed"); + } + } +} + +/// 发布子智能体执行错误事件(ErrorNotification),metadata 含 subagent_task_id。 +async fn publish_subagent_error( + bus: &Option>, + session: &TaskSession, + error_msg: &str, +) { + if let Some(bus) = bus { + let metadata = build_subagent_event_metadata(session); + if let Err(e) = bus + .publish_outbound(OutboundMessage::error_notification( + session.parent_channel_name.clone(), + session.parent_chat_id.clone(), + Some(session.parent_session_id.clone()), + error_msg.to_string(), + None, + metadata, + )) + .await + { + tracing::warn!(error = %e, task_id = %session.id, "Failed to publish subagent error notification"); + } + } +} + impl SystemPromptProvider for StaticSystemPromptProvider { fn build(&self, _context: &SystemPromptContext) -> Option { Some(SystemPrompt { @@ -633,6 +690,8 @@ impl SubAgentRuntime for DefaultSubAgentRuntime { "Task completed, updating session" ); self.task_repository.save_task_session(&session).await?; + // 发布子智能体 ExecutionCompleted,metadata 注入 subagent_task_id 供前端路由到对应子智能体层 + publish_subagent_completion(&self.bus, &session).await; Ok(tool_result) } Err(e) => { @@ -651,6 +710,8 @@ impl SubAgentRuntime for DefaultSubAgentRuntime { session.mark_failed(e.to_string()); } self.task_repository.save_task_session(&session).await?; + // 发布子智能体 ErrorNotification,metadata 注入 subagent_task_id 供前端路由到对应子智能体层 + publish_subagent_error(&self.bus, &session, &e.to_string()).await; Err(e) } } @@ -709,12 +770,16 @@ impl SubAgentRuntime for DefaultSubAgentRuntime { let mut session = session; session.mark_completed(tool_result.summary.clone()); self.task_repository.save_task_session(&session).await?; + // 发布子智能体 ExecutionCompleted,metadata 注入 subagent_task_id 供前端路由到对应子智能体层 + publish_subagent_completion(&self.bus, &session).await; Ok(tool_result) } Err(e) => { let mut session = session; session.mark_failed(e.to_string()); self.task_repository.save_task_session(&session).await?; + // 发布子智能体 ErrorNotification,metadata 注入 subagent_task_id 供前端路由到对应子智能体层 + publish_subagent_error(&self.bus, &session, &e.to_string()).await; Err(e) } }