Conversation
(cherry picked from commit fdce5b8)
(cherry picked from commit ad05eda)
(cherry picked from commit d1ba579)
(cherry picked from commit bb97ab3)
- 新增 241 迁移:user_platform_quotas / composite_model_routes 的 CHECK 约束 加入 typesafe。此前设置 typesafe 默认配额会让注册时的多行配额快照整体 违约(fail-open 后新用户所有平台配额丢失),单用户配额与 Composite 路由保存 500。 - Prompt 审计新增 typesafe_systemone 协议提取(state + 各问题 instructions/ criteria/选项标签,键排序保证哈希稳定);此前提取为空,阻断与异步审计均被放行。 旧内容审核同样覆盖问题文本,且不再丢弃含 <system-reminder> 的 System One 文本。 - TypeSafe 分组及路由到 TypeSafe 的 Composite 请求访问 Messages / count_tokens / Chat Completions / Responses 时返回 404,避免以 x-api-key 打到错误上游路径并 污染账号状态;TypeSafe 账号 base_url 为空时不再回退 api.anthropic.com。 - SystemOne 补在途余额预留、利润控制准入终检、wrapReleaseOnDone,失败切换改用 共享 FailoverState(同账号重试 / 池模式 / 临时封禁)。 - 上游错误沿用共享账号错误策略:402/403、自定义错误码、临时不可调度规则生效, 记录 ops 上游错误;400/422 仍不切换且永不改变账号状态。 - 账号测试改走原生 System One 探测,可用模型只返回 jev-latest; 响应超限显式报错,响应 Content-Type 仅透传 JSON 类型。 (cherry picked from commit 2d8a386)
- System One 校验拒绝重复键与大小写/Unicode 折叠变体键(请求顶层、
questions、问题对象):encoding/json 大小写不敏感且取最后一个重复键,
而原始 body 原样转发,此前 {"model":"x","MODEL":"jev-latest"} 可绕过
jev-latest 限制、模型白名单与流式限制。
- Prompt 审计与旧审核同时收集对象键名、问题 ID 与未知扩展字段(不含规范
字段名与已校验的 type),此前把内容放进键名即可完全绕过审计。
- 上游成功响应的 usage/model 宽松解码(浮点、数字字符串),避免上游已
计费而网关整体 502 不记账;解码失败记录 response_error ops 事件。
- 上游 413 与 400/422 同视为请求错误:透传状态码、不切换、不改账号状态。
- TypeSafe base_url 末尾的 /v1 自动剥离,避免拼出 /v1/v1/systemone;
/v1/systemone 改挂文本请求体上限。
- Composite 静态兜底模型列表、管理端候选列表恢复为不含 jev-latest;
Codex 清单永不列出 TypeSafe 模型;TypeSafe 分组候选默认 jev-latest。
- 创建账号从 Grok 切到 TypeSafe 时重置为白名单模式;错误透传平台列表补 typesafe。
(cherry picked from commit 9eb394e)
(cherry picked from commit fa49647)
- 后台支付设置新增「充值赠送阶梯」(满 X 送 Y%,RECHARGE_BONUS_TIERS)与 Markdown 活动文案 (RECHARGE_BONUS_NOTICE):阈值按用户输入的支付金额命中(取不超过金额的最大档), 赠送按到账基数(输入 × 充值倍率)计算;严格校验写入、宽松解析读取,订阅订单不参与 - 下单时按当时配置计算赠送并落库:payment_orders 新增 bonus_amount 列(迁移 241), amount 仍为到账总额,到账/兑换码/退款逻辑不变;推广返利基数改为 amount - bonus_amount - checkout-info 下发 recharge_bonus_tiers / recharge_bonus_notice;创建订单与订单查询响应带 bonus_amount - 充值页:快捷金额按钮右上角「+N%」角标 + 第二行到账金额,金额卡顶部渲染活动文案, 订单摘要新增赠送额度行并在有赠送时始终显示到账余额;订单列表/详情/支付结果/成功面板显示含赠送 - 后台新增 RechargeBonusTierEditor(行内校验重复/非法阈值,自动排序并显示区间预览) - 补后端单测、契约测试与前端 vitest,zh/en 文案 (cherry picked from commit 1b1039f)
- 新增全局模式开关 RECHARGE_BONUS_MODE(bonus / discount),接入支付配置、后台设置接口与 checkout-info - 折扣模式:到账不变,实付基数按百分比打折(按币种精度取整),手续费 / 每日限额 / 渠道选实例沿用折后基数; 百分比须 < 100,运行时 ≥ 100 按无优惠处理 - 充值页角标改为单行红色价签(赠金「+20%」/ 折扣「20% OFF」),第二行按模式显示到账或折后实付; 摘要卡折扣模式显示优惠行,渠道限额校验改用折后实付 - 后台「充值优惠阶梯」拆为独立卡片:赠金 / 折扣切换、紧凑档位表格、区间预览、活动文案 - 补前后端单测与 zh/en 文案 (cherry picked from commit 1aa34d4)
POST /api/v1/payment/public/orders/verify is unauthenticated and still used by PaymentResultView as a fallback, so keep it but cap it at 20 req/min per client IP (fail-open on Redis errors) to make out_trade_no enumeration impractical without affecting users mid-payment. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit cf19f30)
(cherry picked from commit 0cecf3c)
…ient The antigravity Gemini forward path returned the raw upstream Google error body to end users, which can contain consumer project numbers, GCP project IDs and service account emails. Return a Gemini-style error body with only code/status and a scrubbed message; raw body stays in ops logging. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit d359196)
…okens - Verification code attempts (register + notify email) are now reserved via an atomic Redis INCR (Lua) before comparing, so concurrent wrong guesses cannot exceed the 5-attempt cap. - Password reset tokens are stored as SHA-256 hashes and consumed with an atomic Lua compare-and-delete, so a token can only be used once even under concurrent requests. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit b1ce3c6)
Replace the static priority number in the accounts table with a compact stepper: hover reveals -/+ buttons, clicking the value allows typing (Enter to save, Esc to cancel, arrow keys to nudge). Rapid clicks are debounced into a single priority-only PUT, failures revert the value and surface a toast, and the row is patched in place without a full reload. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 0da18e4)
disabled:opacity-30 overrode opacity-0, so the decrement button stayed faintly visible on every row already at the minimum. Style disabled buttons via text colour instead, and raise idle icon contrast. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 58d6050)
The create form shows the upstream billing auto-probe toggle for every
API-key platform and enables it by default. TypeSafe was added as an
API-key platform but not to IsUpstreamBillingProbeIdentity, so creating a
TypeSafe account with the default form state fails with
400 UPSTREAM_BILLING_PROBE_ACCOUNT_INVALID ("account is not an API key
account").
TypeSafe accounts store credentials.api_key/base_url like every other
API-key platform, which is all the probe reads. Add TypeSafe to the probe
identity set, and add typesafe.ai to the official API domains so accounts
on the default https://api.typesafe.ai base URL record "unsupported"
without sending the key to a path that cannot exist, matching the other
official providers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 66a9e2e)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 8b9788e)
- Pass the API key concurrency limit to AcquireUserSlotWithWait, like the other gateway entry points in this fork. - Drop the in-flight balance reservation the upstream handler calls. The fork does not import upstream's reservation feature (see Wei-Shaw#253); System One keeps the same billing eligibility pre-check as the other endpoints. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The upstream README sections for TypeSafe (v0.2.13) do not fit this fork's README, so the usage notes live in docs/typesafe-jev.md, which is added to the docs allowlist in .gitignore. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fork's quota modal submits every supported platform; with TypeSafe the payload has eleven entries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Upstream added typesafe to the signup default platform quota map in the TypeSafe change but left this spec at five platforms. It is outside the critical CI list, so the mismatch only shows in the full Vitest run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… completes When an API key with quota or rate limits was deleted while a request was still in flight, the key counter update matched no rows and returned ErrAPIKeyNotFound, rolling back the whole billing transaction including the balance/subscription charge. Skip the key-scoped counters in that case and keep settling the user and account side as usual. (cherry picked from commit c2d5bbd)
(cherry picked from commit 432a6a4)
6 tasks done
Brings in 9699d9e and 502db27 (from Wei-Shaw#273). No textual conflicts; the next commit replaces the soft-deleted key counting from 9699d9e with the upstream Wei-Shaw#7816 settlement already on this branch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… of counting tombstones 9699d9e (Wei-Shaw#273) and upstream Wei-Shaw#7816 fix the same rollback when a key is deleted while its request is still being billed, in opposite ways: Wei-Shaw#273 keeps adding to the soft-deleted row's quota and rate-limit counters, upstream skips the key's own counters. Per collaborator decision, keep the upstream approach that this branch already cherry-picks. - Restore the deleted_at IS NULL filters in the key counter updates, so a deleted (or missing) key surfaces ErrAPIKeyNotFound and Wei-Shaw#7816 skips it while the user's balance or subscription is still charged. - Keep Wei-Shaw#273's settlement tests with upstream expectations: a deleted key's counters stay unchanged; database failures still roll back; a missing key row now commits the user charge instead of rolling back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
解决的问题与行为变化
4f651425a单独引入)。production 缺少三项安全加固、Grok 交互式 CLI 身份对齐、TypeSafe / Jev System One 平台、充值优惠阶梯、账号优先级快捷调整和 API Key 按分组排序。-x来源;前 17 条按上游合并顺序,fix(billing): settle usage when the API key is deleted before billing completes Wei-Shaw/sub2api#7816 的 2 条追加在分支末尾),另加 4 个 fork 整合提交,以及合并 production 后把 fix: 完善 Key 删除后的结算与 WebSocket 撤销检查 #273 的计费做法换回上游的 1 个提交(见下)。主要变化:POST /api/v1/payment/public/orders/verify按客户端 IP(按server.trusted_proxies解析)每分钟最多 20 次,超出返回 429;Redis 出错时放行,不影响正在付款的用户。grok-pager/1.0.46 grok-shell/1.0.46 (<系统>; <架构>),系统和架构按网关所在机器生成(如linux; x86_64);x-grok-client-identifier: grok-pager、x-grok-client-mode: interactive;x-authenticateresponse: authenticate-response,降级到官方 API 时去掉这两个新增头。typesafe,只支持 API Key 账号,默认上游https://api.typesafe.ai;POST /v1/systemone,原生非流式 JSON,模型jev-latest,内置价格输入 $0.042/M、输出 $0;bonus_amount记录赠送额度,推广返利只按实充部分计算;ErrAPIKeyNotFound)而更新失败,原来会让整个计费事务回滚,连用户余额和订阅都不扣。现在只跳过这把 Key 自身的计数,用户余额、订阅和账号额度照常结算;其他错误仍然让事务失败。production 现有的9699d9ee4(来自 fix: 完善 Key 删除后的结算与 WebSocket 撤销检查 #273)会继续给软删除的 Key 累计额度和限速,本 PR 的09d226210把它换回上游做法。9699d9ee4计费、502db27d2WebSocket 撤销检查),GitHub 上 fix: 完善 Key 删除后的结算与 WebSocket 撤销检查 #273 仍显示为开启。quota_used、usage_5h保持 0。f165e9589)后,用09d226210恢复计数 SQL 的deleted_at IS NULL条件,并把 fix: 完善 Key 删除后的结算与 WebSocket 撤销检查 #273 的结算测试改成上游语义。502db27d2的 WebSocket 撤销检查与上游做法不冲突,保留不动。2e3c2cf59)不在本次范围,可另行同步。同一 PR 的 axios 升级00940743d,以及 修复 Grok 426 并对齐交互式 CLI 身份头 Wei-Shaw/sub2api#7780 里的53158587a,与 production4f651425a的补丁完全相同(git patch-id一致),所以不重复引入。42bc7f6cf、458b92abd不引入。84e33bbbc。关联记录与来源
5106065716e494204fc0e8db16f68f6e9d576be0;3040209f205472038c1ba745a1bedd2edd9053b1;707992efa修复 Grok CLI 版本门槛并对齐官方无界面请求头fdce5b8d0b79d548fa依据正常交互式 CLI 抓包修正 Grok 身份头ad05eda15ceb605aa9feat: add native TypeSafe Jev System One supportd1ba5797776435f057fix(typesafe): align System One validation with upstream schemabb97ab36478067aa6cfix(typesafe): 补齐平台迁移、审计覆盖、端点隔离与错误策略2d8a38681bcdfe9fdbfix(typesafe): 堵住校验解析差异与审计盲区,收紧模型列表口径9eb394e3ef40ba1bc4test(model): 错误透传平台列表守卫纳入 typesafefa49647c60d13f19a7feat(payment): 充值赠送阶梯(按金额档位额外赠送到账额度)1b1039f4f866cd4adffeat(payment): 充值优惠阶梯支持折扣模式,快捷金额角标改为促销价签1aa34d47863de5fd1dfix(payment): rate-limit anonymous public order verify endpointcf19f30d2abc604072feat(keys): support sorting API keys by group name0cecf3c368b0f500cdfix(antigravity): sanitize upstream error body before returning to clientd359196ad13acb7409fix(email): atomic verify-code attempts and hashed single-use reset tokensb1ce3c6d506ea65d9afeat(admin): inline quick-adjust stepper for account priority0da18e4a599f51102efix(admin): keep disabled priority stepper hidden until hover58d605083decaf9c99fix(billing): allow upstream billing probe for TypeSafe API-key accounts66a9e2e6b7a9859bbetest(billing): drop added comments8b9788eeb7d532bd37fix(billing): settle usage when the API key is deleted before billing completes(分支末尾,位于整合提交之后)c2d5bbd939bb56ce75chore(billing): simplify comment432a6a461fork 整合提交(不对应上游提交):
84e33bbbcfix(sync): adapt TypeSafe System One to fork billing and key concurrencyAcquireUserSlotWithWait(与其他网关入口一致);去掉上游的在途余额预占调用,保留与其他端点相同的计费资格预检和利润控制准入。ceb605aa9~7a9859bbe的internal/handler包要到这一提交才能编译。d9981137fdocs(sync): document TypeSafe / Jev System One usagedocs/typesafe-jev.md,并在.gitignore的 docs 白名单中放行。06ded56b3test(sync): include TypeSafe in the full platform quota payloadb1ad7faddtest(sync): include TypeSafe in default platform quota helperstypesafe加进注册默认配额,但settings.authSourceDefaults.spec.ts仍断言 5 个平台。该用例不在 CI 关键测试清单里,只有全量 Vitest 能发现。f165e9589Merge production into sync/upstream-v0.2.12-v0.2.13-selective9699d9ee4、502db27d2,无文本冲突。09d226210fix(sync): settle deleted keys the upstream Wei-Shaw#7816 way instead of counting tombstonesincrementUsageBillingAPIKeyQuota、incrementUsageBillingAPIKeyRateLimit的deleted_at IS NULL条件(与上游一致),已删除的 Key 返回ErrAPIKeyNotFound后由 Wei-Shaw#7816 跳过。保留 #273 的结算测试,按上游语义调整:集成测试 16 个组合中,已删除 Key 的额度和限速计数保持不变,余额 / 订阅照常扣,重试不重复扣,凭据和删除状态不恢复;单测中数据库错误仍整体回滚,Key 行不存在时提交用户扣费。冲突与适配:
CLIStableVersion = CLIClientVersion:XAI_GROK_CLI_VERSION覆盖值低于 1.0.46 时回退到 1.0.46;上游把通用下限设为 1.0.13,这里不跟进。fork 原来的测试版本号都基于 1.0.44,统一顺延 2 个补丁号。身份头采用上游最终版本;fork 原来的xai-grok-workspace/<version>UA 本身也来自上游(9fb260439),本次随上游一起替换。docs/typesafe-jev.md(d9981137f)。account_service.go、admin_account.go保留 fork 的模型映射模式校验、Codex ticket extra 合并和长上下文计费 extra 归一化,同时加入上游「TypeSafe 只支持 API Key」的检查。typesafe加入 fork 统一的PLATFORM_QUOTA_PLATFORMS,不保留上游在组件里另写的平台列表;相关测试改为 11 个平台(06ded56b3、b1ad7fadd)。keys.concurrencyAndWaiting。测试保留 fork 现有用例,排序用例改用上游的it.each,覆盖并发列升序和分组列升、降序。241_add_payment_order_bonus_amount.sql、241_add_typesafe_platform.sql保留上游原文件名和原内容(先例:239、240)。fork 已有241_add_account_group_rate_multiplier.sql和 242~262,迁移执行器按文件名记录、执行所有未执行的文件,所以已部署实例升级时会补跑这两个文件。typesafe的 CHECK 清单是 fork 238 号清单的超集,存量数据可以通过校验。payment_orders.bonus_amount、配额平台)与 wire 重新生成,和提交内容无差异。复现与验收
502db27d2(含 feat(prism): isolate concurrent turns and select account models #269、fix(pelican): 智商测试/鹈鹕测智对 Claude 不再返回为空,并传递思考强度 #271、feat(pelican): 补齐结果 API 管理开关和用户调用信息 #272,以及维护者直接推送的9699d9ee4、502db27d2)。最初基于bf9405e4a完成同步,后变基到eceb5632b,冲突只有.gitignore末尾(与 production 新增的 docs 白名单行并存);之后 production 新增的两个提交用合并提交f165e9589合入,无冲突。Go 1.27.0、pnpm 9.15.9;在独立克隆中使用 mock、miniredis/本地 Redis 和 Docker 集成测试,没有请求生产上游、没有修改运行配置。POST /api/v1/payment/public/orders/verify超过 20 次;并发提交错误的邮箱验证码;对同一个重置密码链接并发提交两次。POST /v1/systemone,再调/v1/messages。9699d9ee4的版本会让整笔计费回滚,当前 production(含9699d9ee4)照常扣费但继续给已删除的 Key 计数;没有 TypeSafe 平台和充值优惠阶梯。email_cache_atomic_test.go、email_service_reset_token_test.go、payment_public_rate_limit_test.go、antigravity_upstream_error_sanitize_test.go、api_key_repo_sort_test.go、payment_recharge_bonus_test.go、typesafe_platform_migration_test.go、TypeSafe 相关(pkg/typesafe/systemone_test.go、gateway_systemone_test.go两处、content_moderation_systemone_test.go、account_test_service_typesafe_test.go),前端AccountPriorityCell.spec.ts、rechargeBonus.spec.ts;fix(billing): settle usage when the API key is deleted before billing completes Wei-Shaw/sub2api#7816 在usage_billing_repo_unit_test.go、usage_billing_repo_integration_test.go中新增已删除 Key 的结算用例;fix: 完善 Key 删除后的结算与 WebSocket 撤销检查 #273 的usage_billing_deleted_key_unit_test.go、usage_billing_deleted_key_integration_test.go按上游语义调整后保留。另有 34 个已有测试文件随本 PR 更新(含 fix(billing): settle usage when the API key is deleted before billing completes Wei-Shaw/sub2api#7816 的两个)。协议、调度或传输改动补充
POST /v1/systemone(TypeSafe,非流式,使用文本请求体上限);POST /api/v1/payment/public/orders/verify加限流。wrapReleaseOnDone)。实际验证
当前 head:
09d226210,经合并提交f165e9589基于 production502db27d2。backend:go vet -tags=unit ./...、go vet -tags=integration ./...backend:go test -tags=unit -count=1 ./...internal/service的TestPriorityOAuthProfitUsesUserChargeAndTheoreticalCost(浮点 3.9999999999999996 ≠ 4)和internal/reauthruntime的TestStopCancelsPreparationAndCannotRestart,在未改动的 productionbf9405e4a与eceb5632b上同样失败(本机 macOS arm64)。internal/mihomo的时序用例只在全量并发时超时,单独运行该包通过。backend:go test -tags=integration -count=1 ./...internal/repository(Docker 中的 Postgres / Redis)、internal/handler和migrations;失败项与上一行相同。此前一次全量运行中,internal/handler的TestHTTPKeyQueueTimeoutKeepsResponseUnwritten(fork 自有用例,排队超时只有 150ms)在机器满载时失败过一次,单独连续 5 次通过,本次全量运行通过。go test -tags=unit/-tags=integration ./internal/repository/backend:golangci-lint v2.13.2./...backend:go generate ./ent;backend/cmd/server:wire v0.7.0b1ad7fadd上重新生成,与提交内容无差异;之后的提交只改internal/repository,合并进来的 production 提交也不涉及ent和cmd/servermake test-frontendb1ad7fadd;之后的提交和合并进来的 production 提交都只改后端)pnpm --dir frontend run test:runpnpm --dir frontend run build502db27d2go vet通过。两边都改到的后端包(internal/server/...、internal/handler/...、internal/service、internal/domain/...、internal/repository)单测只有上面的浮点用例失败;internal/repository、internal/handler集成测试通过。前端 lint:check、typecheck 和全量 Vitest(400 个文件 3,371 项)通过,这一项取自之前在eceb5632b上的叠加检查,此后两个 PR 和 production 都没有改前端。两个 PR 先合哪个都可以。兼容性与运行影响
RECHARGE_BONUS_TIERS、RECHARGE_BONUS_MODE、RECHARGE_BONUS_NOTICE,默认不配置,充值行为不变;checkout-info和订单响应新增recharge_bonus_*、bonus_amount字段。typesafe和端点POST /v1/systemone。XAI_GROK_CLI_VERSION低于 1.0.46 的覆盖值会被忽略。241_add_payment_order_bonus_amount.sql:payment_orders加bonus_amount DECIMAL(20,2) NOT NULL DEFAULT 0,存量订单为 0。241_add_typesafe_platform.sql:重建user_platform_quotas、composite_model_routes的平台 CHECK 约束,加入typesafe。bonus_amount列和放宽后的 CHECK 约束会保留。旧版本不读取bonus_amount,也不支持typesafe平台;回滚前应先停用 TypeSafe 账号和分组,并关闭充值优惠阶梯。9699d9ee4)相比,合并后已删除 Key 的quota_used、usage_5h/1d/7d不再增长;与更早的版本相比,不再整笔回滚。充值优惠阶梯会改变命中档位订单的到账额度或实付金额,推广返利只按实充部分计算。jev-latest按内置价格计费,渠道定价可覆盖。未做性能测量。文档与用户可见变化
docs/typesafe-jev.md(中英文,整理自上游 v0.2.13 README)。PR 合并不代表已发布或部署。Agent 使用声明
提交前自查
🤖 Generated with Claude Code