From e26fbb3d4604d518a39cb16291d4061d4b5146d5 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Sun, 17 May 2026 01:22:09 +0200 Subject: [PATCH] fix(coding-agent): route global fetch through undici dispatcher closes #4519 --- packages/coding-agent/CHANGELOG.md | 1 + packages/coding-agent/src/cli.ts | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index d27ff42b..4e4c9e52 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -9,6 +9,7 @@ ### Fixed +- Fixed Node 26 OpenAI-compatible streams timing out after five idle minutes by routing global fetch through pi's undici dispatcher ([#4519](https://github.com/earendil-works/pi/issues/4519)). - Fixed macOS clipboard access errors under sandboxed pasteboard denial so they do not abort the process ([#4492](https://github.com/earendil-works/pi/issues/4492)). - Fixed the scoped model startup hint to show the configured model-cycle keybinding ([#4508](https://github.com/earendil-works/pi/issues/4508)). - Fixed `fd` auto-download on macOS x86_64 by pinning the last release that ships an Intel macOS binary ([#4559](https://github.com/earendil-works/pi/issues/4559)). diff --git a/packages/coding-agent/src/cli.ts b/packages/coding-agent/src/cli.ts index 6e0e8403..dcfb4bba 100644 --- a/packages/coding-agent/src/cli.ts +++ b/packages/coding-agent/src/cli.ts @@ -5,7 +5,7 @@ * * Test with: npx tsx src/cli-new.ts [args...] */ -import { EnvHttpProxyAgent, setGlobalDispatcher } from "undici"; +import { EnvHttpProxyAgent, setGlobalDispatcher, fetch as undiciFetch } from "undici"; import { APP_NAME } from "./config.js"; import { main } from "./main.js"; @@ -17,6 +17,15 @@ process.emitWarning = (() => {}) as typeof process.emitWarning; // (e.g. vLLM buffering a large tool call) exceed that and abort the SSE stream // with UND_ERR_BODY_TIMEOUT. Disable both — provider SDKs enforce their own // AbortController-based deadlines via retry.provider.timeoutMs. -setGlobalDispatcher(new EnvHttpProxyAgent({ bodyTimeout: 0, headersTimeout: 0 })); +// Node 26 uses an internal undici for globalThis.fetch that does not honor npm +// undici's global dispatcher, so route global fetch through npm undici as well. +const dispatcher = new EnvHttpProxyAgent({ bodyTimeout: 0, headersTimeout: 0 }); +setGlobalDispatcher(dispatcher); +const fetchWithDispatcher = undiciFetch as unknown as typeof fetch; +globalThis.fetch = (input, init) => + fetchWithDispatcher(input, { + ...init, + dispatcher, + } as unknown as RequestInit); main(process.argv.slice(2));