fix: 子智能体执行路径发布带 subagent_task_id 的完成/错误事件
在 runtime.rs 新增 build_subagent_event_metadata/publish_subagent_completion/publish_subagent_error 函数,在 spawn/resume 的 Ok/Err 分支发布带 subagent_task_id=session.id 的 ExecutionCompleted/ErrorNotification 事件。 load_task_messages.rs 的 reconstruct_task_from_db 硬编码 Completed 加 TODO 注释,记录 DB 重建无法可靠推断 task 状态的已知缺陷。 Spec: fix-subagent-message-refresh-on-exit (Task 1.4, 9)
This commit is contained in:
parent
61c2fca2a7
commit
b4b7c5a208
@ -158,6 +158,8 @@ fn reconstruct_task_from_db(
|
|||||||
parent_channel_name: record.channel_name.clone(),
|
parent_channel_name: record.channel_name.clone(),
|
||||||
description,
|
description,
|
||||||
subagent_type,
|
subagent_type,
|
||||||
|
// TODO: DB 重建时无法可靠推断 task 状态,暂硬编码为 Completed。
|
||||||
|
// 实际 failed/timeout 的子智能体会被错误显示为 completed,需独立跟进。
|
||||||
state: TaskSessionState::Completed,
|
state: TaskSessionState::Completed,
|
||||||
created_at: record.created_at,
|
created_at: record.created_at,
|
||||||
updated_at: now,
|
updated_at: now,
|
||||||
|
|||||||
@ -279,6 +279,63 @@ impl SubAgentEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 构建子智能体事件的基础 metadata,与 SubAgentEmitter 注入的字段保持一致。
|
||||||
|
fn build_subagent_event_metadata(session: &TaskSession) -> HashMap<String, String> {
|
||||||
|
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<Arc<MessageBus>>,
|
||||||
|
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<Arc<MessageBus>>,
|
||||||
|
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 {
|
impl SystemPromptProvider for StaticSystemPromptProvider {
|
||||||
fn build(&self, _context: &SystemPromptContext) -> Option<SystemPrompt> {
|
fn build(&self, _context: &SystemPromptContext) -> Option<SystemPrompt> {
|
||||||
Some(SystemPrompt {
|
Some(SystemPrompt {
|
||||||
@ -633,6 +690,8 @@ impl SubAgentRuntime for DefaultSubAgentRuntime {
|
|||||||
"Task completed, updating session"
|
"Task completed, updating session"
|
||||||
);
|
);
|
||||||
self.task_repository.save_task_session(&session).await?;
|
self.task_repository.save_task_session(&session).await?;
|
||||||
|
// 发布子智能体 ExecutionCompleted,metadata 注入 subagent_task_id 供前端路由到对应子智能体层
|
||||||
|
publish_subagent_completion(&self.bus, &session).await;
|
||||||
Ok(tool_result)
|
Ok(tool_result)
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -651,6 +710,8 @@ impl SubAgentRuntime for DefaultSubAgentRuntime {
|
|||||||
session.mark_failed(e.to_string());
|
session.mark_failed(e.to_string());
|
||||||
}
|
}
|
||||||
self.task_repository.save_task_session(&session).await?;
|
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)
|
Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -709,12 +770,16 @@ impl SubAgentRuntime for DefaultSubAgentRuntime {
|
|||||||
let mut session = session;
|
let mut session = session;
|
||||||
session.mark_completed(tool_result.summary.clone());
|
session.mark_completed(tool_result.summary.clone());
|
||||||
self.task_repository.save_task_session(&session).await?;
|
self.task_repository.save_task_session(&session).await?;
|
||||||
|
// 发布子智能体 ExecutionCompleted,metadata 注入 subagent_task_id 供前端路由到对应子智能体层
|
||||||
|
publish_subagent_completion(&self.bus, &session).await;
|
||||||
Ok(tool_result)
|
Ok(tool_result)
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let mut session = session;
|
let mut session = session;
|
||||||
session.mark_failed(e.to_string());
|
session.mark_failed(e.to_string());
|
||||||
self.task_repository.save_task_session(&session).await?;
|
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)
|
Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user