Conversation
- 支持 Claude/Gemini/OpenAI 三种错误响应格式的验证和覆写 - UI 模板选择:下拉菜单替代单一按钮,可选择不同格式模板 - 简化覆写逻辑:只输出用户配置的字段,不额外注入 request_id - message 为空时自动回退到原始错误消息 - 新增异步版本函数,确保规则在检测前已从数据库加载 - 解决冷启动时规则未初始化导致检测失败的问题 - 保留同步版本向后兼容,供测试使用 - 数据库异常保护:失败时不抛异常,保留现有缓存 - 编辑默认规则时自动转换为自定义规则(isDefault: false) - 防止用户配置的覆写被"同步规则"操作覆盖 - 用户自定义规则(priority=0)优先于默认规则匹配 - 全局 Agent 配置 600 秒超时,覆盖默认 300 秒限制 - HTTP/HTTPS ProxyAgent 同步配置,匹配 LLM 最大响应时间 - 解决长时间请求被 undici 默认超时提前中断的问题 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Gemini 透传立即清除首字节超时:收到 HTTP 响应即视为首字节到达 - undici.request 显式配置超时:解决使用代理时超时失效问题 - 添加 UNDICI_REQUEST_TIMEOUT_MS 常量统一管理超时时间 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Added a new function to determine the redirect target after login based on user role and permissions. - Updated the `validateKey` function to allow read-only access for users without Web UI login permissions. - Modified the dashboard layout to redirect users without admin access to their usage page. - Introduced new methods to retrieve total usage and distinct models for a given API key. This update improves user experience by ensuring appropriate access control and navigation based on user roles.
…-enhancement # Conflicts: # public/seed/litellm-prices.json
- Introduced READ_ONLY_PATH_PATTERNS to allow specific paths to bypass the canLoginWebUi check. - Updated the proxyHandler to check for read-only access, modifying the validateKey function call accordingly. This change improves access control for users without Web UI login permissions, ensuring they can still access necessary information.
- Removed redundant nesting in myUsage JSON files for cleaner structure. - Updated filter handling in the usage logs section to use a default value of "__all__" for model and status filters, enhancing user experience. - Ensured consistent terminology across multiple language files for better localization support. This refactor improves the maintainability of the code and enhances the user interface for filtering usage logs.
- Added `is_enabled` and `expires_at` fields to the users table to manage user activation status and expiration dates. - Updated user-related actions and forms to handle the new fields, including enabling/disabling users and renewing their expiration dates. - Enhanced user interface components to display user status and expiration information. - Implemented backend logic to mark users as expired and handle authentication based on user status. This update improves user management capabilities and enhances the overall user experience in the dashboard.
- Introduced a new function `validateExpiresAt` to validate expiration dates, ensuring they are in the future and do not exceed 10 years. - Updated user-related actions to incorporate expiration date validation, returning appropriate error messages when validation fails. - Enhanced user forms to handle expiration dates correctly, converting input dates to the end of the day to avoid premature expiration. - Added new error messages in both English and Chinese for better user feedback regarding expiration date issues. This update improves the robustness of user management by enforcing expiration date rules and enhancing user experience with clear error messaging.
Feature-user-expiration
feat: 错误覆写支持多格式 + 异步规则检测 + undici 超时优化
…sue, close #274 Previously, date filters were passed as local time strings (e.g., "2025-12-06T00:00") which caused timezone inconsistencies between the browser and server: - Browser interpreted dates in its local timezone - Server interpreted the same strings in its configured timezone (TZ env) - This caused queries to return wrong results when browser/server timezones differed Changes: - Frontend now converts selected dates to millisecond timestamps (Unix epoch) - Backend converts timestamps to ISO strings for PostgreSQL comparison - URL parameters changed from startDate/endDate to startTime/endTime (ms) - Removed unused getEnvConfig import from usage-logs repository This approach eliminates timezone ambiguity by using absolute time points. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Fix #274: Use millisecond timestamps for date filtering to fix timezone issue
…ions with Redis cleanup and UI Add server-side termination of sessions, UI controls, and cache invalidation to prevent long-running sessions from binding to a single provider. This includes per-session termination, batch termination, and permission checks, plus i18n updates and UI refresh behavior.
- Add per-session cache clearing in batch termination to prevent stale cache - Implement chunked processing (20 sessions per batch) to prevent Redis overload - Fix useMemo optimization in user-list by moving Date.now() inside memo These changes address code review feedback to ensure cache consistency, prevent Redis performance issues during large batch operations, and properly optimize React memoization. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…-sessions feat: add proactive termination of active sessions across server and UI
- Fix TypeScript type error in buildResult call - Add allowedFailedCount field to track authorized but failed terminations - Add unauthorizedSessionIds and missingSessionIds arrays for better debugging - Optimize frontend performance using Set for O(1) membership checks - Add comprehensive toast notifications for all failure scenarios - Add i18n translations for new error messages (en/zh-CN/zh-TW/ja/ru) - Fix type definition in active-sessions-utils.ts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add terminate session button in session details page header - Implement confirmation dialog with session ID display - Add loading state and error handling for termination - Auto redirect to sessions list after successful termination - Add i18n translations for dialog in all 5 languages (en/zh-CN/zh-TW/ja/ru) - Import necessary components (AlertDialog, XCircle icon, toast) - Ensure proper user experience with clear feedback messages Now users can terminate sessions directly from the details page without returning to the list view. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- 新增多选模式切换功能,用户可进入或退出多选模式 - 在多选模式下支持批量选择会话进行批量操作 - 添加多选模式相关界面控制按钮和状态显示 - 更新多语言翻译文件,包含英语、日语、俄语、简体中文和繁体中文的多选相关文本 - 优化选择逻辑,多选开关状态与会话选择状态独立管理 - 进入多选模式时保留当前选择状态,退出多选模式时自动清空所有选择
- Fix race condition in multi-select state by tracking terminating sessions - Add input validation to buildResult for NaN/negative values - Improve Redis failure handling in session cleanup (continue on lookup errors) - Remove unnecessary tUsers dependency from useMemo 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Fix TypeScript error where startDateLocal and endDateLocal properties don't exist in UsageLogFilters interface. The interface expects startTime and endTime as millisecond timestamps instead. - Changed from startDateLocal/endDateLocal to startTime/endTime - Convert date strings to millisecond timestamps using Date.getTime() - Use proper time boundaries: 00:00:00 for start, 23:59:59.999 for end
Feat/me usage
- Add missing cache_ttl_preference parameter to editProvider function signature - Add cache_ttl_preference field to updateData type definition in provider-form This fixes the TypeScript compilation error: Object literal may only specify known properties, and 'cache_ttl_preference' does not exist in type
Fix cors preflight
…dateProviderData types
- Added cache_ttl_preference to addProvider function parameters and validateKey function. - Updated clipText function to set a default maxLength value. - Enhanced usage logs to track additional cache creation tokens.
…atter - Added errorMessage property to ProxyForwarder for more detailed error reporting. - Updated provider chain formatter to prioritize errorMessage over errorName for better clarity in error timelines. - Ensured that errorMessage provides complete error details where available.
- Introduced patterns for input length errors that do not trigger retries, including specific messages for content length and validation exceptions. - Added regex patterns to handle context and token limit exceedances, enhancing error categorization and reporting.
- Introduced new regex patterns for model-related errors, including checks for null model parameters and unknown or non-existent models. - Added support for error messages in Chinese regarding empty or unspecified model names, improving localization and error handling.
- Add excludeStatusCode200, endpoint, minRetryCount filters - Add getMyAvailableEndpoints action and getDistinctEndpointsForKey repository function - Add Non-200 status filter option - Update grid layout for filter alignment
- Create reusable DatePickerField component using Calendar + Popover - Replace native date inputs in user-list.tsx, user-form.tsx, add-key-form.tsx, edit-key-form.tsx - Add proper a11y attributes (aria-haspopup, aria-expanded) - Handle timezone correctly to avoid off-by-one day issues
- Add requestSequence column to messageRequest table with composite index
- Implement atomic sequence generation via Redis INCR
- Update Redis key pattern to session:{id}:req:{seq}:messages/response
- Add backward compatibility fallback for legacy Redis keys
- Create getSessionRequests action with pagination support
- Add collapsible request list sidebar to session detail page
- Show request sequence badge in usage logs and error dialog
- Support URL-based state via ?seq=N query parameter
- Add i18n translations for 5 languages (en, zh-CN, ja, zh-TW, ru)
Closes the issue where multiple requests in a 5-min session
overwrote each other's messages/response data.
…e body storage
- Fix URL locale duplication causing 404 when clicking requests in sidebar
- Use usePathname() from @/i18n/routing instead of window.location.pathname
- Prevents locale-aware router.replace() from adding duplicate locale prefix
- Fix response body storage to include requestSequence parameter
- Add session.requestSequence to all 4 storeSessionResponse calls
- Enables independent storage per request: session:{id}:req:{seq}:response
- Resolves issue where early requests in same session lost response body
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 pull request delivers a comprehensive set of features aimed at improving user and API key management, enhancing session visibility and control, and refining error handling within the system. It introduces new database fields and UI components to support user expiration, provider group assignments, and detailed session request logging. A new 'My Usage' page empowers individual users with self-service access to their usage data, while backend logic has been strengthened with asynchronous error rule detection and flexible error override capabilities. 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 Summary
This PR merges dev branch changes into main with 1,632 additions and 175 deletions across 36 files. The changes include comprehensive Gemini CLI support, format converters, response handling improvements, and various bug fixes. After thorough review through all 6 perspectives (Comment Analyzer, Test Analyzer, Silent Failure Hunter, Type Design Auditor, General Code Review, Code Simplifier), no issues meeting the 80% confidence threshold were identified.
PR Size: XL
- Lines changed: 1,807 (1,632+ / 175-)
- Files changed: 36
Split Suggestion for XL PR: For future PRs of this size, consider splitting by feature area:
- Gemini CLI format converters and adapter
- Response handler improvements
- Provider selector refactoring
- Bug fixes and minor changes
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 |
Review Highlights
Error Handling: The codebase demonstrates proper error handling patterns:
- All catch blocks either log errors via
logger.error/logger.warnor return meaningful user-facing errors - Circuit breaker properly records failures and persists state to Redis
- Response handler uses
persistRequestFailurefor comprehensive failure tracking - Fail-open patterns used appropriately for Redis unavailability
Type Safety: TypeScript types are properly defined with interfaces like GeminiResponseState, ProviderChainItem, and UsageMetrics. No unsafe any usage found in critical paths.
Code Quality: Format converters follow consistent patterns with clear state machines for SSE transformation. The provider selector implements proper weighted random selection with priority-based filtering.
Review Coverage
- Logic and correctness - Clean
- Security (OWASP Top 10) - Clean
- Error handling - Proper logging and user feedback throughout
- Type safety - Well-typed with appropriate interfaces
- Documentation accuracy - Comments match implementation
- Test coverage - N/A (no test file changes in diff)
- Code clarity - State machines well-documented
Automated review by Claude AI
There was a problem hiding this comment.
Code Review
This pull request introduces significant database schema changes and new features related to user and key management, session tracking, and error handling. Database migrations add is_enabled and expires_at columns to the users table, provider_group and cache_ttl_preference to the keys table, and request_sequence, cache_creation_5m_input_tokens, cache_creation_1h_input_tokens, and cache_ttl_applied to the message_request table, along with new indexes. The keys table's can_login_web_ui default is changed to false.
New localization strings are added across multiple languages to support these features, including session termination, user expiration statuses, renewal actions, provider groups, and a new 'My Usage' page. Server actions are introduced for batch session termination, fetching session requests, and managing user expiration and enabled status. The error rule detection system is enhanced with lazy initialization and new patterns for client-side errors, and the error override response handling is updated to support Claude, Gemini, and OpenAI formats. The proxy forwarder now applies cache TTL overrides to Anthropic requests and includes more detailed error messages for system errors. The session manager now tracks individual request sequences within a session and stores messages/responses per sequence. Frontend components are updated to reflect these changes, including new UI for user status, expiration, key/user provider groups, session request lists, and batch session termination.
Review comments highlight a potential issue where applyCacheTtlOverrideToMessage mutates the request message in-place, which could lead to incorrect request bodies on retries with different providers. Another comment points out a possible undercharging scenario for 1-hour cached requests due to an incorrect fallback logic in cacheCreation1hCost calculation.
| if ( | ||
| resolvedCacheTtl && | ||
| (provider.providerType === "claude" || provider.providerType === "claude-auth") | ||
| ) { | ||
| const applied = applyCacheTtlOverrideToMessage(session.request.message, resolvedCacheTtl); | ||
| if (applied) { | ||
| logger.info("ProxyForwarder: Applied cache TTL override to request", { | ||
| providerId: provider.id, | ||
| providerName: provider.name, | ||
| cacheTtl: resolvedCacheTtl, | ||
| }); | ||
| } | ||
| } |
There was a problem hiding this comment.
Similar to the format conversion issue, applyCacheTtlOverrideToMessage mutates session.request.message in-place. This modification is specific to Anthropic. If the request is retried with a non-Anthropic provider, the request body will incorrectly contain Anthropic's cache_control fields.
This mutation should be performed on a temporary, deep copy of the message for this attempt only, to avoid leaking provider-specific fields into subsequent retries.
| const cacheCreation1hCost = | ||
| priceData.cache_creation_input_token_cost_above_1hr ?? | ||
| (inputCostPerToken != null ? inputCostPerToken * 2 : undefined) ?? | ||
| cacheCreation5mCost; |
There was a problem hiding this comment.
The fallback logic for cacheCreation1hCost seems incorrect. If priceData.cache_creation_input_token_cost_above_1hr is not defined and inputCostPerToken is also not available, it falls back to cacheCreation5mCost. This would result in undercharging for 1-hour cached requests, as they would be billed at the 5-minute cache rate. The fallback should probably be undefined to indicate that the cost cannot be calculated, which would result in a cost of 0 rather than an incorrect, lower cost.
| const cacheCreation1hCost = | |
| priceData.cache_creation_input_token_cost_above_1hr ?? | |
| (inputCostPerToken != null ? inputCostPerToken * 2 : undefined) ?? | |
| cacheCreation5mCost; | |
| const cacheCreation1hCost = | |
| priceData.cache_creation_input_token_cost_above_1hr ?? | |
| (inputCostPerToken != null ? inputCostPerToken * 2 : undefined); |
Summary
This is a comprehensive release PR merging the
devbranch intomain, containing multiple features and fixes that have been developed and tested over recent weeks. The PR consolidates 60+ commits spanning user management, session controls, proxy improvements, UI enhancements, and i18n updates.Related Issues
Key Features
1. Personal Usage Portal (
/my-usage)2. User Expiration & Status Management
is_enabledandexpires_atcolumns to users table3. Enhanced Session Management
4. Provider Group for Keys
5. Cache TTL Preference
cache_ttl_preferencesetting for providers and keyscache_creation_5m_input_tokens,cache_creation_1h_input_tokens6. CORS Preflight Handling
7. Error Override Enhancements
8. Request Sequence Tracking
request_sequencecolumn for tracking request order within sessionsDatabase Migrations
0028_abnormal_pretty_boy.sqlis_enabled,expires_atto users0029_chemical_tenebrous.sqlcan_login_web_uidefault0030_unusual_goliath.sqlprovider_groupto keys0031_rare_roxanne_simpson.sql0032_add_request_sequence.sqlrequest_sequenceto message_requestUI/UX Improvements
i18n Updates
Added translations for all new features across 5 languages:
Breaking Changes
None - all migrations are backwards compatible with safe defaults.
Checklist
Description enhanced by Claude AI