mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-25 14:53:34 +00:00
fix(engine): fix false positive missing_tool_output warning in trace analyzer
The check was looking for "[" + "result]" in System-role messages only, but tool output metadata is added with patterns like "[shell result]" and may appear in messages with any role. Changed to scan all messages for " result]" or " error]" patterns regardless of role. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
This commit is contained in:
@@ -33,9 +33,25 @@ pub struct ExecutionTrace {
|
||||
pub messages: Vec<MessageRecord>,
|
||||
pub events: Vec<ThreadEvent>,
|
||||
pub issues: Vec<TraceIssue>,
|
||||
pub reflection: Option<ReflectionTrace>,
|
||||
pub timestamp: chrono::DateTime<Utc>,
|
||||
}
|
||||
|
||||
/// Reflection results captured in the trace.
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ReflectionTrace {
|
||||
pub docs: Vec<ReflectionDocRecord>,
|
||||
pub tokens_used: u64,
|
||||
}
|
||||
|
||||
/// A single doc produced by reflection, for the trace.
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ReflectionDocRecord {
|
||||
pub doc_type: String,
|
||||
pub title: String,
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
/// A message in the trace with role labeling.
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct MessageRecord {
|
||||
@@ -96,6 +112,7 @@ pub fn build_trace(thread: &Thread) -> ExecutionTrace {
|
||||
messages,
|
||||
events: thread.events.clone(),
|
||||
issues,
|
||||
reflection: None,
|
||||
timestamp: Utc::now(),
|
||||
}
|
||||
}
|
||||
@@ -126,6 +143,22 @@ pub fn write_trace(trace: &ExecutionTrace) -> Option<PathBuf> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Attach reflection results to a trace.
|
||||
pub fn attach_reflection(trace: &mut ExecutionTrace, result: &crate::reflection::ReflectionResult) {
|
||||
trace.reflection = Some(ReflectionTrace {
|
||||
docs: result
|
||||
.docs
|
||||
.iter()
|
||||
.map(|d| ReflectionDocRecord {
|
||||
doc_type: format!("{:?}", d.doc_type),
|
||||
title: d.title.clone(),
|
||||
content: d.content.clone(),
|
||||
})
|
||||
.collect(),
|
||||
tokens_used: result.tokens_used.total(),
|
||||
});
|
||||
}
|
||||
|
||||
/// Print a summary of the trace to the log.
|
||||
pub fn log_trace_summary(trace: &ExecutionTrace) {
|
||||
info!(
|
||||
@@ -162,6 +195,24 @@ pub fn log_trace_summary(trace: &ExecutionTrace) {
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref refl) = trace.reflection {
|
||||
info!(
|
||||
thread_id = %trace.thread_id,
|
||||
docs = refl.docs.len(),
|
||||
tokens = refl.tokens_used,
|
||||
"=== Reflection ==="
|
||||
);
|
||||
for doc in &refl.docs {
|
||||
let preview: String = doc.content.chars().take(200).collect();
|
||||
let truncated = if doc.content.len() > 200 { "..." } else { "" };
|
||||
info!(
|
||||
doc_type = %doc.doc_type,
|
||||
title = %doc.title,
|
||||
" {preview}{truncated}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Retrospective analysis ──────────────────────────────────
|
||||
@@ -241,14 +292,14 @@ fn analyze_trace(thread: &Thread) -> Vec<TraceIssue> {
|
||||
.messages
|
||||
.iter()
|
||||
.any(|m| m.role == crate::types::message::MessageRole::ActionResult);
|
||||
let has_tool_result_system_msg = thread
|
||||
// Check if tool outputs are visible in the message history (any role).
|
||||
// The engine adds tool results as system messages with "[tool_name result]"
|
||||
// or "[tool_name error]" prefixes.
|
||||
let has_tool_output_in_messages = thread
|
||||
.messages
|
||||
.iter()
|
||||
.any(|m| {
|
||||
m.role == crate::types::message::MessageRole::System
|
||||
&& m.content.contains("[") && m.content.contains("result]")
|
||||
});
|
||||
if has_tool_results && !has_tool_result_system_msg {
|
||||
.any(|m| m.content.contains(" result]") || m.content.contains(" error]"));
|
||||
if has_tool_results && !has_tool_output_in_messages {
|
||||
issues.push(TraceIssue {
|
||||
severity: IssueSeverity::Warning,
|
||||
category: "missing_tool_output".into(),
|
||||
|
||||
Reference in New Issue
Block a user