chore(acp): raise default idle timeout from 320s to 620s (#566)

Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com>
This commit is contained in:
tlongwell-block
2026-05-13 11:04:53 -04:00
committed by GitHub
parent e427581ca3
commit 8d5abb7a09
3 changed files with 23 additions and 11 deletions
+1 -1
View File
@@ -105,7 +105,7 @@ All configuration is via environment variables (or CLI flags — every env var h
| `SPROUT_ACP_AGENT_COMMAND` | no | `goose` | Agent binary to spawn. |
| `SPROUT_ACP_AGENT_ARGS` | no | `acp` | Agent arguments (comma-separated). |
| `SPROUT_ACP_MCP_COMMAND` | no | `sprout-mcp-server` | Path to the Sprout MCP server binary. |
| `SPROUT_ACP_IDLE_TIMEOUT` | no | `300` | Idle timeout: max seconds of silence before cancelling a turn. Resets on any agent stdout activity. |
| `SPROUT_ACP_IDLE_TIMEOUT` | no | `620` | Idle timeout: max seconds of silence before cancelling a turn. Resets on any agent stdout activity. |
| `SPROUT_ACP_MAX_TURN_DURATION` | no | `3600` | Absolute wall-clock cap per turn (safety valve). |
| `SPROUT_API_TOKEN` | no | — | API token (required if relay enforces token auth). |
+21 -9
View File
@@ -13,6 +13,17 @@ use uuid::Uuid;
use crate::filter::SubscriptionRule;
// ── Constants ─────────────────────────────────────────────────────────────────
/// Default idle timeout (seconds) when neither `--idle-timeout` nor the
/// deprecated `--turn-timeout` is set.
///
/// Sized for slow turns where the agent may go silent on its outer ACP channel
/// while running long sub-tools (e.g. a sprout-agent running another agent, or
/// codex/claude doing multi-minute single tool calls). 600s working budget +
/// 20s buffer. Override via `--idle-timeout` / `SPROUT_ACP_IDLE_TIMEOUT`.
pub(crate) const DEFAULT_IDLE_TIMEOUT_SECS: u64 = 620;
// ── Errors ────────────────────────────────────────────────────────────────────
#[derive(Debug, Error)]
@@ -597,7 +608,7 @@ impl Config {
};
// Resolve idle_timeout_secs with deprecation handling.
// Precedence: explicit --idle-timeout > --turn-timeout (deprecated) > default 320.
// Precedence: explicit --idle-timeout > --turn-timeout (deprecated) > `DEFAULT_IDLE_TIMEOUT_SECS`.
let idle_timeout_secs = {
let raw = match (args.idle_timeout, args.turn_timeout) {
(Some(idle), Some(_turn)) => {
@@ -615,7 +626,7 @@ impl Config {
);
turn
}
(None, None) => 320, // default: 20s buffer over goose's 300s turn timeout
(None, None) => DEFAULT_IDLE_TIMEOUT_SECS,
};
if raw == 0 {
tracing::warn!("idle timeout of 0 is invalid — using 1s minimum");
@@ -1092,7 +1103,7 @@ mod tests {
agent_command: "goose".into(),
agent_args: vec!["acp".into()],
mcp_command: "sprout-mcp-server".into(),
idle_timeout_secs: 320,
idle_timeout_secs: DEFAULT_IDLE_TIMEOUT_SECS,
max_turn_duration_secs: 3600,
agents: 1,
heartbeat_interval_secs: 0,
@@ -1800,13 +1811,13 @@ channels = "ALL"
// ── Idle timeout config precedence ─────────────────────────────────────
/// Helper: resolve idle_timeout_secs using the same precedence logic as Config::from_args.
/// Precedence: explicit --idle-timeout > --turn-timeout (deprecated) > default 320.
/// Precedence: explicit --idle-timeout > --turn-timeout (deprecated) > `DEFAULT_IDLE_TIMEOUT_SECS`.
fn resolve_idle_timeout(idle: Option<u64>, turn: Option<u64>) -> u64 {
let raw = match (idle, turn) {
(Some(idle), Some(_)) => idle,
(Some(idle), None) => idle,
(None, Some(turn)) => turn,
(None, None) => 320,
(None, None) => DEFAULT_IDLE_TIMEOUT_SECS,
};
if raw == 0 {
1
@@ -1826,8 +1837,8 @@ channels = "ALL"
}
#[test]
fn idle_timeout_defaults_to_320_when_neither_set() {
assert_eq!(resolve_idle_timeout(None, None), 320);
fn idle_timeout_defaults_to_constant_when_neither_set() {
assert_eq!(resolve_idle_timeout(None, None), DEFAULT_IDLE_TIMEOUT_SECS);
}
#[test]
@@ -1844,9 +1855,10 @@ channels = "ALL"
fn test_config_summary_includes_idle_and_max_turn() {
let config = test_config(SubscribeMode::Mentions);
let summary = config.summary();
let expected_idle = format!("idle_timeout={DEFAULT_IDLE_TIMEOUT_SECS}s");
assert!(
summary.contains("idle_timeout=320s"),
"summary should include idle_timeout: {summary}"
summary.contains(&expected_idle),
"summary should include {expected_idle}: {summary}"
);
assert!(
summary.contains("max_turn=3600s"),
+1 -1
View File
@@ -2729,7 +2729,7 @@ mod build_mcp_servers_tests {
agent_command: "goose".into(),
agent_args: vec!["acp".into()],
mcp_command: "sprout-mcp-server".into(),
idle_timeout_secs: 320,
idle_timeout_secs: config::DEFAULT_IDLE_TIMEOUT_SECS,
max_turn_duration_secs: 3600,
agents: 1,
heartbeat_interval_secs: 0,