kimi-code/packages/agent-core/src/index.ts
Kai 4d113949c8
feat: honor HTTP_PROXY/HTTPS_PROXY/NO_PROXY for all outbound traffic (#487)
* feat: honor HTTP_PROXY/HTTPS_PROXY/NO_PROXY for all outbound traffic

Install a global undici dispatcher at CLI startup so every in-process fetch
(LLM APIs, MCP HTTP, web tools, telemetry, sign-in, update checks) honors the
standard proxy variables, and propagate NODE_USE_ENV_PROXY to spawned stdio
MCP child processes. Loopback hosts always bypass the proxy; an invalid proxy
URL is reported and ignored rather than aborting startup.

* feat: support SOCKS proxies via ALL_PROXY

Recognize SOCKS proxies (socks5/socks5h/socks4/socks alias) from ALL_PROXY or a
socks-scheme HTTP(S)_PROXY, routing traffic through a custom undici connector
backed by the socks client (reusing undici's own TLS handling for https).
HTTP(S) proxies keep precedence; NO_PROXY and loopback are honored for the SOCKS
path too. Child stdio MCP node processes honor HTTP(S) proxies via
NODE_USE_ENV_PROXY; SOCKS applies to the main process only.

* fix: address proxy review comments (env masking, child NO_PROXY, nix hash)

- Resolve HTTP(S)_PROXY explicitly via the first non-blank casing so a blank
  lowercase var can no longer mask a populated uppercase one (the dispatcher
  installed but went direct), and coerce a SOCKS-scheme value sitting in an
  HTTP(S) var to '' so it is never handed to EnvHttpProxyAgent.
- Reconcile a child's NO_PROXY override across both casings using the first
  non-blank value run through resolveNoProxy, so a per-server config override
  is not shadowed by the injected lowercase value, keeps the loopback bypass,
  and passes '*' through verbatim.
- Update flake.nix pnpmDeps hash for the added socks/undici dependencies.

* fix(proxy): honor http ALL_PROXY, match port-qualified NO_PROXY, note child Node version

- Honor an http-scheme ALL_PROXY as the catch-all fallback for both http and
  https (scheme-specific HTTP(S)_PROXY still wins), so an ALL_PROXY-only setup
  no longer installs a no-op dispatcher and connects direct.
- Make the SOCKS-path NO_PROXY matcher port-aware: a `host:port` entry now
  matches only that port (with IPv6-safe parsing for `::1` / `[::1]:443`).
- Document that child stdio MCP proxying via NODE_USE_ENV_PROXY only applies on
  Node versions that support it (>= 22.21 / >= 24.5).

* fix(proxy): IPv6 + wildcard NO_PROXY and per-server child proxy edges

- Strip IPv6 brackets from a SOCKS proxy host (e.g. ALL_PROXY=socks5://[::1]:1080)
  so the socks client connects to the bare address.
- Add the bracketed [::1] to the loopback bypass: undici's EnvHttpProxyAgent
  only exempts IPv6 loopback when the NO_PROXY entry is bracketed (it mis-parses
  bare ::1). The SOCKS-path matcher normalizes brackets on both sides.
- Match *.domain wildcard (and host:port) NO_PROXY entries in the SOCKS matcher.
- Compute the child stdio proxy env from the MERGED env so a proxy declared only
  in a server's config.env also enables NODE_USE_ENV_PROXY.

* fix(proxy): synthesize HTTP(S)_PROXY from ALL_PROXY for child processes

proxyEnvForChild now hands spawned stdio MCP children the resolved
HTTP_PROXY/HTTPS_PROXY (in both casings), synthesizing them from an http-scheme
ALL_PROXY when no scheme-specific variable is set. Node's --use-env-proxy reads
HTTP_PROXY/HTTPS_PROXY (not ALL_PROXY), so an ALL_PROXY-only parent now proxies
the child consistently with the main process. Shared resolveHttpProxyUrls helper
is reused by createProxyDispatcher and proxyEnvForChild.

* chore(changeset): tighten proxy changeset wording
2026-06-06 01:44:54 +08:00

82 lines
2.2 KiB
TypeScript

export * from './agent';
export * from './session';
export * from './rpc';
export * from './config';
export * from './flags';
export * from './session/export';
export * from './telemetry';
export * from './errors';
export * from './plugin';
export {
flushDiagnosticLogs,
getRootLogger,
log,
redact,
resolveGlobalLogPath,
} from './logging/logger';
export { resolveLoggingConfig } from './logging/resolve-config';
export type { ResolveLoggingInput } from './logging/resolve-config';
export { installGlobalProxyDispatcher } from './utils/proxy';
export type {
LogContext,
LogEntry,
LogLevel,
LogPayload,
Logger,
LoggingConfig,
RootLogger,
SessionAttachInput,
SessionLogHandle,
} from './logging/types';
export { USER_PROMPT_ORIGIN } from './agent/context';
export type {
AgentContextData,
ContextMessage,
PromptOrigin,
UserPromptOrigin,
} from './agent/context';
export type {
AgentBackgroundTaskInfo,
BackgroundTaskInfo,
BackgroundTaskStatus,
ProcessBackgroundTaskInfo,
QuestionBackgroundTaskInfo,
} from './agent/background';
export type { ToolServices } from './tools/support/services';
export { SingleModelProvider } from './session/provider-manager';
export type {
BearerTokenProvider,
ModelProvider,
OAuthTokenProviderResolver,
ResolvedRuntimeProvider,
} from './session/provider-manager';
// ─── Wire records (for in-monorepo consumers like apps/vis) ────────────────
export type {
AgentRecord,
AgentRecordEvents,
AgentRecordOf,
AgentRecordPersistence,
} from './agent/records';
export { AGENT_WIRE_PROTOCOL_VERSION } from './agent/records';
export type { AgentConfigUpdateData } from './agent/config';
export type { CompactionBeginData, CompactionResult } from './agent/compaction';
export type {
PermissionApprovalResultRecord,
PermissionMode,
} from './agent/permission';
export type { UsageRecordScope } from './agent/usage';
export type { ToolStoreUpdate } from './tools/store';
export type {
LoopRecordedEvent,
LoopStepBeginEvent,
LoopStepEndEvent,
LoopContentPartEvent,
LoopToolCallEvent,
LoopToolResultEvent,
} from './loop';
export type {
ExecutableToolResult,
ExecutableToolSuccessResult,
ExecutableToolErrorResult,
} from './loop/types';