feat: sub-agent streaming progress — TaskTool emits real-time status events
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

- Rust: LoopEvent::SubtaskStatus variant added to loop_runner.rs
- Rust: ToolContext.event_sender field for streaming tool progress
- Rust: TaskTool emits started/running/completed/failed via event_sender
- Rust: StreamChatEvent::SubtaskStatus mapped in Tauri chat command
- TS: StreamEventSubtaskStatus type + onSubtaskStatus callback added
- TS: kernel-chat.ts handles subtaskStatus event from Tauri
- TS: streamStore.ts wires callback, maps backend→frontend status,
  updates assistant message subtasks array in real-time
This commit is contained in:
iven
2026-04-06 13:05:37 +08:00
parent 15a1849255
commit 9871c254be
7 changed files with 116 additions and 1 deletions

View File

@@ -4,9 +4,11 @@ use std::collections::HashMap;
use std::sync::Arc;
use async_trait::async_trait;
use serde_json::Value;
use tokio::sync::mpsc;
use zclaw_types::{AgentId, Result};
use crate::driver::ToolDefinition;
use crate::loop_runner::LoopEvent;
use crate::tool::builtin::PathValidator;
/// Tool trait for implementing agent tools
@@ -80,6 +82,9 @@ pub struct ToolContext {
pub skill_executor: Option<Arc<dyn SkillExecutor>>,
/// Path validator for file system operations
pub path_validator: Option<PathValidator>,
/// Optional event sender for streaming tool progress to the frontend.
/// Tools like TaskTool use this to emit sub-agent status events.
pub event_sender: Option<mpsc::Sender<LoopEvent>>,
}
impl std::fmt::Debug for ToolContext {
@@ -90,6 +95,7 @@ impl std::fmt::Debug for ToolContext {
.field("session_id", &self.session_id)
.field("skill_executor", &self.skill_executor.as_ref().map(|_| "SkillExecutor"))
.field("path_validator", &self.path_validator.as_ref().map(|_| "PathValidator"))
.field("event_sender", &self.event_sender.as_ref().map(|_| "Sender<LoopEvent>"))
.finish()
}
}
@@ -102,6 +108,7 @@ impl Clone for ToolContext {
session_id: self.session_id.clone(),
skill_executor: self.skill_executor.clone(),
path_validator: self.path_validator.clone(),
event_sender: self.event_sender.clone(),
}
}
}