In this article, we review undici.setGlobalDispatcher function in earendil-works/pi/packages/coding-agent. You will learn:
What is pi-coding-agent?
What is Undici?
setGlobalDispatcher method in pi-coding-agent
What is pi-coding-agent?
Pi is a minimal agent harness. Adapt Pi to your workflows, not the other way around. Customize Pi with extensions, skills, prompt templates and themes. Bundle them as Pi packages and share via npm or git.
Pi ships with powerful defaults but skips features like sub-agents and plan mode. Ask Pi to build what you want, or install a package that does it your way.
Four modes: interactive, print/JSON, RPC, and SDK.. See OpenClaw for a real-world integration.
Learn more about pi-coding-agent.
What is Undici?
Undici is a fast, modern HTTP/1.1 and HTTP/2 client written from scratch for Node.js. Maintained by the Node.js core team, it serves as the underlying engine that powers Node's built-in fetch global API.
Why Use the Standalone Package?
While Node.js embeds a version of Undici internally, installing it explicitly from the undici npm page gives you distinct advantages: [ 1, 2. ]
Advanced Features: Access specialized clients like ProxyAgent, Socks5Agent, and MockAgent.
Maximum Performance: Use the low-level undici.request function for faster request handling than standard fetch.
Connection Pooling: Configure and optimize connection limits and keep-alive behaviors manually.
HTTP Pipelining: Enable concurrent request pipelining over a single connection.
Latest Updates: Receive bug fixes, performance updates, and security patches without waiting for a full Node.js runtime upgrade. [ 1, 2, 3, 4, 5. ]
Learn more about Undici
setGlobalDispatcher method in pi-coding-agent
well, to understand why this method used in pi-coding-agent, we need to first check the official docs for this.
undici.setGlobalDispatcher(dispatcher)
Sets the global dispatcher used by Common API Methods. Global dispatcher is shared among compatible undici modules, including undici that is bundled internally with node.js.
Undici stores this dispatcher under Symbol.for('undici.globalDispatcher.2').
setGlobalDispatcher() also mirrors the configured dispatcher to Symbol.for('undici.globalDispatcher.1') using Dispatcher1Wrapper, so Node.js built-in fetch can keep using the legacy handler contract while Undici uses the new handler API.
Below is an example I picked from the Undici module docs
import { request, fetch, Agent, setGlobalDispatcher } from 'undici';
// Use undici.request for maximum performance
const { statusCode, headers, body } = await request('https://api.example.com/data');
const data = await body.json();
// Or use undici.fetch with custom configuration
const agent = new Agent({ keepAliveTimeout: 10000 });
setGlobalDispatcher(agent);
const response = await fetch('https://api.example.com/data');
This way, you can set your custom configuration and dispatch globally so the fetch uses the configuration dispatched. With this info, let's take a closer look at pi-coding-agent's usage.
The below code snippet is picked from pi/packages/coding-agent/src/core/http-dispatcher.ts..
...
export function configureHttpDispatcher(timeoutMs: number = DEFAULT_HTTP_IDLE_TIMEOUT_MS): void {
const normalizedTimeoutMs = parseHttpIdleTimeoutMs(timeoutMs);
if (normalizedTimeoutMs === undefined) {
throw new Error(`Invalid HTTP idle timeout: ${String(timeoutMs)}`);
}
undici.setGlobalDispatcher(
new undici.EnvHttpProxyAgent({
allowH2: false,
bodyTimeout: normalizedTimeoutMs,
headersTimeout: normalizedTimeoutMs,
}),
);
// Keep fetch and the dispatcher on the same undici implementation. Node 26.0's
// bundled fetch can otherwise consume compressed responses through npm undici's
// dispatcher without decompressing them, causing response.json() failures.
// If a caller replaced fetch after module load, preserve that deliberate override.
const shouldInstallGlobals =
installedGlobalFetch === undefined
? globalThis.fetch === originalGlobalFetch
: globalThis.fetch === installedGlobalFetch;
if (shouldInstallGlobals) {
undici.install?.();
installedGlobalFetch = globalThis.fetch;
}
}
Just like what we learnt, there is a custom configuration applied and dispatched:
new undici.EnvHttpProxyAgent({
allowH2: false,
bodyTimeout: normalizedTimeoutMs,
headersTimeout: normalizedTimeoutMs,
}),
and this comment explains why this was configured this way:
// Keep fetch and the dispatcher on the same undici implementation. Node 26.0's
// bundled fetch can otherwise consume compressed responses through npm undici's
// dispatcher without decompressing them, causing response.json() failures.
// If a caller replaced fetch after module load, preserve that deliberate override.
About me:
Hey, my name is ramunarasinga. Email: ramunarasinga@gmail.com
Tired of AI slop?
I spent 3+ years studying OSS codebases and wrote 350+ articles on what makes them production-grade. I built
Codebase architecture skills, inspired by best OSS projects.


Top comments (0)