WorkBuddy2API-Hub — 国际版、国内版多账号网关中枢
⏸️ 暂停更新(预计 10 天):从 2026-09-29 起暂停发布新版本,预计 10 天后恢复;期间 issue 与 PR 照常收,但合并与回复会慢一些。已发布的版本不受影响,照常可用;恢复更新后会删掉这段说明。
把腾讯 www.workbuddy.ai(国际版)与 codebuddy.cn(国内版)的原生服务封装成标准 OpenAI 兼容接口(Chat Completions 与 Responses API),并补齐多账号调度与运维能力:
- 开箱即用:绿色包自带精简 Python,双击脚本即启;
- 双区域独立路由:国际版 / 国内版独立配置与调度,看板一键切换,状态落盘;
- 模型目录对齐官方桌面端:剔除代码补全通道与底层专线变体,能力与规格按桌面端宣告;
- 设备指纹隔离 (
derive_id):以账号 UID 稳定派生机器码与会话标识,防多号关联风控; - OAuth 免客户端登录:看板点链接完成授权即自动入库;
- 国内版自动化:每日签到、成长任务与积分任务自动接取点亮领奖、猫猫日常旅行与连续打卡;
- 国际版每日活跃打卡:自动建网页端会话并接上沙箱把这一轮真正跑完(ACP over HTTP+SSE),全自动领满官方每日活跃 30/50 积分奖励;
- 后台定时调度器:09:00/21:00 国内签到旅行与国际版活跃打卡 · 22:00 保活 · 01:00 夜猫;
- 双协议支持:Chat Completions 与 Responses API(Codex / Claude Code);
- Web 看板:指标卡片、模型性能与用量大表、实时请求流水一屏可查。
⚡ Vibe Coding 产物:本项目为 100% Vibe Coding 协同产物,由人类开发者提出架构与业务意图,AI 助手端到端完成逆向分析、链路调度、WAF 指纹脱敏与界面编写。
一、快速启动
1. 本机单机使用
Windows:双击 start-wb-proxy.bat,保持窗口运行。macOS:双击 start-wb-proxy.command(首次被 Gatekeeper 拦截时,右键 →「打开」确认一次),或在终端执行:
./start-wb-proxy.sh # 默认 8788 端口
./start-wb-proxy.sh 9000 # 自定义端口
启动后:
- API 接口地址:
http://127.0.0.1:8788/v1 - Web 监控看板:
http://127.0.0.1:8788/
首次启动若无账号,打开看板点 「+ 添加账号 (OAuth)」 完成授权即自动入库。macOS 启动脚本会自动挑选可用的 Python 3.9+(/usr/bin/python3、Homebrew 或包内 python/bin/python3),未安装可用 xcode-select --install / brew install python。
zip 解压后若提示权限不足,先执行一次:
chmod +x start-wb-proxy.sh start-wb-proxy.command start-wb-proxy-lan.sh start-wb-proxy-lan.command allow-firewall.command
2. 面板访问密码
打开看板需要先输入面板访问密码(默认 admin),它与 API Key 相互独立:密码只用于打开看板,可在「设置」页修改(或启动时用 --panel-password 指定),以 PBKDF2-SHA256 摘要存于 accounts/settings.json(不存明文);登录状态保存在浏览器会话中,关闭浏览器或重启网关后需重新输入。
首次登录后请立即修改默认密码。
3. 局域网共享模式
允许局域网内其他设备(手机、平板、协同电脑)访问:
- Windows:双击
start-wb-proxy-lan.bat;macOS:双击start-wb-proxy-lan.command,或:
./start-wb-proxy-lan.sh # 端口 8788,自动生成/复用 API Key
./start-wb-proxy-lan.sh 8788 我的Key # 自定义端口与 Key
- Base URL:
http://:8788/v1;带密钥直达面板:http://:8788/?key=生成的Key; - API Key:不使用写死的默认密钥,首次启动生成高强度随机 Key 保存到
accounts/settings.json并在终端打印,重启复用;也可用第二个参数传入自己的 Key(以传入的为准); - macOS 防火墙:首次监听端口时系统会询问是否允许 Python 接受连接,选「允许」;macOS 15+ 还需在「系统设置 → 隐私与安全性 → 本地网络」中允许终端访问。可用
./allow-firewall.command查看状态并把 Python 加入允许列表。
4. 多 API Key 管理与出口绑定
在「设置」页可管理多个 API Key,并为每个 Key 指定独立出口——不同客户端各用各的 Key,国内 / 国外流量互不干扰,无需频繁切换全局出口:
- 添加与生成:输入名称后点「生成随机 Key」,可随时复制;
- 出口绑定:可固定走 🌐 国际版(
www.workbuddy.ai)或 🇨🇳 国内版(copilot.tencent.com);不绑定则跟随看板顶部的全局出口开关; - 模型限制:可为每个 Key 填写允许调用的模型(如
deepseek*、gpt-6-astra,支持*通配,多个用逗号分隔);留空表示不限制。不在列表内的模型请求在本机直接返回可读的 400,既不会送达上游、也不会消耗任何额度——用来挡掉客户端背景请求偷偷调用的付费模型; - 启停与删除:可单独启用 / 停用,删除即刻失效;所有 Key 保存在
accounts/settings.json,重启保持; - 防冲突:面板保存过 Key 后,启动命令或脚本里的旧参数(如
--api-key)自动失效; - 区域自检:Key 绑定的出口与其请求的模型不匹配时(如用国际版 Key 调国内独占的
deepseek-v4-pro),直接返回可读的 400 校验错误,而不是上游晦涩的 WAF 拒流报错。
5. Docker 容器化部署
自带完整容器配置,零外部依赖:
docker compose up -d # 后台启动(自动构建)
docker compose logs -f # 查看网关日志
也可直接用 docker run:
docker run -d --name wb-proxy --restart unless-stopped -p 8788:8788 \
-v $(pwd)/accounts:/app/accounts -v $(pwd)/usage:/app/usage \
-e API_KEY=your_secret_key $(docker build -q .)
每次 GitHub Release 发布后,也可从 GHCR 拉取预编译镜像运行(正式版同步更新 latest,预发布版只有版本标签):
docker pull ghcr.io/ardeyouxipianyi/workbuddy2api-hub:latest
docker run -d --name wb-proxy --restart unless-stopped -p 8788:8788 \
-v $(pwd)/accounts:/app/accounts -v $(pwd)/usage:/app/usage \
-e API_KEY=your_secret_key ghcr.io/ardeyouxipianyi/workbuddy2api-hub:latest
GHCR 新包默认私有;如需免登录拉取,首次发布后在 Packages 设置中将其改为 Public。保持私有时需先登录 ghcr.io。
- 持久化目录:
./accounts(账号凭证与活动区域)与./usage(请求流水与指标快照); - 配置参数:环境变量
API_KEY、PORT; - 改
PORT要同步改端口映射:PORT只决定容器内监听哪个端口,-p HOST:CONTAINER的右侧必须与之一致,例如-e PORT=9000 -p 9000:9000;只改PORT而映射仍是8788:8788,请求会打到没人监听的端口上。用 compose 时ports与PORT要同时改(默认的8788:8788+PORT=8788本来就一致)。 - 鉴权:容器以
--lan启动(监听0.0.0.0),会生成 API Key 写入./accounts/settings.json,并打印在启动日志里:docker compose logs wb-proxy | grep -i "api key"。不带这个 Key 调/v1会收到 401;想用自己的 Key 就传-e API_KEY=...。
6. 测试
全部测试集中在 tests/,一条命令跑完:
python tests/run_all.py # 全部套件
python tests/run_all.py realm # 只跑名字里含 realm 的
- 20 个套件:17 个 Python + 3 个 JS;JS 需要 PATH 上有
node,缺失时会跳过并提示。 tests/_mobile_check.py是独立的 Playwright 手机/桌面布局检查器(需自行安装 Playwright),按需手动运行,不在上面的套件集里。- CI(
.github/workflows/tests.yml)跑同一条命令:Ubuntu 上 python 3.9 与 3.12(3.9 是本项目声称的最低版本),Windows 上 python 3.12。
二、核心特性详解
1. 模型列表严格按照桌面应用 1:1 对齐
针对官方本地配置清单(50+ 底层模型)进行了深度清洗,剔除行内代码补全专用模型(如 codewise-*、completion-gf、hunyuan-3b/7b)与底层多云专线变体(如 *-volc、*-lkeap),严格对齐官方Windows桌面端,每个模型均宣告完整桌面软件中显示的上下文窗口(K/M 规范)、单次最大输出、视觉支持、工具调用以及推理档位。
- 🌐 国际版 (17 个):
hy4-preview-f、hy3、deepseek-v4.1-flash、gpt-6-astra、gpt-5.6-sol、gpt-5.6-terra、gpt-5.6-luna、gpt-5.5、gpt-5.4、grok-4.7、gemini-3.5-flash、glm-5.3-flash、glm-5.3、glm-5.2、kimi-k3、kimi-k2.6、kimi-k2.8-preview。 - 🇨🇳 国内版 (14 个):
hy4-preview-f、hy3、deepseek-v4.1-flash、deepseek-v4-pro、glm-5.3、glm-5.3-flash、glm-5.2、glm-5.1、glm-5v-turbo、minimax-m3、kimi-k3-1、kimi-k2.8-preview、kimi-k2.7、kimi-k2.6。
清单与上游
GET /v3/config的agents[cli].models保持同步,没装桌面端的机器也能取到同一份(接口不可用时依次回落到桌面端缓存文件、内置快照)。过滤规则:去掉 5 个档位别名与auto,去掉-sg/-x变体,同名的只留 0.00 倍率那一档。上游新上的模型无需发版即可出现在/v1/models。
💡 关于同模型跨区域混合轮询的说明: 目前对于同时存在于国内版和国际版的同名模型(如
deepseek-v4.1-flash等),暂未实现跨国内/国际账号的自动混合轮询,而是作为两个独立区域分别配置与调度,请求只能走当前所选网关的独立出口。这主要是出于各区域网络环境隔离、出站指纹对齐与账号防风控安全考量;待作者后续实测验证确认长期使用稳定且无封号风险后,会尽快跟进并补齐同名模型的跨区域混合轮询能力。
2. 稳定物理设备指纹隔离 (derive_id)
国际版与国内版共用同一套算法内核:以账号 UID 结合固定业务盐值单向哈希派生机器码与会话标识——同一账号每次出站都来自同一台虚拟设备,不随机漂移;不同账号之间彼此独立,阻断跨账号关联风控。
3. 国内版每日签到、成长任务与积分任务全自动完成
- 每日签到:一键完成国内版打卡领积分;
- 成长任务与积分任务:自动批量接取未接任务,构造规范行为事件上报点亮(画布创建、灵感案例、模板使用、模型体验、多轮对话等 14 项),并自动领奖入账;
- 猫猫日常:自动检查旅行状态,在家自动派出、归来自动领奖。
4. 后台常驻定时调度器 (Scheduler) 与每日自动化
常驻后台,每日按固定整点执行自动化运维排程:
- 每日 09:00 & 21:00:国内版账号自动签到与猫猫旅行闭环;国际版账号自动执行每日活跃打卡对话(领官方每日 30/50 积分福利);
- 每日 22:00:集中扫描全库账号,Token 剩余寿命不足 2 小时自动调用 Refresh Token 保活;
- 每日 01:00:深夜时段自动执行夜猫子任务;
- 国际版动态自适应:切换至国际版视图时,看板顶部提供「每日活跃打卡 (国际版)」一键触发按钮。
5. 保留积分(避免余额被用尽)
看板「设置 → 保留积分」可设定一个最低余额,账号剩余积分低于该值时不再接单,账号行会显示「保留积分」标记。
- 上游在余额耗尽后会给账号发提醒短信,设一个阈值即可避免余额被用到 0;
- 填
0表示关闭,这是默认值; - 判定依据是最近一次查询到的余额(看板「积分」列),从未查询过余额的账号不受影响;
- 账号只是停止接单,仍留在池中并继续定时任务(签到与猫猫旅行本身是赚积分),充值后自动恢复可用。
6. 本地网络工具(可选,默认关闭)
部分客户端(如 Codex App)会在 Responses 请求里宣告 web_search / web_fetch 这类服务端工具,而上游没有对应的执行器——声明送上去,模型看得到工具却没有执行器,客户端最后只拿到一句 unsupported call。
看板「设置 → 本地网络工具」打开后,网关把那份声明换成自己的同名 function、拦下模型的调用、在本地执行(搜索走 DuckDuckGo HTML 版,抓页面抓模型给出的 URL),再把结果喂回模型,最多代跑 3 轮(WB_MAX_WEB_ROUNDS 可调,上限 8);搜索过程会作为 web_search_call 卡片事件与 url_citation 引用回到客户端。
- 默认关闭:工具声明原样透传,客户端自己声明的搜索工具照常拿到调用(v1.5.3 之后的既有行为,升级不受影响);
- 打开后网关会主动出网抓取模型给出的 URL(只挡字面私网地址),且每轮代跑都会多跑一次上游、多消耗该账号额度;国内网络下 DuckDuckGo 可能连不上,那时模型拿到的是错误文本;
- 只影响声明了这两个工具的客户端,普通
/v1/chat/completions客户端不经过这条路径。
三、账号添加与管理
打开看板 http://127.0.0.1:8788/,在「账号」区域操作:
若上游对某账号的单个模型返回 429,账号行会显示受限模型和预计恢复时间(浏览器本地时间);该账号仍可用于其他模型。模型冷却状态仅在当前服务进程中保留,重启后清空。
方式一:浏览器 OAuth 授权(推荐,免客户端)
- 点击 「+ 添加账号 (OAuth)」;
- 选择要登录的区域(国际版 / 国内版),点击弹出的官方授权链接并在浏览器完成登录;
- 程序自动检测回调,完成后账号自动加入账号池,无需手动复制凭证。
方式二:从本地桌面应用导入(暂不可用)
桌面客户端自 2026-09-24 起把 accessToken / refreshToken 改成加密存储($wbEncrypted 信封)。扫描仍能读到文件,但拿不到可用的 token——导入后每个请求都会返回 401(聊天、刷新凭证、查积分都会被拒)。看板上的「扫描桌面客户端账号」入口已暂时隐藏,请改用上面的 OAuth 方式添加账号。
相关代码保留未删(前端 scanDesktop() 与后端 /accounts/import/desktop 都在),等解密打通或改走其他凭据来源之后再放出来。
四、客户端配置与接入
- API 接口地址 (Base URL):
http://127.0.0.1:8788/v1(局域网为http://:8788/v1) - API Key:
- 本机单机模式(未配置 Key 且未开 LAN):可留空或填任意字符;
- 已在看板配置 Key 或 LAN 模式:在看板「设置」页面添加或复制已绑好出口的 API Key(如固定走国际版的 Key 或国内版的 Key)。
- 模型名称:填入
/v1/models中列出的任意官方对齐模型 ID(如deepseek-v4.1-flash、gpt-6-astra、glm-5.3等)
Codex CLI / Claude Code (Responses API)
网关原生内置 Responses 协议双向转换与 WAF 指纹脱敏:
export OPENAI_BASE_URL="http://127.0.0.1:8788/v1"
export OPENAI_API_KEY="你在看板设置中添加并绑定的API_Key"
五、看板与接口一览
访问 http://127.0.0.1:8788/ 即可使用集成看板,核心接口包括:
「数据指标看板」页顶部可切换统计口径:今日 / 本周 / 本月 / 全部历史 / 自定义。本周自周一零点起算、本月自 1 号零点起算,自定义可指定起止时间(任一侧留空表示不限)。切换后 KPI 卡片、账号用量透视表与模型性能表会一起切到同一窗口。
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | / | Web 用量与任务监控看板 |
| POST | /v1/chat/completions | 标准 Chat Completions 接口 |
| POST | /v1/responses | Responses API 协议接口 |
| GET | /v1/models | 官方对齐模型列表(含能力与规格宣告) |
| GET | /tasks | 国内版成长任务、连续打卡与猫猫日常状态 |
| POST | /tasks/run | 触发国内成长任务全自动点亮与领奖 |
| POST | /tasks/travel | 触发猫猫日常旅行(派出 / 领奖) |
| GET | /scheduler | 定时调度器运行状态与排程日志 |
| POST | /scheduler/trigger | 手动立即执行后台巡检保活 |
六、版本更新记录 (Changelog)
v1.6.10
- 修复停用账号会丢掉出口绑定(issue #89,感谢 @lkxlzx):此前停用账号时会顺手把它的
proxySlot清空(set_all_enabled与启动时的迁移也一样),重新启用不会恢复,那条账号就回落到直连——报告人说的「启用禁用账号后代理出口会被重置为直连」正是这个。现在绑定是操作者的选择,停用/启用不再动它:停用只是不接单,重新启用仍走原来的出口。- 槽位卡片的「已绑定」计数依旧只统计启用中的账号(表示这条出口当前有谁在用);要真正解绑就显式选「直连」,或把槽位删掉(删槽位仍会把绑在它上面的账号解绑)。
tests/_test_proxy_slots.py与tests/_test_proxy_slot_lifecycle.py里那几条「停用即释放」的断言改成钉住新行为:停用后绑定仍在、运行时出口不变、重新启用仍走同一槽位。
v1.6.9
- 修好网页通道打卡:会话会被真正驱动到完成(issue #90,感谢 @Saracino34 的准确定位;issue #75):v1.6.4 只建了会话,而建会话只是排队——agent 要等客户端接上这条会话的沙箱并请求这一轮才会跑,所以网关建的那些会话全部停在
CREATING、没有任何输出,第二天自然不加积分(报告人 4/4 复现:手动发的会话十几秒completed,网关建的一条都没动过)。现在按网页端的顺序走完:建会话 →GET /console/as/conversations/{id}/session取沙箱link+token→ ACP(JSON-RPC over HTTP,服务端事件走 SSE)initialize→session/load→session/prompt→ 轮询到completed。实现放在新的wb_webagent.py,只用标准库。- 打卡结果里带上会话状态与输出段数(如「网页通道 completed:12 段输出,15420 ms」),跑没跑成一眼可见,不用等第二天看积分;失败时错误里带会话 id。
- 一轮最多等 120 秒(
WB_WEB_TURN_TIMEOUT可调);实测一条「Hi」18.6 秒跑完、12 段输出。 - 顺带更正 v1.6.4 的一条判断:
GET /v2/activity/banner返回的{"code":12302,"msg":"activity is offline"}只是 banner 模块自己的状态,不能当作「活动停发」的证据。
- 本地网络工具(
web_search/web_fetch)改成默认关闭的看板开关(PR #87,感谢 @Cekxri):默认「直通」——工具声明原样透传,客户端自己声明的搜索工具照常拿到调用(v1.5.3 之后的既有行为,升级不受影响);要在看板「设置 → 本地网络工具」打开,网关才会把声明换成自己的同名函数、在本地执行并喂回模型。关闭时连同名调用的拦截也一并关掉,客户端自己的web_search不会被吞。 - 新增
tests/_test_web_agent.py(6 项,钉住驱动顺序与结果上报);tests/_test_daily_chat.py扩到 10 项、tests/_test_local_web_tools.py扩到 68 项;整套 29 个测试文件全绿。
v1.6.8
- 模型列表改为跟随上游
GET /v3/config的实时清单(issue #85,感谢 @Jay-Young):此前只认桌面端缓存文件与内置快照,没装桌面端的机器(Docker / NAS / Linux 服务器)拿不到桌面端 picker 的那份列表。现在/v1/models直接向出口要agents[cli].models——与桌面端同一份清单,缓存文件退为回落。- 过滤规则:去掉 5 个档位别名(
default-model、fast-model、balanced-model、primary-model、deep-model)与国内版的auto路由项,去掉-sg/-x变体,同名的只留 0.00 倍率那一档(国际版留deepseek-v4.1-flash、丢-sg,留hy4-preview-f、丢hy4-preview)。 - 上游新上的模型无需发版即可出现在
/v1/models(表外的新名字按上游顺序追加在末尾);表顺序与国内版hy4-preview-f这类免费档的保留不变。 - 回落顺序:远端 → 桌面端缓存文件 → 窄端点(仍走旧白名单)→ 内置快照;10 秒一次、最多两次(聊天桌面 UA 失败后换应用 UA)。
- 顺带修掉一处隐性退化:缓存文件是同一份文档但没有
data信封,旧解析只认data.agents,会让缓存路径悄悄退回旧读取器(数量对、元数据丢);现在两种形态都认,并优先取cli这个 agent。
- 过滤规则:去掉 5 个档位别名(
- 国际版模型清单补上
grok-4.7:16 → 17,看板国际版专属标记同步。 - 新增
tests/_test_remote_catalog.py(10 项)钉住解析、过滤规则、免费同级优先、免发版追加、缓存文件驱动与回落不泄漏窄端点未知名。
v1.6.5
v1.6.6
v1.6.7
新增:按 API Key 限制可用模型(issue #73 由 PR #84 实现,感谢 @Cekxri):每个 Key 可以填一个模型白名单(如
deepseek*、gpt-6-astra,支持*通配、多个用逗号分隔),不在名单里的模型请求在网关本地直接返回可读的 400——不送上游、不消耗额度。留空 = 不限制,旧settings.json读回来一律不限制,升级无需迁移。主要用来挡客户端自己发的背景请求(标题生成、记忆整理、自动复核这类不经过模型选择器、直接按目录模型 ID 发出的调用)。面板 Key 编辑卡新增「模型限制」一栏,设了限制的 Key 会显示徽章。- 匹配用
fnmatch、大小写不敏感;deepseek*同时覆盖deepseek-v4.1-flash这种裸 ID 和deepseek/deepseek-v4.1-flash这种带前缀的形态;精确名字不会连带命中后缀(gpt-6-astra不含gpt-6-astra-high,要连带就写gpt-6-astra*)。 /settings/save在提交的行省略该字段时保留已存的值,旧版缓存面板不会把限制洗掉;/v1/chat/completions与/v1/responses两条路径都会拦。
- 匹配用
修复
BLOCK_BACKGROUND_REQUESTS误拦使用者的「压缩上下文」(PR #86,感谢 @Cekxri):该开关的关键字表里有compaction,而使用者按「压缩上下文」时发出的请求request_kind同样是compaction,于是开关一打开,按钮收到的是拒绝报文而不是摘要。现在按「这次压缩是谁发起的」区分:客户端自己发起的压缩带thread_source=memory_consolidation(继续拦),使用者在自己线程上按的压缩放行;auto_review这类即使跑在用户线程上也仍然拦。新增tests/_test_background_requests.py钉住区分规则。新增 Docker 镜像发布工作流(PR #83,感谢 @xihan123):Release 发布后自动构建并推送
linux/amd64+linux/arm64双架构镜像到 GHCR(ghcr.io/ardeyouxipianyi/workbuddy2api-hub,正式版同步打latest),README 补了从 GHCR 拉取运行的说明(GHCR 新包默认私有,要免登录拉取需在 Packages 设置里改为 Public)。新增「每日 Token 限额」:按账号当天用量提前停用、自动切号(issue #82,感谢 @RiggTIan、@lkxlzx):上游的免费额度是按 token 计窗口的(如
deepseek-v4.1-flash约 2 亿 / 12 小时),打满后该账号当天只能等窗口重置——报告里「把用满的号停用后,另一个号也请求失败」,实际是上游把第二个号的大请求也判了限额(code 6004),而 1 条消息的小请求仍能通过,所以账号行「测试」显示正常、大请求却 429。现在看板「设置 → 每日 Token 限额」填一个数即可:账号当日消耗的 token 达到该值后暂停接单、请求自动切到其他账号,本地时间 0 点后自动恢复;填 0 表示不限(默认值)。- 计数取自
usage.jsonl里该账号当天的 token 合计,与看板「今日消耗」同一口径(跳过客户端中断的行);增量扫描 + 15 秒缓存,热路径只读新增的行。计数由日志折算,重启后停用状态依然有效。 - 被停用的账号在账号行显示「日限额」徽章(悬停可看今日已用 / 上限),池子卡片显示「N 个达日限额」,控制台打印
account xxx parked: daily token limit reached (...);所有账号都达额时请求返回429+Retry-After(到本地 0 点),文案说明是本地限额,不碰上游。 - 定时任务(签到、打卡、保活)不受影响,与「保留积分」一致:只是不接新单。两个限制各自独立、按「或」生效——账号要同时不触发两者才会接单(卡片说明里已写明)。
- 新增
tests/_test_daily_token_limit.py:钉住「0 = 不限」「只有计数过的天才拦」「只统计今天、跳过客户端中断的行、按字节偏移增量折叠」「池子跳过被停账号并发布状态」;_test_model_cooldowns.py的桩池补上了新的池方法。
- 计数取自
修复代理槽编辑器被轮询刷掉(issue #79,感谢 @lkxlzx):点「+ 添加槽位」后刚加的那一行撑不过 15 秒就消失——
loadAccounts()挂在 15 秒轮询上,而它会顺带刷新代理槽,刷新是「拉服务端列表 → 整体替换 → 重绘整张表」,那一行还没保存到服务端,于是被旧列表顶掉,正好是报告里说的「还没来得及填写内容就返回了」。(同一个机制也会把已有行的改动打回服务端版本,只是行还在、不容易察觉。)- 现在编辑器里有未保存改动时会跳过刷新,「代理槽」标题旁显示「(N 个 · 未保存)」,让「列表为什么不再自动刷新」是看得见的;保存成功后清零、轮询恢复——点「测试」时触发的那次自动保存同样会清零。
- 新增
tests/_test_slot_editor.js:在假 DOM 下加一行、调用轮询用的loadProxySlots(),断言工作副本没有被服务端列表替换;再断言保存之后会正常刷新。
v1.6.4
- 国际版每日活跃打卡改走网页通道(issue #75、issue #59):两位报告人的实测一致——网关自动发出的桌面端身分对话拿不到每日 30 积分,而在网页版手动发一句就能拿到。顺着这条线索抓包后确认:网页版 app 的「对话」根本不是
chat/completions,而是/console/as/conversations/下的 agent 会话,创建会话时带上 prompt,后端就按该 prompt 起一次任务;而且这条链路只用Authorization: Bearer与X-User-Id两个凭据头(没有桌面端的X-IDE-*指纹),所以网关手里同一份账号凭据可以直接调用,不需要额外的网页登录——实测 GET 会话列表、POST batch-get 都返回业务响应而不是 401。- 现在国际版打卡是两步:先发一条桌面端身分的轻量对话(保持原行为),再在网页通道建一个带 prompt 的会话;返回结果里会带上会话 id,便于核对是否真的建上。
- 账号栏新增 「网页通道打卡 (国际版)」 按钮:手动为所有已启用的国际版账号各建一个网页端会话,点击后会先弹一次确认(它会真的起任务、消耗少量积分)。这个按钮不写
lastDailyChat,所以不会让定时巡检跳过当天的正常打卡流程。 - 「设置」页新增「国际版每日活跃打卡」开关(默认开启),关掉即回到只发桌面端对话的旧行为;取值同样严格限定 JSON 布尔,字符串一律 400 拒绝。
- 需要留意:网页通道会真的起一次任务,会消耗该账号少量积分,换来的是每日 30/50 积分活跃奖励;面板上已写明这一点。
- 另外记录一条上游状态:抓包期间
GET /v2/activity/banner返回{"code":12302,"msg":"activity is offline"},即该活动模块当前处于下线状态。如果网页端也拿不到积分,原因可能在上游而不在通道——这条留待后续观察。
v1.6.3
修复空状态「登录新账号 (OAuth)」按钮点击无反应(issue #66,感谢 @shis23 的准确定位):该按钮调用的是
startLogin(),而这个函数早在 v1.1.0 引入openLoginModal()时就已经不存在了,因此从 v1.1.0 起,账号池为空的首次部署用户点它不会有任何反应,浏览器控制台报startLogin is not defined,而顶部工具栏的同名入口一直正常。现已改为调用真实存在的入口,并新增tests/_test_dashboard_handlers.js:扫描dashboard.html中全部内联事件处理器,断言每一个都能找到对应的函数定义。这类「按钮绑定了一个不存在的函数」的问题只会在浏览器里、且只在该按钮被点击时暴露,任何服务端测试都看不见它。看板时间范围扩展:本周 / 本月 / 自定义区间(issue #68):
- 除「今日 / 全部历史」外,新增「本周」(周一零点起)、「本月」(1 号零点起)与「自定义」(起止时间自选,任一侧留空表示该侧不限)。口径与既有「今日」保持一致,都是本地零点锚定的自然区间;刻意不提供「最近 7 天 / 30 天」这类滚动别名,否则按钮标签在一周里有六天是错的。
/usage、/usage/perf、/usage/analytics三个取数端点统一接受range/since/until参数,KPI 卡片、账号透视表与模型性能表会一起切到同一窗口,第一列的标题同步变为「本周消耗 Token」等,不会再出现「卡片显示今日、表格显示全部」的口径分裂。- 缓存键由原来的 today/all 二值改为真实窗口边界:本周与本月是重叠区间,二值键会让其中一个窗口的数字被另一个顶掉。
- 模型性能表的延迟 / 速度列取自日志末尾的采样,窗口比采样更宽时会在表头注明覆盖起点,不再让局部数据冒充整个窗口。
修复出站身分切换后重启即丢失(issue #76,感谢 @1766266028 的完整定位与复现):账号加载时把出站身分硬编码成默认的 WorkBuddy 桌面端,凭证文件里保存的值被读进一个全仓无人使用的字段(
saved_product),于是面板上的 WB / VSC / CLI 切换(以及启用后的 429 自动切换)虽然确实写进了凭证文件,重启后却一律打回 WB——set_product()的注释承诺「重启后仍然有效」,与实际行为矛盾。现在加载时读回凭证文件中的身分,非法值仍由normalize_product()回退到默认;同时面板切换在改完内存后立即落盘,不必再等 refresh / 签到 / 查积分之类的路径顺带保存——切完就重启容器的人不会再白白丢掉这次切换。新增tests/_test_product_persistence.py(17 项断言)覆盖加载、别名归一、非法值回退、切换落盘与重载,以及身分最终落到端点与出站标头。429 自动切换出站身分改为面板开关(issue #67):切换逻辑本身一直存在(WB / VSC / CLI 轮转、每轮最多 4 次、60 秒内算同一轮、成功即归零),但总开关是源码里的常量
AUTO_SWITCH_PRODUCT = False,面板上没有入口,想用只能改代码。现在改为「设置」页的开关,默认关闭(与改动前行为一致),保存后下一次请求即生效,不再需要动源码。取值严格限定为 JSON 布尔:字符串"false"之类一律 400 拒绝,否则一个真值字符串会把开关悄悄打开,而这正是关掉它的人最不希望发生的事。需要留意的是,开启后切换到的身分同样会随凭证文件持久化(见上一条),重启后不会自动回到 WB——面板上已写明这一点。
v1.6.2
- 全套测试收拢与官方 CI 流水线建设(PR #65,感谢 @teddyli18000):
- 将散落在根目录的 20 个测试套件整齐规整至
tests/目录下; - 新增统一测试运行器
tests/run_all.py,支持一键隔离运行全部 20 个测试套件或按关键词过滤; - 引入官方 GitHub Actions 自动化 CI 流水线(
.github/workflows/tests.yml),每次提交与 PR 自动覆盖 Ubuntu(Python 3.9/3.12)与 Windows 跨平台测试矩阵。
- 将散落在根目录的 20 个测试套件整齐规整至
v1.6.1
- 修复 Docker 部署默认无鉴权开放代理漏洞(PR #64,感谢 @teddyli18000):容器 CMD 默认追加
--lan启动并移除写死的--port 8788。无显式API_KEY时将自动生成高强度 Key 持久化保存并打印在日志中,拒绝匿名公网调用,消除未授权盗刷风险,同时支持通过PORT环境变量动态指定内部端口。 - 修复签到与活跃打卡后视图强制跳转(PR #63,感谢 @teddyli18000):拆分
refreshActiveRealm()与initRealm(),国内签到和国际版每日活跃打卡完成后仅更新出口状态与用量,不再将当前浏览的区域视图强行跳回默认出口。
v1.6.0
- 国际版每日活跃自动打卡领 30/50 积分(issue #59):官方国际站订阅规则规定「通过客户端发起有效对话可领每日活跃 30 积分(Pro 为 50 积分),网页端对话不计入」。现为国际版账号新增每日活跃自动化支持:
- 后台调度器排程自动在 09:00 / 21:00 巡检时为当日未活跃的国际版账号发送一条轻量微型对话(默认走官方
WB客户端出站标头与低消耗模型); - 看板切换至国际版视图时,顶部工具栏提供「每日活跃打卡 (国际版)」一键触发按钮;
- 严格记录
lastDailyChat,保证每个账号每天仅触发一次,不浪费额度。
- 后台调度器排程自动在 09:00 / 21:00 巡检时为当日未活跃的国际版账号发送一条轻量微型对话(默认走官方
v1.5.9
- 修复 OmO / OpenCode 子代理 11128 WAF 拦截(PR #62,感谢 @Sakura1618,issue #61):在
deepseek-v4.1-flash上驱动 OmO 等多智能体调度框架时,上游 WAF 会对Sisyphus-Junior - Focused executor from OhMyOpenCode这一连续短语进行指纹特征匹配并拒流返回code: 11128 (Illegal API invocation from an unapproved channel)。现于脱敏管线中针对性将该短语清洗为Sisyphus-Junior - Focused executor(去掉末尾归属文本),既保留子代理业务身份与指令执行,又彻底消除拦截。
v1.5.8
- 隐藏「扫描桌面客户端账号」入口:桌面客户端自 2026-09-24 起把
accessToken/refreshToken改成加密存储($wbEncrypted信封),扫描仍能读到文件,但拿不到可用的 token——导入后聊天、刷新凭证、查积分全部返回 401。入口已隐藏,请改用 OAuth 添加账号;相关代码(前端scanDesktop()与后端/accounts/import/desktop)保留未删,等解密打通或改走其他凭据来源后再放出来。 - 两个按钮改名:「一键自动分配出口」→「分配代理出口给未绑定账号」(它只给尚未绑定出口的已启用账号轮询分配,已有绑定的账号不动,原名容易被读成重新平衡全部账号;同时补了 tooltip 并修正两条 toast 的措辞);账号行的「刷新」→「刷新凭证」(换的是该账号的登录凭证,不是页面、积分或账号列表)。
- README 全面精简:345 行压到 305 行、字符数减少约 23%,事实与贡献者记录一条未删;顺带修掉两处已失效的说法——头部特性里的「亦支持扫描本地客户端导入」,以及 Docker 那节整段的桌面凭据挂载说明。
v1.5.7
tool_choice="none"不再删除工具声明(PR #57,感谢 @zhangzm0,issue #56):此前客户端发tool_choice="none"时,normalize_tool_choice()会把tools/functions声明整个删掉。模型失去结构化工具通道后,把调用降级成 DSML/伪 JSON 文本塞进content(tool_calls为空、finish_reason=stop),Agent 客户端解析不到调用只能再追问一轮,模型重复一遍 —— 上下文每轮 +2 条消息、token 线性膨胀,直到撑爆窗口或用户手动断开。现在保留工具声明,由tool_choice字段自己表达「本轮不许调用」;上游只认字符串,对象形式仍降级成字符串(发对象会 11101)。实测上游并不真正遵守tool_choice="none",保留声明后它仍可能返回tool_calls——这比让 Agent 原地空转好;确实需要禁止调用时,请由客户端不传tools。
v1.5.6
- Docker 部署下的 Linux 桌面凭据挂载(PR #55,感谢 @LuFering):新增
docker-compose.override.yml.example,以只读方式把宿主机~/.local/share/CodeBuddyExtension/Data/Public/auth挂进容器,补上 Linux + Docker 场景下看板扫描不到桌面凭据的说明;.gitignore同时忽略本地docker-compose.override.yml。 - 保留积分开关(issue #44):看板「设置」新增最低保留积分,账号余额低于该值时不再接单,避免余额被用尽后触发上游的提醒短信。填
0关闭(默认);从未查询过余额的账号不受影响;账号只是停止接单,仍在池中并继续定时任务,充值后自动恢复。阈值保存在accounts/settings.json的reserve_credits,改动即时生效、无需重启。
v1.5.5
- 出站身分改为三套模式:账号行新增
WB/VSC/CLI三档切换,默认WB(WorkBuddy 独立桌面客户端,X-IDE-Type: WorkBuddy),另可切到官方 VSCode 插件(VSCode)或官方 CodeBuddy CLI(CLI),三者各自对应不同的出站指纹与端点。原先的两档实现把桌面端与插件端混为一谈,且默认走 CLI。 - 国际版 CLI 端点修正:
www.codebuddy.ai在实测网络上无法解析(getaddrinfo 失败,系统解析器回 0.0.0.1 空路由),国际版 CLI 身分改走www.workbuddy.ai,该域名接受 CLI 头并正常应答。此前国际版账号在默认身分下直接 502。 - 国际版模型列表对齐官方客户端(issue #51):现为 16 个,取自官方缓存
agents[0]声明的真实模型(已排除 5 个档位别名与同名的 SG 区域变体)。补上glm-5.3-flash(0.06x)与kimi-k2.8-preview(0.77x),移除官方并未提供的hy4-preview与gpt-5.3-codex。 kimi-k2.8-preview解除国内独占限制:此前被CN_EXCLUSIVE拦下并提示“请改用对应出口的 Key”,但官方国际版账号实测可正常调用(HTTP 200 且正常出内容),现已在两个区域同时开放。同类误判的glm-5.1、glm-5v-turbo、minimax-m3已实测可用但未动,留待后续处理。- 国内版
deepseek-v4.1-flash倍率修正(issue #51):看板此前对该模型写死显示「独家优惠 0.03x」,与实际上游计价的 0.11x 无关(官方国内版缓存中该模型没有任何促销折扣),现已改为直接沿用上报倍率。内置快照同步由 0.03 修正为 0.11。 /health鉴权状态修正(PR #52,感谢 @teddyli18000):api_key_required此前只反映启动参数里的 Key,仅配了面板 Key 时会误报false,与/v1实际拒绝无 Key 请求的行为矛盾。现改为复用手持路径的判定。- 单模型限流可视化(PR #50,感谢 @teddyli18000):
/accounts新增modelCooldowns,看板账号行显示受限模型与本地恢复时间;429 状态改由独立短锁保护,避免看板读取与请求线程更新竞争。 - 国内账号昵称容错:国内桌面端把昵称存成
{"$wbEncrypted": ...}加密信封,此前会被str()成一整行字典画在账号行上;现在非字符串值一律回退显示 UID 前缀。
v1.5.4
- 国内版目录补上
hy4-preview-f:内置静态目录里只有旧 idhy4-preview(x0.29),它不在白名单里会被裁掉,而hy4-preview-f只能靠本机桌面端缓存补进来——没装过国内版桌面端的机器上该模型会消失。现按桌面端缓存补进静态目录(x0.00、1M 输入 / 64k 输出、推理档 high)。 - 看板显示积分消耗与账号昵称(PR #45,感谢 @Pro-XK):最近请求表新增「积分」列,账号列改显示昵称(tooltip 保留完整 uid,账号不在池中时回退 uid 前缀);「网关调用量」卡片副标题追加累计积分;账号透视表新增「消耗积分」列。
- 积分口径统一:卡片与透视表此前一个只累计成功请求、一个含失败请求,同一页面上两个「消耗积分」永远对不上。现统一为「上游实际计费过的请求都计入,客户端取消不计」,并各自写明覆盖范围;credit 为 0 的行显示
0.00而非—。
v1.5.3
- 移除网关内置的
web_search/web_fetch代跑(issue #43):实测上游本来就没有服务端搜索能力(声明与不声明工具时模型反应一致、调用次数为 0),而代跑实现有参数名只认query、工具重复下发、失败时发合成resp_wrapup把失败伪装成正常结束三处缺陷。现工具声明原样透传,客户端自己声明的搜索工具会正常拿到调用。
v1.5.2
- 修复 Docker 镜像缺少运行时模块(PR #41,感谢 @wiggins-kong):Dockerfile 的显式 COPY 清单漏掉 v1.5.0 新增的
wb_identity.py与wb_webtools.py,容器启动即ModuleNotFoundError。现改为COPY wb_*.py dashboard.html ./。仅影响 Docker 部署,绿色包与本地运行不受影响。
v1.5.1
- 看板时间范围与筛选修正(issue #39):「今日 / 全部历史」此前只影响部分指标卡,现首张卡跟随切换、第二张固定为累计并注明差异原因;模型性能表跟随所选范围(
/usage与/usage/perf新增range参数),并新增「账号」「模型」筛选,汇总行随筛选重算、失效筛选自动清除。 - 修复账号用量透视表丢失:该表格标记曾被误删,
getElementById恒为 null,整个「各账号用量透视」区块从未渲染;现恢复并适配移动端卡片布局。 - 新增测试:
_test_usage_range.py(22 项断言)与_test_matrix_filters.js(19 项断言)。
v1.5.0
- Codex App namespace 工具支持(PR #33,感谢 @Cekxri):展开
namespace后转发,回程补上该字段;同时支持agent_message(子代理)与无call_id的function_call_output。 - 出站身分标头修正(PR #33):原
X-Product: WorkBuddy为自创组合,官方为X-Product: SaaS;账号行可按需切换 WB / VSC / CLI 三套身分。 - 本地
web_search/web_fetch(PR #33):客户端声明时由网关代跑(v1.5.3 已移除)。 - DeepSeek 多轮
reasoning_content回填补全(PR #36,感谢 @ayeaaaa):thinking 开启即回填,并把字段镜像到reasoning且保证非空;与 v1.4.9 的档位注入互补。 - 看板移动端布局(PR #37,感谢 @ayeaaaa):新增
≤640px手机布局与≤400px微调,桌面布局不变。 - API Key 行 id 唯一化(PR #40,感谢 @wiggins-kong):避免两行同 id 时
/settings/reveal返回别人的 key;读取时也去重,历史文件自愈。 - 修复
/v1/responses非流式路径崩溃:该路径引用了未定义的ns_map,任何非流式请求都会抛NameError断开连接;流式路径不受影响。
v1.4.9
- DeepSeek 思维链默认开启:此前只注入
thinking:{type:"enabled"}而不带推理档位,上游仍按「不思考」应答。现缺档时按模型目录声明的默认档补齐(无声明回退high);客户端显式档位不覆盖,thinking:{type:"disabled"}与reasoning_effort:"none"照常退出。 - 工具调用配对自愈:客户端写不回工具结果时,坏历史被每轮重放、上游对之后每条消息返回
400 code 11148,一次失败调用即可报废整条会话;并行调用间插入的消息(如 Codex 的image_resize_notice)同样打断配对。现出站前把结果块移回所属批次,并按同一份 id 集合对称裁剪孤儿。 prompt_cache_key注入(默认关闭):按账号隔离的缓存键(wb2a--),用WB_PROMPT_CACHE_KEY=1开启。默认关闭是因为实测该上游本就会复用重复前缀,带不带结果一致。- 新增
_test_upstream_repairs.py(49 项断言,无网络依赖)。
v1.4.8
- HTTP 连接同步修复(PR #30):请求被提前拒绝时未读取请求体,会让后续请求在同一 keep-alive 连接上解析失败(日志表现为空请求行的伪 414);同时支持 chunked 请求体、
Expect: 100-continue、超大请求体立即 413。 - 超长请求行回复丢失修复:414 后直接关闭会因未读数据触发 RST,客户端收不到响应;现先有限度排空再回复。
- macOS 启动脚本(PR #31):新增
start-wb-proxy.sh/.command、局域网版本与防火墙助手;Windows.bat未修改。
v1.4.7
- 每账号独立出口代理(PR #26,感谢 @ayeaaaa):新增可命名、可启停的代理槽位,账号绑定后其全部出站请求固定走该出口;看板支持槽位增删、出口 IP 测试与逐账号绑定。
- 账号身份请求全量走代理:
refresh/checkin/fetch_credits此前从宿主机真实 IP 发出,会把账号身份与宿主 IP 关联在一起。 - 槽位 ID 不再回收:ID 改由持久化计数器分配,删除槽位时同步解绑指向它的账号。
- 顶部 GitHub 仓库入口。
v1.4.6
- 看板数据口径与展示修正:指标看板固定展示两区合计,不再跟随当前出口;模型性能表按「模型 × 出口 × 账号」逐行展开,新增「失败」列与三色分列。
- 看板会话与页面保持:会话失效后立即停止轮询并清除旧凭证,不再刷 401 日志;刷新后保持所在页面。
v1.4.5
- GPT 系列流式 Token 与生成速度修复:忽略中间帧全 0 的 usage 占位,并加入断流 Fallback 估算,修复
gpt-5.6-luna/gpt-6-astra等模型输入输出为 0、生成速度缺失的问题。
七、致谢与引用声明 (Credits & References)
协议兼容、风控规避与任务链路设计过程中,参考并吸纳了以下开源项目的经验与逆向成果:
- Sliverkiss/workbuddy2api:成长任务全链路逆向、设备指纹稳定派生(
derive_id)、整点排程调度(Scheduler)、指纹脱敏与reasoning_content回填; - CangShui/workbuddy-cliproxy-fix:早期客户端代理修复与接口差异参考;
- lovingfish/workbuddy-cliproxy 与 mmqz/cpa-multi-plugins:网关通信与多插件管理原型参考;
- ardeyouxipianyi/workbuddy2api:国内版分发包逆向分析与出站 User-Agent 规范参考。
PR 贡献者(v1.4.5 之前的改动未进上方更新记录,这里一并列出):
- @ddddd-ren:用量日志倒序检索与看板防堆叠(PR #14)、原子写入与并发竞争修复(PR #13)、账号池 JSON 导出导入(PR #5);
- @wylftw0314-glitch:Responses API custom 工具协议双向转译(PR #12);
- @shuishuipingan:成长任务领取竞态与专家/团队事件 id 去重、猫猫旅行派出修复、夜猫子任务接入调度器、启动端口误判(PR #21)、按模型冷却限流(PR #22)、任务接取强化与轮询加速(PR #27)、网络抖动重试与 403 直通(PR #28)、HTTP 连接同步(PR #30);
- @ayeaaaa:按账号绑定出口代理槽(PR #26)、DeepSeek
reasoning_content回填(PR #36)、看板移动端布局(PR #37); - @t-789:macOS 启动脚本与防火墙助手(PR #31);
- @Cekxri:Codex App namespace 工具支持(PR #33);
- @wiggins-kong:API Key 行 id 唯一化(PR #40)、Docker 镜像缺少运行时模块(PR #41);
- @Pro-XK:看板积分消耗与账号昵称(PR #45);
- @teddyli18000:单模型限流可视化(PR #50)、
/health鉴权状态修正(PR #52); - @LuFering:Docker 部署下的 Linux 桌面凭据挂载说明(PR #55);
- @zhangzm0:
tool_choice="none"保留工具声明(PR #57)。
八、免责声明 (Disclaimer)
- 本项目为非官方自托管网关,仅供技术研究、逆向协议学习与个人合法授权账号在私有环境测试使用。
- 本项目不提供任何账号及额度。请严格遵守官方服务条款,禁止用于任何商业转售、恶意并发或违规滥用。