Conversation
| */ | ||
| export function acpPromptStallMs(raw = process.env['ARI_ACP_PROMPT_STALL_MS']): number { | ||
| if (raw === undefined || raw.trim() === '') return 300_000 | ||
| if (raw === undefined || raw.trim() === '') return 1_200_000 |
There was a problem hiding this comment.
🟡 Idle sessions reject fresh prompts
After 20 minutes without ACP traffic, prompt can reject a fresh turn on its first watchdog tick. #lastInboundAt still timestamps the previous turn instead of the new request.
Learn more
The stall limit describes silence during one prompt, but the watchdog uses a connection-wide timestamp. A connection can remain open between turns. Starting a prompt does not reset that timestamp, so the first interval callback can see more than 20 minutes of silence even though the request was just sent. The default interval checks every two seconds.
Example: A user finishes one turn at 10:00 and sends another at 10:25. The new agent receives the request, but Ari can reject it around 10:25:02 instead of allowing 20 minutes for a response.
Recommended fix: Give each stalled request a fresh baseline when #request starts. Preserve subsequent updates from inbound traffic, preferably with request-local liveness state so unrelated concurrent requests cannot distort the deadline.
Was this helpful? React with 👍 or 👎 to provide feedback.
| const BASH_DEFAULT_TIMEOUT_SECONDS = 600 | ||
| const BASH_MAX_TIMEOUT_SECONDS = 1_800 |
There was a problem hiding this comment.
🟡 Interrupted Bash commands keep running
After an Ari Core turn is interrupted, executeBash keeps its child alive for the new 600-second default. ToolContext carries no AbortSignal, so cancelled commands can keep changing workspace files in the background.
Learn more
The engine calls the adapter's interrupt method immediately, and Ari Core aborts only its model requests and parked UI requests. Tool execution awaits executeBash without passing that signal. Node's execFile therefore retains the shell until it exits or its independent timeout fires. This PR raises that default lifetime from two to ten minutes and the maximum from ten to thirty minutes.
Example: A model starts bash with command: "sleep 300; echo changed > result.txt". The user interrupts after five seconds. The turn becomes interrupted, but the shell writes result.txt five minutes later.
Recommended fix: Add an AbortSignal to ToolContext, pass the turn signal from runAgentLoop, and supply it to execFile. Treat abort termination as an interrupted tool execution and ensure the entire spawned process tree is stopped on every platform.
Was this helpful? React with 👍 or 👎 to provide feedback.
Task
Harness idle timeouts kill legitimate long work: Ari Core streams die after 120s of silence (
endpoint sent nothing for 120s), and ACP prompts stall after 300s while a child is runningpnpm verify/ tests / builds with no protocol traffic.What changed
ARI_ACP_PROMPT_STALL_MSstill overrides;0still disables.bashdefault/max: 120s/600s → 600s/1800s, so verify-class commands finish without the model having to pass an explicit timeout.Wedge detection remains: a truly silent endpoint or ACP child still fails legibly instead of hanging forever.
How verified
VITEST_MAX_WORKERS=2 pnpm verifygreen (typecheck + lint + test). Desktop: 154 passed, 3 skipped (1404 tests). Focused:http-retry.test.ts,tools.test.ts,connection.test.ts.