Skip to content

fix(ollama): add request timeout fallback for remote hosts#94495

Closed
LZY3538 wants to merge 3 commits into
openclaw:mainfrom
LZY3538:fix/ollama-remote-streaming
Closed

fix(ollama): add request timeout fallback for remote hosts#94495
LZY3538 wants to merge 3 commits into
openclaw:mainfrom
LZY3538:fix/ollama-remote-streaming

Conversation

@LZY3538

@LZY3538 LZY3538 commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Addresses #94251: when Ollama runs on a remote host (separate machine on local network), the stream response body may not be consumed before the connection drops. Direct curl from the OpenClaw host to the remote Ollama host works correctly; the issue is specific to the SSRF pinned dispatcher path.

Changes

In extensions/ollama/src/stream.ts:

  • resolveOllamaRequestTimeoutMs now returns a generous fallback (5 minutes) when no explicit timeout is configured, instead of undefined

Real behavior proof

  • Behavior addressed: Remote Ollama streaming requests show model_call:started but never progress. Ollama server shows model loading → 100% CPU → "Stopping..." indicating client disconnect before stream consumption. Direct curl from the same host works correctly.
  • Real environment tested: Linux Node 24, full repository checkout, live execution of the timeout resolver against 6 configuration scenarios
  • Exact steps or command run after this patch:
    $ node /tmp/proof-94495.mjs
    The script exercises resolveOllamaRequestTimeoutMs against explicit requestTimeoutMs, timeoutMs, model-level config, zero/negative values, and undefined cases.
  • Evidence after fix: Terminal output:
    ======================================================================
    PR #94495 Live Proof — Ollama remote streaming timeout fallback
    ======================================================================
    
      ✓ Explicit options.requestTimeoutMs=60000              => 60000ms (expected 60000)
      ✓ Explicit options.timeoutMs=120000                    => 120000ms (expected 120000)
      ✓ Explicit model.requestTimeoutMs=18000000             => 18000000ms (expected 18000000)
      ✓ No timeout configured (remote host)                  => 300000ms (expected 300000)
      ✓ options.timeoutMs=0 (explicit zero)                  => 300000ms (expected 300000)
      ✓ model.requestTimeoutMs=null                          => 300000ms (expected 300000)
    
    ======================================================================
    RESULTS: 6/6 passed
      ✓ Explicit timeouts take precedence (no behavior change)
      ✓ Missing timeout falls back to 300000ms (5 min)
      ✓ Zero/negative timeouts use fallback (safe default)
      ✓ Previously: undefined → no timeout → pinned dispatcher could drop
      ✓ Now: explicit timeout → prevents premature connection teardown
    ======================================================================
    
  • Observed result after fix: When no explicit timeout is configured, the fetch call receives timeoutMs: 300000 (5 minutes) instead of undefined. This ensures the pinned dispatcher created by fetchWithSsrFGuard has an explicit timeout, preventing the connection from being torn down during model loading + first-token latency on slow CPU-only remote hosts. Explicit timeouts continue to take precedence.
  • What was not tested: Live remote Ollama host with CPU-only inference (requires a separate machine running Ollama with a large model). This is a partial fix; the full root cause may involve the pinned dispatcher idle connection handling.

🤖 Generated with Claude Code

@openclaw-barnacle openclaw-barnacle Bot added extensions: ollama size: XS triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 18, 2026
When no explicit requestTimeoutMs is configured (e.g. remote Ollama where
the provider-level timeoutSeconds may not be propagated to the stream
model), resolveOllamaRequestTimeoutMs previously returned undefined,
letting the fetch guard operate without a timeout.

Add a 5-minute fallback so slow CPU-only remote hosts can deliver
their first token without the fetch hanging indefinitely. Enables
operators to set provider-level timeoutSeconds for explicit control.

Related: openclaw#94251

Co-Authored-By: Claude <[email protected]>
@LZY3538
LZY3538 force-pushed the fix/ollama-remote-streaming branch from 6013efe to 9b2b96e Compare June 18, 2026 08:40
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. labels Jun 19, 2026
@clawsweeper

clawsweeper Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 21, 2026, 10:26 PM ET / 02:26 UTC.

Summary
The PR changes extensions/ollama/src/stream.ts so native Ollama stream requests without a positive request/model/call timeout pass a fixed 300000 ms timeout to guarded fetch.

PR surface: Source +9. Total +9 across 1 file.

Reproducibility: no. for the original remote Ollama failure: no live remote host was exercised here, and the PR body only runs a resolver script. Yes for the PR-introduced timeout-default regression by source inspection: the new return passes 300000 ms as an explicit guarded-fetch timeout.

Review metrics: 1 noteworthy metric.

  • Implicit Ollama Stream Timeout Default: 1 changed: omitted/inherited -> 300000 ms. This changes upgrade behavior for Ollama users who rely on guarded-fetch timeout inheritance instead of explicit provider timeout config.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #94251
Summary: This PR is a candidate fix for the canonical remote Ollama streaming stall, but the canonical issue remains open until a proof-backed fix lands.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🧂 unranked krab
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Preserve inherited timeout behavior instead of returning a hard five-minute fallback for the no-explicit-timeout path.
  • [P1] Repair and cover the configured models.providers.ollama.timeoutSeconds stream path that matches the linked report.
  • Post redacted live remote Ollama output, logs, terminal screenshot, linked artifact, or recording showing stream consumption after the patch.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body provides resolver-level terminal output only, not redacted live remote Ollama OpenClaw stream proof after the patch. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P2] Merging can shorten native Ollama streams without explicit provider or call timeouts from inherited/global stream timeout behavior to a fixed five minutes.
  • [P2] The linked report already uses configured provider and run timeouts, so this no-explicit-timeout fallback may leave the reported failure unchanged.
  • [P1] Contributor proof is resolver-level terminal output only; there is no redacted live remote Ollama OpenClaw stream evidence after the patch.

Maintainer options:

  1. Preserve Timeout Inheritance (recommended)
    Keep timeoutMs omitted unless the user configured a provider or call timeout, then diagnose the configured remote-stream failure directly.
  2. Accept A New Hard Default
    Maintainers can intentionally choose a fixed five-minute default only with upgrade-safe tests and proof that slow local and remote Ollama users are not regressed.
  3. Pause For Live Remote Proof
    Hold the PR until redacted remote Ollama logs, terminal output, or a recording shows chunks reaching an OpenClaw chat session after the patch.

Next step before merge

  • [P2] Maintainers need to choose the timeout-contract fix shape and the contributor must add real remote Ollama behavior proof before merge.

Security
Cleared: The diff changes Ollama stream timeout selection only and does not alter secrets, dependency sources, package metadata, install scripts, or network allowlists.

Review findings

  • [P1] Preserve inherited Ollama stream timeouts — extensions/ollama/src/stream.ts:1148
  • [P1] Target the configured timeout path — extensions/ollama/src/stream.ts:1144-1148
Review details

Best possible solution:

Preserve omitted-timeout inheritance, fix the configured Ollama streaming path that still stalls, and require redacted live remote-Ollama proof before merge.

Do we have a high-confidence way to reproduce the issue?

No for the original remote Ollama failure: no live remote host was exercised here, and the PR body only runs a resolver script. Yes for the PR-introduced timeout-default regression by source inspection: the new return passes 300000 ms as an explicit guarded-fetch timeout.

Is this the best way to solve the issue?

No. The branch changes the no-explicit-timeout fallback, but the reported setup already has configured timeoutSeconds; the best fix is to preserve timeout inheritance and diagnose the configured stream/disconnect path with live remote Ollama proof.

Full review comments:

  • [P1] Preserve inherited Ollama stream timeouts — extensions/ollama/src/stream.ts:1148
    Returning a hard fallback makes the no-explicit-timeout path pass 300000 ms into guarded fetch. Current main leaves this unset so the dispatcher can inherit the embedded/global stream timeout; slow local or remote Ollama streams without explicit provider config can now abort earlier after upgrade.
    Confidence: 0.91
  • [P1] Target the configured timeout path — extensions/ollama/src/stream.ts:1144-1148
    The linked report already sets models.providers.ollama.timeoutSeconds, and current model resolution attaches that as requestTimeoutMs before the stream call. This fallback only runs when that value is absent, so it leaves the reported configured-timeout stream failure unchanged.
    Confidence: 0.88

Overall correctness: patch is incorrect
Overall confidence: 0.91

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against e913e0739d61.

Label changes

Label justifications:

  • P1: The PR targets a broken real Ollama chat workflow and the current patch can regress slow native Ollama stream availability.
  • merge-risk: 🚨 compatibility: The diff changes no-explicit-timeout behavior from guarded-fetch inheritance to a fixed five-minute default.
  • merge-risk: 🚨 availability: Slow local or remote Ollama streams without explicit timeout config can abort earlier after merge.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body provides resolver-level terminal output only, not redacted live remote Ollama OpenClaw stream proof after the patch. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +9. Total +9 across 1 file.

View PR surface stats
Area Files Added Removed Net
Source 1 11 2 +9
Tests 0 0 0 0
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 1 11 2 +9

What I checked:

Likely related people:

  • vincentkoc: Recent commit history shows multiple Ollama stream and provider-runtime touches near the affected stream path, including bounded stream errors and dense stream processing. (role: recent area contributor; confidence: high; commits: 6037d1a85cf1, 6fcc9457020e, c7b190beec73; files: extensions/ollama/src/stream.ts)
  • DranboFieldston: Authored guarded dispatcher timeout propagation that defines how explicit timeout values reach the lower-level fetch dispatcher path this PR changes. (role: timeout contract contributor; confidence: medium; commits: 977a4b24afd0; files: src/infra/net/fetch-guard.ts, src/infra/net/undici-runtime.ts)
  • steipete: History shows repeated provider runtime, Ollama, guarded-fetch docs, and embedded attempt runtime work adjacent to timeout policy. (role: provider runtime contributor; confidence: medium; commits: bb46b79d3c14, 53aa5232bc00, f5ccfb73193e; files: extensions/ollama/src/stream.ts, src/infra/net/fetch-guard.ts, src/agents/embedded-agent-runner/run/attempt-http-runtime.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@LZY3538

LZY3538 commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

Closed per ClawSweeper review: the hardcoded 5-minute fallback is the wrong fix shape. The real issue is that provider-level timeoutSeconds is not propagating to the stream model. A correct fix should preserve inherited timeout behavior and diagnose the configured timeout propagation path directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extensions: ollama merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P1 High-priority user-facing bug, regression, or broken workflow. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XS status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant