diff --git a/src/config/agent.rs b/src/config/agent.rs index 973bc8d..8ffb077 100644 --- a/src/config/agent.rs +++ b/src/config/agent.rs @@ -439,6 +439,10 @@ impl Agent { self.config.summarization_threshold } + pub fn escalation_timeout(&self) -> u64 { + self.config.escalation_timeout + } + pub fn continuation_count(&self) -> usize { self.continuation_count } @@ -655,6 +659,8 @@ pub struct AgentConfig { pub summarization_model: Option, #[serde(default = "default_summarization_threshold")] pub summarization_threshold: usize, + #[serde(default = "default_escalation_timeout")] + pub escalation_timeout: u64, } fn default_max_auto_continues() -> usize { @@ -677,6 +683,10 @@ fn default_summarization_threshold() -> usize { 4000 } +fn default_escalation_timeout() -> u64 { + 300 +} + impl AgentConfig { pub fn load(path: &Path) -> Result { let contents = read_to_string(path) diff --git a/src/function/user_interaction.rs b/src/function/user_interaction.rs index cfd48ff..501e069 100644 --- a/src/function/user_interaction.rs +++ b/src/function/user_interaction.rs @@ -11,7 +11,7 @@ use tokio::sync::oneshot; pub const USER_FUNCTION_PREFIX: &str = "user__"; -const ESCALATION_TIMEOUT: Duration = Duration::from_secs(300); +const DEFAULT_ESCALATION_TIMEOUT_SECS: u64 = 300; pub fn user_interaction_function_declarations() -> Vec { vec![ @@ -206,7 +206,7 @@ async fn handle_escalated(config: &GlobalConfig, action: &str, args: &Value) -> .collect() }); - let (from_agent_id, from_agent_name, root_queue) = { + let (from_agent_id, from_agent_name, root_queue, timeout_secs) = { let cfg = config.read(); let agent_id = cfg .self_agent_id @@ -221,7 +221,12 @@ async fn handle_escalated(config: &GlobalConfig, action: &str, args: &Value) -> .root_escalation_queue .clone() .ok_or_else(|| anyhow!("No escalation queue available; cannot reach parent agent"))?; - (agent_id, agent_name, queue) + let timeout = cfg + .agent + .as_ref() + .map(|a| a.escalation_timeout()) + .unwrap_or(DEFAULT_ESCALATION_TIMEOUT_SECS); + (agent_id, agent_name, queue, timeout) }; let escalation_id = new_escalation_id(); @@ -238,7 +243,8 @@ async fn handle_escalated(config: &GlobalConfig, action: &str, args: &Value) -> root_queue.submit(request); - match tokio::time::timeout(ESCALATION_TIMEOUT, rx).await { + let timeout = Duration::from_secs(timeout_secs); + match tokio::time::timeout(timeout, rx).await { Ok(Ok(reply)) => Ok(json!({ "answer": reply })), Ok(Err(_)) => Ok(json!({ "error": "Escalation was cancelled. The parent agent dropped the request", @@ -246,8 +252,7 @@ async fn handle_escalated(config: &GlobalConfig, action: &str, args: &Value) -> })), Err(_) => Ok(json!({ "error": format!( - "Escalation timed out after {} seconds waiting for user response", - ESCALATION_TIMEOUT.as_secs() + "Escalation timed out after {timeout_secs} seconds waiting for user response" ), "fallback": "Make your best judgment and proceed", })),