logging: include runtime and skill versions
This commit is contained in:
@@ -94,6 +94,14 @@ fn missing_llm_configuration_summary() -> String {
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn runtime_version_log_message() -> String {
|
||||
format!(
|
||||
"sgclaw runtime version={} protocol={}",
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
crate::pipe::protocol::PROTOCOL_VERSION
|
||||
)
|
||||
}
|
||||
|
||||
fn execute_plan<T: Transport>(
|
||||
transport: &T,
|
||||
browser_tool: &BrowserPipeTool<T>,
|
||||
@@ -173,6 +181,10 @@ pub fn handle_browser_message_with_context<T: Transport + 'static>(
|
||||
page_url: (!page_url.trim().is_empty()).then_some(page_url),
|
||||
page_title: (!page_title.trim().is_empty()).then_some(page_title),
|
||||
};
|
||||
let _ = transport.send(&AgentMessage::LogEntry {
|
||||
level: "info".to_string(),
|
||||
message: runtime_version_log_message(),
|
||||
});
|
||||
if !task_context.messages.is_empty() {
|
||||
let _ = transport.send(&AgentMessage::LogEntry {
|
||||
level: "info".to_string(),
|
||||
|
||||
@@ -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}");
|
||||
}
|
||||
|
||||
|
||||
@@ -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)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,12 +161,30 @@ impl RuntimeEngine {
|
||||
sections.join("\n\n")
|
||||
}
|
||||
|
||||
pub fn loaded_skills(
|
||||
&self,
|
||||
config: &ZeroClawConfig,
|
||||
skills_dir: &Path,
|
||||
) -> Vec<zeroclaw::skills::Skill> {
|
||||
let mut skills = load_runtime_skills(config, skills_dir);
|
||||
skills.sort_by(|left, right| {
|
||||
left.name
|
||||
.cmp(&right.name)
|
||||
.then(left.version.cmp(&right.version))
|
||||
});
|
||||
skills.dedup_by(|left, right| {
|
||||
left.name == right.name && left.version == right.version
|
||||
});
|
||||
skills
|
||||
}
|
||||
|
||||
pub fn loaded_skill_names(
|
||||
&self,
|
||||
config: &ZeroClawConfig,
|
||||
skills_dir: &Path,
|
||||
) -> Vec<String> {
|
||||
let mut names = load_runtime_skills(config, skills_dir)
|
||||
let mut names = self
|
||||
.loaded_skills(config, skills_dir)
|
||||
.into_iter()
|
||||
.map(|skill| skill.name)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Reference in New Issue
Block a user