Skip to content

Plan 323 — a long prompt on a local model no longer reads as an unreachable runtime - #125

Merged
munchist merged 1 commit into
mainfrom
aflow/323-ollama-timeout
Oct 17, 2026
Merged

munchist merged 1 commit into
mainfrom
aflow/323-ollama-timeout

Conversation

@munchist

Copy link
Copy Markdown
Contributor

What broke

In the live test of #123, Helmsman's first turn on Gemma 4 26B failed three times, each attempt at almost exactly 300 s (11:16:29, 11:21:42, 11:26:58). Each time it was reported as Ollama is not reachable at http://127.0.0.1:11434: fetch failed, and Ollama was running throughout.

Why: Node's fetch (undici) abandons a response whose headers take 5 minutes (headersTimeout), and a body that stays silent for 5 (bodyTimeout). Ollama sends no headers until it has read the whole prompt, and Helmsman's prompt on this 24 GB machine took longer than that. The platform's own 15-minute idle window for local models (AI_LOCAL_MODEL_IDLE_TIMEOUT_MS, §9 G5) never got the chance to apply.

The cause is reproduced with a probe: an undici Agent with a 1 s headersTimeout fails as fetch failed, cause UND_ERR_HEADERS_TIMEOUT, and with 0 it waits. That holds on this machine's Node 22.16, which bundles undici 6.21, with undici 7 passed in as the dispatcher.

The fix

  • No transport limit on local-runtime requests. localRuntimeFetch sends every Ollama request (chat, embed, warm, status reads, pull, delete) through an undici Agent with neither limit. The caller's signal is the only limit: the idle window for a turn, the lease for a download. The pull stream needed this as well, because Ollama is silent while it checks a large layer's digest.
    • undici@^7 is now a declared dependency of @aflow/ai-client. 8.x requires Node ≥ 22.19, and this machine runs 22.16.
  • "Not reachable" only when nothing answers. That message is kept for connection causes (ECONNREFUSED, ENOTFOUND, EHOSTUNREACH, …). Any other broken request names its cause.
  • No retry after a silent idle window. When Ollama stays silent through the whole platform idle window, the turn fails non-retryable, with "Ollama sent nothing for 15 minutes…" and the remedy: a smaller window or a smaller model. A retry would read the prompt again from the start. The agent-turn "keep this turn short" advice is appended only to retryable timeouts.
  • Spill wording. The 32K estimate now says the model will spill as its conversations fill the window. While loaded, the model sits fully on the GPU.

Not in this PR

  • A long Helmsman prompt is still slow on a local model; that is the planned slimmer local prompt. After this fix, the first turn waits for the prompt rather than failing at 5 minutes.
  • The run surface still shows "internal platform error" rather than the stored provider message. That is a separate surface.

Testing

  • ollama.test.ts: four tests replace the old network-failure one:
    • nothing answering at the URL;
    • a request that broke off, reported by its cause;
    • requests carry the dispatcher;
    • silence through the idle window is not retried.
  • 40 tests across the three affected files pass, and yarn typecheck passes.
  • yarn test:changed: 16250 pass, 1 fails. The failure is the host checkoutReplacement test, which also failed on Plan 323 P3 + P3b — models on this computer, diagnosed, managed, and changed by Helmsman with approval #123 and imports nothing touched here.
  • Not yet run live. Once this is in live, a Helmsman turn in Walkthrough should run past 5 minutes and answer.

🤖 Generated with Claude Code

…hable runtime

Node's fetch abandons a response whose headers take five minutes. Ollama
sends none until it has read the whole prompt, and Helmsman's prompt on
Gemma took longer than that on a 24 GB machine: each attempt failed at
300 s as "Ollama is not reachable", three times, well inside the 15-minute
idle window the platform gives a local model.

- Every request to the local runtime goes through localRuntimeFetch, an
  undici Agent with no header or body limit, so the caller's signal is the
  only limit. The pull stream needed the same: the runtime is silent while
  it checks a large layer's digest.
- "Not reachable" only for causes that mean nothing answers at the URL;
  any other broken request names its cause.
- Silence through the whole idle window fails without a retry, naming the
  remedy (a smaller window or model), since a retry re-reads the prompt.
- The spill estimate says the model will spill as its conversations fill
  the window, not that it is spilling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@munchist
munchist merged commit e154e5a into main Oct 17, 2026
3 checks passed
@munchist
munchist deleted the aflow/323-ollama-timeout branch October 17, 2026 13:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant