Per-eval / per-call runtime knobs for the loop: Python-sandbox eval timeouts
(with clamping and a shell-timeout-aware widener), the svar/ask-code! stream
watchdog defaults, and the dynamic vars the loop binds per call.
A LEAF — depends on nothing else in the engine, so the loop and its tests read these settings from one place instead of carrying them in the loop namespace.
Per-eval / per-call runtime knobs for the loop: Python-sandbox eval timeouts (with clamping and a shell-timeout-aware widener), the `svar/ask-code!` stream watchdog defaults, and the dynamic vars the loop binds per call. A LEAF — depends on nothing else in the engine, so the loop and its tests read these settings from one place instead of carrying them in the loop namespace.
Dynamic timeout in milliseconds for Python code evaluation.
Dynamic timeout in milliseconds for Python code evaluation.
Dynamic context for RLM debug logging.
Dynamic context for RLM debug logging.
Default inter-chunk idle timeout for Vis svar/ask-code! calls (ms).
Fires when the transport itself goes silent — not one byte, not even an
SSE keepalive comment. 300s = CODEX PARITY with
DEFAULT_STREAM_IDLE_TIMEOUT_MS; see ASK_CODE_SEMANTIC_TIMEOUT_MS for
why nothing shorter is safe against the OpenAI Responses wire. All three
stream watchdogs now share ONE budget, so no phase can hang up early on
a model that is still working.
Default inter-chunk idle timeout for Vis `svar/ask-code!` calls (ms). Fires when the transport itself goes silent — not one byte, not even an SSE keepalive comment. 300s = CODEX PARITY with `DEFAULT_STREAM_IDLE_TIMEOUT_MS`; see `ASK_CODE_SEMANTIC_TIMEOUT_MS` for why nothing shorter is safe against the OpenAI Responses wire. All three stream watchdogs now share ONE budget, so no phase can hang up early on a model that is still working.
Default model/progress timeout for Vis svar/ask-code! streams (ms).
Catches the failure mode idle-timeout-ms cannot: the transport
keeps emitting bytes (SSE : ping comments, blank separators, or
any framing-layer keepalive that returns from .readLine) which
resets the idle watchdog forever, yet zero response.*.delta /
message.* events ever arrive. Without this watchdog the iteration
loop blocks on .readLine until the model finally streams output.
300s (300000 ms) is CODEX PARITY: the OpenAI Codex CLI runs exactly
one stream watchdog, stream_idle_timeout_ms, whose built-in default
is DEFAULT_STREAM_IDLE_TIMEOUT_MS = 300_000 — nothing shorter is
safe against the OpenAI Responses wire, where a gpt-5.x turn with
encrypted reasoning and no summary deltas legitimately emits NOTHING
for minutes between response.* events. It also clears Anthropic's
documented worst case for extended thinking on Opus 4.5
(anthropics/claude-agent-sdk-typescript#44).
A shorter budget (this was 185s) does not surface a real provider fault — it HANGS UP on a model that is still thinking, and the turn dies mid-reasoning.
Disable per call with :semantic-timeout-ms nil.
Default model/progress timeout for Vis `svar/ask-code!` streams (ms). Catches the failure mode `idle-timeout-ms` cannot: the transport keeps emitting bytes (SSE `: ping` comments, blank separators, or any framing-layer keepalive that returns from `.readLine`) which resets the idle watchdog forever, yet zero `response.*.delta` / `message.*` events ever arrive. Without this watchdog the iteration loop blocks on `.readLine` until the model finally streams output. 300s (300000 ms) is CODEX PARITY: the OpenAI Codex CLI runs exactly one stream watchdog, `stream_idle_timeout_ms`, whose built-in default is `DEFAULT_STREAM_IDLE_TIMEOUT_MS = 300_000` — nothing shorter is safe against the OpenAI Responses wire, where a gpt-5.x turn with encrypted reasoning and no summary deltas legitimately emits NOTHING for minutes between `response.*` events. It also clears Anthropic's documented worst case for extended thinking on Opus 4.5 (anthropics/claude-agent-sdk-typescript#44). A shorter budget (this was 185s) does not surface a real provider fault — it HANGS UP on a model that is still thinking, and the turn dies mid-reasoning. Disable per call with `:semantic-timeout-ms nil`.
Default time-to-first-token timeout for Vis svar/ask-code! calls (ms).
300s = CODEX PARITY. The Codex CLI has NO separate first-token budget:
its single stream_idle_timeout_ms (default
DEFAULT_STREAM_IDLE_TIMEOUT_MS = 300_000) governs the wait for the
FIRST event exactly like every later gap. Vis splits the watchdog into
ttft/idle/semantic phases, so each phase gets that same budget — a
shorter one only means Vis hangs up first on a queued, cold-starting or
long-reasoning provider, and a stricter pre-header window buys nothing:
a genuinely dead connection still fails on its own transport error.
Default time-to-first-token timeout for Vis `svar/ask-code!` calls (ms). 300s = CODEX PARITY. The Codex CLI has NO separate first-token budget: its single `stream_idle_timeout_ms` (default `DEFAULT_STREAM_IDLE_TIMEOUT_MS = 300_000`) governs the wait for the FIRST event exactly like every later gap. Vis splits the watchdog into ttft/idle/semantic phases, so each phase gets that same budget — a shorter one only means Vis hangs up first on a queued, cold-starting or long-reasoning provider, and a stricter pre-header window buys nothing: a genuinely dead connection still fails on its own transport error.
(clamp-eval-timeout-ms candidate)Clamp a candidate eval timeout to [MIN_EVAL_TIMEOUT_MS, MAX_EVAL_TIMEOUT_MS].
Clamp a candidate eval timeout to [MIN_EVAL_TIMEOUT_MS, MAX_EVAL_TIMEOUT_MS].
Default timeout in milliseconds for code evaluation in the Python sandbox.
Default timeout in milliseconds for code evaluation in the Python sandbox.
(explicit-shell-timeout-secs code)Best-effort scan for explicit shell/subprocess timeout overrides in Python code. The real shell tool still owns validation/clamping; this only prevents the outer eval watchdog (default 120s) from preempting a longer requested shell timeout.
Best-effort scan for explicit shell/subprocess timeout overrides in Python code. The real shell tool still owns validation/clamping; this only prevents the outer eval watchdog (default 120s) from preempting a longer requested shell timeout.
Hard ceiling for :eval-timeout-ms.
Hard ceiling for :eval-timeout-ms.
(native-tool-timeout-ms input)Return the outer wall-clock deadline for a native handler. Always sits a short
grace period ABOVE the tool's own budget — an explicit timeout_ms, otherwise
the 30-second fallback — so a tool whose internal timeout equals the fallback
(e.g. repl_eval's 30s default) still gets to produce its STRUCTURED timeout
result before the wall fires. Capped at MAX_EVAL_TIMEOUT_MS.
Return the outer wall-clock deadline for a native handler. Always sits a short grace period ABOVE the tool's own budget — an explicit `timeout_ms`, otherwise the 30-second fallback — so a tool whose internal timeout equals the fallback (e.g. repl_eval's 30s default) still gets to produce its STRUCTURED timeout result before the wall fires. Capped at `MAX_EVAL_TIMEOUT_MS`.
Wall-clock fallback for Clojure-native tool handlers when the caller does not
request a timeout_ms — 30 seconds. Calls expected to take longer must
explicitly request a timeout or use a background workflow. Slow synchronous
SETUP (e.g. a cold project-REPL boot) runs OUTSIDE this wall via the loop's
:vis/outside-tool-wall hook, so it never bills against this budget.
Wall-clock fallback for Clojure-native tool handlers when the caller does not request a `timeout_ms` — 30 seconds. Calls expected to take longer must explicitly request a timeout or use a background workflow. Slow synchronous SETUP (e.g. a cold project-REPL boot) runs OUTSIDE this wall via the loop's `:vis/outside-tool-wall` hook, so it never bills against this budget.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |