Conversation
#559) * feat(my-usage): add Statistics Summary with auto-refresh, improve UX - Add StatisticsSummaryCard with date range picker and 30s auto-refresh - Add getMyStatsSummary API for fetching stats by time range - Show expiration date in parentheses for Expired status - Remove Today's Statistics (functionality merged into Statistics Summary) - Remove subtitle from header - Add translations for stats section (en/ru/ja/zh-CN/zh-TW) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * test(my-usage): add unit tests for getMyStatsSummary - Register getMyStatsSummary endpoint in Actions API with OpenAPI schema - Add 3 tests: unauthorized 401, basic aggregation with warmup exclusion, date range filtering - Tests verify key/user breakdown separation and data isolation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ui): logs table and heading style improvements - Use currency symbol instead of code in logs table - Improve Russian translations - Unify heading style in provider-group-info 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(my-usage): collapsible usage logs with header summary Make Usage Logs section collapsible like Quota card with informative header showing: - Last request status with relative time (color-coded) - Success rate percentage with ✓/✗ indicator - Active filters count badge - Auto-refresh indicator Header adapts for mobile with compact layout. Collapsed by default. - Replace Card with Radix Collapsible component - Add metrics calculation (lastLog, successRate, activeFiltersCount) - Add responsive header (desktop/mobile variants) - Add logsCollapsible translations for all 5 locales 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ui): correct RefreshCw animation in usage-logs-section Animation should trigger on isRefreshing state, not on autoRefreshSeconds config value. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ui): address CodeRabbit review feedback - Add optional chaining for CURRENCY_CONFIG to prevent runtime errors - Use ∞ symbol for unlimited RPM instead of "neverExpires" text - Add index to React keys in model breakdown to prevent duplicates 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: format code (fix-my-usage-43169ad) --------- Co-authored-by: John Doe <johndoe@example.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Add new error rule to handle Claude API's media count limit error when total media (document pages + images) exceeds 100. - Pattern: "Too much media" (contains match) - Category: media_limit - Priority: 79 (after PDF limit rules) - Override message explains the limit and suggests reducing media count Closes #571
* feat: port FluxFix response fixer * fix: polish response fixer and usage date parsing
* feat: unify special settings display * fix: address review feedback for special settings * fix(ui): move special settings display into details dialog
* feat(providers): add auto-sort priority by costMultiplier (#555) * 变更概要: - 5 个语言的 dashboard.json 添加顶层 actions 翻译键 - 2 个测试文件 import 真实 locale 文件替代硬编码 mock - 测试断言收敛到具体 tab 容器作用域 - CLAUDE.md 语言列表校正 (ko/de → ru/zh-TW) fix(i18n): add top-level dashboard.actions keys and improve test i18n strategy - Add `actions` (copy/download/copied) to dashboard.json for all 5 locales to fix CodeDisplay component missing translation keys - Refactor test files to import real locale messages instead of hardcoded mocks, ensuring tests stay in sync with actual translations - Scope test assertions to specific tab containers for better precision - Fix CLAUDE.md language list to match actual locales (ru/zh-TW, not ko/de) * 变更概要: - tsconfig.json 添加 @messages/* 路径别名 - tsconfig.json 移除 src/components/ui/** exclude - vitest.config.ts 添加 @messages 别名 - 测试文件使用新别名,修复类型断言 chore(config): add @messages path alias and fix TypeScript exclude - Add `@messages/*` path alias to tsconfig.json and vitest.config.ts for cleaner locale imports in tests - Remove `src/components/ui/**` from tsconfig exclude to enable TypeScript checking and IDE support for UI component tests - Update test imports to use @messages/en/dashboard.json - Fix non-null assertion in code-display.test.tsx to resolve TS error * fix(ui): 为纯图标导出按钮补充 aria-label,修复相关单测 - 为请求复制/下载两个纯图标按钮添加 aria-label,避免依赖 Tooltip 文本,同时提升可访问性 - 单测改为按 aria-label 定位按钮,并补齐 SessionMessagesDetailsTabs 的 mock(提供复制响应按钮) * fix(ui): 修复 session-messages-client 组件缩进混乱问题 - 将 Tab+空格混合缩进统一为纯空格,符合项目 Biome 规范 - 测试文件长行拆分以保持代码风格一致 * fix(providers): 统一 React Query QueryClient,改用 invalidate 刷新供应商列表 - 移除 ProviderManagerLoader 内部 QueryClientProvider,避免页面存在两个 QueryClient 导致 invalidate 不生效 - 将 staleTime/refetchOnWindowFocus 下沉到各个 useQuery,保持原有缓存/刷新行为一致 - AutoSortPriorityDialog 应用后改为 invalidateQueries(["providers"]),不再使用 window.location.reload() * ⏺ fix(test): 将需要数据库的 API 测试移入集成测试配置 - vitest.config.ts: 排除 my-usage-readonly.test.ts(需要 DSN) - vitest.integration.config.ts: 统一管理所有需要 DB 的 API 测试 - users-actions.test.ts - providers-actions.test.ts - keys-actions.test.ts - my-usage-readonly.test.ts 确保 `bun run test` 在无数据库环境下正常通过, 需要 DB 的测试通过 `bun run test:integration` 单独运行。 * fix(ui): 修复 AlertDialogDescription 内嵌套 div 导致的 hydration 错误 AlertDialogDescription 默认渲染为 <p> 标签,内部嵌套 <div> 违反 HTML 规范, 导致 React hydration mismatch 警告。使用 asChild 属性让其渲染为 <div> 解决。 * fix(ui): remove duplicate aria-label
* feat: add thinking signature rectifier * fix: skip rectifier retry when no-op
* fix: enable provider group editing in edit user dialog - Always show providerGroup field in edit mode (was hidden when user had no providerGroup) - Replace read-only Badge display with editable ProviderGroupSelect component - Move modelSuggestions hook after form declaration to support dynamic updates Regression from #539 * fix: add complete translations for ProviderGroupSelect in edit user dialog Pass full translations object to ProviderGroupSelect including: - tagInputErrors for validation messages (empty, duplicate, too_long, etc.) - errors.loadFailed for API error handling - providersSuffix for provider count display This fixes untranslated error messages when users input invalid provider group tags. * feat(prices): 添加手动模型价格管理功能 - 新增 source 字段区分 litellm/manual 来源 - 支持手动添加、编辑、删除模型价格 - LiteLLM 同步时自动跳过手动价格,避免覆盖 - 添加冲突检测和解决 UI,支持批量处理 - 完整的单元测试覆盖 closes #405 * fix: 修复 CI 检查问题 - 移除未使用的 ModelPriceSource 导入 - 修复 useEffect 依赖数组 (fetchPrices) - 修复 fetchPrices 声明前使用问题 - 添加价格非负数验证 - 格式化代码 * fix: wrap upsertModelPrice in transaction for data integrity
* fix: disable thinking when tool_use is first block - Extend thinking signature rectifier to detect tool_use-first error and drop top-level thinking on retry - Add default error rule guidance for thinking/tool_use mismatch - Add unit tests for rectifier, forwarder retry path, and default rule sync * fix: improve thinking/tool_use error fallback
* fix(db): make latest drizzle migrations idempotent Use ADD COLUMN IF NOT EXISTS in 0044_uneven_donald_blake.sql (line 1) Use ADD COLUMN IF NOT EXISTS in 0049_shocking_ultimatum.sql (line 1) Use ADD COLUMN IF NOT EXISTS in 0050_flippant_jack_flag.sql (line 1) Use ADD COLUMN IF NOT EXISTS in 0051_silent_maelstrom.sql (line 1) Use ADD COLUMN IF NOT EXISTS in 0052_model_price_source.sql (line 1) * config: 添加 .codex 目录到 .gitignore
* refactor(prices): sync TOML cloud price table and harden billing * fix(prices): address PR review feedback
* fix: prevent provider badge overflow in logs table * fix: make provider chain trigger shrinkable * fix: hide invalid cost multiplier badge * fix: avoid invalid multiplier in usage logs * fix: hide invalid multiplier in error details * test: add provider chain popover layout regression * test: cover invalid multiplier rendering branches * test: cover empty and undefined cost multiplier
* feat: update pricing table UI * chore: format code (feat-prices-ui-custom-model-6ffe413) * fix: address pricing UI review feedback
* docs: add OpenCode config guide to usage-doc * docs: fix OpenCode Scoop command and refactor config snippet * docs: remove OpenAI-compatible wording from OpenCode guide * docs: refine OpenCode install and config
* chore: remove seed price table and force cloud sync * Update src/lib/price-sync/seed-initializer.ts Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * chore: format code (chore-force-cloud-price-table-f1ab426) --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
|
Important Review skippedToo many files! 5 files out of 155 files are above the max files limit of 150. You can disable this status message by setting the ✨ Finishing touches🧪 Generate unit tests (beta)
Comment |
|
Too many files changed for review. ( |
Summary of ChangesHello @ding113, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! 此版本发布了 v0.4.1,引入了多项核心功能,旨在提升系统的健壮性、灵活性和用户体验。通过新增的整流器和响应修复器,系统能够更智能地处理上游服务问题。对模型价格管理进行了全面升级,支持更精细的控制和更友好的同步机制。同时,扩展了对新 CLI 工具的集成,并对用户界面进行了优化,以提供更直观的信息展示。 Highlights
Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
🧪 测试结果
总体结果: ✅ 所有测试通过 |
There was a problem hiding this comment.
[Medium] [TYPE-ANY-USAGE] Unsafe use of any type in object destructuring
Why this is a problem: Using as any to destructure and discard the signature property bypasses type safety. While this works, it sets a precedent for untyped code and loses compiler assistance for catching refactoring errors.
Suggested fix:
// Replace this:
const { signature: _signature, ...rest } = blockObj as any;
// With this typed version:
const { signature: _signature, ...rest } = blockObj as Record<string, unknown> & { signature?: unknown };There was a problem hiding this comment.
Code Review Summary
This is a large release PR (v0.4.1) adding rectifier support, OpenCode compatibility, custom model pricing, and provider auto-sorting. The changes are extensive but well-structured with comprehensive test coverage. The core proxy pipeline changes are well-designed with proper error handling and audit logging.
PR Size: XL
- Lines changed: 56,844 (22,923 additions, 33,921 deletions)
- Files changed: 155
Split Suggestion: For future releases, consider breaking changes into feature-specific PRs:
- Response Fixer module (encoding, SSE, JSON fixers)
- Thinking Signature Rectifier
- Model Price Management UI & API
- Provider Auto-Sort feature
- i18n updates
Issues Found
| Category | Critical | High | Medium | Low |
|---|---|---|---|---|
| Logic/Bugs | 0 | 0 | 0 | 0 |
| Security | 0 | 0 | 0 | 0 |
| Error Handling | 0 | 0 | 0 | 0 |
| Types | 0 | 0 | 2 | 0 |
| Comments/Docs | 0 | 0 | 0 | 0 |
| Tests | 0 | 0 | 0 | 0 |
| Simplification | 0 | 0 | 0 | 0 |
High Priority Issues (Should Fix)
None identified.
Medium Priority Issues (Consider Fixing)
- [TYPE-ANY-USAGE]
src/app/v1/_lib/proxy/thinking-signature-rectifier.ts- Two instances ofas anytype casts (lines ~110 and ~180) that could be replaced with proper typing for better type safety.
Positive Observations (Not requiring action)
- Error Handling: Good error handling patterns throughout. The
ResponseFixer.process()wrapper inresponse-handler.tsproperly catches exceptions and falls back gracefully. - Logging: Consistent use of structured logging with context.
- Test Coverage: New features have corresponding test files with good coverage.
- Security: The
isPriceDataEqualfunction includes prototype pollution protection. - DoS Protection: The ChunkBuffer in response-fixer has memory bounds checking to prevent unbounded growth.
Review Coverage
- Logic and correctness - Clean
- Security (OWASP Top 10) - Clean
- Error handling - Clean (proper try/catch with logging)
- Type safety - Minor issues noted
- Documentation accuracy - Clean
- Test coverage - Adequate (new tests for all major features)
- Code clarity - Good
Automated review by Claude AI
There was a problem hiding this comment.
Code Review
这个 PR 包含了一系列重要的功能增强和重构,显著提升了系统的稳定性和用户体验。主要亮点包括:
- 响应整流器 (Response Fixer):这是一个非常出色的功能,能够自动修复上游供应商常见的响应问题(如编码、SSE 格式、截断的 JSON),极大地增强了系统的健壮性。
- Thinking 签名整流器:针对 Anthropic 模型的特定错误增加了自动修复和重试机制,这是一个非常精细和实用的优化。
- 模型价格管理重构:完全重构了模型价格管理页面,支持了手动添加/编辑模型、从云端同步价格,并增加了冲突检测,用户体验得到了巨大提升。
- 供应商自动排序:新增了根据成本倍率自动排序供应商优先级的功能,简化了配置。
- “我的用量”页面重构:用一个更强大、支持日期范围选择的统计卡片替换了原有的“今日用量”,并用可折叠卡片优化了布局,信息展示更清晰、灵活。
- OpenCode 支持:增加了对新的 AI 编程代理 OpenCode 的支持。
- 代码健壮性:在成本计算、Redis 追踪等关键路径上增加了
try...catch保护,防止因次要错误导致整个请求失败,这是一个很好的防御性编程实践。
代码质量很高,改动考虑周全。我只发现了一个可以进一步优化的地方,关于一个自定义的深度相等比较函数。
总体来说,这是一次非常出色的更新,恭喜!
| function isPriceDataEqual(data1: ModelPriceData, data2: ModelPriceData): boolean { | ||
| // 深度比较两个价格对象 | ||
| return JSON.stringify(data1) === JSON.stringify(data2); | ||
| const stableStringify = (value: unknown): string => { | ||
| const seen = new WeakSet<object>(); | ||
|
|
||
| const canonicalize = (node: unknown): unknown => { | ||
| if (node === null || node === undefined) return node; | ||
| if (typeof node !== "object") return node; | ||
|
|
||
| if (seen.has(node as object)) { | ||
| return null; | ||
| } | ||
| seen.add(node as object); | ||
|
|
||
| if (Array.isArray(node)) { | ||
| return node.map(canonicalize); | ||
| } | ||
|
|
||
| const obj = node as Record<string, unknown>; | ||
| const result: Record<string, unknown> = Object.create(null); | ||
| for (const key of Object.keys(obj).sort()) { | ||
| // 防御:避免 __proto__/constructor/prototype 触发原型链污染 | ||
| if (key === "__proto__" || key === "constructor" || key === "prototype") { | ||
| continue; | ||
| } | ||
| result[key] = canonicalize(obj[key]); | ||
| } | ||
| return result; | ||
| }; | ||
|
|
||
| return JSON.stringify(canonicalize(value)); | ||
| }; | ||
|
|
||
| return stableStringify(data1) === stableStringify(data2); | ||
| } |
There was a problem hiding this comment.
isPriceDataEqual 函数实现了一个自定义的、用于深层对象比较的规范化字符串转换函数。虽然这个实现考虑了键排序和原型链污染等问题,显得很巧妙,但它也相对复杂,并且重新实现了一个常见的功能。
建议使用一个经过充分测试的库(如 fast-deep-equal)来代替。这样做有几个好处:
- 简化代码:可以移除大约 30 行的自定义实现,使代码更简洁易读。
- 增强健壮性:库函数通常能处理更多的边界情况(例如
Date、RegExp对象,或属性值为undefined的情况),减少了潜在的细微 bug。 - 降低维护成本:依赖于一个标准的库,未来维护会更容易。
虽然当前的实现可能满足需求,但从长期维护和代码清晰度的角度来看,使用标准库是更好的选择。
您还需要在文件顶部导入 isEqual 并将 fast-deep-equal 添加到您的依赖项中:
import isEqual from "fast-deep-equal";function isPriceDataEqual(data1: ModelPriceData, data2: ModelPriceData): boolean {
return isEqual(data1, data2);
}
Summary
Release v0.4.0 introduces several major features: thinking signature rectifier, FluxFix response fixer, OpenCode support, manual model pricing, and automatic provider priority sorting. This release also includes numerous bug fixes and performance optimizations.
Related Issues
signatureinthinkingblock #518 - Thinking signature rectifier handles invalid signature errorsBREAKING CHANGE
Custom models previously added via JSON configuration will no longer work. Users must re-add custom models using the new manual price management UI.
New Features
Thinking Signature Rectifier (#576)
enableThinkingSignatureRectifier(default: enabled)specialSettingsfor request loggingFluxFix Response Fixer (#570)
data:prefix, line endings)ResponseFixerSpecialSettingManual Model Pricing (#573)
sourcefield distinguisheslitellmvsmanualpricesAuto-Sort Provider Priority (#569)
OpenCode Support (#582, #586)
Statistics Summary (#559)
getMyStatsSummaryAPI with model breakdown aggregationBug Fixes
IF NOT EXISTSInfrastructure Improvements
TOML Cloud Price Table (#580)
https://claude-code-hub.app/config/prices-base.tomlDatabase Changes
enable_response_fixerandresponse_fixer_configcolumnsenable_thinking_signature_rectifiercolumnsourcecolumn to model_prices tableUI/UX Improvements
Changes Summary
Core Changes (91 files)
i18n
Tests
Pre-commit Verification
Checklist
Description enhanced by Claude AI