Skip to content

Commit 682c488

Browse files
authored
Merge pull request #596 from kev1n77/fmy/bugfix
fix: make tool loop detection signatures include args hash
2 parents 4bbe9d2 + f0eaa24 commit 682c488

1 file changed

Lines changed: 24 additions & 3 deletions

File tree

src/crates/core/src/agentic/execution/execution_engine.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use crate::util::types::Message as AIMessage;
3333
use crate::util::types::ToolDefinition;
3434
use crate::util::{elapsed_ms_u64, truncate_at_char_boundary};
3535
use log::{debug, error, info, trace, warn};
36+
use sha2::{Digest, Sha256};
3637
use std::collections::{HashMap, HashSet};
3738
use std::path::Path;
3839
use std::sync::Arc;
@@ -112,10 +113,12 @@ impl ExecutionEngine {
112113
return args_str.to_string();
113114
}
114115

116+
let args_hash = hex::encode(Sha256::digest(args_str.as_bytes()));
115117
format!(
116-
"{}..#{}",
118+
"{}..#{}:sha256={}",
117119
truncate_at_char_boundary(args_str, 64),
118-
args_str.len()
120+
args_str.len(),
121+
args_hash
119122
)
120123
}
121124

@@ -1961,6 +1964,7 @@ mod tests {
19611964
use crate::service::config::types::AIConfig;
19621965
use crate::service::config::types::AIModelConfig;
19631966
use serde_json::json;
1967+
use sha2::{Digest, Sha256};
19641968

19651969
fn build_model(id: &str, name: &str, model_name: &str) -> AIModelConfig {
19661970
AIModelConfig {
@@ -2008,10 +2012,14 @@ mod tests {
20082012
#[test]
20092013
fn tool_signature_args_summary_truncates_on_utf8_boundary() {
20102014
let args = format!("{}{}", "a".repeat(62), "案".repeat(30));
2015+
let args_hash = hex::encode(Sha256::digest(args.as_bytes()));
20112016

20122017
let summary = ExecutionEngine::tool_signature_args_summary(&args);
20132018

2014-
assert_eq!(summary, format!("{}..#{}", "a".repeat(62), args.len()));
2019+
assert_eq!(
2020+
summary,
2021+
format!("{}..#{}:sha256={}", "a".repeat(62), args.len(), args_hash)
2022+
);
20152023
}
20162024

20172025
#[test]
@@ -2023,6 +2031,19 @@ mod tests {
20232031
assert_eq!(summary, args);
20242032
}
20252033

2034+
#[test]
2035+
fn tool_signature_args_summary_distinguishes_same_prefix_and_length() {
2036+
let first = format!("{}{}", "x".repeat(64), "a".repeat(80));
2037+
let second = format!("{}{}", "x".repeat(64), "b".repeat(80));
2038+
2039+
let first_summary = ExecutionEngine::tool_signature_args_summary(&first);
2040+
let second_summary = ExecutionEngine::tool_signature_args_summary(&second);
2041+
2042+
assert_eq!(first.len(), second.len());
2043+
assert_ne!(first, second);
2044+
assert_ne!(first_summary, second_summary);
2045+
}
2046+
20262047
#[test]
20272048
fn assistant_has_tool_calls_detects_mixed_tool_message() {
20282049
let message = Message::assistant_with_tools(

0 commit comments

Comments
 (0)