topology_exec: bump TURN_TIMEOUT to 700s to outlast daemon claude_cli
ci / gates (push) Successful in 5s
ci / frontend (push) Successful in 28s
ci / rust (push) Failing after 1m51s
ci / e2e (push) Has been skipped
ci / publish (push) Has been skipped

Verbose daemon logs revealed the real turn failure: the daemon's own
claude_cli provider was timing out at 180s while running a 10-15k
token coordinator prompt. The daemon reads its per-provider timeout
from ZEROCLAW_providers__models__claude_cli__default__timeout_ms —
we set that to 600000 (10 min) on gw-04 via a compose patch. Now the
executor's TURN_TIMEOUT (was 300s) must exceed the daemon's own
limit, or we kill the ws before the daemon can reply.

New sequence: daemon has up to 600s to invoke claude and return a
response; executor waits up to 700s (100s headroom) for the ws
event stream to drain. If claude takes 500s, both survive. If the
daemon really does hang past 600s, its own timeout fires first and
we get a proper "provider timed out" error instead of a phantom
executor timeout.

Compose env applied on gw-04 in the same session:
- ZEROCLAW_providers__models__claude_cli__default__timeout_ms=600000
- ZEROCLAW_providers__models__claude_cli__door__timeout_ms=600000
(backup: /opt/clawmates/docker-compose.yml.bak-timeout)
Server container recreated to pick them up; env verified.

Follow-up: the coordinator prompt is legitimately huge (autonomy
contract + roster + description + repo tree + integration-plan
template + operator notes = 10-15k tokens). We should consider
either shrinking it or breaking the work into multiple smaller
turns so the daemon isn't gambling on a single call taking 3-8
minutes.
This commit is contained in:
Omar Sobh
2026-07-11 09:37:52 -07:00
parent 7e0620fd08
commit 3373f57da0
+9 -6
View File
@@ -24,12 +24,15 @@ use tokio::sync::Mutex;
use tokio_tungstenite::connect_async;
use tokio_tungstenite::tungstenite::Message;
/// Overall wall-clock budget for draining one turn's event stream. 90s
/// was tripping legitimate research-coordinator turns (long prompt plus
/// cold tool-selection routinely runs 60-120s). 300s gives room for a
/// real turn while still bounding worst-case at a walk-away limit so a
/// stuck daemon can't hang the worker forever.
const TURN_TIMEOUT: Duration = Duration::from_secs(300);
/// Overall wall-clock budget for draining one turn's event stream. Must
/// exceed the daemon's own claude_cli provider timeout (600s on gw-04
/// via ZEROCLAW_providers__models__claude_cli__default__timeout_ms) —
/// otherwise the executor kills the ws before the daemon can reply and
/// we see a phantom "turn timed out" while the daemon still logs a
/// successful llm response coming back. 700s gives 100s of headroom so
/// a daemon that just barely made it under its own limit doesn't lose
/// its answer here.
const TURN_TIMEOUT: Duration = Duration::from_secs(700);
/// Drives ZeroClaw role-agents (in one container) to execute topology turns.
pub struct ZeroClawDriveExecutor {