feat(acp,desktop): bump idle timeout default from 300s to 320s (#195)

This commit is contained in:
tlongwell-block
2026-03-27 22:57:08 -04:00
committed by GitHub
parent 1dcba0a200
commit e33c6bc0f2
7 changed files with 21 additions and 21 deletions
+2 -2
View File
@@ -137,8 +137,8 @@ RUST_LOG=sprout_relay=debug,sprout_db=debug,sprout_auth=debug,sprout_pubsub=debu
# SPROUT_ACP_MODEL=
# ── Timeouts & sessions ──────────────────────────────────────────────────────
# Max seconds per agent turn before timeout (default 300 = 5 min).
# SPROUT_ACP_TURN_TIMEOUT=300
# Max seconds per agent turn before timeout (default 320 = ~5 min).
# SPROUT_ACP_TURN_TIMEOUT=320
# Max turns per session before proactive rotation. 0 = disabled (rotate only
# on MaxTokens / MaxTurnRequests). Recommended: 50 for long-running agents.
+2 -2
View File
@@ -1558,10 +1558,10 @@ mod tests {
#[test]
fn idle_timeout_error_includes_duration() {
let err = AcpError::IdleTimeout(std::time::Duration::from_secs(300));
let err = AcpError::IdleTimeout(std::time::Duration::from_secs(320));
let msg = err.to_string();
assert!(
msg.contains("300"),
msg.contains("320"),
"IdleTimeout display should include duration: {msg}"
);
}
+8 -8
View File
@@ -486,7 +486,7 @@ impl Config {
};
// Resolve idle_timeout_secs with deprecation handling.
// Precedence: explicit --idle-timeout > --turn-timeout (deprecated) > default 300.
// Precedence: explicit --idle-timeout > --turn-timeout (deprecated) > default 320.
let idle_timeout_secs = {
let raw = match (args.idle_timeout, args.turn_timeout) {
(Some(idle), Some(_turn)) => {
@@ -504,7 +504,7 @@ impl Config {
);
turn
}
(None, None) => 300, // default
(None, None) => 320, // default: 20s buffer over goose's 300s turn timeout
};
if raw == 0 {
tracing::warn!("idle timeout of 0 is invalid — using 1s minimum");
@@ -889,7 +889,7 @@ mod tests {
agent_command: "goose".into(),
agent_args: vec!["acp".into()],
mcp_command: "sprout-mcp-server".into(),
idle_timeout_secs: 300,
idle_timeout_secs: 320,
max_turn_duration_secs: 3600,
agents: 1,
heartbeat_interval_secs: 0,
@@ -1579,13 +1579,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 300.
/// Precedence: explicit --idle-timeout > --turn-timeout (deprecated) > default 320.
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) => 300,
(None, None) => 320,
};
if raw == 0 {
1
@@ -1605,8 +1605,8 @@ channels = "ALL"
}
#[test]
fn idle_timeout_defaults_to_300_when_neither_set() {
assert_eq!(resolve_idle_timeout(None, None), 300);
fn idle_timeout_defaults_to_320_when_neither_set() {
assert_eq!(resolve_idle_timeout(None, None), 320);
}
#[test]
@@ -1624,7 +1624,7 @@ channels = "ALL"
let config = test_config(SubscribeMode::Mentions);
let summary = config.summary();
assert!(
summary.contains("idle_timeout=300s"),
summary.contains("idle_timeout=320s"),
"summary should include idle_timeout: {summary}"
);
assert!(
+1 -1
View File
@@ -368,7 +368,7 @@ pub async fn create_managed_agent(
.turn_timeout_seconds
.filter(|seconds| *seconds > 0)
.unwrap_or(DEFAULT_AGENT_TURN_TIMEOUT_SECONDS),
// 0 or None → harness uses its own default (300s idle, 3600s max), and the CLI also clamps 0 → minimum.
// 0 or None → harness uses its own default (320s idle, 3600s max), and the CLI also clamps 0 → minimum.
idle_timeout_seconds: input.idle_timeout_seconds.filter(|s| *s > 0),
max_turn_duration_seconds: input.max_turn_duration_seconds.filter(|s| *s > 0),
parallelism: input
@@ -319,11 +319,11 @@ pub const DEFAULT_ACP_COMMAND: &str = "sprout-acp";
pub const DEFAULT_ADMIN_COMMAND: &str = "sprout-admin";
pub const DEFAULT_AGENT_COMMAND: &str = "goose";
pub const DEFAULT_MCP_COMMAND: &str = "sprout-mcp-server";
/// 5 min — matches the CLI harness default (SPROUT_ACP_IDLE_TIMEOUT).
pub const DEFAULT_AGENT_TURN_TIMEOUT_SECONDS: u64 = 300;
/// ~5 min (320s) — matches the CLI harness default (SPROUT_ACP_IDLE_TIMEOUT).
pub const DEFAULT_AGENT_TURN_TIMEOUT_SECONDS: u64 = 320;
/// 1 hour — absolute wall-clock safety cap per turn.
pub const DEFAULT_AGENT_MAX_TURN_DURATION_SECONDS: u64 = 3600;
pub const DEFAULT_AGENT_PARALLELISM: u32 = 1;
pub const DEFAULT_AGENT_PARALLELISM: u32 = 3;
fn default_agent_parallelism() -> u32 {
DEFAULT_AGENT_PARALLELISM
@@ -63,8 +63,8 @@ export function CreateAgentDialog({
const [selectedScopes, setSelectedScopes] = React.useState<Set<TokenScope>>(
() => new Set<TokenScope>(DEFAULT_MANAGED_AGENT_SCOPES),
);
const [turnTimeoutSeconds, setTurnTimeoutSeconds] = React.useState("300");
const [parallelism, setParallelism] = React.useState("1");
const [turnTimeoutSeconds, setTurnTimeoutSeconds] = React.useState("320");
const [parallelism, setParallelism] = React.useState("3");
const [systemPrompt, setSystemPrompt] = React.useState("");
const [selectedProviderId, setSelectedProviderId] =
React.useState<string>("custom");
@@ -212,8 +212,8 @@ export function CreateAgentDialog({
setAgentCommand("goose");
setAgentArgs("acp");
setMcpCommand("sprout-mcp-server");
setTurnTimeoutSeconds("300");
setParallelism("1");
setTurnTimeoutSeconds("320");
setParallelism("3");
setSystemPrompt("");
setSelectedProviderId("custom");
setHasSyncedProviderSelection(false);
+1 -1
View File
@@ -2578,7 +2578,7 @@ async function handleCreateManagedAgent(args: {
? [...args.input.agentArgs]
: ["acp"],
mcp_command: args.input.mcpCommand ?? "sprout-mcp-server",
turn_timeout_seconds: args.input.turnTimeoutSeconds ?? 300,
turn_timeout_seconds: args.input.turnTimeoutSeconds ?? 320,
idle_timeout_seconds: args.input.idleTimeoutSeconds ?? null,
max_turn_duration_seconds: args.input.maxTurnDurationSeconds ?? null,
parallelism: args.input.parallelism ?? 1,