reset filter suppression state between tool calls (still broken)
This commit is contained in:
@@ -4,8 +4,8 @@
|
||||
// 3. Only elide JSON content between first '{' and last '}' (inclusive)
|
||||
// 4. Return everything else as the final filtered string
|
||||
|
||||
use std::cell::RefCell;
|
||||
use regex::Regex;
|
||||
use std::cell::RefCell;
|
||||
use tracing::debug;
|
||||
|
||||
// Thread-local state for tracking JSON tool call suppression
|
||||
@@ -23,8 +23,7 @@ struct FixedJsonToolState {
|
||||
}
|
||||
|
||||
impl FixedJsonToolState {
|
||||
|
||||
fn new() -> Self {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
suppression_mode: false,
|
||||
brace_depth: 0,
|
||||
@@ -34,8 +33,7 @@ fn new() -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn reset(&mut self) {
|
||||
fn reset(&mut self) {
|
||||
self.suppression_mode = false;
|
||||
self.brace_depth = 0;
|
||||
self.buffer.clear();
|
||||
@@ -70,7 +68,10 @@ pub fn fixed_filter_json_tool_calls(content: &str) -> String {
|
||||
debug!("JSON tool call completed - exiting suppression mode");
|
||||
|
||||
// Extract the complete result with JSON filtered out
|
||||
let result = extract_fixed_content(&state.buffer, state.json_start_in_buffer.unwrap_or(0));
|
||||
let result = extract_fixed_content(
|
||||
&state.buffer,
|
||||
state.json_start_in_buffer.unwrap_or(0),
|
||||
);
|
||||
|
||||
// Return only the part we haven't returned yet
|
||||
let new_content = if result.len() > state.content_returned_up_to {
|
||||
@@ -92,7 +93,7 @@ pub fn fixed_filter_json_tool_calls(content: &str) -> String {
|
||||
|
||||
// Check for tool call pattern using corrected regex
|
||||
// More flexible than the strict specification to handle real-world JSON
|
||||
let tool_call_regex = Regex::new(r#"(?m)^.*\{\s*"tool"\s*:\s*""#).unwrap();
|
||||
let tool_call_regex = Regex::new(r#"(?m)^\s*\{\s*"tool"\s*:\s*""#).unwrap();
|
||||
|
||||
if let Some(captures) = tool_call_regex.find(&state.buffer) {
|
||||
let match_text = captures.as_str();
|
||||
@@ -101,7 +102,10 @@ pub fn fixed_filter_json_tool_calls(content: &str) -> String {
|
||||
if let Some(brace_offset) = match_text.find('{') {
|
||||
let json_start = captures.start() + brace_offset;
|
||||
|
||||
debug!("Detected JSON tool call at position {} - entering suppression mode", json_start);
|
||||
debug!(
|
||||
"Detected JSON tool call at position {} - entering suppression mode",
|
||||
json_start
|
||||
);
|
||||
|
||||
// Return content before JSON that we haven't returned yet
|
||||
let content_before_json = if json_start >= state.content_returned_up_to {
|
||||
@@ -136,7 +140,8 @@ pub fn fixed_filter_json_tool_calls(content: &str) -> String {
|
||||
""
|
||||
};
|
||||
|
||||
let final_result = format!("{}{}", content_before_json, content_after_json);
|
||||
let final_result =
|
||||
format!("{}{}", content_before_json, content_after_json);
|
||||
state.reset();
|
||||
return final_result;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ Some text after"#;
|
||||
"{\"tool\": \"",
|
||||
"shell\", \"args\": {",
|
||||
"\"command\": \"ls\"",
|
||||
"}}\nText after"
|
||||
"}}\nText after",
|
||||
];
|
||||
|
||||
let mut results = Vec::new();
|
||||
@@ -64,26 +64,48 @@ Text after"#;
|
||||
#[test]
|
||||
fn test_regex_pattern_specification() {
|
||||
// Test the corrected regex pattern that's more flexible with whitespace
|
||||
let pattern = Regex::new(r#"(?m)^.*\{\s*"tool"\s*:"#).unwrap();
|
||||
let pattern = Regex::new(r#"(?m)^\s*\{\s*"tool"\s*:"#).unwrap();
|
||||
|
||||
let test_cases = vec![
|
||||
(r#"line
|
||||
{"tool":"#, true),
|
||||
(r#"line
|
||||
{"tool" :"#, true),
|
||||
(r#"line
|
||||
{ "tool":"#, true), // Space after { DOES match with \s*
|
||||
(r#"line
|
||||
abc{"tool":"#, true),
|
||||
(r#"line
|
||||
{"tool123":"#, false), // "tool123" is not exactly "tool"
|
||||
(r#"line
|
||||
{"tool" : "#, true),
|
||||
(
|
||||
r#"line
|
||||
{"tool":"#,
|
||||
true,
|
||||
),
|
||||
(
|
||||
r#"line
|
||||
{"tool" :"#,
|
||||
true,
|
||||
),
|
||||
(
|
||||
r#"line
|
||||
{ "tool":"#,
|
||||
true,
|
||||
), // Space after { DOES match with \s*
|
||||
(
|
||||
r#"line
|
||||
abc{"tool":"#,
|
||||
true,
|
||||
),
|
||||
(
|
||||
r#"line
|
||||
{"tool123":"#,
|
||||
false,
|
||||
), // "tool123" is not exactly "tool"
|
||||
(
|
||||
r#"line
|
||||
{"tool" : "#,
|
||||
true,
|
||||
),
|
||||
];
|
||||
|
||||
for (input, should_match) in test_cases {
|
||||
let matches = pattern.is_match(input);
|
||||
assert_eq!(matches, should_match, "Pattern matching failed for: {}", input);
|
||||
assert_eq!(
|
||||
matches, should_match,
|
||||
"Pattern matching failed for: {}",
|
||||
input
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,18 +286,7 @@ More text"#;
|
||||
|
||||
// Test streaming with very small chunks
|
||||
let chunks = vec![
|
||||
"Text\n",
|
||||
"{",
|
||||
"\"",
|
||||
"tool",
|
||||
"\"",
|
||||
":",
|
||||
" ",
|
||||
"\"",
|
||||
"test",
|
||||
"\"",
|
||||
"}",
|
||||
"\nAfter"
|
||||
"Text\n", "{", "\"", "tool", "\"", ":", " ", "\"", "test", "\"", "}", "\nAfter",
|
||||
];
|
||||
|
||||
let mut results = Vec::new();
|
||||
@@ -301,7 +312,7 @@ More text"#;
|
||||
"{\"tool\": \"",
|
||||
"shell\", \"args\": {",
|
||||
"\"command\": \"ls\"",
|
||||
"}}\nText after"
|
||||
"}}\nText after",
|
||||
];
|
||||
|
||||
let mut results = Vec::new();
|
||||
|
||||
@@ -706,6 +706,10 @@ impl<W: UiWriter> Agent<W> {
|
||||
show_timing: bool,
|
||||
cancellation_token: CancellationToken,
|
||||
) -> Result<TaskResult> {
|
||||
// Reset the JSON tool call filter state at the start of each new task
|
||||
// This prevents the filter from staying in suppression mode between user interactions
|
||||
fixed_filter_json::reset_fixed_json_tool_state();
|
||||
|
||||
// Generate session ID based on the initial prompt if this is a new session
|
||||
if self.session_id.is_none() {
|
||||
self.session_id = Some(self.generate_session_id(description));
|
||||
@@ -1635,6 +1639,10 @@ The tool will execute immediately and you'll receive the result (success or erro
|
||||
}
|
||||
tool_executed = true;
|
||||
|
||||
// Reset the JSON tool call filter state after each tool execution
|
||||
// This ensures the filter doesn't stay in suppression mode for subsequent streaming content
|
||||
fixed_filter_json::reset_fixed_json_tool_state();
|
||||
|
||||
// Reset parser for next iteration
|
||||
parser.reset();
|
||||
// Clear current_response for next iteration to prevent buffered text
|
||||
|
||||
Reference in New Issue
Block a user