Files
OmniRoute/changelog.d
Markus Hartung 4d2abc313e fix(sse): cap streaming headers-wait timeout to a client-realistic ceiling (#11526)
The fetch-start (headers-wait) phase inherited the flat, non-adaptive
FETCH_TIMEOUT_MS (default 600_000ms) with no ceiling comparable to a real
client's patience, unlike the body-phase readiness watchdog which already
adapts per payload shape. Codex's own hard client-abort window for a
stalled turn is ~120s, 5x shorter than the old default — so when an
upstream never returned any response at all (not even headers, e.g. a
stalled NVIDIA target behind a tool-heavy Responses->Chat translation),
OmniRoute kept the connection open on keepalives only, guaranteeing the
client gave up first with an opaque 499 instead of OmniRoute detecting and
failing the stall fast.

Adds resolveFetchStartTimeout() (open-sse/utils/fetchStartTimeoutPolicy.ts)
that caps the headers-wait timeout to 110s for STREAMING requests only,
leaving non-streaming requests on the existing flat default. Wired into
BaseExecutor.execute(). The existing TimeoutError classification path
(chatCore.ts) already maps this to a 504, so no change was needed there.

Regression test: tests/unit/issue-11526-repro.test.ts.
2026-08-26 13:13:51 -03:00
..

changelog.d/ — changelog fragments

A PR never edits CHANGELOG.md directly during the cycle. Instead it adds ONE new file here — its changelog entry as a fragment. Two PRs never touch the same file, so changelog merge conflicts (the "CHANGELOG-eat" cascade that forced a re-sync push + full CI re-run after every sibling merge) are structurally impossible.

Convention

Directory Aggregates under
features/ ### ✨ New Features
fixes/ ### 🐛 Bug Fixes
maintenance/ ### 📝 Maintenance
  • Filename: <PR-number>-<short-slug>.md (e.g. fixes/6700-dockerfile-better-sqlite3.md). The PR number prefix keeps aggregation order deterministic.
  • Content: the exact bullet line(s) that should land in CHANGELOG.md, starting with - . Multi-line (continuation) bullets are fine. Keep the repo's credit format: (#PR — thanks @user).
  • One fragment per PR (rarely more, e.g. a PR that both fixes and adds).

Example

changelog.d/fixes/6496-cloudflare-relay-worker-syntax.md:

- **fix(providers):** Cloudflare relay Worker deploys use Service Worker syntax with `body_part` metadata ([#6496](https://github.com/diegosouzapw/OmniRoute/pull/6496)) — thanks @SeaXen

Aggregation

The release captain (or /generate-release) folds all fragments into CHANGELOG.md and deletes them:

node scripts/release/aggregate-changelog.mjs            # write + delete fragments
node scripts/release/aggregate-changelog.mjs --dry-run  # preview only

Fragment well-formedness is enforced by npm run check:changelog-integrity (the same gate that guards against CHANGELOG-eat for legacy direct edits).