From 126b6faeaf5eef00c149e85c184b9401c82d8fd7 Mon Sep 17 00:00:00 2001 From: Alexey Leshchenko Date: Fri, 29 May 2026 23:16:05 +0000 Subject: [PATCH 1/2] feat(feedback): store bash command in feedback ledger metadata --- src/brain/agent/service/tool_loop.rs | 34 ++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/brain/agent/service/tool_loop.rs b/src/brain/agent/service/tool_loop.rs index 6611eb5a..887742e5 100644 --- a/src/brain/agent/service/tool_loop.rs +++ b/src/brain/agent/service/tool_loop.rs @@ -3790,11 +3790,26 @@ impl AgentService { } // Auto-record to feedback ledger (fire-and-forget) + let feedback_snippet = if !success && tool_name == "bash" { + let cmd_prefix = tool_input + .get("command") + .and_then(|v| v.as_str()) + .map(|cmd| { + let truncated: String = cmd.chars().take(300).collect(); + format!("[command: {}] ", truncated) + }) + .unwrap_or_default(); + Some(format!("{}{}", cmd_prefix, content)) + } else if !success { + Some(content.clone()) + } else { + None + }; self.record_tool_feedback( session_id, &tool_name, success, - if success { None } else { Some(&content) }, + feedback_snippet.as_deref(), ); // Record tool execution for usage dashboard @@ -3995,11 +4010,26 @@ impl AgentService { } // Auto-record to feedback ledger (fire-and-forget) + let feedback_snippet = if !success && tool_name == "bash" { + let cmd_prefix = tool_input + .get("command") + .and_then(|v| v.as_str()) + .map(|cmd| { + let truncated: String = cmd.chars().take(300).collect(); + format!("[command: {}] ", truncated) + }) + .unwrap_or_default(); + Some(format!("{}{}", cmd_prefix, content)) + } else if !success { + Some(content.clone()) + } else { + None + }; self.record_tool_feedback( session_id, &tool_name, success, - if success { None } else { Some(&content) }, + feedback_snippet.as_deref(), ); // Record tool execution for usage dashboard From d643025ad9028d931965f6436f8613a5eb4df8ba Mon Sep 17 00:00:00 2001 From: Alexey Leshchenko Date: Fri, 29 May 2026 23:29:24 +0000 Subject: [PATCH 2/2] fix: clone tool_input before execute() to avoid borrow-after-move E0382 The new feedback snippet code references tool_input.get("command") after tool_input is moved into execute(). Adding .clone() at both execute() call sites resolves the borrow checker error. --- src/brain/agent/service/tool_loop.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/brain/agent/service/tool_loop.rs b/src/brain/agent/service/tool_loop.rs index 887742e5..589b032c 100644 --- a/src/brain/agent/service/tool_loop.rs +++ b/src/brain/agent/service/tool_loop.rs @@ -3742,7 +3742,7 @@ impl AgentService { tracing::warn!("🛑 Tool '{}' cancelled mid-execution", tool_name); break; } - r = self.tool_registry.execute(&tool_name, tool_input, &approved_tool_context) => r, + r = self.tool_registry.execute(&tool_name, tool_input.clone(), &approved_tool_context) => r, }; match exec_result { Ok(result) => { @@ -3969,7 +3969,7 @@ impl AgentService { tracing::warn!("🛑 Tool '{}' cancelled mid-execution", tool_name); break; } - r = self.tool_registry.execute(&tool_name, tool_input, &approved_context) => r, + r = self.tool_registry.execute(&tool_name, tool_input.clone(), &approved_context) => r, }; match exec_result { Ok(result) => {