feat: Adds max_turns for the agent without user input (#3208)
This commit is contained in:
@@ -312,6 +312,15 @@ enum Command {
|
||||
)]
|
||||
max_tool_repetitions: Option<u32>,
|
||||
|
||||
/// Maximum number of turns (iterations) allowed in a single response
|
||||
#[arg(
|
||||
long = "max-turns",
|
||||
value_name = "NUMBER",
|
||||
help = "Maximum number of turns allowed without user input (default: 1000)",
|
||||
long_help = "Set a limit on how many turns (iterations) the agent can take without asking for user input to continue."
|
||||
)]
|
||||
max_turns: Option<u32>,
|
||||
|
||||
/// Add stdio extensions with environment variables and commands
|
||||
#[arg(
|
||||
long = "with-extension",
|
||||
@@ -449,6 +458,15 @@ enum Command {
|
||||
)]
|
||||
max_tool_repetitions: Option<u32>,
|
||||
|
||||
/// Maximum number of turns (iterations) allowed in a single response
|
||||
#[arg(
|
||||
long = "max-turns",
|
||||
value_name = "NUMBER",
|
||||
help = "Maximum number of turns allowed without user input (default: 1000)",
|
||||
long_help = "Set a limit on how many turns (iterations) the agent can take without asking for user input to continue."
|
||||
)]
|
||||
max_turns: Option<u32>,
|
||||
|
||||
/// Identifier for this run session
|
||||
#[command(flatten)]
|
||||
identifier: Option<Identifier>,
|
||||
@@ -635,6 +653,7 @@ pub async fn cli() -> Result<()> {
|
||||
history,
|
||||
debug,
|
||||
max_tool_repetitions,
|
||||
max_turns,
|
||||
extensions,
|
||||
remote_extensions,
|
||||
builtins,
|
||||
@@ -683,6 +702,7 @@ pub async fn cli() -> Result<()> {
|
||||
settings: None,
|
||||
debug,
|
||||
max_tool_repetitions,
|
||||
max_turns,
|
||||
scheduled_job_id: None,
|
||||
interactive: true,
|
||||
quiet: false,
|
||||
@@ -731,6 +751,7 @@ pub async fn cli() -> Result<()> {
|
||||
no_session,
|
||||
debug,
|
||||
max_tool_repetitions,
|
||||
max_turns,
|
||||
extensions,
|
||||
remote_extensions,
|
||||
builtins,
|
||||
@@ -826,6 +847,7 @@ pub async fn cli() -> Result<()> {
|
||||
settings: session_settings,
|
||||
debug,
|
||||
max_tool_repetitions,
|
||||
max_turns,
|
||||
scheduled_job_id,
|
||||
interactive, // Use the interactive flag from the Run command
|
||||
quiet,
|
||||
@@ -950,6 +972,7 @@ pub async fn cli() -> Result<()> {
|
||||
settings: None::<SessionSettings>,
|
||||
debug: false,
|
||||
max_tool_repetitions: None,
|
||||
max_turns: None,
|
||||
scheduled_job_id: None,
|
||||
interactive: true, // Default case is always interactive
|
||||
quiet: false,
|
||||
|
||||
@@ -45,6 +45,7 @@ pub async fn agent_generator(
|
||||
max_tool_repetitions: None,
|
||||
interactive: false, // Benchmarking is non-interactive
|
||||
scheduled_job_id: None,
|
||||
max_turns: None,
|
||||
quiet: false,
|
||||
sub_recipes: None,
|
||||
final_output_response: None,
|
||||
|
||||
@@ -846,6 +846,11 @@ pub async fn configure_settings_dialog() -> Result<(), Box<dyn Error>> {
|
||||
"Tool Output",
|
||||
"Show more or less tool output",
|
||||
)
|
||||
.item(
|
||||
"max_turns",
|
||||
"Max Turns",
|
||||
"Set maximum number of turns without user input",
|
||||
)
|
||||
.item(
|
||||
"experiment",
|
||||
"Toggle Experiment",
|
||||
@@ -876,6 +881,9 @@ pub async fn configure_settings_dialog() -> Result<(), Box<dyn Error>> {
|
||||
"tool_output" => {
|
||||
configure_tool_output_dialog()?;
|
||||
}
|
||||
"max_turns" => {
|
||||
configure_max_turns_dialog()?;
|
||||
}
|
||||
"experiment" => {
|
||||
toggle_experiments_dialog()?;
|
||||
}
|
||||
@@ -1289,3 +1297,35 @@ fn configure_scheduler_dialog() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn configure_max_turns_dialog() -> Result<(), Box<dyn Error>> {
|
||||
let config = Config::global();
|
||||
|
||||
let current_max_turns: u32 = config.get_param("GOOSE_MAX_TURNS").unwrap_or(1000);
|
||||
|
||||
let max_turns_input: String =
|
||||
cliclack::input("Set maximum number of agent turns without user input:")
|
||||
.placeholder(¤t_max_turns.to_string())
|
||||
.default_input(¤t_max_turns.to_string())
|
||||
.validate(|input: &String| match input.parse::<u32>() {
|
||||
Ok(value) => {
|
||||
if value < 1 {
|
||||
Err("Value must be at least 1")
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Err(_) => Err("Please enter a valid number"),
|
||||
})
|
||||
.interact()?;
|
||||
|
||||
let max_turns: u32 = max_turns_input.parse()?;
|
||||
config.set_param("GOOSE_MAX_TURNS", Value::from(max_turns))?;
|
||||
|
||||
cliclack::outro(format!(
|
||||
"Set maximum turns to {} - Goose will ask for input after {} consecutive actions",
|
||||
max_turns, max_turns
|
||||
))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -483,6 +483,7 @@ async fn process_message_streaming(
|
||||
working_dir: std::env::current_dir()?,
|
||||
schedule_id: None,
|
||||
execution_mode: None,
|
||||
max_turns: None,
|
||||
};
|
||||
|
||||
// Get response from agent
|
||||
|
||||
@@ -41,6 +41,8 @@ pub struct SessionBuilderConfig {
|
||||
pub debug: bool,
|
||||
/// Maximum number of consecutive identical tool calls allowed
|
||||
pub max_tool_repetitions: Option<u32>,
|
||||
/// Maximum number of turns (iterations) allowed without user input
|
||||
pub max_turns: Option<u32>,
|
||||
/// ID of the scheduled job that triggered this session (if any)
|
||||
pub scheduled_job_id: Option<String>,
|
||||
/// Whether this session will be used interactively (affects debugging prompts)
|
||||
@@ -122,7 +124,13 @@ async fn offer_extension_debugging_help(
|
||||
std::env::temp_dir().join(format!("goose_debug_extension_{}.jsonl", extension_name));
|
||||
|
||||
// Create the debugging session
|
||||
let mut debug_session = Session::new(debug_agent, Some(temp_session_file.clone()), false, None);
|
||||
let mut debug_session = Session::new(
|
||||
debug_agent,
|
||||
Some(temp_session_file.clone()),
|
||||
false,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
|
||||
// Process the debugging request
|
||||
println!("{}", style("Analyzing the extension failure...").yellow());
|
||||
@@ -367,6 +375,7 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> Session {
|
||||
session_file.clone(),
|
||||
session_config.debug,
|
||||
session_config.scheduled_job_id.clone(),
|
||||
session_config.max_turns,
|
||||
);
|
||||
|
||||
// Add extensions if provided
|
||||
@@ -516,6 +525,7 @@ mod tests {
|
||||
settings: None,
|
||||
debug: true,
|
||||
max_tool_repetitions: Some(5),
|
||||
max_turns: None,
|
||||
scheduled_job_id: None,
|
||||
interactive: true,
|
||||
quiet: false,
|
||||
@@ -528,6 +538,7 @@ mod tests {
|
||||
assert_eq!(config.builtins.len(), 1);
|
||||
assert!(config.debug);
|
||||
assert_eq!(config.max_tool_repetitions, Some(5));
|
||||
assert!(config.max_turns.is_none());
|
||||
assert!(config.scheduled_job_id.is_none());
|
||||
assert!(config.interactive);
|
||||
assert!(!config.quiet);
|
||||
@@ -547,6 +558,7 @@ mod tests {
|
||||
assert!(config.additional_system_prompt.is_none());
|
||||
assert!(!config.debug);
|
||||
assert!(config.max_tool_repetitions.is_none());
|
||||
assert!(config.max_turns.is_none());
|
||||
assert!(config.scheduled_job_id.is_none());
|
||||
assert!(!config.interactive);
|
||||
assert!(!config.quiet);
|
||||
|
||||
@@ -52,6 +52,7 @@ pub struct Session {
|
||||
debug: bool, // New field for debug mode
|
||||
run_mode: RunMode,
|
||||
scheduled_job_id: Option<String>, // ID of the scheduled job that triggered this session
|
||||
max_turns: Option<u32>,
|
||||
}
|
||||
|
||||
// Cache structure for completion data
|
||||
@@ -113,6 +114,7 @@ impl Session {
|
||||
session_file: Option<PathBuf>,
|
||||
debug: bool,
|
||||
scheduled_job_id: Option<String>,
|
||||
max_turns: Option<u32>,
|
||||
) -> Self {
|
||||
let messages = if let Some(session_file) = &session_file {
|
||||
match session::read_messages(session_file) {
|
||||
@@ -135,6 +137,7 @@ impl Session {
|
||||
debug,
|
||||
run_mode: RunMode::Normal,
|
||||
scheduled_job_id,
|
||||
max_turns,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -757,6 +760,7 @@ impl Session {
|
||||
.expect("failed to get current session working directory"),
|
||||
schedule_id: self.scheduled_job_id.clone(),
|
||||
execution_mode: None,
|
||||
max_turns: self.max_turns,
|
||||
}
|
||||
});
|
||||
let mut stream = self
|
||||
|
||||
Reference in New Issue
Block a user