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.
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.
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 performanceconst { statusCode, headers, body } = await request('https://api.example.com/data');const data = await body.json();// Or use undici.fetch with custom configurationconst 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.
...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.