From d6a986ce0f91d5d552f0adbf1f8385df4bc96ba6 Mon Sep 17 00:00:00 2001 From: "Dhanji R. Prasanna" Date: Mon, 26 Jan 2026 15:59:55 +1100 Subject: [PATCH] refactor(cli): extract execute_user_input() to eliminate duplication Both multiline and single-line input paths in interactive.rs had identical code for: - Template processing (process_template) - Task execution (execute_task_with_retry) - Auto-memory reminder with error handling Extracted to a single execute_user_input() helper function that handles all three steps. This eliminates code-path aliasing where the two paths could drift over time. File reduced from 401 to 393 lines (-2%). All 106 g3-cli tests pass. Agent: fowler --- crates/g3-cli/src/interactive.rs | 64 ++++++++++++++------------------ 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/crates/g3-cli/src/interactive.rs b/crates/g3-cli/src/interactive.rs index 6411533..2a8de55 100644 --- a/crates/g3-cli/src/interactive.rs +++ b/crates/g3-cli/src/interactive.rs @@ -44,6 +44,28 @@ pub fn build_prompt(in_multiline: bool, agent_name: Option<&str>, active_project } } +/// Execute user input with template processing and auto-memory reminder. +/// +/// This is the common path for both single-line and multiline input. +async fn execute_user_input( + agent: &mut Agent, + input: &str, + show_prompt: bool, + show_code: bool, + output: &SimpleOutput, + skip_auto_memory: bool, +) { + let processed_input = process_template(input); + execute_task_with_retry(agent, &processed_input, show_prompt, show_code, output).await; + + // Send auto-memory reminder if enabled and tools were called + if !skip_auto_memory { + if let Err(e) = agent.send_auto_memory_reminder().await { + debug!("Auto-memory reminder failed: {}", e); + } + } +} + /// Run interactive mode with console output. /// If `agent_name` is Some, we're in agent+chat mode: skip session resume/verbose welcome, /// and use the agent name as the prompt (e.g., "butler>"). @@ -210,24 +232,9 @@ pub async fn run_interactive( break; } - // Process the multiline input (with template expansion) - let processed_input = process_template(&input); - execute_task_with_retry( - &mut agent, - &processed_input, - show_prompt, - show_code, - &output, - ) - .await; - - // Send auto-memory reminder if enabled and tools were called - // Skip per-turn reminders when from_agent_mode - we'll send once on exit - if !from_agent_mode { - if let Err(e) = agent.send_auto_memory_reminder().await { - debug!("Auto-memory reminder failed: {}", e); - } - } + execute_user_input( + &mut agent, &input, show_prompt, show_code, &output, from_agent_mode + ).await; } else { // Single line input let input = line.trim().to_string(); @@ -250,24 +257,9 @@ pub async fn run_interactive( } } - // Process the single line input (with template expansion) - let processed_input = process_template(&input); - execute_task_with_retry( - &mut agent, - &processed_input, - show_prompt, - show_code, - &output, - ) - .await; - - // Send auto-memory reminder if enabled and tools were called - // Skip per-turn reminders when from_agent_mode - we'll send once on exit - if !from_agent_mode { - if let Err(e) = agent.send_auto_memory_reminder().await { - debug!("Auto-memory reminder failed: {}", e); - } - } + execute_user_input( + &mut agent, &input, show_prompt, show_code, &output, from_agent_mode + ).await; } } Err(ReadlineError::Interrupted) => {