Commit Graph
6608 Commits
Author SHA1 Message Date
刘佳林 19382f275e feat(minimax): 增加 MiniMax 平台支持
把 MiniMax 做成与 Kimi / 智谱 / DeepSeek 同级的国产供应商平台:账号创建/编辑、分组、Composite 路由、原生 Token Plan / Coding Plan 额度,以及 OpenAI 兼容模型列表。

额度走 GET api.minimaxi.com|io /v1/api/openplatform/coding_plan/remains(Bearer)。只解析 model_name=general 的 remaining percent;周窗口仅在 current_weekly_status=1 时计入。

Related to #6742
2026-09-07 18:22:56 +08:00
Wesley Liddick 909b8c7ef4 Merge pull request #6648 from ouchihao/codex/issue-3667-turnstile-loading
fix(auth): show a loading placeholder for Turnstile
2026-09-07 17:38:11 +08:00
Wesley Liddick b8ff74ad70 Merge pull request #6668 from ssharkkky/fix/channel-monitor-gemini-role
fix(monitors): send explicit user role in Gemini monitor probes
2026-09-07 17:38:00 +08:00
Wesley Liddick 96cf8bd76a Merge pull request #6665 from ssharkkky/fix/grok-cross-client-map-default-doc
fix(settings): describe Grok cross-client mapping default as enabled
2026-09-07 17:37:47 +08:00
Wesley Liddick 1f716aa181 Merge pull request #6667 from ssharkkky/fix/antigravity-user-agent-version
fix(antigravity): refresh default user agent version
2026-09-07 17:37:37 +08:00
Wesley Liddick 111c41cf3f Merge pull request #6684 from SakuraPuare/feat/i18n-build-gate
fix(i18n): fail builds on missing locale keys
2026-09-07 17:37:25 +08:00
Wesley Liddick 787a6a33df Merge pull request #6481 from alfadb/fix/claude-cli-version-floor
fix(claude): 让伪装的 Claude Code 版本真正生效,修复 Fable 5.1 仍然 400
2026-09-07 17:37:12 +08:00
Wesley Liddick f8e1e7fed6 Merge pull request #6711 from wucm667/fix/issue-6701-model-not-found-failover
Fix failover for model-not-found responses
2026-09-07 17:36:58 +08:00
Wesley Liddick f09a5b602e Merge pull request #6704 from aofee/codex/fix-http-bridge-session-isolation
fix(openai-ws): 修复 HTTP bridge 并发连接抢占与状态串用
2026-09-07 17:36:36 +08:00
Wesley Liddick 027e3f2d54 Merge pull request #6688 from suixincrazy/fix/codex-manifest-failover-alias
fix(openai): honor model_routing for Codex manifests and scheduling
2026-09-07 17:36:26 +08:00
Wesley Liddick 8116d235ef Merge pull request #6629 from superdav42/fix/preserve-function-arguments-done
fix(apicompat): preserve function arguments from done events
2026-09-07 17:36:10 +08:00
Wesley Liddick 959cbe3d87 Merge pull request #5453 from wucm667/fix/issue-5451-ws-passthrough-before-turn
fix(openai): reacquire passthrough turn slots
2026-09-07 17:35:57 +08:00
Wesley Liddick c0420e2b8a Merge pull request #6484 from aofee/codex/fix-fable-credits-required-scope
fix(anthropic): keep Fable credits_required model-scoped
2026-09-07 17:33:59 +08:00
Wesley Liddick 9578ddbddd Merge pull request #6687 from Chenning-Tao/codex/fix-native-delegation-ws
fix(openai): preserve named standalone Responses inputs
2026-09-07 17:31:17 +08:00
Wesley Liddick e274de45b7 Merge pull request #6702 from a1gaoshanlaiyige/fix/message-cache-json-escaping
fix(gateway): use JSON escaping for message cache promotion
2026-09-07 17:30:54 +08:00
Wesley Liddick ce328fb37a Merge pull request #6670 from ssharkkky/fix/payment-fulfillment-isolation
fix(payment): isolate fulfillment from redeem limits
2026-09-07 17:30:43 +08:00
Wesley Liddick 8f7f2b5d92 Merge pull request #6727 from wucm667/feat/issue-6723-subscription-usage-link
feat(admin): link subscriptions to user usage
2026-09-07 16:45:32 +08:00
alfadb 3efeba33a4 test(claude): 版本覆盖用例字面量随内置基线升至 2.1.259
这三个用例的字面量 2.1.251 写于内置基线为 2.1.220 的时期,本意是取一个
高于基线的补丁位验证"覆盖不得低于 pin"规则。基线升至 2.1.258 后,2.1.251
落在 pin 之下:IsSupportedCLIVersion 应判 false、resolveCLIVersion 应回落
基线,与用例原意相悖,CI 随之失败。

改为真正高于当前 pin 的最小补丁位 2.1.259,用例语义不变;实现未放宽,
constants_cli_version_test.go 中独立的 Fable 5.1 闸门下限 2.1.251 保持不变。
2026-09-07 16:34:35 +08:00
alfadb ce157b32ed fix(claude): 指纹自愈路径同样执行 claude-cli 版本下限
GetOrCreateFingerprint 的 heal 分支(畸形缓存自愈)此前在版本下限逻辑之外:
畸形缓存 + 合法但过旧的客户端 UA 会在首次读取时把过旧 UA 原样落库并返回,
下一次读取才被抬到下限——该窗口内账号仍以过旧版本撞上游客户端版本闸门
(PR #6481 review 指出的边界 case)。

修复:把 floorClaudeCLIUserAgentVersion 后置块从 healthy else 内移到
heal/healthy if-else 之后、TTL 续期检查之前,作为两条缓存命中路径的共同
后置条件;heal 分支 needWrite 本已为 true,单次落库语义不变。

测试:TestGetOrCreateFingerprintHealsPoisonedCacheUsingValidClientUA
期望改为首次返回/落库即 claude-cli/CLICurrentVersion(保留 ClientID 不变、
恰好一次落库断言);floor/UA 全部既有用例保持绿。
2026-09-07 16:34:35 +08:00
alfadb 3cb2381bdc fix(claude): 让伪装的 Claude Code 版本真正生效,修复 Fable 5.1 仍然 400
claude-fable-5-1 已登记进 DefaultModels,但 OAuth 账号实际调用仍然全部失败:

  400 claude_code_version_too_old
  "Claude Code 2.1.220 does not support this model;
   version 2.1.251 or newer is required."

两个独立的原因,缺一不可:

1. CLICurrentVersion 停留在 2.1.220,低于上游对该模型的客户端版本闸门。
   升到 2.1.258(当前官方 CLI 最新版,npm @anthropic-ai/claude-code)。

2. 只升常量对所有已有账号无效。上游请求实际发送的 User-Agent 来自账号级
   持久指纹(IdentityService,Redis fingerprint:<accountID>),不是
   DefaultHeaders;defaultFingerprint 只在首次创建指纹时使用。
   GetOrCreateFingerprint 的缓存命中路径只有两条改写分支:UA 畸形时自愈,
   或客户端送来更新版本时升级。指纹 7 天 TTL 但活跃账号每 24h 续期,实际
   近乎永不过期,系统内也没有重置入口——客户端版本比缓存旧时(例如缓存
   2.1.220、客户端 2.1.75),存量账号会永远对上游声称 2.1.220。

   生产实测:升级 CLICurrentVersion 并部署后仍报同样的 400,读 Redis 确认
   出问题账号的缓存值为 "claude-cli/2.1.220 (external, cli)"。

修复:新增 floorClaudeCLIUserAgentVersion,把 CLICurrentVersion 作为缓存
指纹里 claude-cli 版本的下限,缓存命中与首次创建两条路径共用。

  - 只对 claude-cli 产品生效,其它客户端一律不动
  - 只升不降:版本等于或高于下限(含客户端上报的更新版本)不做任何改动
  - 只替换版本号段,UA 其余部分原样保留,例如
    "(external, claude-desktop-3p, agent-sdk/0.3.100)" 不受影响
  - 与既有的"客户端更新版本"升级分支相互独立、二者取更新者
  - X-Stainless-* 维持既有 merge 语义,不被下限逻辑覆盖

cc_version 无需单独处理:billing attribution block 的版本已由
syncBillingHeaderVersion 跟随实际发送的 User-Agent 同步。

测试:identity_service_version_floor_test.go 覆盖 helper 的 8 种 UA 形态与
5 个 GetOrCreateFingerprint 场景,其中一个直接复现线上故障(缓存 2.1.220 +
客户端 2.1.75 → 写回 2.1.258,Stainless 字段保持不变)。
constants_cli_version_test.go 锁定常量与 DefaultHeaders 的 UA 同源,并断言
不低于 Fable 5.1 的闸门下限。回退实现后对应用例确认转红。

identity_service_user_agent_validation_test.go 中 3 个把版本钉死在旧字面量
的既有用例改为钉 CLICurrentVersion 或更高版本——它们断言的正是本次有意改变
的行为,各自的原始意图(哨兵拒绝、合法升级生效、健康缓存不重写)保持不变。
2026-09-07 16:34:35 +08:00
Wesley Liddick a7d2c782df Merge pull request #5717 from wucm667/feat/issue-2629-current-main
feat(simple-mode): allow basic account grouping
2026-09-07 15:43:22 +08:00
Wesley Liddick a3aa9bae6d Merge pull request #6662 from ZeroClover/fix/codex-manifest-pinned-accounts
fix(openai): reuse pinned accounts for model lists and fix manifest controls
2026-09-07 15:35:49 +08:00
wucm667 8c8fd6e298 feat(admin): link subscriptions to user usage 2026-09-07 10:13:18 +08:00
wucm667 b59f3bf46c fix(simple-mode): enforce basic group boundaries 2026-09-07 09:20:48 +08:00
Zero Clover f88d62ad28 fix(openai): use live account models in connection tests 2026-09-07 00:23:49 +08:00
wucm667 8363d537e0 fix(gateway): fail over model-not-found responses 2026-09-06 20:38:17 +08:00
aofee 96884dd1ae fix(openai-ws): isolate HTTP bridge connection state 2026-09-06 17:05:06 +08:00
a1gaoshanlaiyige 0b061c5fa1 fix(gateway): use JSON escaping for message cache promotion
Use encoding/json instead of Go string quoting when promoting message content to cached text blocks. Add regression coverage for control characters, Unicode, literal backslashes, text preservation, and idempotence.
2026-09-06 16:42:57 +08:00
suixincrazy 28167bbf85 fix(openai): honor model_routing for Codex manifests and scheduling
An OpenAI group that keeps a failover account for a shared public alias
produced a Codex model descriptor with no reasoning levels and text-only
input, which leaves the client's reasoning-effort slider with nothing to
select.

Two accounts explicitly mapping one alias to different upstream models
makes codexExplicitModelTargetsConflictForPlatform true. With no
upstream_model_metadata snapshot to intersect, groupCodexModelMetadata
short-circuits to {reasoningConflict, inputModalitiesConflict}, so
DefaultReasoningLevel is nil (the key vanishes under omitempty) and
SupportedReasoningLevels is an empty array. mergeMissingCodexModelFields
fills only missing-or-null fields, so an empty array is never repaired.

Failing closed is right when the alias target is genuinely ambiguous, but
a group that declares model_routing for the alias has already resolved
that ambiguity: the operator stated which accounts serve it and which is
primary. Treating that as a conflict rejects a deliberate failover setup.

Manifest side: when a routing rule names the alias, restrict capability
declaration to the routed accounts and skip the conflict override.
Capabilities then fall back to the same by-name derivation used for a
single account without a metadata snapshot. Groups with no rule, a
disabled rule, or a rule for another alias keep failing closed.

Scheduling side: model_routing was stored and read platform-agnostically
(admin_group.go, Group.GetRoutingAccountIDs) but four gates in
gateway_scheduling.go only consulted it for Anthropic, so an OpenAI
group's rules were accepted and displayed yet never honored. Without
this, the manifest would honor a rule that scheduling ignores. Both
gates now share one predicate, with the allowed platform set defined in
a single place.

Selection inside a routing list is unchanged: the list is a membership
set, and the winner is still decided by Priority, then load, then
LastUsedAt.

Tests: alias-failover manifest recovery plus the three negative cases,
the platform predicate table, and an OpenAI routed selection that must
beat a higher-priority unrouted account.
2026-09-06 10:12:20 +08:00
Chenning-Tao 985428d9d2 fix(openai): preserve named standalone Responses inputs 2026-09-06 09:33:53 +08:00
wucm667 4a4fd35e0c fix(simple-mode): guard non-empty group deletion 2026-09-06 08:11:23 +08:00
wucm667 f46038820b fix(simple-mode): enforce group capability allowlist 2026-09-06 08:11:23 +08:00
wucm667 05ad6b49a1 fix(simple-mode): enforce basic group capabilities 2026-09-06 08:10:41 +08:00
wucm667 a3675552bd feat(simple-mode): allow basic account grouping 2026-09-06 08:10:41 +08:00
Steven Moder b3ad9b67cf fix(i18n): fail builds on missing locale keys 2026-09-06 04:16:06 +08:00
TT 7a70de401c fix(payment): isolate fulfillment from redeem limits
Payment and admin fulfillment shared the public Redeem entry point, so
fulfillment retries were blocked by, and contributed to, the user's
public redeem failure counter, and lookup errors were silently treated as
"code does not exist" on a partial re-run.

- resolveRedeemAction now distinguishes a genuine not-found lookup from
  other lookup errors (which now fail the fulfillment instead of being
  swallowed and re-created).
- Add validatePaymentRedeemCode: before reusing an existing code during
  fulfillment, verify it belongs to the order (code id, balance type,
  amount, user, status), so a stale or foreign code can never be
  credited against the wrong order/user.
- Split Redeem into a policy-based core: public redemption enforces the
  failure counter; payment fulfillment (redeemForPaymentFulfillment) and
  admin fulfillment (RedeemForAdminFulfillment) bypass it, while all code
  validation and transactional updates remain identical. Admin
  fulfillment keeps the normal redeem-level affiliate rebate.
- The admin CreateAndRedeem endpoint now uses RedeemForAdminFulfillment.

Tests: updated resolveRedeemAction cases, new TestValidatePaymentRedeemCode,
code-used-by-another-user rejection, payment/admin rate-limit bypass
coverage, and public-path regression coverage.
2026-09-05 23:56:59 +08:00
TT c7343d2aa2 fix(monitors): send explicit user role in Gemini monitor probes
The Antigravity native Gemini route (generateContent) expects each
contents entry to carry an explicit "user" role, matching the request
shape used by the established Antigravity account-test flow. Without it
the probe body is rejected with 400 INVALID_ARGUMENT, so Gemini channel
monitors report false failures.

Add the explicit role to the Gemini provider adapter body and cover it
with a regression test that parses the generated request body.
2026-09-05 23:30:45 +08:00
TT a6430bfe20 fix(antigravity): refresh default user agent version
The Antigravity service fingerprints clients by the version embedded in the User-Agent header. The built-in default (1.23.2) had drifted far behind current real client builds, so requests using the default UA started failing OAuth and probe flows.

Bump DefaultUserAgentVersion from 1.23.2 to 2.9.1 (current client build) and update the constant test accordingly. The default remains overridable via ANTIGRAVITY_USER_AGENT_VERSION and the admin setting.
2026-09-05 23:28:33 +08:00
TT 32bf3d0f33 fix(settings): describe Grok cross-client mapping default as enabled
The Grok cross-client model mapping is enabled by default: InitializeDefaultSettings writes "true", and the parser treats a missing/empty value as enabled ("Default true (missing/empty -> enabled)"). However the comment above the defaults and the admin settings UI hint (EN and ZH) both claimed "disabled by default", contradicting the actual behavior.

Align the comment and both UI hints with the real default. No behavior change.
2026-09-05 23:17:34 +08:00
Zero Clover cb31033972 feat(openai): reuse pinned accounts for standard model discovery 2026-09-05 19:58:47 +08:00
Zero Clover f3bbb95310 fix(groups): react immediately to Codex manifest edits and unify dialog toggles 2026-09-05 19:46:25 +08:00
chihao.ou a16070ccf6 fix(auth): show a loading placeholder for Turnstile 2026-09-05 18:25:51 +08:00
github-actions[bot] ab99d56e96 chore: sync VERSION to 0.2.1 [skip ci] 2026-09-05 09:45:17 +00:00
Wesley Liddick 578785ee7f Merge pull request #6640 from cyhhao/fix/claude-billing-fingerprint
fix(claude): align billing fingerprint with outbound User-Agent
v0.2.1
2026-09-05 16:59:33 +08:00
Wesley Liddick ed7c8f2208 Merge pull request #6572 from lyy0709/codex/gpt-6-astra
feat(openai): complete GPT-6 Astra support
2026-09-05 16:50:40 +08:00
cyh 2e1c7c00a6 test(claude): check request body close errors 2026-09-05 16:43:54 +08:00
cyh 994ca26e92 fix(claude): align billing fingerprint with outbound user agent 2026-09-05 16:34:00 +08:00
Wesley Liddick d2f87c612e Merge pull request #6638 from feeeei/feat/images-url-to-b64json-backfill
feat(images): 账户开关将生图结果 url 下载回填为 b64_json
2026-09-05 16:24:40 +08:00
lyy0709 62cd63bfda fix(openai): retain capabilities when model listing is unavailable 2026-09-05 16:24:15 +08:00
lyy0709 dee35a841d merge: reconcile Astra fixes with upstream capability sync 2026-09-05 16:19:57 +08:00