Skip to content

feat: add WorkBuddy GLOBAL (workbuddy.ai) region support + refreshed model catalog - #23

Closed
bimapopo345 wants to merge 4 commits into
Sliverkiss:masterfrom
bimapopo345:feat/global-region-and-model-catalog
Closed

bimapopo345 wants to merge 4 commits into
Sliverkiss:masterfrom
bimapopo345:feat/global-region-and-model-catalog

Conversation

@bimapopo345

Copy link
Copy Markdown

Summary

Adds WorkBuddy Global (workbuddy.ai) support alongside the existing CN realm, and refreshes the static model catalog to match the current WorkBuddy Global UI.

Motivation

The login tool was hardcoded to the CN realm (copilot.tencent.com, "CN realm only"), while the server itself already supports both regions via ChatBaseGlobal. Users holding Global accounts had no way to log in through this tool — the OAuth flow would always send them to codebuddy.cn.

Changes

cmd/login (region-aware OAuth)

  • login url [cn|global] and login poll [cn|global]global is the default
  • Global base: https://www.workbuddy.ai with identical /v2/plugin/auth/state|token|login/account?platform=CLI endpoints (verified against Maquer/workbuddy-checkin login.sh, which documents the Global realm)
  • Origin/Referer headers switch per region (codebuddy.cn vs workbuddy.ai)
  • Per-region state files stored in the repo directory instead of /tmp (Windows has no /tmp; this bit me on Windows Server RDP)
  • domain defaults to www.workbuddy.ai for global when upstream omits it, so auth.Region() classifies correctly

internal/server (model catalog)

  • Static fallback catalog refreshed from the current WorkBuddy Global UI (20 models): hy4-preview (free tier, ~1M ctx), hy3/hy3-preview/hy3-preview-agent, gpt-5.6-sol/terra/luna, gpt-5.5, gpt-5.4, gpt-5.3-codex, gemini-3.5-flash, glm-5.3, kimi-k3, plus the existing ones

Testing (Windows Server RDP, Go 1.26)

  • login url global → valid authUrl from workbuddy.ai ✅
  • Browser login → login poll global → token JSON with domain: www.workbuddy.ai
  • Converted credential loaded into pool (healthy: 1) ✅
  • /v1/chat/completions through the proxy: glm-5.1 ✅ 200, hy3 ✅ 200, hy4-preview ✅ 200, minimax-m3 ✅ 200
  • kimi-k2.7 / deepseek-v4-flash currently return upstream 503 (code 11134/11102, "service unavailable / service info not found") — upstream-side, unrelated to this PR
  • Note: the Global upstream requires a system message first (code 11128: first message is not system prompt) — worth documenting

Notes

  • The CN flow is untouched (default headers/URLs identical to before when cn is passed)
  • Context lengths in the catalog are approximated from public model info; happy to adjust

Copilot AI lite review requested due to automatic review settings September 7, 2026 03:14

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The login tool currently hard-codes state file paths to a machine-specific Windows location and accepts invalid region values silently, both of which can break or misroute logins in real usage.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds WorkBuddy GLOBAL (workbuddy.ai) support to the CLI OAuth login flow and refreshes the server’s static fallback model catalog to reflect the current Global UI, improving usability for non-CN accounts when dynamic model discovery fails.

Changes:

  • Add region-aware OAuth login to cmd/login with login url [cn|global] / login poll [cn|global] (default: global), switching base URLs and Origin/Referer per region.
  • Refresh internal/server static fallback model catalog with additional Global models.
File summaries
File Description
cmd/login/main.go Makes the CLI login flow region-aware (CN vs Global) and adjusts state/token/account requests accordingly.
internal/server/handler.go Updates the static fallback model list used when dynamic model fetch fails.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cmd/login/main.go
Comment on lines +31 to +32
stateFileCN = "C:/Users/Administrator/Desktop/Mod/workbuddy2api/.wb2api-login-state-cn.json"
stateFileGlobal = "C:/Users/Administrator/Desktop/Mod/workbuddy2api/.wb2api-login-state-global.json"
Comment thread cmd/login/main.go
Comment on lines +103 to +107
region := "global"
if len(os.Args) >= 3 {
region = os.Args[2]
}
// 每个流程独立 cookie jar(oauth.go:22-29:多账号登录互不串会话)
base, origin, stateFile := bases(region)
@bimapopo345

Copy link
Copy Markdown
Author

Update 2: Follow-up commit `5581402` — `/v1/quota` now exposes per-account cooling status (cool_until RFC3339 + pre-formatted cool_remaining like '2h 13m 05s', reason, success/error counters). While an account is cooling, the live billing probe is skipped automatically (avoids extending upstream 429s). Verified with 2 Global accounts in the pool: both appear with their own package lists and rotation works via the 9Router chat path.

@bimapopo345

Copy link
Copy Markdown
Author

Update 3: Commit `caa382c` adds per-account pinned endpoints — `POST /v1/a//chat/completions`, `GET /v1/a//quota`, and `GET /v1/accounts` (machine-readable pool listing with chat_path/quota_path per member). This lets an upstream gateway create one connection per account and round-robin across them at its own layer, instead of sharing a single pooled connection. Verified live with 2 Global accounts behind a 9Router instance: both pinned paths return 200 and rotation alternates accounts.

287775856 added a commit to 287775856/workbuddy2api that referenced this pull request Sep 11, 2026
从上游 Sliverkiss#23 合并并修正后落地:

## 上游 PR 提供的功能
- cmd/login 支持 cn|global 双 region(workbuddy.ai vs codebuddy.cn)
- 静态模型回退表刷新到 20 个(hy4-preview/gpt-5.6*/gemini-3.5-flash 等)
- 新增 GET /v1/quota、GET /v1/accounts、/v1/a/<uid>/chat/completions、
  /v1/a/<uid>/quota(供 9Router 等上游网关按账号做连接级轮转)
- pool.PeekByUID:只读取凭证、不占在途、不记 lastUsed

## 合并时修正的缺陷(原 PR 直接合并会引入生产故障)
1. 【崩溃】Session=nil 时 nil 解引用 panic
   固定号端点在账号失败/需刷新时走 fail() → Session.Unbind(0x0) 直接崩进程。
   触发条件:session_sticky.enabled=false + 固定号端点 + 该号请求失败。
   已加 nil-safe 包装 bindSession/unbindSession 并补回归测试。
2. 【平台破坏】login state 文件硬编码 C:/Users/Administrator/...,
   Linux 部署直接 fatal。改为 os.TempDir()(Linux /tmp、Windows %TEMP%),
   支持 WB2A_STATE_DIR 覆盖。
3. 【静默行为变化】默认 region 从 PR 的 global 改回 cn:
   login.sh 以 `login url`(无参)调用,默认 global 会让现有 CN 用户
   静默切到另一个 realm。保持 cn 默认,./login.sh global 显式切换。
4. 【region 不生效】server 侧 chatBase/billingBase/originRefererFor 全部
   硬编码 CN,Global 账号登录后所有请求仍打向 CN。改为按账号 domain 分流,
   workbuddy.ai → global,其余 → cn,并补测试。

## 额外加固(防止配额端点拖垮网关)
- /v1/quota 原实现逐账号串行探测、无总超时:46 账号最坏 46×120s≈92 分钟。
  改为并发 + 15s 总预算 + 30s 短 TTL 缓存;冷却账号跳过探测避免延长限流。
- /v1/a/<uid>/quota 复用缓存结果而非每连接全池探测(避免 N² 上游调用)。
Sliverkiss added a commit that referenced this pull request Sep 14, 2026
对 auths/ 下真实 global 账号(bfb03c91)发起只读探测,覆盖
PR #23/#44/#45 标【待实测】的 10 项端点,全部只记录响应不断言。

关键实测结论:
- R1 billing:/billing/meter/get-user-resource 无 /v2 直接 200(R1 成立)
- R2 chat:console/v2 双路径均 403 code 11140 "request illegal"(账号级推理门
  禁,非路径问题;生产 ChatStream 403 当场返回不换路,行为正确)
- R9 SSE usage.credit:chat 被 403 拦截无法取流,三态暂无法定论(缺失不记账
  的安全处理已覆盖)
- refresh:/v2/plugin/auth/token/refresh 可用,token/refreshToken/expiresAt 更新
- FetchModels:console 400 "Client not found" / v2 401 → 回落静态 21 名
- trial:GET 404 / POST 200 code 14051 "has applied trial",ClaimTrial 幂等识别成功
- R4 错误码:采集到 11140(chat 风控)/14051(trial 已领)/401(models v2);
  11140 在 global 是 request-illegal 而非 CN 的限流文案,Classify 默认 ErrClient 安全
- 网关:/v1/models 双前缀(37 名=21 global + 16 cn)、/status realm=global +
  realm_totals 双分组、global: 前缀 chat 全链路路由正确但上游 403 → 503

边界:只读探测;不写 auths/ 落盘凭证(token 脱敏);SaveAtomic 绝不调用。
build tag 隔离,常规 go test ./... 不受影响。

Co-Authored-By: Claude Code <noreply@anthropic.com>
@Sliverkiss

Copy link
Copy Markdown
Owner

国际版 GLOBAL region support + model catalog 已在 master 实现(global realm 建模 + 前缀路由 + FetchGlobalModels + 模型路径按 realm 切),感谢贡献。

@Sliverkiss Sliverkiss closed this Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants