Skip to content

release#289

Merged
ding113 merged 59 commits intomainfrom
dev
Dec 7, 2025
Merged

release#289
ding113 merged 59 commits intomainfrom
dev

Conversation

@ding113
Copy link
Owner

@ding113 ding113 commented Dec 7, 2025

Summary

This is a comprehensive release PR merging the dev branch into main, 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)

  • New self-service page for non-admin users to view quotas, usage, and request logs
  • Shows 5h/daily/weekly/monthly/total quota limits with visual progress bars
  • Today's statistics with auto-refresh (30s interval)
  • Paginated request history with filtering (date, model, status)
  • Supports both fixed and rolling daily reset modes

2. User Expiration & Status Management

  • Added is_enabled and expires_at columns to users table
  • Lazy expiration check in ProxyAuthenticator (auto-disable expired users)
  • UI controls for enable/disable toggle and expiration date picker
  • Quick renew actions (30d/90d/1y/custom)

3. Enhanced Session Management

  • Multi-select mode with batch session termination
  • Single session termination from details page
  • Improved error handling with detailed failure reporting
  • Performance optimization using Set for O(1) selection checks

4. Provider Group for Keys

  • Keys can now specify a provider group for routing
  • Enables token-level provider group control (similar to newapi)

5. Cache TTL Preference

  • Added cache_ttl_preference setting for providers and keys
  • Differentiated billing for 5-minute vs 1-hour cache tokens
  • New columns: cache_creation_5m_input_tokens, cache_creation_1h_input_tokens

6. CORS Preflight Handling

  • Proper OPTIONS request handling for Electron/browser environments
  • Dynamic origin echoing with exposed headers
  • No security degradation - auth chain unchanged for actual requests

7. Error Override Enhancements

  • Multi-format response support (Claude/OpenAI/Codex)
  • Async rule detection ensuring rules load before checking
  • Undici timeout optimization (600s) for LLM responses

8. Request Sequence Tracking

  • New request_sequence column for tracking request order within sessions
  • Sidebar component for viewing individual requests in session details

Database Migrations

Migration Purpose
0028_abnormal_pretty_boy.sql Add is_enabled, expires_at to users
0029_chemical_tenebrous.sql Recreate index, change can_login_web_ui default
0030_unusual_goliath.sql Add provider_group to keys
0031_rare_roxanne_simpson.sql Add cache TTL preference fields
0032_add_request_sequence.sql Add request_sequence to message_request

UI/UX Improvements

i18n Updates

Added translations for all new features across 5 languages:

  • English, Simplified Chinese, Traditional Chinese, Japanese, Russian

Breaking Changes

None - all migrations are backwards compatible with safe defaults.

Checklist

  • All merged PRs passed CI
  • Database migrations tested
  • i18n translations complete
  • No breaking changes to existing functionality

Description enhanced by Claude AI

sususu98 and others added 30 commits December 3, 2025 09:25
- 支持 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.
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
github-actions bot and others added 17 commits December 7, 2025 08:26
- 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
- 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
@github-actions github-actions bot added size/XL Extra Large PR (> 1000 lines) enhancement New feature or request labels Dec 7, 2025
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @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

  • Database Schema Enhancements: Introduced new database migrations to add is_enabled and expires_at fields to the users table, provider_group and cache_ttl_preference to the keys table, and request_sequence along with detailed cache token fields (cache_creation_5m_input_tokens, cache_creation_1h_input_tokens, cache_ttl_applied) to the message_request table. Corresponding indexes were also created or updated.
  • User and Key Management: Implemented new functionalities for user and API key management, including user expiration, the ability to renew user access, and toggling user enabled/disabled status. Keys can now be assigned to specific provider groups and have custom cache TTL preferences.
  • Session Tracking and Control: Enhanced session tracking to include a request_sequence for individual requests within a session, allowing for more granular logging and retrieval of messages/responses. Added features for single and batch termination of active sessions, providing administrators with better control over resource usage.
  • Error Handling and Overrides: Improved the error handling mechanism with asynchronous error rule detection to ensure rules are loaded before processing. The error override functionality now supports different API error response formats (Claude, Gemini, OpenAI) and includes new default rules for common client-side errors like input/context/token limits and model-related issues.
  • New 'My Usage' Page: Introduced a dedicated 'My Usage' page for non-admin users, allowing them to view their personal quotas, daily usage statistics, and detailed usage logs. This page provides a read-only dashboard for individual key holders.
  • Internationalization Updates: Updated internationalization files across English, Japanese, Russian, Simplified Chinese, and Traditional Chinese to support the new UI features and terminology.
  • API Proxy Enhancements: Integrated CORS middleware for the API proxy, added user status and expiration checks during authentication, and configured undici global dispatcher timeouts for more robust request handling. Cache TTL preferences are now applied to Anthropic requests.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. Gemini CLI format converters and adapter
  2. Response handler improvements
  3. Provider selector refactoring
  4. 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.warn or return meaningful user-facing errors
  • Circuit breaker properly records failures and persists state to Redis
  • Response handler uses persistRequestFailure for 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

@ding113 ding113 linked an issue Dec 7, 2025 that may be closed by this pull request
@ding113 ding113 merged commit 6dd0ee6 into main Dec 7, 2025
3 checks passed
@github-project-automation github-project-automation bot moved this from Backlog to Done in Claude Code Hub Roadmap Dec 7, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +812 to +824
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,
});
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

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.

Comment on lines +46 to +49
const cacheCreation1hCost =
priceData.cache_creation_input_token_cost_above_1hr ??
(inputCostPerToken != null ? inputCostPerToken * 2 : undefined) ??
cacheCreation5mCost;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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.

Suggested change
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);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size/XL Extra Large PR (> 1000 lines)

Projects

Status: Done

4 participants

Comments