@mx_/pi-custom-provider
v0.5.0
Published
Auto-register custom API providers (new-api/one-api/any OpenAI-compatible proxy) in pi — dynamic model discovery, multi-protocol, zero-code config.
Maintainers
Readme
pi-custom-provider(通用多协议自定义 API 扩展)
把任意 AI API 面板接入 pi:new-api、one-api、Claude 代理、Gemini 代理…,模型列表实时从各 API 拉取,面板里增删模型、增删渠道,pi 的 /model 自动跟着变,全程不用改扩展代码。
特性
- 🚀 动态模型列表:打开
/model时自动调用各 API 的模型列表端点拉取最新模型,无需手写模型清单 - ⚡ 条件请求:模型列表带 ETag / Last-Modified 重验证,网关返回 304 时直接用缓存目录——每次打开
/model不会重复下载全量列表,面板里增删模型仍即时生效 - 🎛 多 provider 自动注册:models.json 里写几个自定义 provider,扩展就自动注册几个(跳过 pi 内置 provider 名)
- 🔀 多协议支持:每个 provider 可指定
api字段,自动适配 OpenAI / Anthropic / Gemini 协议 - 📦 真实元数据:contextWindow / maxTokens / cost / reasoning 优先取 pi 内置目录(models.dev),取不到按 id 启发式推断
- 🔧 零代码适配:加渠道、改名字、换 key、换协议,全部只改
~/.pi/agent/models.json - 🛡 上游兼容:OpenAI 协议强制
supportsDeveloperRole: false,系统提示用systemrole 发送,兼容 dfmodel 等不认developerrole 的渠道
安装
# 方式一:pi install(推荐)
pi install npm:@mx_/pi-custom-provider # npm
pi install git:github.com/pgjh/pi-custom-provider # git
# 方式二:手动克隆
git clone https://github.com/pgjh/pi-custom-provider ~/.pi/agent/extensions/pi-custom-provider或直接把扩展目录放在:
- 全局:
~/.pi/agent/extensions/pi-custom-provider/(推荐,所有项目生效) - 项目级:
<项目>/.pi/extensions/pi-custom-provider/
配置:只需 models.json
编辑 ~/.pi/agent/models.json(文件不存在就新建):
{
"providers": {
"newapi": {
"baseUrl": "http://localhost:3333",
"apiKey": "sk-xxxx"
},
"claude-proxy": {
"baseUrl": "https://proxy.example.com",
"apiKey": "sk-yyyy",
"api": "anthropic-messages"
},
"gemini-proxy": {
"baseUrl": "https://generativelanguage.googleapis.com",
"apiKey": "AIza-zzzz",
"api": "google-generative-ai"
}
}
}字段说明
| 字段 | 必填 | 说明 |
|---|---|---|
| baseUrl | ✅ | API 地址,不用写协议后缀——扩展按 api 自动拼:OpenAI 协议补 /v1、Anthropic 自动去掉 /v1(SDK 自拼)、Gemini 补 /v1beta。写 http://host 或 http://host/v1 都行 |
| apiKey | ⚠️ | API key。不填则无法认证(模型也拉不到),建议填 |
| api | ❌ | 协议类型,默认 openai-completions(见下) |
| headers | ❌ | 自定义请求头(见下) |
| modelOverrides | ❌ | 按模型 id 微调单个模型的元数据(见下文) |
自定义请求头(headers)
有些 API 需要特殊请求头(自定义鉴权、上游标识等):
{
"providers": {
"newapi": {
"baseUrl": "http://localhost:3333",
"apiKey": "sk-xxxx",
"headers": {
"X-Custom": "yes",
"X-Api-Token": "$MY_TOKEN",
"X-Debug": "${DEBUG_FLAG}"
}
}
}
}- 对话请求与模型列表请求都会带上(headers 已传给 provider 注册)
- 注意:同时设置
headers.Authorization和authHeader: true时,生成的 Authorization 会覆盖自定义值(pi 的 provider-composer 行为,扩展的模型列表请求也遵循同一覆盖)——需要自定义认证头时不要开 authHeader(或改用非 Authorization 头名) - 值支持
$VAR/${VAR}环境变量模板,$$转义为字面$、$!转义为字面!,!command开头则执行命令取结果(与 models.json 语法一致)。对话请求由 pi 解析(扩展不重复展开);模型列表请求由扩展按同一语法解析(!command执行失败或环境变量缺失则该头不发送),两边行为保持一致 - 配置目录默认
~/.pi/agent,设置PI_CODING_AGENT_DIR可覆盖(扩展自动跟随)
api 字段(协议类型,可选)
| api 值 | 协议 | 认证方式 |
|---|---|---|
| openai-completions(默认) | OpenAI Chat Completions | Authorization: Bearer |
| openai-responses | OpenAI Responses API | Authorization: Bearer |
| anthropic-messages | Anthropic Messages | x-api-key |
| google-generative-ai | Gemini | ?key= 查询参数 |
| mistral-conversations | Mistral SDK 会话流 | Authorization: Bearer |
| azure-openai-responses | Azure OpenAI Responses | Authorization: Bearer |
| openai-codex-responses | OpenAI Codex Responses | Authorization: Bearer |
| bedrock-converse-stream | AWS Bedrock Converse | SDK 认证 |
| google-vertex | Google Vertex AI | SDK 认证 |
| pi-messages | pi 自有消息协议 | Authorization: Bearer |
| 其他 pi 支持的值 | 由 pi 内置转换器处理 | — |
不写 api 就默认走 OpenAI 兼容(new-api / one-api / Ollama 的 /v1 都适用)。
规则
- provider 名随便起(
newapi/oneapi2/my-gateway…),/model里就显示哪个名字 - 内置 provider 名会被跳过(anthropic / openai / deepseek / gemini 等由 pi 自己管理),不会误注册
- 没有
baseUrl的条目会被忽略(视为不完整配置) - 改完配置在 pi 里
/reload生效
微调单个模型(modelOverrides)
API 的 /v1/models 只返回模型 id,不返回上下文/价格等元数据。扩展会先用 pi 内置目录匹配,匹配不到用启发式默认值。不准的可以按模型 id 覆盖:
{
"providers": {
"newapi": {
"baseUrl": "http://localhost:3333",
"apiKey": "sk-xxxx",
"modelOverrides": {
"my-custom-model": {
"contextWindow": 262144,
"maxTokens": 32768,
"reasoning": true,
"cost": { "input": 2, "output": 8, "cacheRead": 1, "cacheWrite": 1 }
},
"DeepSeek-V4-Flash": {
"thinkingLevelMap": { "minimal": "low", "low": "low", "medium": "medium", "high": "high", "xhigh": "high", "max": "high" }
}
}
}
}
}覆盖语义:
compat/cost/thinkingLevelMap是浅合并——只覆盖你写的键,builtin/启发式的其余字段保留(例如给 DeepSeek-V4-Flash 只写"thinkingLevelMap": {"low": "low"}会在保留 high/max 的基础上解锁 low,不会丢档位;改compat单个字段也不会丢掉supportsDeveloperRole: false等关键开关)。其他字段(contextWindow、maxTokens、reasoning 等)直接替换。
思考档位(Shift+Tab 循环:off → minimal → low → medium → high → xhigh → max)
- 档位策略:builtin 目录(models.dev)有
thinkingLevelMap的模型完全透传(null 档保留,如 hy3 只有 off/low/high);没有的用同值映射兜底(xhigh→"xhigh"、max→"max",发原值不钳制)——否则 pi 对无 map 模型默认不支持 xhigh/max,档位会消失(实测 new-api 网关对所有 reasoning 模型接受 xhigh/max) supportsReasoningEffort不做配置,由 pi 的detectCompat自动检测(custom provider 默认 true);builtin 标 false 的模型(deepseek-v3.2 / kimi-k2.7-code 发 effort 会 500/400)自然保留- 想按自己网关的能力调整,用
modelOverrides覆盖thinkingLevelMap或compat.supportsReasoningEffort
用法
启动 pi 后(扩展会自动加载):
| 操作 | 命令 |
|---|---|
| 打开模型选择器 | /model(或 Ctrl+L) |
| 直接切换模型 | /model newapi/deepseek-v4-pro(大小写不敏感) |
| 切换思考档位 | Shift+Tab(off → minimal → low → medium → high → xhigh → max) |
| 展开思考内容 | Ctrl+T |
| 切换上一个/下一个模型 | Ctrl+P / Shift+Ctrl+P |
| 刷新扩展配置 | /reload |
模型在 /model 里显示为 模型id [provider名],例如 DeepSeek-V4-Pro [newapi]。
提示:同名大小写可能是不同渠道的独立模型(如
glm-5.2走 A 渠道、GLM-5.2走 B 渠道),扩展全部保留。面板返回的模型 id 不一定都有可用渠道(请求可能 401/404),选模型时按需试。同一 provider 内不去重。
