feat: add tool repetition monitoring to prevent infinite loops (#2527)

This commit is contained in:
Max Novich
2025-05-14 14:46:37 -07:00
committed by GitHub
parent 70020f1b45
commit 4e1b091d91
6 changed files with 139 additions and 0 deletions
+23
View File
@@ -220,6 +220,15 @@ enum Command {
)]
debug: bool,
/// Maximum number of consecutive identical tool calls allowed
#[arg(
long = "max-tool-repetitions",
value_name = "NUMBER",
help = "Maximum number of consecutive identical tool calls allowed",
long_help = "Set a limit on how many times the same tool can be called consecutively with identical parameters. Helps prevent infinite loops."
)]
max_tool_repetitions: Option<u32>,
/// Add stdio extensions with environment variables and commands
#[arg(
long = "with-extension",
@@ -324,6 +333,15 @@ enum Command {
)]
no_session: bool,
/// Maximum number of consecutive identical tool calls allowed
#[arg(
long = "max-tool-repetitions",
value_name = "NUMBER",
help = "Maximum number of consecutive identical tool calls allowed",
long_help = "Set a limit on how many times the same tool can be called consecutively with identical parameters. Helps prevent infinite loops."
)]
max_tool_repetitions: Option<u32>,
/// Identifier for this run session
#[command(flatten)]
identifier: Option<Identifier>,
@@ -446,6 +464,7 @@ pub async fn cli() -> Result<()> {
resume,
history,
debug,
max_tool_repetitions,
extensions,
remote_extensions,
builtins,
@@ -475,6 +494,7 @@ pub async fn cli() -> Result<()> {
extensions_override: None,
additional_system_prompt: None,
debug,
max_tool_repetitions,
})
.await;
setup_logging(
@@ -511,6 +531,7 @@ pub async fn cli() -> Result<()> {
resume,
no_session,
debug,
max_tool_repetitions,
extensions,
remote_extensions,
builtins,
@@ -576,6 +597,7 @@ pub async fn cli() -> Result<()> {
extensions_override: input_config.extensions_override,
additional_system_prompt: input_config.additional_system_prompt,
debug,
max_tool_repetitions,
})
.await;
@@ -647,6 +669,7 @@ pub async fn cli() -> Result<()> {
extensions_override: None,
additional_system_prompt: None,
debug: false,
max_tool_repetitions: None,
})
.await;
setup_logging(
+1
View File
@@ -41,6 +41,7 @@ pub async fn agent_generator(
extensions_override: None,
additional_system_prompt: None,
debug: false,
max_tool_repetitions: None,
})
.await;
+7
View File
@@ -35,6 +35,8 @@ pub struct SessionBuilderConfig {
pub additional_system_prompt: Option<String>,
/// Enable debug printing
pub debug: bool,
/// Maximum number of consecutive identical tool calls allowed
pub max_tool_repetitions: Option<u32>,
}
pub async fn build_session(session_config: SessionBuilderConfig) -> Session {
@@ -55,6 +57,11 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> Session {
let new_provider = create(&provider_name, model_config).unwrap();
let _ = agent.update_provider(new_provider).await;
// Configure tool monitoring if max_tool_repetitions is set
if let Some(max_repetitions) = session_config.max_tool_repetitions {
agent.configure_tool_monitor(Some(max_repetitions)).await;
}
// Handle session file resolution and resuming
let session_file = if session_config.no_session {
// Use a temporary path that won't be written to