Commit Graph
5630 Commits
Author SHA1 Message Date
alfadb a2e1618700 fix(opencode): 纠正 CASE 求值顺序注释并补齐 mode 语义护栏 2026-09-23 15:26:44 +08:00
alfadb d03274ad5f feat(opencode): 用量窗口资格支持 OpenCode 平台并扩展到其它厂商挂载 2026-09-23 15:26:44 +08:00
alfadb 0a43efb9a4 fix(opencode): preserve managed usage state on account updates 2026-09-23 15:26:35 +08:00
alfadb f7f0a56f35 fix(opencode): preserve auto-refresh on usage refresh 2026-09-23 15:26:35 +08:00
alfadb ae2735cdb6 feat(opencode): 用量窗口支持同 Key 组共享、活动防抖与超窗强刷
与 Ollama Cloud usage 对齐:OpenCode Go 作为同 Key 聚合订阅,
多个 openai/apikey/base_url=opencode.ai/zen/go/v1 账号共享同一份
用量状态与刷新节奏:

- 组共享:组指纹 sha256("opencode.ai\0"+api_key);auto_refresh 开关
  与 snapshot 按组写(事务 + FOR NO KEY UPDATE + 锚点 CAS + 纯合并,
  写 snapshot 不会抹掉开关);列表/详情经 ResolveAccounts 组内共享;
  账号换 Key → IdentityChanged → 组级关闭 auto_refresh 并清快照
- 活动防抖 + 超窗强刷:settings 新增 debounce_minutes(默认 1,
  1-60,必须小于 interval_minutes);模型请求活动经网关 5 处调用点
  驱动刷新,due = min(lastUsed+debounce, fetchedAt+maxWait),
  成功路径有 5 分钟最小抓取间隔,失败路径退避优先
- 手动刷新限频 10s→30s 且按组;singleflight/RunDue 按组去重;
  ListDue 在 SQL 内按组算 due(CTE 分组取组内 MAX(last_used_at))

验证:go build + 五包回归 OK;新增组共享/三态 due/组单飞/
IdentityChanged/debounce 校验单测全绿;vitest 11 例全绿;
vue-tsc 零错误。
2026-09-23 15:26:35 +08:00
alfadb 6624947b62 feat(opencode): 支持 OpenCode Go 官方用量窗口查询与自动刷新
OpenCode Go 上游(https://opencode.ai/zen/go/v1)官方提供用量端点
GET /zen/go/v1/usage(Bearer 复用消费 key),返回 rolling(5h)/weekly/monthly
三窗口的 percent 与 resetsAt。本提交为 openai apikey 账号(base_url 为
opencode.ai/zen/go/v1)接入该用量窗口:

- 后端:OpenCodeGoUsageService——手动刷新(每账号 10s 节流)、
  周期自动刷新(全局开关 + 账号开关双开启,interval 5-1440 分钟,
  leader lock + 每轮 20 账号 + 并发 4)、失败指数退避(上限 24h)、
  Retry-After 尊重;401→unauthorized、403→failed;snapshot 持久化于
  accounts.extra(单账号写入,无分组 CAS、无会话加密)
- admin API:settings GET/PUT、/:id/opencode-go-usage GET、
  auto-refresh PUT、refresh POST(与 Ollama Cloud usage 同构)
- 前端:账号列表行内三窗口进度条(复用 UsageProgressBar)、
  编辑弹窗内配置面板(详情+手动刷新+auto-refresh)、全局设置卡片、
  en/zh i18n

验证:
- 上游端点已用生产真实 Go key 实测 200,响应
  {"usage":{"rolling":{"status":"ok","percent":6,...},...}}(2026-08-13)
- go build ./... OK;service/handler/repo/dto/cmd 全量回归 OK
- 新增单测 20 例(解析 401/403/畸形 JSON、退避、节流等)全绿
- frontend vitest 新增 7 例 + Ollama 回归 4 例全绿;vue-tsc 零错误
2026-09-23 15:26:35 +08:00
Wesley Liddick afd069b169 Merge pull request #7532 from alfadb/feature/claude-cli-version-sync
feat(claude): 自动同步 Claude Code 客户端版本号,无需改代码跟随官方版本
2026-09-23 14:54:36 +08:00
shaw 6452aeffa1 fix(claude): 修复版本同步契约测试和缓存刷新 2026-09-23 14:39:29 +08:00
alfadb ca08825935 feat(claude): 自动同步 Claude Code 客户端版本号
出站伪装用的 Claude Code 版本号此前硬编码在 claude.CLICurrentVersion,
只能靠环境变量 SUB2API_CLAUDE_CLI_VERSION 覆盖且需重启;Anthropic 抬高
版本下限时(如 Opus 5.5 要求 >= 2.1.280)必须改代码发版才能跟上。

改为每小时从官方 GitHub Releases 同步最新稳定版,无需重启也无需发版。

- 新增 ClaudeCodeVersionSyncService:1 小时间隔,数据源 anthropics/claude-code
  的 releases/latest,失败回退最近 30 条列表;过滤 draft/prerelease;
  只向前推进,拉取失败保留上次值不降级;面板可关闭
- 新增三个设置项:claude_code_client_version(管理员手动固定)、
  claude_code_client_version_synced(同步服务独占写)、
  claude_code_version_auto_sync_enabled(开关,默认开)
- 取值优先级:面板手动值 -> 同步值 -> SUB2API_CLAUDE_CLI_VERSION -> 内置基线,
  每层经 IsSupportedCLIVersion 校验,含 60s 缓存与 singleflight
- 版本号运行期化:claude.DefaultHeaders 由包级 var 改为函数,新增
  EffectiveCLIVersion/DefaultUserAgent 与 SetCLIVersionResolver(未注入时
  与 CLIVersion() 等价);identity 的 defaultFingerprint 不再在包 init 固化,
  指纹下限与主版本超前校验改用运行期值
- 守住一致性铁律:buildUpstreamRequest 与 count_tokens 各取一次 UA 字符串,
  同时喂给出站 User-Agent 头与请求体 billing 的 cc_version,避免缓存翻转
  瞬间头体版本不一致被判非正版客户端
- 管理后台设置页新增配置区块,含中英文案与「当前同步到」只读展示
2026-09-23 13:35:44 +08:00
lyy0709 c060aa0031 fix(models): repair tests after rebasing onto upstream main
Close the existing catalog identity test before the new capability test and
assert that an explicit null capability remains present. Update the quota
snapshot fixture to the pointer parameter already used by the current base.

Verified six full backend unit packages, scoped lint and CGO-disabled build.
2026-09-23 12:01:40 +08:00
HuntercodeT ecba49f711 fix(gateway): let OpenAI passthrough accounts supplement model discovery instead of hiding mapped models
A single passthrough account made GetAvailableModels return nil for the whole
group, so every other account's model_mapping was dropped from /v1/models and
the Codex catalog. Treat passthrough accounts like unmapped ones: skip their
(possibly stale) mapping and let supplementUnmappedOpenAIModels add the
default set, while ordinary accounts' mappings still reach the list.

Refs #6647, #7517
2026-09-23 11:51:06 +08:00
Achord Chan 17ce21c038 test(scheduler): pass explicit multiplier pointer to snapshot 2026-09-23 11:38:23 +08:00
shaw 5e244e7382 fix(test): 修复调度倍率参数变更后的 CI 编译失败 2026-09-23 11:36:08 +08:00
Achord Chan b5b5f1f94b fix(model-plaza): apply independent video billing multipliers 2026-09-23 11:28:41 +08:00
lyy0709 c4c2e66070 feat(models): support GPT-6 Sol, Luna and Claude Opus 5.5 2026-09-23 11:27:49 +08:00
Wesley Liddick d8d5e1dd35 Merge pull request #7282 from feeeei/feat/affiliate-offline-withdrawal
feat(affiliate): 提取记录支持登记线下提现
2026-09-23 11:20:32 +08:00
Wesley Liddick 59a00631ed Merge pull request #7478 from superzcj/codex/simple-mode-key-window-limits
feat: optionally enforce API-key spending windows in simple mode
2026-09-23 11:19:17 +08:00
Wesley Liddick b2d6b954a1 Merge pull request #7090 from Brisbanehuang/codex/scheduling-rate-account-fallback
fix(scheduler): 无有效探测时回退账号倍率,支持 OAuth 参考倍率留空
2026-09-23 11:18:37 +08:00
Wesley Liddick 1947add842 Merge pull request #7288 from feeeei/feat/backup-monthly-archive
feat(backup): 支持月度归档与独立保留策略
2026-09-23 11:18:08 +08:00
Wesley Liddick 6b71d75bde Merge pull request #4867 from coo1white/fix-backup-s3-secret-reencrypt
fix(backup): keep the S3 secret encrypted when a save inherits it
2026-09-23 11:17:55 +08:00
shaw d68a68fd0d chore(docs): 清理 PR 误入的文档和截图 2026-09-23 10:35:34 +08:00
Wesley Liddick 31a6e74770 Merge pull request #7491 from Thinker-Joe/fix/openai-picker-model-mapping
fix(openai): scope the account test picker to the account model mapping
2026-09-23 10:31:36 +08:00
Wesley Liddick 7c0a2a556c Merge pull request #7160 from StarryKira/codex/log-retention-upstream
feat: 支持运维与请求日志的滚动保留设置
2026-09-23 10:07:25 +08:00
Wesley Liddick 0dd71286f2 Merge pull request #7060 from heathermhuang/fix/composite-image-models-6076
fix(images): allow compatible Gemini models on API-key upstreams
2026-09-23 10:07:02 +08:00
Wesley Liddick b350e079f8 Merge pull request #7139 from HP-network/fix/api-key-model-401-failover
fix: keep API-key accounts available for unknown models
2026-09-23 10:05:42 +08:00
Wesley Liddick 5ad7cf4fb9 Merge pull request #7300 from lizhaoxinlizhaoxin2-lab/fix/responses-stream-error-schema
fix(responses): emit protocol-correct stream errors once
2026-09-23 10:03:00 +08:00
Wesley Liddick 60b9bf7558 Merge pull request #7308 from HuntercodeT/fix/codex-manifest-non-gpt-identity
fix(codex-models): 非 GPT 模型的 Codex 提示词模板去掉 GPT 身份声明,避免 Antigravity 429
2026-09-23 10:01:45 +08:00
Wesley Liddick d6e8b44bcb Merge pull request #7411 from HuntercodeT/fix/antigravity-vendor-identity-429
fix(antigravity): neutralize Claude Agent SDK identity in system prompts
2026-09-23 10:01:18 +08:00
Wesley Liddick fa3f526785 Merge pull request #7489 from doublepi123/fix/tool-schema-null-required
fix(tools): 清洗工具 Schema 里非法的 null required,修复 xAI / Moonshot 400
2026-09-23 10:01:03 +08:00
zhangcj 3b336b2eca feat: optionally enforce API-key spending windows in simple mode 2026-09-23 08:17:48 +08:00
Thinker-Joe 9d7c636db9 fix(openai): respect passthrough in picker image choices
Validate mapped targets for default image models as well as aliases. Preserve native image choices in passthrough and cover mapping changes over the shared catalog cache.
2026-09-23 01:43:06 +08:00
feeeei c19204289d fix(affiliate): 线下提现登记按 Idempotency-Key 幂等
登记请求只有金额,提交成功但响应丢失时,管理员重试会把同一笔站外打款再扣
一次返利额度。现在一次登记由 Idempotency-Key 标识,数据库在同一事务内以唯一
约束去重:

- user_affiliate_ledger 新增 operation_id(幂等键派生的 SHA-256)与部分唯一
  索引(迁移 240);接口要求 Idempotency-Key,缺失或非法返回 400
- 事务内先以 operation_id 写入占位流水,再解冻、扣减并补写额度快照;同键
  重试返回首笔流水的结果并带 X-Idempotency-Replayed,不重复扣减;同键换了
  用户或金额返回 409 IDEMPOTENCY_KEY_CONFLICT;额度不足时占位随事务回滚
- 并发的同键请求在唯一索引上等待先到者:先到者提交则返回同一条流水,回滚
  则自行登记
- 弹窗在网络错误、超时、5xx、408/409 时锁定用户与金额,重试沿用同一请求与
  幂等键;幂等键按管理员、用户、金额暂存于 sessionStorage,登记有确定结果后
  释放
2026-09-23 01:24:59 +08:00
feeeei 8f8358cc67 fix(backup): 关闭月度归档后不再改写旧归档的保留份数 2026-09-23 00:44:29 +08:00
Wesley Liddick 20a94fbb56 Merge pull request #6920 from aofee/codex/grok-quota-cooldown
fix(grok): allow quota queries during account cooldowns
2026-09-22 22:01:24 +08:00
Wesley Liddick da25b18db7 Merge pull request #7077 from ggllzz04/fix/antigravity-tuple-array-schema
fix(antigravity): handle prefixItems and ensure array schema has valid items fallback
2026-09-22 22:01:09 +08:00
Wesley Liddick 02d9901b49 Merge pull request #7038 from zenggang/contribute/gpt55-lite-compat
fix(openai): remove Responses Lite markers after OAuth mapping to GPT-5.5
2026-09-22 22:00:51 +08:00
Wesley Liddick 13be6ca27c Merge pull request #7276 from cyhhao/fix/openai-keepalive-semantic-output
fix(openai): keep transport heartbeats outside semantic output
2026-09-22 22:00:08 +08:00
Wesley Liddick e26abaef7d Merge pull request #6473 from cxx-cod/pr/openai-stream-terminal-eof
fix(openai): end streaming at terminal event instead of waiting for u…
2026-09-22 21:57:45 +08:00
Wesley Liddick 583398d186 Merge pull request #7303 from little-greenbean/fix/upstream-response-close-lifecycle
fix(upstream): prevent EOF stalls when closing response bodies
2026-09-22 21:57:24 +08:00
Wesley Liddick 5cc6ca6f5b Merge pull request #7311 from YogaSakti/fix/scheduler-cache-rpm-fields
fix(scheduler): keep account RPM config in the scheduler projection
2026-09-22 21:57:05 +08:00
Wesley Liddick b12a187d4f Merge pull request #7097 from MHJoy99/contrib/upstream-5203-ping-filter
fix(streaming): drop Anthropic ping keepalives before OpenAI conversion
2026-09-22 21:56:46 +08:00
Wesley Liddick fa9f104a93 Merge pull request #7169 from HuntercodeT/fix/gemini-mixed-model-listing
fix(gateway): list mixed Antigravity models for Gemini groups
2026-09-22 21:56:04 +08:00
Wesley Liddick 51f73840a1 Merge pull request #7272 from zoutao212/fix/responses-function-call-arguments-done
fix(apicompat): 修复 Anthropic 转 Responses 流中 function_call_arguments.done 缺少 arguments 参数的问题
2026-09-22 21:55:48 +08:00
Wesley Liddick bb1f40e35f Merge pull request #7487 from wucm667/fix/issue-7482-anthropic-moderation
Handle trailing system messages in moderation input
2026-09-22 21:54:26 +08:00
Wesley Liddick 7be1628a74 Merge pull request #7488 from wucm667/fix/issue-7484-responses-item-id
Strip oversized input item IDs
2026-09-22 21:54:02 +08:00
Thinker-Joe 4daea093f9 fix(openai): keep OAuth image aliases in the test picker
Image choices were resolved from DefaultModels IDs and from mapping keys, so an
alias whose target is a local image model (paint -> gpt-image-2.5-flare) never
reached the picker: IsModelSupported only matches keys, and a public name is not
an image model. Resolve the public name to its target before deciding, and only
synthesize an entry when the target is an image model.

Update the fixture of
TestFetchOpenAIAccountModelsOAuthLabelsLocalImageModelsLikeUpstream: it asserted
on an upstream slug the account did not configure, which conflicts with the
account-scoped projection. Coverage is preserved by configuring that slug and by
a new test asserting unconfigured text models stay out.
2026-09-22 21:15:20 +08:00
lcy 1d640c40e5 fix(tools): 清洗工具 Schema 里非法的 null required,修复上游 400
JSON Schema 规定 required 必须是属性名数组,但部分客户端会发成 null,
严格校验的上游直接拒绝整个请求:

  xAI       400 /required: null is not of type "array"
  Moonshot  400 At path 'required': required must be an array

同样的模型发纯文本请求一切正常,只有带 tools 时才失败,因此表现得像模型
或渠道故障。

三处改动:

1. 清洗 required:null 时整键删除,而不是替换成 []。JSON Schema 里缺省
   required 等价于无必填项,删除保留了客户端原意,置 [] 反而凭空造出一条
   客户端从未声明的约束。

2. 把 input_schema 也识别为 schema 根。此前只认 OpenAI Responses 的
   parameters 拼法,Anthropic Messages 的工具定义因此绕过整套清洗。

3. 在 ForwardAsAnthropic 入口调用清洗。/v1/messages 此前不做任何工具
   Schema 处理;该函数会分流到原生 Anthropic 直通、Chat Completions 与
   Responses 三条路径,每条都原样透传 tools,所以必须在分流之前处理。

另外把 contentSchema 补进子 schema 关键字:它承载嵌套 schema,其中的
null required 此前会漏网。

配套测试同时锁定反向保证:default / examples / const / enum 里装的是实例
数据,字面量 {"required": null} 属于客户端 payload,不能被改写。现有的
关键字白名单下降本就如此,测试用于防止它退化成无差别遍历。
2026-09-22 20:49:24 +08:00
Wesley Liddick b0e32fe5be Merge pull request #7427 from xlplbo/fix/openai-legacy-scheduler-decision
fix(openai): 非高级调度补齐选号决策并按 previous_response 路由
2026-09-22 20:34:59 +08:00
Wesley Liddick 65f086d2d0 Merge pull request #7479 from lzfxxx/fix/opencode-commandcode-cf1010
fix(gateway): prevent Cloudflare 1010 from disabling OpenCode and Command Code accounts
2026-09-22 20:32:42 +08:00
Wesley Liddick de6388aeca Merge pull request #5443 from llissery/fix/vertex-429-cooldown
fix(gemini): honor RetryInfo on 429 and stop cooling Vertex service accounts until PST midnight
2026-09-22 20:30:37 +08:00