pi-proxy-router
v1.2.0
Published
Per-model and auth-flow proxy routing for pi with session commands (/proxy, /noproxy, /allproxy) and dedicated proxy-router.json rules
Maintainers
Readme
pi-proxy-router
Pi coding agent 的按模型和认证流程路由代理扩展。为不同模型、会话内 OAuth 认证配置代理策略(SOCKS5 / HTTP),支持会话级临时开关,无需修改任何 provider 配置。
特性
- 按模型规则路由:
provider/模型模式匹配(*通配),每个模型可独立指定代理或直连 - 按认证 provider 路由:会话内 OAuth 登录、token exchange、refresh 和 device-code 请求按 provider 指定代理
- 多协议支持:
socks5h://、http://、https://代理,或direct显式直连 - 独立配置文件:优先读取
~/.pi/agent/proxy-router.json或项目.pi/proxy-router.json,修改后自动重载(mtime 检测);旧settings.json配置仍兼容 - 启动开关:
pi --noproxy禁用全部代理规则 - 会话内命令:
/allproxy <url>— Pi 的 HTTP(S) 流量及全部模型强制走一个代理(临时,不写配置)/noproxy [on|off]— 禁用/恢复规则/proxy [provider/model]— 查看当前代理状态(含环境变量)
- 主/子 agent 通用:子 agent 与主 agent 共享请求链路,规则自动生效
安装
# 全局安装(~/.pi/agent/extensions/)
mkdir -p ~/.pi/agent/extensions/pi-proxy-router
cd ~/.pi/agent/extensions/pi-proxy-router
# 将本项目文件复制到该目录(index.ts、socks-dispatcher.ts、package.json)
npm install然后在 pi 中 /reload,或在下次启动时自动加载。启动日志中看到 [proxy-router] loaded 即成功。
项目级安装:放到
.pi/extensions/pi-proxy-router/(需先信任项目目录)。
或作为 pi 包安装:
pi install npm:pi-proxy-router配置
推荐使用独立配置文件:全局 ~/.pi/agent/proxy-router.json,或项目 .pi/proxy-router.json。项目配置在同名规则上覆盖全局配置;全局配置作为默认值。独立文件可以直接写 models / auth,也兼容外层包裹 proxy-router:
{
"models": {
"openai-codex/*": "socks5h://127.0.0.1:7890",
"openai/*": "socks5h://127.0.0.1:7890",
"opencode-go/gpt*": "socks5h://proxy.example.test:7890",
"opencode-go/deepseek*": "direct",
"opencode-go/glm*": "direct"
},
"auth": {
"openai-codex": "socks5h://127.0.0.1:7890"
}
}旧配置仍会从全局/项目 settings.json 的 proxy-router 节点读取,旧键名 model-proxy 也兼容;它们作为迁移期间的低优先级回退。规则来源优先级为:旧全局 settings.json → 旧项目 settings.json → 独立全局配置 → 独立项目配置。
规则语法
- models key:
provider/模型模式,*通配任意字符(如openai-codex/gpt*、opencode-go/*) - auth key:provider id(如
openai-codex),只匹配 Pi 已知的认证 endpoint - value:
- 代理 URL:
socks5h://(推荐,远端 DNS 解析)、socks5://(自动归一化为 socks5h)、http://、https:// direct:显式直连
- 代理 URL:
models按合并后的书写顺序首个命中生效;不在列表中的模型使用 Pi 默认链路auth只对配置了 provider 的认证流程生效;未配置的认证请求使用 Pi 默认链路
优先级
--noproxy / /noproxy(禁用) > /allproxy(临时进程代理) > 独立配置规则 > 旧 settings 规则 > Pi 默认链路会话内 OAuth 认证
auth 规则只覆盖扩展已经声明的 Pi 认证 endpoint。目前支持 openai-codex 的:
auth.openai.com/oauth/tokenauth.openai.com/api/accounts/deviceauth/usercodeauth.openai.com/api/accounts/deviceauth/token
会话内 /login 的 token exchange、refresh 和 device-code 请求会经过该规则。浏览器打开的授权页面不经过扩展;独立执行的 pi auth ... 也不会加载扩展,仍需使用 HTTP_PROXY / HTTPS_PROXY 等环境变量。
命令
| 命令 | 说明 |
|---|---|
| /proxy | 查看当前状态:flag、开关、allproxy、环境变量、模型规则和认证规则 |
| /proxy openai-codex/gpt-5.6-luna | 附带参数时额外显示该模型的实际解析结果 |
| /allproxy http://127.0.0.1:7890 | Pi 的 HTTP(S) 流量、OAuth 刷新及全部模型强制走该代理(会话级临时,不写配置) |
| /allproxy | 取消临时代理,恢复规则 |
| /noproxy | 切换禁用/恢复(不带参数时 toggle) |
| /noproxy on / /noproxy off | 显式设置 |
| pi --noproxy | 启动时禁用全部代理规则 |
架构与原理
pi 的 provider-composer 允许扩展通过 pi.registerProvider(name, { api, streamSimple }) 覆盖指定 provider 在指定 API 类型上的流式实现。本扩展分两条链路路由:
models在streamSimple钩子中按模型 id 解析规则,命中时用 undici fetch + 自定义 dispatcher 注入传输层。auth在 Pi 进程内安装一个保留默认 dispatcher 的路由包装器,只对已知 OAuth endpoint 选择认证 provider 的 dispatcher,其他请求继续交给 Pi 默认链路。http:///https://→ undiciProxyAgentsocks5h://→ 内置SocksDispatcher(基于socks-proxy-agent实现 undici Dispatcher 接口,转发为 node http/https.request)
启用 /allproxy 后,路由包装器会把 Pi 默认 HTTP(S) 请求(包括 OAuth)和全部模型请求交给临时代理。该设置不写入 settings.json,取消 /allproxy 后恢复。Codex 模型启用代理时会固定使用 SSE,因为默认 WebSocket 链路不能使用注入的 fetch dispatcher。
pi.registerProvider("openai-codex", {
api: "openai-codex-responses",
streamSimple: (model, context, options) => {
const proxy = resolveProxyUrl(false, model.provider, model.id);
// proxy 命中 → 用注入 dispatcher 的 fetch;否则直连
},
});URL 匹配(待实现)
暂不支持把任意 URL 或域名写成规则,例如:
"urls": {
"*.abc.com": "socks5h://127.0.0.1:7890"
}该能力需要单独定义 URL、域名、端口、路径、重定向和规则优先级,且容易扩大代理范围。后续如确有需要,将作为显式的 urls 节点评估,不与 models、auth 规则混用。
环境变量
pi 启动时全局安装 EnvHttpProxyAgent(undici),所有 fetch 默认读取 HTTP_PROXY / HTTPS_PROXY 环境变量。因此:
- 被扩展接管的模型走显式 dispatcher(规则优先,不受环境变量影响)
- 执行
/allproxy后,Pi 的默认 HTTP(S) 链路(包括 OAuth)也走选定的 dispatcher - 不被接管的模型(见下方限制)走默认链路——设置了代理环境变量时它们会走 HTTP 代理
已知限制
- API 类型接管限制:一个 provider 只能注册一种
api的钩子。目前接管:opencode-go/openai→openai-responses(gpt-* 等)openai-codex→openai-codex-responses(gpt-5.6-luna 等)- 不接管
openai-completions(opencode-go/deepseek-、glm-)与anthropic-messages(qwen、minimax)—— 这些模型走 pi 默认链路(直连,或随HTTP_PROXY环境变量走代理)
- 若要覆盖这些 api,需要再扩展对应 api 的注册(欢迎 PR)
/allproxy只在启用期间覆盖 Pi 进程内的 HTTP(S) 流量,不包括浏览器导航、任意子进程自己的网络请求、无关的原生 WebSocket 客户端,以及扩展加载前处理的独立pi auth ...命令。auth只覆盖扩展内置的 provider 认证 endpoint;新增 provider 需要补充 endpoint 映射,不接受任意 URL 通配。
License
MIT
