Read PR, linked issues, and comments.
UnderstandAnalyzed relevant source files and changelogs.
UnderstandInvestigated SDK fetch and proxy setup behavior.
UnderstandPrepared detailed review with findings and recommendations.
VerifyYou are given one or more GitHub PR URLs: https://github.com/badlogic/pi-mono/pull/939
For each PR URL, do the following in order:
packages/*/CHANGELOG.md files. Report whether an entry exists. If missing, state that a changelog entry is required before merge and that you will add it if the user decides to merge. Follow the changelog format rules in AGENTS.md. Verify:
### Breaking Changes, ### Added, ### Fixed, etc.)Fixed foo ([#123](https://github.com/badlogic/pi-mono/pull/123) by [@user](https://github.com/user))### Breaking Changes, not just ### FixedOutput format per PR: PR: Changelog:
If no issues are found, say so under Bad and Ugly.
>cd /Users/badlogic/workspaces/pi-mono && gh pr view 939 --json title,body,comments,commits,files,author,labels,state,baseRefName,headRefName{"author":{"id":"MDQ6VXNlcjI1MzkzMzE1","is_bot":false,"login":"zicklag","name":"Zicklag"},"baseRefName":"main","body":"Fixes #931.","comments":[{"id":"IC_kwDOPbFNk87iP8eq","author":{"login":"github-actions"},"authorAssociation":"CONTRIBUTOR","body":"Hi @zicklag, thanks for your interest in contributing!\n\nWe ask new contributors to open an issue first before submitting a PR. This helps us discuss the approach and avoid wasted effort.\n\n**Next steps:**\n1. Open an issue describing what you want to change and why (keep it concise, write in your human voice, AI slop will be closed)\n2. Once a maintainer approves with `lgtm`, you'll be added to the approved contributors list\n3. Then you can submit your PR\n\nThis PR will be closed automatically. See https://github.com/badlogic/pi-mono/blob/main/CONTRIBUTING.md for more details.","createdAt":"2026-01-25T02:06:06Z","includesCreatedEdit":false,"isMinimized":false,"minimizedReason":"","reactionGroups":[],"url":"https://github.com/badlogic/pi-mono/pull/939#issuecomment-3795830698","viewerDidAuthor":false},{"id":"IC_kwDOPbFNk87iQAAH","author":{"login":"badlogic"},"authorAssociation":"OWNER","body":"Did you test this?","createdAt":"2026-01-25T02:22:12Z","includesCreatedEdit":false,"isMinimized":false,"minimizedReason":"","reactionGroups":[],"url":"https://github.com/badlogic/pi-mono/pull/939#issuecomment-3795845127","viewerDidAuthor":true}],"commits":[{"authoredDate":"2026-01-25T02:03:46Z","authors":[{"email":"[REDACTED]","id":"MDQ6VXNlcjI1MzkzMzE1","login":"zicklag","name":"Zicklag"}],"committedDate":"2026-01-25T02:03:46Z","messageBody":"","messageHeadline":"fix: support http proxy configuration through environment variables.","oid":"98c6566988788a1fdbe443fd898d7c9765ded52f"}],"files":[{"path":"packages/ai/scripts/generate-models.ts","additions":8,"deletions":0},{"path":"packages/coding-agent/src/main.ts","additions":13,"deletions":0}],"headRefName":"fix/http-proxy-support","labels":[],"state":"OPEN","title":"fix: support http proxy configuration through environment variables."}>cd /Users/badlogic/workspaces/pi-mono && gh pr diff 939diff --git a/packages/ai/scripts/generate-models.ts b/packages/ai/scripts/generate-models.ts
index f6e7af091..bf01f60da 100644
--- a/packages/ai/scripts/generate-models.ts
+++ b/packages/ai/scripts/generate-models.ts
@@ -1,5 +1,13 @@
#!/usr/bin/env tsx
+import { setGlobalDispatcher, EnvHttpProxyAgent, } from "undici";
+if (process.env['HTTP_PROXY'] || process.env['HTTPS_PROXY'] || process.env['NO_PROXY'] ||
+ process.env['http_proxy'] || process.env['https_proxy'] || process.env['no_proxy']
+) {
+ setGlobalDispatcher(new EnvHttpProxyAgent());
+}
+
+
import { writeFileSync } from "fs";
import { join, dirname } from "path";
import { fileURLToPath } from "url";
diff --git a/packages/coding-agent/src/main.ts b/packages/coding-agent/src/main.ts
index 12f40c775..87392ffc8 100644
--- a/packages/coding-agent/src/main.ts
+++ b/packages/coding-agent/src/main.ts
@@ -5,6 +5,19 @@
* createAgentSession() options. The SDK does the heavy lifting.
*/
+import { EnvHttpProxyAgent, setGlobalDispatcher } from "undici";
+
+if (
+ process.env["HTTP_PROXY"] ||
+ process.env["HTTPS_PROXY"] ||
+ process.env["NO_PROXY"] ||
+ process.env["http_proxy"] ||
+ process.env["https_proxy"] ||
+ process.env["no_proxy"]
+) {
+ setGlobalDispatcher(new EnvHttpProxyAgent());
+}
+
import { type ImageContent, modelsAreEqual, supportsXhigh } from "@mariozechner/pi-ai";
import chalk from "chalk";
import { createInterface } from "readline";Now let me read the linked issue #931:
>cd /Users/badlogic/workspaces/pi-mono && gh issue view 931 --json title,body,comments,labels,state,author{"author":{"id":"MDQ6VXNlcjk0MDA1ODI=","is_bot":false,"login":"haoqixu","name":"xu0o0"},"body":"### What do you want to change?\n\nAutomatically read the proxy related environment variables (`http_proxy`, `https_proxy`, and `no_proxy`) and set up the http agents accordingly.\n\n### Why?\n\nIn some scenarios, the network can only be accessed through a proxy. And these proxy related environment variables are widely adopted in developer tools.\n\n### How? (optional)\n\nIf the proxy related environment variables are set:\n \n1. for `http` based SDK (e.g., amazon bedrock client), use `proxy-agent` to set up http agent.\n1. for `fetch` based SDK (e.g., openai and anthropic),\n 1. in `node`, use `undici` to set up the dispatcher of `fetch`\n 2. in `bun`, there is built-in support for these environment variables","comments":[{"id":"IC_kwDOPbFNk87iQAC_","author":{"login":"badlogic"},"authorAssociation":"OWNER","body":"Moving discussion to #939 ","createdAt":"2026-01-25T02:22:27Z","includesCreatedEdit":false,"isMinimized":false,"minimizedReason":"","reactionGroups":[],"url":"https://github.com/badlogic/pi-mono/issues/931#issuecomment-3795845311","viewerDidAuthor":true}],"labels":[],"state":"CLOSED","title":"Support HTTP proxy through environment variables"}Let me read the relevant source files to understand the context:
Let me check the changelog for packages/ai and packages/coding-agent:
Now let me check the coding-agent README and docs to see if proxy documentation would be needed:
>cd /Users/badlogic/workspaces/pi-mono && rg -l "proxy" packages/coding-agent/README.md packages/coding-agent/docs/*.md 2>/dev/null | head -5packages/coding-agent/README.md
packages/coding-agent/docs/extensions.md
packages/coding-agent/docs/custom-provider.md>cd /Users/badlogic/workspaces/pi-mono && rg -l "proxy|HTTP_PROXY" packages/ai/README.md 2>/dev/null | head -5packages/ai/README.md>cd /Users/badlogic/workspaces/pi-mono && rg "proxy|HTTP_PROXY" packages/ai/README.md packages/coding-agent/README.md --context 2packages/coding-agent/README.md-{
packages/coding-agent/README.md- "providers": {
packages/coding-agent/README.md: "custom-proxy": {
packages/coding-agent/README.md: "baseUrl": "https://proxy.example.com/v1",
packages/coding-agent/README.md- "apiKey": "MY_API_KEY",
packages/coding-agent/README.md- "api": "anthropic-messages",
--
packages/coding-agent/README.md-**Overriding built-in providers:**
packages/coding-agent/README.md-
packages/coding-agent/README.md:To route a built-in provider (anthropic, openai, google, etc.) through a proxy without redefining all models, just specify the `baseUrl`:
packages/coding-agent/README.md-
packages/coding-agent/README.md-```json
--
packages/coding-agent/README.md- "providers": {
packages/coding-agent/README.md- "anthropic": {
packages/coding-agent/README.md: "baseUrl": "https://my-proxy.example.com/v1"
packages/coding-agent/README.md- }
packages/coding-agent/README.md- }
--
packages/coding-agent/README.md- "providers": {
packages/coding-agent/README.md- "anthropic": {
packages/coding-agent/README.md: "baseUrl": "https://my-proxy.example.com/v1",
packages/coding-agent/README.md- "apiKey": "ANTHROPIC_API_KEY",
packages/coding-agent/README.md- "api": "anthropic-messages",
--
packages/ai/README.md-};
packages/ai/README.md-
packages/ai/README.md:// Example: LiteLLM proxy with explicit compat settings
packages/ai/README.md-const litellmModel: Model<'openai-completions'> = {
packages/ai/README.md- id: 'gpt-4o',
--
packages/ai/README.md-
packages/ai/README.md-// Example: Custom endpoint with headers (bypassing Cloudflare bot detection)
packages/ai/README.md:const proxyModel: Model<'anthropic-messages'> = {
packages/ai/README.md- id: 'claude-sonnet-4',
packages/ai/README.md- name: 'Claude Sonnet 4 (Proxied)',
packages/ai/README.md- api: 'anthropic-messages',
packages/ai/README.md: provider: 'custom-proxy',
packages/ai/README.md: baseUrl: 'https://proxy.example.com/v1',
packages/ai/README.md- reasoning: true,
packages/ai/README.md- input: ['text', 'image'],
--
packages/ai/README.md-```
packages/ai/README.md-
packages/ai/README.md:> **Security Warning**: Exposing API keys in frontend code is dangerous. Anyone can extract and abuse your keys. Only use this approach for internal tools or demos. For production applications, use a backend proxy that keeps your API keys secure.
packages/ai/README.md-
packages/ai/README.md-### Environment Variables (Node.js only)The current README refers to "proxy" in the context of API endpoint proxies (like baseUrl), not HTTP_PROXY environment variables. Let me check if undici is already a dependency:
>cd /Users/badlogic/workspaces/pi-mono && cat packages/ai/package.json | grep undici(no output)
Command exited with code 1>cd /Users/badlogic/workspaces/pi-mono && cat packages/coding-agent/package.json | grep undici(no output)
Command exited with code 1>cd /Users/badlogic/workspaces/pi-mono && cat package.json | grep undici(no output)
Command exited with code 1undici is not currently a dependency. Let me check if Node's native fetch uses undici under the hood:
>node -e "console.log(typeof globalThis.fetch)"functionLet me now understand the issue better by checking the original issue description. The issue #931 mentions that for fetch based SDKs, they suggest using undici to set up the dispatcher. Let me see if the approach is correct by checking how undici.setGlobalDispatcher works:
>cd /Users/badlogic/workspaces/pi-mono && node -e "
const { EnvHttpProxyAgent, setGlobalDispatcher } = require('undici');
console.log('EnvHttpProxyAgent exists:', !!EnvHttpProxyAgent);
console.log('setGlobalDispatcher exists:', !!setGlobalDispatcher);
" 2>&1 || echo "undici not installed"node:internal/modules/cjs/loader:1423
throw err;
^
Error: Cannot find module 'undici'
Require stack:
- /Users/badlogic/workspaces/pi-mono/[eval]
at Module._resolveFilename (node:internal/modules/cjs/loader:1420:15)
at defaultResolveImpl (node:internal/modules/cjs/loader:1058:19)
at resolveForCJSWithHooks (node:internal/modules/cjs/loader:1063:22)
at Module._load (node:internal/modules/cjs/loader:1226:37)
at TracingChannel.traceSync (node:diagnostics_channel:328:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:245:24)
at Module.require (node:internal/modules/cjs/loader:1503:12)
at require (node:internal/modules/helpers:152:16)
at [eval]:2:52
at runScriptInThisContext (node:internal/vm:219:10) {
code: 'MODULE_NOT_FOUND',
requireStack: [ '/Users/badlogic/workspaces/pi-mono/[eval]' ]
}
Node.js v25.2.1
undici not installedThe PR adds undici which is not currently a dependency. This is a problem because:
undici to any package.jsonLet me verify the PR doesn't touch package.json files:
>cd /Users/badlogic/workspaces/pi-mono && gh pr diff 939 | grep -E "^diff|package.json"diff --git a/packages/ai/scripts/generate-models.ts b/packages/ai/scripts/generate-models.ts
diff --git a/packages/coding-agent/src/main.ts b/packages/coding-agent/src/main.tsConfirmed. The PR imports undici but doesn't add it as a dependency. Let me also check if undici is bundled with newer Node.js versions:
>node -e "const undici = require('node:undici'); console.log('exists:', !!undici?.EnvHttpProxyAgent)" 2>&1 || echo "not available as node:undici"node:internal/modules/cjs/loader:1052
throw new ERR_UNKNOWN_BUILTIN_MODULE(specifier);
^
Error [ERR_UNKNOWN_BUILTIN_MODULE]: No such built-in module: node:undici
at defaultResolveImpl (node:internal/modules/cjs/loader:1052:15)
at resolveForCJSWithHooks (node:internal/modules/cjs/loader:1063:22)
at Module._load (node:internal/modules/cjs/loader:1226:37)
at TracingChannel.traceSync (node:diagnostics_channel:328:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:245:24)
at Module.require (node:internal/modules/cjs/loader:1503:12)
at require (node:internal/modules/helpers:152:16)
at [eval]:1:16
at runScriptInThisContext (node:internal/vm:219:10)
at node:internal/process/execution:451:12 {
code: 'ERR_UNKNOWN_BUILTIN_MODULE'
}
Node.js v25.2.1
not available as node:undiciThe PR has a fundamental issue. Now let me also check if this approach even works for all SDK calls. The SDKs (Anthropic, OpenAI, Google GenAI) have their own HTTP clients:
>cd /Users/badlogic/workspaces/pi-mono && rg "new (Anthropic|OpenAI|GoogleGenerativeAI)" packages/ai/src --type ts | head -10packages/ai/src/providers/anthropic.ts: const client = new Anthropic({
packages/ai/src/providers/anthropic.ts: const client = new Anthropic({
packages/ai/src/providers/openai-completions.ts: return new OpenAI({
packages/ai/src/providers/openai-responses.ts: return new OpenAI({Now let me see if the Anthropic SDK respects setGlobalDispatcher:
>cd /Users/badlogic/workspaces/pi-mono && rg "httpAgent|agent|dispatcher|fetch" node_modules/@anthropic-ai/sdk/src/*.ts 2>/dev/null | head -20node_modules/@anthropic-ai/sdk/src/client.ts: * Additional `RequestInit` options to be passed to `fetch` calls.
node_modules/@anthropic-ai/sdk/src/client.ts: * Properties will be overridden by per-request `fetchOptions`.
node_modules/@anthropic-ai/sdk/src/client.ts: fetchOptions?: MergedRequestInit | undefined;
node_modules/@anthropic-ai/sdk/src/client.ts: * Specify a custom `fetch` function implementation.
node_modules/@anthropic-ai/sdk/src/client.ts: * If not provided, we expect that `fetch` is defined globally.
node_modules/@anthropic-ai/sdk/src/client.ts: fetch?: Fetch | undefined;
node_modules/@anthropic-ai/sdk/src/client.ts: fetchOptions: MergedRequestInit | undefined;
node_modules/@anthropic-ai/sdk/src/client.ts: private fetch: Fetch;
node_modules/@anthropic-ai/sdk/src/client.ts: * @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls.
node_modules/@anthropic-ai/sdk/src/client.ts: * @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
node_modules/@anthropic-ai/sdk/src/client.ts: this.fetchOptions = options.fetchOptions;
node_modules/@anthropic-ai/sdk/src/client.ts: this.fetch = options.fetch ?? Shims.getDefaultFetch();
node_modules/@anthropic-ai/sdk/src/client.ts: fetch: this.fetch,
node_modules/@anthropic-ai/sdk/src/client.ts: fetchOptions: this.fetchOptions,
node_modules/@anthropic-ai/sdk/src/client.ts: const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError);
node_modules/@anthropic-ai/sdk/src/client.ts: // undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)"
node_modules/@anthropic-ai/sdk/src/client.ts: async fetchWithTimeout(
node_modules/@anthropic-ai/sdk/src/client.ts: const fetchOptions: RequestInit = {
node_modules/@anthropic-ai/sdk/src/client.ts: fetchOptions.method = method.toUpperCase();
node_modules/@anthropic-ai/sdk/src/client.ts: // use undefined this binding; fetch errors if bound to something else in browser/cloudflareThe Anthropic SDK uses its own fetch implementation. The setGlobalDispatcher from undici affects the global fetch, but the SDK might use its own bundled fetch. Let me check the issue description more carefully:
Looking at issue #931:
- for
httpbased SDK (e.g., amazon bedrock client), useproxy-agentto set up http agent.- for
fetchbased SDK (e.g., openai and anthropic),
- in
node, useundicito set up the dispatcher offetch- in
bun, there is built-in support for these environment variables
The key insight is that Node.js 18+ uses undici under the hood for its native fetch. So calling setGlobalDispatcher should affect the native fetch. However, the SDKs might use their own fetch implementation.
Let me check if this approach is valid:
>cd /Users/badlogic/workspaces/pi-mono && cat node_modules/@anthropic-ai/sdk/src/shims/node-runtime.ts 2>/dev/null | head -50(no output)>cd /Users/badlogic/workspaces/pi-mono && find node_modules/@anthropic-ai/sdk -name "*.ts" -exec grep -l "fetch" {} \; 2>/dev/null | head -5node_modules/@anthropic-ai/sdk/resources/beta/messages/messages.d.ts
node_modules/@anthropic-ai/sdk/resources/beta/messages/batches.d.ts
node_modules/@anthropic-ai/sdk/resources/beta/models.d.ts
node_modules/@anthropic-ai/sdk/resources/beta/files.d.ts
node_modules/@anthropic-ai/sdk/resources/beta/skills/versions.d.ts>cd /Users/badlogic/workspaces/pi-mono && cat node_modules/@anthropic-ai/sdk/shims/node-runtime.mjs 2>/dev/null | head -20(no output)>cd /Users/badlogic/workspaces/pi-mono && ls node_modules/@anthropic-ai/sdk/ 2>/dev/null_vendor
api-promise.d.mts
api-promise.d.mts.map
api-promise.d.ts
api-promise.d.ts.map
api-promise.js
api-promise.js.map
api-promise.mjs
api-promise.mjs.map
bin
CHANGELOG.md
client.d.mts
client.d.mts.map
client.d.ts
client.d.ts.map
client.js
client.js.map
client.mjs
client.mjs.map
core
error.d.mts
error.d.mts.map
error.d.ts
error.d.ts.map
error.js
error.js.map
error.mjs
error.mjs.map
helpers
index.d.mts
index.d.mts.map
index.d.ts
index.d.ts.map
index.js
index.js.map
index.mjs
index.mjs.map
internal
lib
LICENSE
package.json
pagination.d.mts
pagination.d.mts.map
pagination.d.ts
pagination.d.ts.map
pagination.js
pagination.js.map
pagination.mjs
pagination.mjs.map
README.md
resource.d.mts
resource.d.mts.map
resource.d.ts
resource.d.ts.map
resource.js
resource.js.map
resource.mjs
resource.mjs.map
resources
resources.d.mts
resources.d.mts.map
resources.d.ts
resources.d.ts.map
resources.js
resources.js.map
resources.mjs
resources.mjs.map
src
streaming.d.mts
streaming.d.mts.map
streaming.d.ts
streaming.d.ts.map
streaming.js
streaming.js.map
streaming.mjs
streaming.mjs.map
uploads.d.mts
uploads.d.mts.map
uploads.d.ts
uploads.d.ts.map
uploads.js
uploads.js.map
uploads.mjs
uploads.mjs.map
version.d.mts
version.d.mts.map
version.d.ts
version.d.ts.map
version.js
version.js.map
version.mjs
version.mjs.map>cd /Users/badlogic/workspaces/pi-mono && cat node_modules/@anthropic-ai/sdk/core/fetch-utils.mjs 2>/dev/null | head -30(no output)>cd /Users/badlogic/workspaces/pi-mono && ls node_modules/@anthropic-ai/sdk/core/api-promise.d.mts
api-promise.d.mts.map
api-promise.d.ts
api-promise.d.ts.map
api-promise.js
api-promise.js.map
api-promise.mjs
api-promise.mjs.map
error.d.mts
error.d.mts.map
error.d.ts
error.d.ts.map
error.js
error.js.map
error.mjs
error.mjs.map
pagination.d.mts
pagination.d.mts.map
pagination.d.ts
pagination.d.ts.map
pagination.js
pagination.js.map
pagination.mjs
pagination.mjs.map
resource.d.mts
resource.d.mts.map
resource.d.ts
resource.d.ts.map
resource.js
resource.js.map
resource.mjs
resource.mjs.map
streaming.d.mts
streaming.d.mts.map
streaming.d.ts
streaming.d.ts.map
streaming.js
streaming.js.map
streaming.mjs
streaming.mjs.map
uploads.d.mts
uploads.d.mts.map
uploads.d.ts
uploads.d.ts.map
uploads.js
uploads.js.map
uploads.mjs
uploads.mjs.map>cd /Users/badlogic/workspaces/pi-mono && cat node_modules/@anthropic-ai/sdk/internal/shims.mjs | head -50// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
export function getDefaultFetch() {
if (typeof fetch !== 'undefined') {
return fetch;
}
throw new Error('`fetch` is not defined as a global; Either pass `fetch` to the client, `new Anthropic({ fetch })` or polyfill the global, `globalThis.fetch = fetch`');
}
export function makeReadableStream(...args) {
const ReadableStream = globalThis.ReadableStream;
if (typeof ReadableStream === 'undefined') {
// Note: All of the platforms / runtimes we officially support already define
// `ReadableStream` as a global, so this should only ever be hit on unsupported runtimes.
throw new Error('`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`');
}
return new ReadableStream(...args);
}
export function ReadableStreamFrom(iterable) {
let iter = Symbol.asyncIterator in iterable ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator]();
return makeReadableStream({
start() { },
async pull(controller) {
const { done, value } = await iter.next();
if (done) {
controller.close();
}
else {
controller.enqueue(value);
}
},
async cancel() {
await iter.return?.();
},
});
}
/**
* Most browsers don't yet have async iterable support for ReadableStream,
* and Node has a very different way of reading bytes from its "ReadableStream".
*
* This polyfill was pulled from https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490
*/
export function ReadableStreamToAsyncIterable(stream) {
if (stream[Symbol.asyncIterator])
return stream;
const reader = stream.getReader();
return {
async next() {
try {
const result = await reader.read();
if (result?.done)
reader.releaseLock(); // release lock when stream becomes closedThe Anthropic SDK uses the global fetch by default (typeof fetch !== 'undefined'). This means setGlobalDispatcher should work because Node.js 18+'s native fetch uses undici internally.
However, there's still the issue that undici needs to be added as a dependency.
Let me also check the PR's placement of the proxy setup code. The issue is that the code is placed at the top of files, which means it runs at import time:
>cd /Users/badlogic/workspaces/pi-mono && gh pr diff 939 | head -40diff --git a/packages/ai/scripts/generate-models.ts b/packages/ai/scripts/generate-models.ts
index f6e7af091..bf01f60da 100644
--- a/packages/ai/scripts/generate-models.ts
+++ b/packages/ai/scripts/generate-models.ts
@@ -1,5 +1,13 @@
#!/usr/bin/env tsx
+import { setGlobalDispatcher, EnvHttpProxyAgent, } from "undici";
+if (process.env['HTTP_PROXY'] || process.env['HTTPS_PROXY'] || process.env['NO_PROXY'] ||
+ process.env['http_proxy'] || process.env['https_proxy'] || process.env['no_proxy']
+) {
+ setGlobalDispatcher(new EnvHttpProxyAgent());
+}
+
+
import { writeFileSync } from "fs";
import { join, dirname } from "path";
import { fileURLToPath } from "url";
diff --git a/packages/coding-agent/src/main.ts b/packages/coding-agent/src/main.ts
index 12f40c775..87392ffc8 100644
--- a/packages/coding-agent/src/main.ts
+++ b/packages/coding-agent/src/main.ts
@@ -5,6 +5,19 @@
* createAgentSession() options. The SDK does the heavy lifting.
*/
+import { EnvHttpProxyAgent, setGlobalDispatcher } from "undici";
+
+if (
+ process.env["HTTP_PROXY"] ||
+ process.env["HTTPS_PROXY"] ||
+ process.env["NO_PROXY"] ||
+ process.env["http_proxy"] ||
+ process.env["https_proxy"] ||
+ process.env["no_proxy"]
+) {
+ setGlobalDispatcher(new EnvHttpProxyAgent());
+}
+
import { type ImageContent, modelsAreEqual, supportsXhigh } from "@mariozechner/pi-ai";Now I have enough information to provide the review.
PR: https://github.com/badlogic/pi-mono/pull/939
Changelog:
packages/ai/CHANGELOG.md or packages/coding-agent/CHANGELOG.md. A changelog entry is required before merge and will be added if the user decides to merge.Good:
EnvHttpProxyAgent which automatically reads standard proxy environment variables (HTTP_PROXY, HTTPS_PROXY, NO_PROXY, and lowercase variants)Bad:
undici but doesn't add it to any package.json. The code will fail at runtime with Cannot find module 'undici'.undici to:
packages/ai/package.json (for generate-models.ts)packages/coding-agent/package.json (for main.ts)http based SDK requiring proxy-agent. This PR only handles fetch-based providers.Ugly:
npm run generate-models command, not runtime usage.Questions or Assumptions:
packages/ai instead, so all downstream packages get it automatically?Change summary:
undici.EnvHttpProxyAgent for Node.js native fetchpackages/ai/scripts/generate-models.ts and packages/coding-agent/src/main.tsTests: