Skip to content

fix(adapters): switch off Bun's fetch idle wait for model calls - #119

Open
DaXu999 wants to merge 1 commit into
mainfrom
fix/bun-fetch-timeout
Open

DaXu999 wants to merge 1 commit into
mainfrom
fix/bun-fetch-timeout

Conversation

@DaXu999

@DaXu999 DaXu999 commented Nov 8, 2026

Copy link
Copy Markdown
Collaborator

Why

#118 stopped Node's built-in fetch from cutting off a model that thinks for more than 300 s. Bun has the same kind of limit and #118 did not reach it: Bun's fetch fails a request after 5 minutes with no data either way (BUN_CONFIG_HTTP_IDLE_TIMEOUT), in practice at 6 because its timer ticks once a minute. Bun sets process.versions.node, so modelFetch took the Node path, and Bun's built-in stand-in for undici has an empty Agent that ignores headersTimeout and bodyTimeout. A model that thought for more than 6 minutes failed on Bun, every retry the same way.

What

  • On Bun, modelFetch now calls Bun's own fetch with timeout: false, which switches that wait off for the request. Bun is checked before Node. A timeout the caller passes is kept.
  • Node, Deno and a host that passes its own fetch are unchanged. Deno's fetch has no such wait (20-minute silences got through on Deno 2.9.8).
  • Two tests stand Bun in on Node (the process.versions.bun Bun sets and a recording global fetch). A CHANGELOG entry under Unreleased, Fixed.

Checks

  • On Node 24 and Node 22.19: format, typecheck, vitest 1172/1172, test:release and conformance:check. docs:api:check in a plain clone: up to date.
  • The two new tests fail with the Bun path turned off.
  • On Bun 1.4.4 at its default limit, against the built package: plain fetch failed at 360 s, while modelFetch and OpenAiCompatibleModelClient waited out 8 minutes of silence before the headers and in the body.

Related

Follow-up, not in this PR: stream model replies (stream: true). Today the reply comes in one response, so the connection is silent for the whole generation and any idle limit on the way (a proxy, a gateway) can still cut it. With streaming, text flows as it is written and OpenRouter sends keep-alive comments while the model thinks.

Bun's fetch fails a request after 5 minutes with no data either way
(BUN_CONFIG_HTTP_IDLE_TIMEOUT), in practice at 6 because its timer
ticks once a minute. Bun sets process.versions.node, so modelFetch
took the Node path, and Bun's built-in stand-in for undici has an
empty Agent that ignores headersTimeout and bodyTimeout. A model that
thought for more than 6 minutes failed on Bun, every retry the same.

On Bun, modelFetch now calls Bun's fetch with `timeout: false`, which
switches that wait off for the request. A timeout the caller passes is
kept. Deno's fetch has no such wait and is unchanged.

Checked on Bun 1.4.4 with the idle limit shrunk to 5 s: plain fetch
failed at 12 s, while modelFetch and OpenAiCompatibleModelClient waited
out a 30 s silence before the headers and in the body.
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