Feat/auto group - #6590
Conversation
The Auto group highlight previously tinted the whole control surface with a gradient and animated only a 1px top sweep, which read as a background color rather than a flowing border. Replace it with a border-only effect: an aria-hidden, pointer-events-none overlay whose conic gradient is masked down to a thin ring hugging the rounded perimeter, so the highlight travels around all four edges and corners every 3.2s. The interior stays neutral with a restrained static primary border and glow; prefers-reduced-motion hides the moving layer while keeping the static emphasis. The inherited global Auto order also rendered as spacious two-line rows with circular sequence markers, wasting drawer space. Render it as a compact wrapping strip of one-line chips (index, name, ratio badge) with descriptions kept accessible via title and sr-only text, scrolling only past a much smaller max height. Custom add/remove/reorder editing, empty-array inheritance semantics, and the submit payload are unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (57)
WalkthroughThis change adds token-specific automatic-group snapshots. The backend validates, persists, caches, and resolves them for model and channel selection. The web interface supports inherited or custom ordering, limits, validation, visualization, localization, and reduced-motion styling. ChangesToken automatic-group backend
API-key automatic-group interface
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Sequence Diagram(s)sequenceDiagram
participant APIKeyDrawer
participant TokenAutoGroupsAPI
participant TokenController
participant TokenModel
participant ChannelSelector
APIKeyDrawer->>TokenAutoGroupsAPI: GET /api/token/auto-groups
TokenAutoGroupsAPI->>TokenController: resolve selectable groups and limit
TokenController-->>APIKeyDrawer: groups and max_count
APIKeyDrawer->>TokenController: create or update token snapshot
TokenController->>TokenModel: persist auto_groups
TokenModel-->>TokenController: update cache
ChannelSelector->>TokenController: resolve request auto-groups
TokenController-->>ChannelSelector: ordered permitted groups
Poem
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
* feat(token): support custom auto group order
* feat(keys): enhance auto group presentation
* fix(keys): rework Auto flow border and compact inherited order
The Auto group highlight previously tinted the whole control surface
with a gradient and animated only a 1px top sweep, which read as a
background color rather than a flowing border. Replace it with a
border-only effect: an aria-hidden, pointer-events-none overlay whose
conic gradient is masked down to a thin ring hugging the rounded
perimeter, so the highlight travels around all four edges and corners
every 3.2s. The interior stays neutral with a restrained static
primary border and glow; prefers-reduced-motion hides the moving
layer while keeping the static emphasis.
The inherited global Auto order also rendered as spacious two-line
rows with circular sequence markers, wasting drawer space. Render it
as a compact wrapping strip of one-line chips (index, name, ratio
badge) with descriptions kept accessible via title and sr-only text,
scrolling only past a much smaller max height.
Custom add/remove/reorder editing, empty-array inheritance semantics,
and the submit payload are unchanged.
* fix(keys): preserve Auto inheritance and unify effects
* refactor(keys): temporarily disable AutoGroupBadge in api-key-group-cell
(cherry picked from commit 0ab020206603d22e5613bc4cf46bfab06f8567769)
Fork 适配:
- model.Token / controller.token 的字段与我们 fork 的 token 级限速字段并存
- service/group.go 保留 fork 的 GetGroupsEnabledModels 注释
- i18n 后端 YAML 与前端 JSON 保留双方新增 key(i18n:sync 报告 7 语言 0 缺失)
- relay_aws_test.go 的 relaykit/{dto,types} 引用映射回根包 dto/types
- auto-group-form.test.ts fixture 补齐 fork 的 rate_limit_* 字段
- api-key-group-cell.test.tsx 的 frame/ring 计数对齐实现:上游同一提交里
注释掉了 AutoGroupBadge,但未同步这 3 个用例,导致其在上游即为失败状态
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
合并上游 16 个提交,主要是 token Auto 分组 (QuantumNous#6590)、deepseek responses API (QuantumNous#6562)、Bedrock 客户端断开取消 (QuantumNous#6589)、分层重试计费加固 (QuantumNous#6518/QuantumNous#6570)、 zstd 请求解压 (QuantumNous#6545)、OIDC 自定义显示名 (QuantumNous#6012)、日志暴露 stream_status (QuantumNous#6558)。 33 处冲突的处理: - 11 个 legacy channel adaptor:上游删除 panic 之后的死代码以配合新增的 go vet CI,本仓早已把整段 panic 换成返回 ErrLegacyAdaptorNotImplemented, 已达成同一目的且不会让中继链路 panic,保留本仓实现。 - relay-aws.go 流式循环:两侧改动正交,合并保留 —— 上游的 ctx.Done() 取消 分支(客户端断开时不再空转上游),加本仓的 finalizeClaudeOnError(提前 返回时补发流终止符,否则 Claude 格式调用方会一直挂着)。 - 7 个 locale:两侧各自插入相邻 key,按字母序归并;上游 24 个新 key 与本仓 1278 个 fork key 全部保留,逐一核对无丢失。 - keys / oauth / profile 前端:上游 Auto 分组为主体,叠加本仓改动; account-bindings-tab 与 oauth/$provider 保留本仓实现,理由见下。 测试取舍: - 不引入 model/token_auto_groups_cache_test.go:它依赖上游的 truncateTables, 该助手全局清表,与本仓行级清理原则冲突(共享库里有开发数据)。 - 不携带上游 controller/token_test.go:其迁移兼容测试会替换 model.DB 并在 cleanup 里关闭,后续用 harness 连接的测试会拿到已关闭的句柄。按既有约定, token_auto_groups_test.go 需要的四个助手放进 zz_upstream_test_shims_test.go, 其中 openTokenControllerTestDB 增加了 model.DB/LOG_DB 的成对保存还原。 本仓原 token_test.go 的 controller 行为测试迁到 gen_ctrl_token_handlers_test.go,与上游文件名脱钩以免再冲突。 - 三处断言随上游行为更新:stream_status 现对日志所有者可见;deepseek 的 ConvertOpenAIResponsesRequest 已实现不再返回错误;计费路径判定收紧为 「标记之外还需带对应 usage payload」,并补了三个反向用例锁住该语义。 遗留:oauth 绑定回调仍用 window.opener 判定 bind/login,上游 QuantumNous#6425 已改为 sessionStorage 标记 + state 比对。该修复要求 popup 先以 about:blank 打开再打 标记,本仓四个内置 provider 走 window.open(url) 直开,直接套用会让绑定永远 判成 login,故本次未采纳,需单独改造。
Sync upstream/main (rc.11 → rc.23, 46 commits) into main. Key upstream changes: QuantumNous#6369 relaykit module extraction (dto/types/service/relayconvert moved to relaykit/ submodule with require+replace), QuantumNous#6518/QuantumNous#6570 tiered retry billing, QuantumNous#6558 stream status exposed to log owners, QuantumNous#6562 DeepSeek responses API, QuantumNous#6590 auto group, QuantumNous#6545 zstd decompression, per-channel HTTP transport controls. Conflicts resolved: - constant/api_type.go, constant/channel.go: keep LH channel numbering (OspreyAI=58/HappyHorse=59/Seedance=60/AdvancedCustom=61 via reserved placeholders), append upstream Sub2API=62/NewAPI=63 before Dummy. - relay/common/relay_info_test.go: union imports (LH common2/constant/gin + upstream convmeta/relaykit-types/assert), keep both test sets. LH-only packages (ospreyai/happyhorse/seedance/task variants) had stale host dto/types imports after relaykit extraction — migrated to relaykit/dto and relaykit/types (task-family TaskError kept on host dto via taskdto alias, matching upstream doubao pattern). Co-Authored-By: Claude <noreply@anthropic.com>
合并官方上游 Calcium-Ion/new-api main 分支的 10 个新 commit: - Feat/auto group (QuantumNous#6590) - fix(aws): cancel Bedrock requests on client disconnect (QuantumNous#6589) - fix(billing): harden tiered retry group-switch billing (QuantumNous#6570) - fix(billing): settle tiered retries with final group (QuantumNous#6518) - feat: deepseek responses api (QuantumNous#6562) - fix(oauth): stop treating a foreign window.opener as a bind flow (QuantumNous#6425) - fix(relay): preserve multipart image edits for New API channels (QuantumNous#6559) - feat(logs): expose stream status to log owners (QuantumNous#6558) - feat: support zstd request decompression (QuantumNous#6545) - style: use text-sm for public header nav links (QuantumNous#6557) 冲突解决: model/option.go 的 switch case 区域,双方各自新增了选项注册 (我方 GroupPassThrough + 官方 MaxTokenAutoGroups),取并集保留两者。 其余文件均自动合并成功。 验证: go build + go test 全过(relay/helper、middleware、controller)
…s / 84 files) 上游本次内容: - Feat/auto group (QuantumNous#6590):令牌自动分组(含前端 auto-group 编排 UI 与后端组选择) - fix(aws): Bedrock 请求在客户端断连时取消 (QuantumNous#6589) - fix(relay): 设置 Request.GetBody,让 HTTP/2 传输在上游 stream reset 后可透明重试 (QuantumNous#6249) - refactor(relay): 把 replay 元数据移到请求体上(RelayInfo.UpstreamRequestBodySize 移除) 冲突 1 处,纯新增函数相邻,两侧保留: - relay/channel/api_request.go:我方 upstreamRequestIDFromHeaders 与上游 keepUpstreamRedirectResponse
Sync 71 upstream commits (rc.21 -> rc.23). Major upstream changes adopted: - stateless-token dashboard auth (sessions removed); fork site scoping re-grafted fail-closed via model.GetUserSiteId in setDashboardAuthContext - relaykit module extraction; fork billing guards, error override, and O(N^2) DoS fix re-applied inside relaykit paths - web/default -> web frontend move; web/classic theme deleted (fork's classic-only edits verified ported to the new tree before deletion) - auto-group (QuantumNous#6590), per-channel HTTP transport, tool pricing, zstd, New API channel, tiered-retry billing fixes (QuantumNous#6518/QuantumNous#6570) Fork features preserved and verified: multi-site scoping, tickets, captcha suite (per-request verification now, no session memo), email campaigns, request-body recording, epay three-path settlement, quota saturation invariants, model-redirect hiding, token multi-group priority. Notable resolutions: - 76 fork-only frontend files missed by rename detection were manually relocated from web/default/src to web/src (tickets/referral/site-admin/ sub-site-management/contact/affiliate + routes + locale extras) - altcha dependency restored in web/package.json - getModelListGroups adopts upstream empty-on-filtered-snapshot semantics - relayconvert goldens regenerated for fork's BillingUsage json:"-" privacy - upstream tests adapted to fork signatures (site scope args, SSRF-off TestMain in controller) Semantic changes accepted from upstream: external identity binding is now platform-global (was per-site); captcha verification is per-request. go build/vet/test green in root and relaykit modules.
Brings in from QuantumNous/new-api: - fix: 修复兑换码额度精度损失 (QuantumNous#6685) - feat(rate-limit): user critical rate limit for access token and aff transfer routes - fix: test Claude/Gemini endpoints with native request format (QuantumNous#6698) - feat(channels): refine fetched model categorization (QuantumNous#6632) - security: atomic access-token rotation and aff updates (merge commit from fork) - refactor(relay): move replay metadata onto request bodies - fix(relay): set Request.GetBody for transparent HTTP/2 retry (QuantumNous#6249) - Feat/auto group (QuantumNous#6590) - fix(aws): cancel Bedrock requests on client disconnect (QuantumNous#6589) Conflicts resolved: - controller/model.go: adopt upstream's unified group-model loop with FormatMatchingModelName token-limit matching; keep fork's hiddenMappedModels filter inside the loop - model/user.go: keep fork's BatchDeleteUsers; adopt upstream's atomic gorm.Expr-based inviteUser - relay/channel/task/sora/adaptor_test.go: keep both fork's New API Video channel tests and upstream's replayable-body test Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ZteapnbTWdP52n7wZ6NsN
Upstream PR QuantumNous#6590 shipped with AutoGroupBadge temporarily disabled (e17c647) but left these tests expecting the badge frame, so they fail on upstream main as well. Assert the shipped single-frame behavior; the failing async tests were also poisoning every later node:test file in the bun test run with "describe() inside another test()" errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ZteapnbTWdP52n7wZ6NsN
* feat(token): support custom auto group order * feat(keys): enhance auto group presentation * fix(keys): rework Auto flow border and compact inherited order The Auto group highlight previously tinted the whole control surface with a gradient and animated only a 1px top sweep, which read as a background color rather than a flowing border. Replace it with a border-only effect: an aria-hidden, pointer-events-none overlay whose conic gradient is masked down to a thin ring hugging the rounded perimeter, so the highlight travels around all four edges and corners every 3.2s. The interior stays neutral with a restrained static primary border and glow; prefers-reduced-motion hides the moving layer while keeping the static emphasis. The inherited global Auto order also rendered as spacious two-line rows with circular sequence markers, wasting drawer space. Render it as a compact wrapping strip of one-line chips (index, name, ratio badge) with descriptions kept accessible via title and sr-only text, scrolling only past a much smaller max height. Custom add/remove/reorder editing, empty-array inheritance semantics, and the submit payload are unchanged. * fix(keys): preserve Auto inheritance and unify effects * refactor(keys): temporarily disable AutoGroupBadge in api-key-group-cell
…toGroupBadge The three failing assertions expected two auto-group frames (AutoGroupBadge plus GroupRatioBadge), but AutoGroupBadge has been commented out in ApiKeyGroupCell since it was introduced in QuantumNous#6590 — the Cross-group StatusBadge occupies that slot instead. The test never matched the implementation. Corrected the expectations to the actual render output rather than re-enabling a badge that was deliberately disabled: - ratio present: 1 frame + 1 flow border (was 2 + 2) - reduced motion: 1 static frame, 0 flow borders (was 2 + 0) - ratio absent: GroupRatioBadge returns null, so 0 frames and 0 flow borders, with only the Cross-group badge left (was 1 + 1 asserting an 'Auto' text that the cell no longer renders on its own) Renamed the affected test titles to describe the single ring, and noted why only one frame exists so the next reader does not re-add the second. Verified: bun test passes 155/155 across 31 files, bun run typecheck clean.
Upstream commit e17c647 is titled "temporarily disable AutoGroupBadge" and landed three minutes later in the squash for QuantumNous#6590. Its CI run was already red on the three tests that assert the badge renders, the PR had no reviews, and the run log quoted in its description predates the change. The same hunk also dropped the props.crossGroupRetry guard, so whatever the intent behind hiding the badge, that part was not deliberate. Left as merged, an auto-group key with no ratio data rendered an empty cell with nothing identifying its group, and every auto key claimed cross-group retry was on regardless of its own setting. This restores the file to 18132fc, the author's own version from before the temporary disable, so it is byte-identical to upstream's intent rather than a local rewrite. Adds the regression test the original set was missing: the earlier three all pass with the guard removed, so nothing covered that contract. Worth reporting upstream; the commit message makes the case on its own. Co-authored-by: Cursor <cursoragent@cursor.com>
* v1.0.0-rc.24: (117 commits) CI: enhance release synchronization workflow with optional file syncing fix: 修复兑换码额度精度损失 (QuantumNous#6685) feat(rate-limit): add user critical rate limit middleware for access token and aff transfer routes fix: test Claude/Gemini endpoints with native request format (QuantumNous#6698) feat(channels): refine fetched model categorization (QuantumNous#6632) Merge commit from fork refactor(relay): move replay metadata onto request bodies fix(relay): set Request.GetBody so the HTTP/2 transport can transparently retry after an upstream stream reset (QuantumNous#6249) Feat/auto group (QuantumNous#6590) fix(aws): cancel Bedrock requests on client disconnect (QuantumNous#6589) fix(billing): harden tiered retry group-switch billing (QuantumNous#6570) fix(billing): settle tiered retries with final group (QuantumNous#6518) feat: deepseek responses api (QuantumNous#6562) style: use text-sm for public header nav links to match other nav components (QuantumNous#6557) fix(oauth): stop treating a foreign window.opener as a bind flow (QuantumNous#6425) fix(relay): preserve multipart image edits for New API channels (QuantumNous#6559) feat(logs): expose stream status to log owners (QuantumNous#6558) feat: support zstd request decompression (QuantumNous#6545) fix: preserve Qwen thinking_budget passthrough (QuantumNous#5836) feat(oidc): 支持自定义 OIDC 登录显示名称 (QuantumNous#6012) ... # Conflicts: # service/text_quota.go # web/src/features/models/components/drawers/model-mutate-drawer.tsx # web/src/features/pricing/components/model-details.tsx # web/src/features/pricing/lib/price.ts
Both arrived from upstream unformatted — api-key-group-cell.tsx in 0ab0202 (Feat/auto group QuantumNous#6590) and redemption-form.ts in e926e5c (兑换码额度精度损失 QuantumNous#6685) — and both fail for the same reason: a call and an import were split across lines that fit inside the 80-column printWidth, so oxfmt joins them back. Whitespace only, no semantics. Upstream CI does not run a format gate, so files can land there unformatted; expect to redo this occasionally after a sync. Kept separate from the guide.html reflow, which is far larger and unrelated.
* feat(token): support custom auto group order * feat(keys): enhance auto group presentation * fix(keys): rework Auto flow border and compact inherited order The Auto group highlight previously tinted the whole control surface with a gradient and animated only a 1px top sweep, which read as a background color rather than a flowing border. Replace it with a border-only effect: an aria-hidden, pointer-events-none overlay whose conic gradient is masked down to a thin ring hugging the rounded perimeter, so the highlight travels around all four edges and corners every 3.2s. The interior stays neutral with a restrained static primary border and glow; prefers-reduced-motion hides the moving layer while keeping the static emphasis. The inherited global Auto order also rendered as spacious two-line rows with circular sequence markers, wasting drawer space. Render it as a compact wrapping strip of one-line chips (index, name, ratio badge) with descriptions kept accessible via title and sr-only text, scrolling only past a much smaller max height. Custom add/remove/reorder editing, empty-array inheritance semantics, and the submit payload are unchanged. * fix(keys): preserve Auto inheritance and unify effects * refactor(keys): temporarily disable AutoGroupBadge in api-key-group-cell
* feat(token): support custom auto group order * feat(keys): enhance auto group presentation * fix(keys): rework Auto flow border and compact inherited order The Auto group highlight previously tinted the whole control surface with a gradient and animated only a 1px top sweep, which read as a background color rather than a flowing border. Replace it with a border-only effect: an aria-hidden, pointer-events-none overlay whose conic gradient is masked down to a thin ring hugging the rounded perimeter, so the highlight travels around all four edges and corners every 3.2s. The interior stays neutral with a restrained static primary border and glow; prefers-reduced-motion hides the moving layer while keeping the static emphasis. The inherited global Auto order also rendered as spacious two-line rows with circular sequence markers, wasting drawer space. Render it as a compact wrapping strip of one-line chips (index, name, ratio badge) with descriptions kept accessible via title and sr-only text, scrolling only past a much smaller max height. Custom add/remove/reorder editing, empty-array inheritance semantics, and the submit payload are unchanged. * fix(keys): preserve Auto inheritance and unify effects * refactor(keys): temporarily disable AutoGroupBadge in api-key-group-cell
Important
📝 变更描述 / Description
为 Auto 令牌增加令牌级有序分组配置。用户可以在创建或编辑令牌时添加、删除及拖拽调整分组顺序;未提供配置、传入
null或空数组时,令牌会继承完整的全局 Auto 顺序。前端使用独立的继承/自定义状态,避免把全局继承误保存为分组快照。启用默认 Auto 后,新建及批量创建的令牌均默认提交
auto_groups: [];切换普通分组后再切回 Auto,也会保留尚未保存的自定义顺序。后端在令牌实际使用时统一过滤当前用户可用分组并应用配置上限,同时保持原有分组接口结构兼容。令牌表格和分组下拉框增加 Auto 及 Auto 倍率的流光边框,并支持减少动态效果设置。
🚀 变更类型 / Type of change
🔗 关联任务 / Related Issue
✅ 提交前检查项 / Checklist
Bug fix。📸 运行证明 / Proof of Work
本地验证结果:
bun test:149 passed,0 failedbun run typecheck:通过bun run build:通过bun run i18n:sync:七种语言均无缺失、额外或未翻译条目oxlint:通过oxfmt --check:通过补充说明:全仓库
bun run format:check仍会报告两个本 PR 未修改文件的既有格式问题:src/features/channels/components/drawers/channel-mutate-drawer.tsxsrc/features/channels/lib/channel-form.tsSummary by CodeRabbit