Conversation
* fix: my-usage stats and readonly usage API * fix: bearer-only my-usage auth
* docs: fix Codex model config in usage-doc (#542) * test: fix Biome formatting in system-config update test
Add new error rule to handle the case where a `tool_use` block is missing its corresponding `tool_result` in the next message. This is the reverse direction of the existing rule for `tool_result` missing `tool_use`. The new pattern matches: - `tool_use` ids were found without `tool_result` blocks immediately after - Each `tool_use` block must have a corresponding `tool_result` block Closes #550
* feat(error-rules): add Gemini non-streaming error rule 部分服务商仅支持流式的 gemini 请求, 这种情况下需要返回 400 状态码, 以便 gemini 检测到 generateContent 不可用时, 自动切换到 streamGenerateContent Signed-off-by: Kevin Cui <bh@bugs.cc> * fix: lint Signed-off-by: Kevin Cui <bh@bugs.cc> --------- Signed-off-by: Kevin Cui <bh@bugs.cc>
Move AddProviderDialog creation from Server Component (page.tsx) to Client Component (ProviderManagerLoaderContent) to ensure useQueryClient() correctly accesses the QueryClient instance within QueryClientProvider. This fixes the issue where invalidateQueries() calls did not trigger React Query to refetch data after adding a new provider.
* refactor: 拆分 unified-edit-dialog 为专用对话框组件 (#413) 将 1120 行的 unified-edit-dialog.tsx 拆分为 4 个单一职责组件: - CreateUserDialog: 创建用户 + 首个密钥 - EditUserDialog: 编辑用户信息 - AddKeyDialog: 添加新密钥 - EditKeyDialog: 编辑单个密钥 主要改动: - 提取共享逻辑到 hooks/ (翻译、模型建议) - 提取工具函数到 utils/ (表单处理、provider group) - 新增 getModelSuggestionsByProviderGroup action - 修复 expiresAt 清除时传参问题 (使用空字符串) - 添加单元测试覆盖新组件 BREAKING CHANGE: 删除 unified-edit-dialog.tsx,引用需更新为新组件 * fix: 为 Key Dialog 组件定义精确类型,消除 as any - 新增 KeyDialogUserContext 类型,替代过于宽泛的 User 类型 - 移除 4 处 as any 类型断言 - 清理 key-list-header.tsx 中伪造的字段 Addresses Gemini Code Review feedback on type safety
…552) * fix: ensure openai endpoints use GuardPipeline * fix: avoid concurrent count mismatch on pipeline early return
- Add YesCode as fourth sponsor with logo - Update Cubence discount from 20% to 10%
Remove custom X button, keep browser native clear button from type="search". - Remove custom clear button code and unused X icon import - Remove unnecessary right padding (pr-9)
* feat: 添加供应商查询缓存, 改善性能 * fix: 让后台管理函数不经过缓存 * fix: 初始化 Redis 订阅时避免未正确设置 subscriptionInitialized
* feat: 添加供应商缓存开关配置, 默认启用 * refactor: 优化缓存开关读取方式, 避免热路径函数中频繁调用
- Redesign request list sidebar with minimized/expanded views - Add icons to tabs and make tab list horizontally scrollable - Add copy response button to session details - Enhance code-display component with copy functionality - Update storageTip i18n messages (zh-CN, en, ja, ru, zh-TW) - Add new dashboard-main wrapper component - Add session-stats component for request statistics
Add className prop support to CodeDisplayProps interface and apply it to the component wrapper divs using cn() utility. This fixes the TypeScript error where session-details-tabs.tsx was passing className prop that didn't exist in the interface. CI Run: https://github.com/ding113/claude-code-hub/actions/runs/20778497724 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
Skipped: This PR changes more files than the configured file change limit: ( |
|
Important Review skippedToo many files! 24 files out of 174 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. |
1 similar 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! This release focuses on significant infrastructure and user interface improvements, enhancing the platform's ability to manage AI providers and user access. Key updates include expanded database capabilities for more detailed provider configuration and usage tracking, a complete overhaul of the user and API key management flows in the dashboard, and optimizations for handling specific API request types like Anthropic warmup probes. These changes aim to provide greater control, better performance, and a more intuitive administrative experience. Highlights
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.
Code Review
This pull request appears to be for release v0.3.42, containing a wide range of updates. This includes new features like provider caching, database schema migrations for new settings and limits, and significant refactoring of the UI for user and key management. I've identified a few areas for improvement, mainly concerning consistency in database migrations and data fetching to ensure robustness and prevent stale data. Overall, the changes are substantial and move the project forward.
I am having trouble creating individual review comments. Click here to see my feedback.
src/actions/providers.ts (3174)
The function getModelSuggestionsByProviderGroup uses findAllProviders(), which likely returns cached data. Other functions in this file that need fresh provider data were updated to use findAllProvidersFresh(). If a provider's allowedModels are updated, this function might return stale model suggestions until the cache expires. To ensure correctness, it should probably use findAllProvidersFresh() as well.
const providers = await findAllProvidersFresh();
AGENTS.md (1)
The content of this file is just the text "CLAUDE.md". This seems unintentional. If the goal was to point to CLAUDE.md, a symbolic link might be more appropriate, or this file might need different content. As it is, it will just render the plain text "CLAUDE.md".
drizzle/0049_shocking_ultimatum.sql (1)
This migration is not idempotent. If it fails and is re-run, it will fail again. Other recent migration files in this PR, like 0047_fix_system_settings_columns.sql, use IF NOT EXISTS to ensure idempotency. It would be good to apply the same pattern here for consistency and robustness.
ALTER TABLE "message_request" ADD COLUMN IF NOT EXISTS "special_settings" jsonb;There was a problem hiding this comment.
Code Review Summary
This XL release PR (v0.3.42) introduces multiple new features and refactors across 173 files. The implementation demonstrates solid engineering practices with proper error handling, test coverage for new functionality, and backward-compatible database migrations.
PR Size: XL
- Lines changed: 32,747 (27,778 additions + 4,969 deletions)
- Files changed: 173
Split Recommendation: Given this is a release PR consolidating 25+ individual PRs that were already reviewed and merged to dev, the monolithic structure is acceptable. However, for future releases of this size, consider staged deployments or feature flagging.
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 | 0 | 0 |
| Comments/Docs | 0 | 0 | 0 | 0 |
| Tests | 0 | 0 | 0 | 0 |
| Simplification | 0 | 0 | 0 | 0 |
Analysis Summary
Provider Cache Implementation (src/lib/cache/provider-cache.ts):
- Solid design with 30s TTL, version tracking to prevent race conditions during concurrent refresh
- Redis Pub/Sub for cross-instance invalidation with graceful degradation
- Proper async initialization that doesn't block hot paths
- CI/build environment detection to skip Redis subscription
Warmup Guard (src/app/v1/_lib/proxy/warmup-guard.ts):
- Well-structured request detection with strict criteria
- Proper audit logging with database persistence
- Error handling logs failures without affecting the response
Guard Pipeline Refactor:
- Chat completions handler correctly refactored to use
GuardPipelineBuilder - Concurrent count tracking properly uses
finallyblock for cleanup - Pipeline step reordering (sensitive before session, warmup added) follows logical design
Provider Selector Enhancements:
- Cost limit checks added for session reuse path
- Total cost limit enforcement with proper logging
- Provider snapshot pattern maintains consistency during failover
Dialog Component Refactor:
- Clean extraction of
CreateUserDialog,EditUserDialog,AddKeyDialog,EditKeyDialog - Shared hooks (
useKeyTranslations,useModelSuggestions,useUserTranslations) reduce duplication - Form utilities properly typed
Test Coverage:
- New tests for warmup guard, chat completions handler guard pipeline, Codex provider overrides
- Rate limit guard tests, provider selector total limit tests
- UI component tests for provider form and user dialogs
Review Coverage
- Logic and correctness - Clean
- Security (OWASP Top 10) - Clean
- Error handling - Proper logging throughout, no silent failures
- Type safety - Clean, type annotations consistent
- Documentation accuracy - Comments match implementation
- Test coverage - Adequate for new features
- Code clarity - Well-structured refactors
Automated review by Claude AI
| <button | ||
| type="button" | ||
| className="text-muted-foreground hover:text-foreground transition-colors" | ||
| aria-label={`${label} - help`} |
There was a problem hiding this comment.
[MEDIUM] [STANDARD-VIOLATION] Hardcoded English in aria-label breaks i18n
Why this is a problem: src/app/[locale]/settings/providers/_components/forms/provider-form.tsx:87 hardcodes an English suffix in an accessibility label:
aria-label={`${label} - help`}This violates the project rule: CLAUDE.md:14 — “All user-facing strings must use i18n (5 languages supported). Never hardcode display text”. aria-label is user-facing via screen readers, so it should be localized.
Suggested fix:
<button
type="button"
className="text-muted-foreground hover:text-foreground transition-colors"
aria-label={label}
>
<Info className="h-4 w-4" />
</button>| try { | ||
| const session = await getSession(); | ||
| if (!session || session.user.role !== "admin") { | ||
| return { ok: false, error: "无权限执行此操作" }; |
There was a problem hiding this comment.
[MEDIUM] [STANDARD-VIOLATION] Server action returns non-i18n error strings
Why this is a problem: src/actions/providers.ts:793 returns hardcoded Chinese error strings (also at src/actions/providers.ts:798, src/actions/providers.ts:806):
return { ok: false, error: "无权限执行此操作" };This violates the project rule: CLAUDE.md:14 — “All user-facing strings must use i18n (5 languages supported). Never hardcode display text”. These ActionResult.error messages are displayed in UI toasts (e.g. src/app/[locale]/settings/providers/_components/provider-rich-list-item.tsx:274).
Suggested fix (server-side i18n + error codes):
import { getTranslations } from "next-intl/server";
import { ERROR_CODES } from "@/lib/utils/error-messages";
const tError = await getTranslations("errors");
if (!session || session.user.role !== "admin") {
return {
ok: false,
error: tError("PERMISSION_DENIED"),
errorCode: ERROR_CODES.PERMISSION_DENIED,
};
}
if (!ok) {
return {
ok: false,
error: tError("NOT_FOUND"),
errorCode: ERROR_CODES.NOT_FOUND,
};
}|
Too many files changed for review. |
| router.refresh(); | ||
| } else { | ||
| toast.error(tList("resetUsageFailed"), { | ||
| description: res.error || tList("unknownError"), |
There was a problem hiding this comment.
[MEDIUM] [STANDARD-VIOLATION] UI surfaces raw server error text (bypasses i18n)
Why this is a problem: src/app/[locale]/settings/providers/_components/provider-rich-list-item.tsx:274 displays ActionResult.error directly:
description: res.error || tList("unknownError"),This can show non-localized strings (the new resetProviderTotalUsage action currently returns Chinese literals), violating CLAUDE.md:14 — “All user-facing strings must use i18n… Never hardcode display text”. It also makes it easy for other server actions to accidentally leak mixed-language or overly-internal messages.
Suggested fix: prefer errorCode translation when present.
import { getErrorMessage } from "@/lib/utils/error-messages";
const tErrors = useTranslations("errors");
// ...
const description = res.errorCode
? getErrorMessage(tErrors, res.errorCode, res.errorParams)
: res.error || tList("unknownError");
toast.error(tList("resetUsageFailed"), { description });There was a problem hiding this comment.
Code Review Summary
This is an XL release PR combining core proxy/rate-limit behavior changes, provider caching/quota features, large UI refactors, DB migrations, and many new tests. The size makes it hard to validate regressions and increases rollback risk; please split by feature area before merging.
PR Size: XL
- Lines changed: 32737
- Files changed: 172
- Split suggestions: (1) Warmup intercept + system settings + related UI/tests, (2) Provider total-limit + provider cache invalidation + related UI/tests, (3) Dashboard/user-management UI changes, (4) DB migrations + schema updates, (5) Documentation updates.
Issues Found
| Category | Critical | High | Medium | Low |
|---|---|---|---|---|
| Logic/Bugs | 0 | 0 | 1 | 0 |
| Security | 0 | 0 | 0 | 0 |
| Error Handling | 0 | 0 | 2 | 0 |
| Types | 0 | 0 | 0 | 0 |
| Comments/Docs | 0 | 0 | 0 | 0 |
| Tests | 0 | 0 | 0 | 0 |
| Simplification | 0 | 0 | 0 | 0 |
Critical Issues (Must Fix)
None.
High Priority Issues (Should Fix)
- [MEDIUM] [STANDARD-VIOLATION] Hardcoded English in accessibility label:
src/app/[locale]/settings/providers/_components/forms/provider-form.tsx:87(aria-label={${label} - help}) (Confidence: 80) - [MEDIUM] [STANDARD-VIOLATION] New server action returns hardcoded, non-i18n error strings:
src/actions/providers.ts:793(Confidence: 85) - [MEDIUM] [STANDARD-VIOLATION] UI surfaces raw
ActionResult.errordirectly (bypasses i18n):src/app/[locale]/settings/providers/_components/provider-rich-list-item.tsx:274(Confidence: 85)
Review Coverage
- Logic and correctness
- Security (OWASP Top 10)
- Error handling
- Type safety
- Documentation accuracy
- Test coverage
- Code clarity
Automated review by Codex AI
There was a problem hiding this comment.
- Reviewed PR
#561(ding113/claude-code-hub), classified it as XL, and applied labelsize/XL. - Left 3 inline review comments (i18n/accessibility + UI/server error-message i18n compliance).
- Submitted the required Code Review Summary via
gh pr review --comment.
Change firstRequestAt and lastRequestAt from string to Date type to match aggregateSessionStats return type. Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
Too many files changed for review. |
performance - Remove all revalidatePath blocking calls from CRUD operations - Add getProviderStatisticsAsync() for independent statistics loading - Frontend: separate useQuery for statistics with 30s staleTime, 60s refetchInterval - Add Skeleton loading states for statistics columns - Add ProviderStatistics and ProviderStatisticsMap types - Fix Chinese console.error messages to English for consistency - Add 9 unit tests for async optimization Expected performance improvement: - Create provider: 30s -> <500ms - Update provider: 10-20s -> <500ms - Delete provider: 5-10s -> <200ms Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Summary
Release v0.3.42 consolidates major features, bug fixes, and refactors from the dev branch since v0.3.41. This release introduces provider query caching, Anthropic warmup interception, Codex provider-level parameter overrides with audit tracking, improved session details UX, and multiple quota/expiration bug fixes.
Highlights
New Features
Provider Query Cache (#554, #556)
enableProviderCache(default: enabled)Anthropic Warmup Request Interception (#525)
blocked_by=warmupand excluded from billing/statisticsCodex Provider-Level Parameter Overrides (#536)
Provider Override Audit Tracking (#557)
special_settingsJSONB column)Bug Fixes
Security/Pipeline Fixes
/v1/chat/completionsand/v1/responsesnow properly use GuardPipeline (critical fix for client restrictions, model guards, warmup interception)Quota & Rate Limit Fixes
limit_total_usd) now editable, enforced, and resettableUI/UX Fixes
Refactors
Dialog Component Refactor (#539)
unified-edit-dialog.tsxinto 4 focused componentsCreateUserDialog,EditUserDialog,AddKeyDialog,EditKeyDialogas any)Error Rules
tool_usemissingtool_resulterror rule (Fixes 添加错误规则:Eachtool_useblock must have a correspondingtool_resultblock in the next message #550)Database Migrations
0044_uneven_donald_blake.sqlintercept_anthropic_warmup_requestscolumn0045_mushy_human_torch.sql0046_woozy_dark_phoenix.sql0047_fix_system_settings_columns.sql0048_unknown_bushwacker.sqlspecial_settingsJSONB column0049_shocking_ultimatum.sqlenable_provider_cachesystem settingBreaking Changes
None. All changes are backward compatible:
Related Issues
tool_useblock must have a correspondingtool_resultblock in the next message #550 - tool_use missing tool_result error rule (via Fix #550: Add error rule for tool_use missing tool_result #551)Included PRs
Checklist
Description enhanced by Claude AI