logging: include runtime and skill versions

This commit is contained in:
zyl
2026-03-30 00:31:08 +08:00
parent c7d3d45c68
commit f7e2ff256e
6 changed files with 82 additions and 81 deletions

View File

@@ -1,13 +1,18 @@
use std::collections::HashMap;
use serde_json::Value;
use zeroclaw::agent::TurnEvent;
use crate::pipe::AgentMessage;
pub fn log_entry_for_turn_event(event: &TurnEvent) -> Option<AgentMessage> {
pub fn log_entry_for_turn_event(
event: &TurnEvent,
skill_versions: &HashMap<String, String>,
) -> Option<AgentMessage> {
match event {
TurnEvent::ToolCall { name, args } => Some(AgentMessage::LogEntry {
level: "info".to_string(),
message: format_tool_call(name, args),
message: format_tool_call(name, args, skill_versions),
}),
TurnEvent::ToolResult { output, .. } if is_tool_error(output) => Some(AgentMessage::LogEntry {
level: "error".to_string(),
@@ -17,12 +22,19 @@ pub fn log_entry_for_turn_event(event: &TurnEvent) -> Option<AgentMessage> {
}
}
fn format_tool_call(name: &str, args: &Value) -> String {
fn format_tool_call(
name: &str,
args: &Value,
skill_versions: &HashMap<String, String>,
) -> String {
if name == "read_skill" {
let skill_name = args
.get("name")
.and_then(Value::as_str)
.unwrap_or("<missing-skill>");
if let Some(version) = skill_versions.get(skill_name) {
return format!("read_skill {skill_name}@{version}");
}
return format!("read_skill {skill_name}");
}

View File

@@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use async_trait::async_trait;
@@ -104,11 +105,19 @@ pub async fn execute_task_with_provider<T: Transport + 'static>(
message,
})?;
}
let loaded_skill_names = engine.loaded_skill_names(&config, &skills_dir);
if !loaded_skill_names.is_empty() {
let loaded_skills = engine.loaded_skills(&config, &skills_dir);
let loaded_skill_versions = loaded_skills
.iter()
.map(|skill| (skill.name.clone(), skill.version.clone()))
.collect::<HashMap<_, _>>();
let loaded_skill_labels = loaded_skills
.iter()
.map(|skill| format!("{}@{}", skill.name, skill.version))
.collect::<Vec<_>>();
if !loaded_skill_labels.is_empty() {
transport.send(&crate::pipe::AgentMessage::LogEntry {
level: "info".to_string(),
message: format!("loaded skills: {}", loaded_skill_names.join(", ")),
message: format!("loaded skills: {}", loaded_skill_labels.join(", ")),
})?;
}
let mut tools: Vec<Box<dyn zeroclaw::tools::Tool>> = if browser_surface_present {
@@ -161,7 +170,7 @@ pub async fn execute_task_with_provider<T: Transport + 'static>(
let task = tokio::spawn(async move { agent.turn_streamed(&instruction, event_tx).await });
while let Some(event) = event_rx.recv().await {
if let Some(log_entry) = log_entry_for_turn_event(&event) {
if let Some(log_entry) = log_entry_for_turn_event(&event, &loaded_skill_versions) {
transport.send(&log_entry)?;
}
}