用 Node.js 把 ZeroTwo 的聊天接口转换成 OpenAI Chat Completions 兼容的本地代理,并提供多账号 Token 轮询、自动续期、网页导入与手动强制刷新。
API_KEY='你的自定义Key' \
HOST=127.0.0.1 \
PORT=8787 \
node server.js调试上游流(默认关闭):
DEBUG_MODE=1 DEBUG_RAW_STREAM=1 node server.jsDEBUG_MODE=1:打印上游请求摘要、请求 payload(截断)和非 2xx 响应体。DEBUG_RAW_STREAM=1:额外打印上游原始 SSE chunk 与data:事件(日志量较大)。DEBUG_LOG_MAX_CHARS:单条日志最大长度,默认4000。
在服务器上执行:
cp .env.example .env
# 编辑 .env:至少把 API_KEY 改掉
docker compose build
docker compose up -d访问:
- 管理页:
http://<服务器IP>:<PORT>/admin - 代理:
http://<服务器IP>:<PORT>/v1/chat/completions(带x-api-key: <API_KEY>)
POST /v1/chat/completions- 需要
x-api-key: <API_KEY>或Authorization: Bearer <API_KEY> - 支持
stream: true(SSE)与非流式 - 支持
reasoning_effort,会同时透传到 ZeroTwo 的顶层reasoning_effort与contextData.reasoning_effort - 支持
model写成openai/gpt-5.2:会自动拆分为provider=openai、model=gpt-5.2转发给 ZeroTwo(也支持直接传provider字段) reasoning_effort默认值为highinstructions默认值为You are a helpful assistant.- 流式模式默认返回
usage(无需额外设置stream_options.include_usage) - 当
provider为anthropic(或model形如anthropic/claude-...)时,支持 Claude 风格thinking:{"thinking":{"type":"off"}}关闭{"thinking":{"type":"enabled","budget_tokens":1024}}开启(budget 仅允许1024/4096/10000/16000,其他数值会自动取最近)
- 当
provider为anthropic时,会把reasoning_effort(支持字符串或数字)归一化为上游需要的“数字预算或off”,并同时写入顶层与contextData.reasoning_effort;thinking仅用于推导该值,不会透传给上游 - 路由规则:当
provider为gemini或anthropic时,只会选用isPro=true的账号;否则按默认轮询选择 - 当
messages[].content为数组时,仅提取text/input_text作为文本内容转发(忽略非文本段) - 图片(实验性):
- 当
messages[].content包含image_url/input_image时,会自动调用上游POST /api/rag/upload上传图片并注入payload.attachments,再开启thread检索(contextData.mode.retrieval=["thread"]) - 支持
data:(base64)与http(s)图片 URL;默认等待20s处理完成(IMAGE_PROCESSING_WAIT_MS=20 * 1000),如需等待可设置为毫秒数(例如3000/60000)
- 当
- 系统指令走
instructions字段:默认把messages[].role=system拼接后注入到顶层instructions;仅当没有 system 消息时,才使用顶层instructions
- 需要
POST /api/rag/upload- 需要
x-api-key: <API_KEY> multipart/form-data:字段对齐 ZeroTwo(file/filename/contentType/threadId/processAsync/...)
- 需要
GET /api/rag/file-processing-queue?id=<queueId>- 需要
x-api-key: <API_KEY> - 代理查询
file_processing_queue状态(用于前端轮询展示进度)
- 需要
GET /admin:管理页(页面本身不鉴权,但所有管理 API 都需要 API Key)- 管理 API:
GET /admin/api/accountsPOST /admin/api/accounts/importPOST /admin/api/accounts/:id/toggle-proPOST /admin/api/accounts/:id/refresh-accessPOST /admin/api/accounts/:id/refresh-securityPOST /admin/api/accounts/:id/toggleDELETE /admin/api/accounts/:id
- 无法直接调用生图模型。只能通过语言模型间接调用生图模型。
- 其中语言模型调用的参数中只有
gpt-image-1具体模型取决于网页端配置的用户设置。 - 并无精细调用参数,但是可以通过命令语言模型来调整,目前已知的是
sizequalityprompt等
- 后台定时任务默认每
20s扫描一次需要刷新的账号(见BACKGROUND_TICK_MS/backgroundTickMs)。 - 后台每轮最多处理
4个账号,并发最多2,未处理的账号会等下一轮,降低“同一时刻扎堆刷新”的风险。 - 当 Security 刷新遇到
authentication rate limit的 429 时,会对该账号进入10min冷却期,并额外增加5-30s抖动,避免冷却结束后同一轮集中重试;其它 429 仍按熔断退避处理。
从浏览器 LocalStorage 拿到 app-session 的 JSON(整段),粘贴到管理页导入。
默认会把账号信息写到 data/accounts.json(已在 .gitignore 忽略)。