fix(runtime,kernel): HandTool 空壳修复 — 桥接到 HandRegistry 真实执行
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

B-HAND-1 修复: LLM 调用 hand_quiz/hand_researcher 等 Hand 工具后,
HandTool::execute() 原来返回假成功 JSON, 实际 Hand 并不执行.

修复方案 (沿用 SkillExecutor 模式):
- tool.rs: 新增 HandExecutor trait + ToolContext.hand_executor 字段
- hand_tool.rs: execute() 通过 context.hand_executor 分发到真实执行
- loop_runner.rs: AgentLoop 新增 hand_executor 字段 + builder + 3处 ToolContext 传递
- adapters.rs: 新增 KernelHandExecutor 桥接 HandRegistry.execute()
- kernel/mod.rs: 初始化 KernelHandExecutor + 注册到 AgentLoop
- messaging.rs: 两处 AgentLoop 构建添加 .with_hand_executor()

数据流: LLM tool call → HandTool::execute() → ToolContext.hand_executor
         → KernelHandExecutor → HandRegistry.execute() → Hand trait impl

809 tests passed, 0 failed.
This commit is contained in:
iven
2026-04-20 12:50:47 +08:00
parent 3b97bc0746
commit f89b2263d1
8 changed files with 111 additions and 21 deletions

View File

@@ -3,11 +3,12 @@
use std::pin::Pin;
use std::sync::Arc;
use async_trait::async_trait;
use serde_json::Value;
use serde_json::{json, Value};
use zclaw_runtime::{LlmDriver, tool::SkillExecutor};
use zclaw_runtime::{LlmDriver, tool::{SkillExecutor, HandExecutor}};
use zclaw_skills::{SkillRegistry, LlmCompleter};
use zclaw_types::Result;
use zclaw_hands::HandRegistry;
use zclaw_types::{AgentId, Result};
/// Adapter that bridges `zclaw_runtime::LlmDriver` -> `zclaw_skills::LlmCompleter`
pub(crate) struct LlmDriverAdapter {
@@ -134,3 +135,47 @@ impl AgentInbox {
self.pending.push_back(envelope);
}
}
/// Hand executor implementation for Kernel
///
/// Bridges `zclaw_runtime::tool::HandExecutor` → `zclaw_hands::HandRegistry`,
/// allowing `HandTool::execute()` to dispatch to the real Hand implementations.
pub struct KernelHandExecutor {
hands: Arc<HandRegistry>,
}
impl KernelHandExecutor {
pub fn new(hands: Arc<HandRegistry>) -> Self {
Self { hands }
}
}
#[async_trait]
impl HandExecutor for KernelHandExecutor {
async fn execute_hand(
&self,
hand_id: &str,
agent_id: &AgentId,
input: Value,
) -> Result<Value> {
let context = zclaw_hands::HandContext {
agent_id: agent_id.clone(),
working_dir: None,
env: std::collections::HashMap::new(),
timeout_secs: 300,
callback_url: None,
};
let result = self.hands.execute(hand_id, &context, input).await?;
if result.success {
Ok(result.output)
} else {
Ok(json!({
"hand_id": hand_id,
"status": "failed",
"error": result.error.unwrap_or_else(|| "Unknown hand execution error".to_string()),
"output": result.output,
"duration_ms": result.duration_ms,
}))
}
}
}