Skip to main content

thoughts_tool/utils/
logging.rs

1//! Shared tool-call logging for `thoughts_tool`.
2//!
3//! This module provides logging helpers used by both MCP and agentic-tools
4//! wrappers to ensure consistent logging behavior.
5
6use crate::documents::active_logs_dir;
7use agentic_logging::CallTimer;
8use agentic_logging::LogWriter;
9use agentic_logging::ToolCallRecord;
10
11fn classify_failure_kind(success: bool, error: Option<&str>) -> Option<String> {
12    if success {
13        return None;
14    }
15
16    let error = error.unwrap_or_default().to_ascii_lowercase();
17    if error.contains("timed out") || error.contains("timeout") {
18        Some("timeout".to_string())
19    } else if error.contains("cancelled") || error.contains("canceled") {
20        Some("cancelled".to_string())
21    } else {
22        Some("error".to_string())
23    }
24}
25
26/// Log a tool call. Behavior identical to MCP.
27///
28/// If logging is unavailable (e.g., no active branch), this function
29/// returns silently without panicking or affecting the caller.
30pub fn log_tool_call(
31    timer: &CallTimer,
32    tool: &str,
33    request: serde_json::Value,
34    success: bool,
35    error: Option<String>,
36    summary: Option<serde_json::Value>,
37) {
38    let writer = match active_logs_dir() {
39        Ok(dir) => LogWriter::new(dir),
40        Err(_) => return, // Logging unavailable (e.g., branch lockout)
41    };
42
43    let (completed_at, duration_ms) = timer.finish();
44    let record = ToolCallRecord {
45        call_id: timer.call_id.clone(),
46        server: "thoughts_tool".into(),
47        tool: tool.into(),
48        started_at: timer.started_at,
49        completed_at,
50        duration_ms,
51        request,
52        response_file: None,
53        success,
54        failure_kind: classify_failure_kind(success, error.as_deref()),
55        error,
56        model: None,
57        token_usage: None,
58        summary,
59    };
60
61    if let Err(e) = writer.append_jsonl(&record) {
62        tracing::warn!("Failed to append JSONL log: {}", e);
63    }
64}