Introduce two new visualizations to the “Model Data Analysis” panel:
1. Model Consumption Trend (line chart)
• Added `spec_model_line` state and legend support.
• Calculates per-model counts over time and updates via `updateChartData`.
2. Model Call Ranking (bar chart)
• Added `spec_rank_bar` state with `seriesField` and legend enabled.
• Ranks models by total call count.
Additional changes:
• Extended tab navigation with two new `TabPane`s and adjusted chart rendering logic.
• Swapped icons/texts to match new chart purposes.
• Reused existing color mapping to ensure consistent palette.
No breaking changes; UI now offers richer insights into model usage patterns.
Summary:
• Imported InputNumber from @douyinfe/semi-ui.
• Swapped plain Input for InputNumber in “Add Quota” modal.
• Added UX tweaks: full-width styling, showClear, step = 500 000.
• Initialized addQuotaLocal to an empty string so the field starts blank.
• Adjusted state handling and kept quota calculation logic unchanged.
This improves numeric input accuracy and overall user experience without breaking existing functionality.
Motivation
• Remove unused UI components to keep the bundle lean and silence linter warnings.
• Ensure every time the side-sheet opens it reflects the latest tag data, avoiding stale form values (e.g., model / group mismatches).
Key Changes
1. UI Imports
– Dropped `Input`, `Select`, `TextArea` from `@douyinfe/semi-ui` (unused in Form-based version).
2. State Reset & Form Sync
– On `visible` or `tag` change:
• Refresh model & group options.
• Reset `inputs` to clean defaults (`originInputs`) carrying the current `tag`.
• Pre-fill Form through `formApiRef` to keep controlled fields aligned.
3. Minor Cleanup
– Added inline comment clarifying local state reset purpose.
Result
Opening the “Edit Tag” side-sheet now always displays accurate data without residual selections, and build output is cleaner due to removed dead imports.
Overview
• Migrated both `EditChannel.js` and `EditToken.js` to fully leverage Semi UI `Form.*` components, removing legacy `Input/Select/TextArea` + manual labels.
• Unified data-loading strategy: when the drawer becomes visible we load (or reset) data via `props.visible + id` effect and `formApi.setValues()`, guaranteeing fields are always populated; form resets on close.
• Fixed blank-form bug when opening the same record twice.
Key improvements
1. Validation
• `type`, `models` always required.
• `key` required only while creating (not on edit).
2. Batch key creation
• Checkbox moved into `extraText`; hidden when editing or when channel type = 41.
3. Layout & UI
• `Row / Col` (12 + 12) for “Priority” and “Weight”.
• Placeholders revised; model selector now shows creation hint; removed obsolete banner.
• Help / extraText used for long hints, template buttons (`model_mapping`, `status_code_mapping`, `param_override`, etc.), and API address notice.
• Added `showClear`, `min`, rounded card class names for consistency.
4. Reusable helpers
• `batchAllowed`, `batchExtra` utilities.
• `getInitValues()` + centralized `inputs`→form synchronization.
5. Token editor aligned to the same pattern (`props.visiable` watcher).
Result
Cleaner code, consistent UX, instant field population on every open, and clearer validation/error feedback across both editors.
* backend
- constant/endpoint_type.go
• Add EndpointTypeMidjourney, EndpointTypeSuno, EndpointTypeKling, EndpointTypeJimeng.
- common/endpoint_type.go
• Map Midjourney / MidjourneyPlus, SunoAPI, Kling, Jimeng channel types to the new endpoint types.
* frontend
- ModelPricing.js
• Add “Supported Endpoint Type” column.
• Implement renderSupportedEndpoints with `stringToColor` for consistent tag colors.
These changes allow `/api/pricing` and model lists to return accurate
`supported_endpoint_types` covering all non-OpenAI providers and display
them clearly in the UI.
No breaking changes.
This update replaces instances of DecodeJson and DecodeJsonStr with UnmarshalJson and UnmarshalJsonStr in various relay handlers, enhancing code consistency and clarity in JSON processing. The changes improve maintainability and align with recent refactoring efforts in the codebase.
This update adds the IOCopyBytesGracefully function to the common package, which simplifies the process of copying response bodies in the OpenAI handlers. It enhances error handling and ensures proper resource management by encapsulating the logic for setting headers and writing response data. The OpenAI handlers have been refactored to utilize this new function, improving code clarity and maintainability.
This update standardizes the closure of HTTP response bodies across multiple stream handlers, enhancing error management and resource cleanup. The new method ensures that any errors during closure are handled gracefully, preventing potential request termination issues.
Changes:
- Replaced error returns with logging for response body copy failures to prevent early termination of the request.
- Ensured that the response body is closed properly after writing to the client.
- Added comments to clarify the handling of billing and error reporting after the response has been sent.
This update improves error handling and maintains resource management in the OpenAI handler.
Previously, the "Fetch Model List" button was visible in the channel-creation view even though
it only functions once a channel record exists, leading to user confusion.
Changes introduced:
• Render the "Fetch Model List" button only when editing an existing channel (`isEdit === true`).
• Display an informational Banner in creation mode to remind users that the upstream model list
can be fetched after the channel has been created.
• Refactored JSX to apply the above conditional rendering without altering existing logic.
This update streamlines the creation workflow and sets clearer expectations for users.
Changes in `web/src/pages/User/EditUser.js`:
• Added `rules` to
– `Form.Select group`: now required with error “Please select group”.
– `Form.InputNumber quota`: now required with error “Please enter quota”.
• Added `step={500000}` to quota `InputNumber` for quicker numeric input.
• Replaced invalid `readonly` with React-correct `readOnly`, and added descriptive placeholders for all binding-info fields (GitHub/OIDC/WeChat/Email/Telegram).
• Removed unused `downloadTextAsFile` import.
These updates tighten form validation, improve data entry ergonomics, and restore clear read-only indicators for third-party bindings.
Summary:
The redemption list occasionally displayed an invalid range such as “Items -9 - 0” and failed to highlight page 1 after a refresh. This was caused by the table being initialized with `currentPage = 0`.
Changes:
• update `useEffect` to load data starting from page 1 instead of page 0
• refactor `loadRedemptions` to accept `page` (default 1) and sanitize backend‐returned pages (`<= 0` coerced to 1)
• keep other logic unchanged
Impact:
Pagination text and page selection now show correct values on first load or refresh, eliminating negative ranges and ensuring the first page is properly highlighted.
Previously, the table did not enter the loading state after performing actions such as deleting, enabling, or disabling a redemption code. This caused a brief period where the UI appeared unresponsive while awaiting the backend response.
Changes made:
• Added `setLoading(true)` at the beginning of `loadRedemptions` to activate the loading spinner whenever data is (re)fetched.
• Added an explanatory code comment to clarify the intent.
This improves user experience by clearly indicating that the system is processing and prevents confusion during data refresh operations.
SUMMARY
• Re-implemented `EditToken.js` with Semi Form components, eliminating manual state handling and reducing re-renders.
• Added grid-based layout; “Expiration Time” selector now sits inline with quick-set buttons for consistent alignment on desktop & mobile.
• Introduced dedicated “Quota”, “Access”, “Model Limits”, and “Group” cards for clearer field grouping.
• Reworked model-limit interaction: single multi-select list replaces checkbox toggle; backend flag `model_limits_enabled` is now inferred automatically.
• Applied required validation rules to critical fields (`name`, `remain_quota`, `group`, `expired_time`, `tokenCount`) with localized messages.
• Enabled dynamic option loading for models & groups; default auto-group honoured.
• Added unlimited-quota switch, quota presets, and helpful extraText/tooltips.
• Removed obsolete `handleInputChange` & `setUnlimitedQuota` helpers; formApi now manages all data flow.
• Cleaned imports (e.g., dropped unused `IconUserGroup`), fixed linter errors, and updated submit logic to use `formApi.submitForm()`.
RESULT
The token creation/editing experience is faster, more accessible, and easier to maintain, fully aligned with Semi Design best practices.
Summary
• Replaced gradient header blocks with compact, neutral headers wrapped in `Avatar` across the following pages:
- Channel / EditChannel.js
- Channel / EditTagModal.js
- Redemption / EditRedemption.js
- Token / EditToken.js
- User / EditUser.js
- User / AddUser.js
Details
1. Added `Avatar` import and substituted raw icon elements, assigning semantic colors (`blue`, `green`, `purple`, `orange`, etc.) and consistent 16 px icons for a cleaner look.
2. Removed gradient backgrounds, decorative “blur-ball” shapes, and extra paddings from header containers to achieve a tight, flat design.
3. Stripped all `size="large"` attributes from `Button`, `Input`, `Select`, `DatePicker`, `AutoComplete`, and `Avatar` components, allowing default sizing for better visual density.
4. Eliminated redundant `bodyStyle` background overrides in some `SideSheet` components.
5. No business logic touched; all changes are purely presentational.
Result
The editing and creation dialogs now share a unified, compact style consistent with the latest design language, improving readability and user experience without altering functionality.
• Add conditional rendering (`!status.self_use_mode_enabled`) to LoginForm
• Suppress “Don't have an account? Register” CTA in self-hosted scenarios
• Keeps UI clean and prevents unintended user sign-ups under self-use mode
• No impact on regular multi-user deployments
Login Form used to display the message “未登录或登录已过期,请重新登录” twice
because the `useEffect` that inspects the `expired` query parameter was
re-executed on every re-render (e.g. language change or React StrictMode’s
double-mount in development).
### What's changed
• **LoginForm.js** – `useEffect` that shows the toast now has an empty
dependency array so it runs only once on initial mount.
• Reviewed **PasswordResetConfirm.js**, **PasswordResetForm.js** and
**RegisterForm.js** and confirmed they do not contain the same issue;
no changes were required.
### Impact
Users now see the “session expired” notification exactly once, removing
confusion and improving the overall UX.
Why
Clicking the “Continue” button on the login page no longer triggered the submission logic. The issue was introduced when `useState`/`useContext` hooks were destructured incorrectly, breaking the setter reference and omitting required values.
What’s changed
• **LoginForm.js**
– Re-added setter in `useSearchParams` (`[searchParams, setSearchParams]`).
– Corrected order of destructuring for `inputs` so `username`/`password` are available after hooks.
– Switched `useContext` to `[userState, userDispatch]` for consistency.
• **RegisterForm.js**
– Adopted `[userState, userDispatch]` from `UserContext` to mirror LoginForm and retain full state access.
Outcome
Login button now successfully invokes `handleSubmit`, and both auth components have consistent, fully-featured hook destructuring, preventing runtime errors and ensuring future state usage is straightforward.
This commit refreshes the visual design of the authentication pages and aligns them with the Home banner style.
Details
• LoginForm.js / RegisterForm.js / PasswordResetForm.js / PasswordResetConfirm.js
– Wrap top-level container with `relative overflow-hidden` to provide a positioning context.
– Inject two decorative blur balls:
▸ Indigo ball on the top-right (`blur-ball-indigo`).
▸ Teal ball on the middle-left (`blur-ball-teal`).
– Disabled the default X-axis transform on the indigo ball to keep the ball anchored to the corner.
– Removed redundant `mt-[64px]` from the outer container and shifted it to the inner wrapper to maintain vertical rhythm without affecting the background placement.
Result
The auth screens now feature subtle, non-intrusive atmospheric gradients in the top-right and mid-left corners, offering a cohesive look & feel across the application without obstructing the main content.
• LoginForm / RegisterForm now initialise `status` directly from localStorage,
avoiding a post-mount state update that caused a UI flash between OAuth
options and email/username forms.
• Move Turnstile configuration into a dedicated effect that depends on
`status`, ensuring setState is not called during rendering.
• Remove unused `setStatus` setter to resolve ESLint “declared but never read”
warnings.
• Minor refactors: reorder hooks, de-duplicate navigate/context variables and
streamline state destructuring for improved readability.
- Changed the type of `Document` in `XinRerankResponseDocument` from `string` to `any` to accommodate various data types.
- Updated the `RerankHandler` to handle `Document` as `any`, ensuring proper assignment based on its actual type.
These modifications enhance the handling of document data, allowing for greater versatility in response structures.
• Removed the custom `renderArrow` helper and its `Dropdown`-based arrow navigation, simplifying the component logic.
• Switched the `<Tabs>` component to rely on Semi UI’s built-in behaviour (no more `renderArrow` override).
• Kept `type="card"` and `collapsible` props for consistent visual appearance while still using the default style.
• Eliminated the now-unused `Dropdown` import.
This cleanup reduces bespoke UI code, makes future maintenance easier, and keeps the interface consistent with the rest of the application.
• Added read-only Base URL input that shows `status.server_address` (fallback `window.location.origin`) and copies value on click.
• Embedded `ScrollList` as input `suffix`; auto-cycles common endpoints every 3 s and allows manual selection.
• Introduced `API_ENDPOINTS` array in `web/src/constants/common.constant.js` for centralized endpoint management.
• Implemented custom CSS to hide ScrollList wheel indicators / scrollbars for a cleaner look.
• Created two blurred colour spheres behind the banner (`blur-ball-indigo`, `blur-ball-teal`) with light-/dark-mode opacity tweaks and lower vertical placement.
• Increased letter-spacing for Chinese heading via conditional `tracking-wide` / `md:tracking-wider` classes to improve readability.
• Misc: updated imports, helper functions, and responsive sizes to keep UI consistent across devices.
- Updated TokenAuth middleware to handle requests for both `/v1beta/models/` and `/v1/models/`.
- Adjusted distributor middleware to recognize the new model path.
- Enhanced relay mode determination to include the new model path.
- Added route for handling POST requests to `/models/*path`.
These changes ensure compatibility with the new model API structure, improving the overall routing and authentication flow.
• Removed the dropdown menu previously used for tag-level operations.
• Added a standalone “Edit” button directly after the “Disable All” button, reducing the number of clicks required to edit a tag group.
• Deleted the now-unused `IconEdit` import and its icon reference.
This streamlines the tag management flow and keeps the UI cleaner and more accessible.
All operation-related UI controls in `ChannelsTable` (buttons, dropdowns,
switches, inputs, tags, etc.) now explicitly use `size="small"`.
Reasons & benefits:
- Creates a more compact and consistent look across the table and modals.
- Improves visual coherence between desktop and mobile views.
- Purely presentational; no functional logic is affected.
No database changes or API interactions are involved.
* ChannelsTable
- Added row-level checkboxes to the model-testing table for multi-selection
- Implemented cross-page “Select All / Deselect All” via rowSelection.onSelectAll
- Introduced allSelectingRef to ignore redundant onChange after onSelectAll
- Added “Copy Selected” button to copy chosen model names (comma-separated) using helpers.copy
- Added “Select Successful” button to auto-tick all models that passed testing
- Moved search bar and new action buttons into the modal title for better UX
- Centralised page size constant MODEL_TABLE_PAGE_SIZE in channel.constants.js
- Fixed pagination slicing and auto-page-switch logic during batch testing
* channel.constants
- Exported MODEL_TABLE_PAGE_SIZE (default 10) for unified pagination control
This commit enables users to conveniently copy or filter successful models, fully supports cross-page bulk operations, and resolves previous selection inconsistencies.
Refs: #1288
Frontend (`ChannelsTable.js`)
1. Initialize `loading` state to `true` so the spinner is visible while the first data request is in-flight.
2. Set `<Table>` prop `loading={loading || searching}` — the spinner now appears for both the initial load and any subsequent search requests.
Result
Users immediately see a loading indicator on page entry and whenever a search is running, improving perceived responsiveness.
1. Backend
• `controller/channel.go`
– Added pagination (`p`, `page_size`) support to `SearchChannels`.
– Added independent `type` filter (keeps `type_counts` unaffected).
– Returned `total`, `type_counts` to match `/api/channel/` response.
2. Frontend
• `ChannelsTable.js`
– `loadChannels` / `searchChannels` now pass `p`, `page_size`, `id_sort`, `type`, `status` correctly.
– Pagination, page-size selector and type tabs work for both normal list and search mode.
– Switch for “ID sort” calls proper API and keeps UI state in sync.
– Removed unnecessary `normalize` helper; `getFormValues` back to concise form.
Result
• Search mode and normal listing now share identical pagination and filtering behavior.
• Type tabs show correct counts even after searching.
• “ID Sort” toggle no longer inverses actual behaviour.
Refactors `ChannelsTable.js` to ensure that the selected group filter is **never lost** when:
1. Cycling between channel-type tabs.
2. Changing the status dropdown (all / enabled / disabled).
Key points:
• `loadChannels` now detects active search filters (keyword / group / model) and transparently delegates to `searchChannels`, guaranteeing all parameters are sent in every request.
• `searchChannels` accepts optional `typeKey` and `statusF` arguments, enabling reuse without code duplication.
• Loading state handling is unified; no extra renders or side effects were introduced, keeping UI performance intact.
• Duplicate logic removed and responsibilities clearly separated for easier future maintenance.
Replaced the verbose placeholder “Search channel ID, name, key and API address ...”
with a concise version “Channel ID, name, key, API address” in
`ChannelsTable.js` and synchronized the corresponding i18n entries.
This improves readability and keeps UI text consistent across languages.
Ensure that the selected "group" filter (and other form search values) persist across
type tab changes, status filter updates, pagination, and page-size changes.
Changes include:
• loadChannels: added `searchParams` argument and now appends keyword, group and model
query strings to API calls.
• refresh / page handlers / type tabs / status Select: now pass current form values
to loadChannels, keeping filters intact.
• searchChannels: maintains active type and status filters when issuing search requests.
• Form.Select (searchGroup): triggers loadChannels when only group filter is active,
preventing parameter loss.
• Minor cleanup and comment adjustments.
• Unify the Select option structure as `{ key, label, value }`; add missing `key` to prevent duplicated rendering by Semi-UI.
• Trim and deduplicate the `models` array via `Set` inside `handleInputChange`, ensuring state always contains unique values.
• In the options-merging `useEffect`, use a `Map` keyed by `value` (after `trim`) to guarantee a unique `optionList` when combining backend data with currently selected models.
• Apply the same structure and de-duplication when:
– Fetching models from `/api/channel/models`
– Adding custom models (`addCustomModels`)
– Fetching upstream model lists (`fetchUpstreamModelList`)
• Replace obsolete `text` field with `label` in custom option objects for consistency.
No backend changes are required; the fix is entirely front-end.
Closes#1292
* Added a dedicated effect to merge origin and selected models, ensuring selected items always remain in the dropdown list.
* Enhanced “Copy all models” button:
* Shows info message when list is empty.
* Displays success / error notification based on copy result.
* Unified UI look-and-feel by applying `!rounded-lg` class to inputs, selects, banners and buttons.
* i18n: added English translations for new prompts
- "No models to copy"
- "Model list copied to clipboard"
- "Copy failed"
WHAT’S NEW
• Backend
– Introduced `parseStatusFilter` helper to normalize `status` query across handlers.
– `GET /api/channel` & `GET /api/channel/search` now accept `status=enabled|disabled` to return only enabled or disabled channels.
– Tag-mode branch respects both `statusFilter` and `typeFilter`; SQL paths trimmed to one query + one lightweight `GROUP BY` for `type_counts`.
• Frontend (`ChannelsTable.js`)
– Added “Status Filter” `<Select>` (All / Enabled / Disabled) with localStorage persistence.
– All data-loading and search requests now always append `type` (when not “all”) and `status` params, so filtering & pagination are handled entirely server-side.
– Removed client-side post-filtering for type, preventing short pages and reducing CPU work.
– Tabs’ type counts stay in sync via backend-provided `type_counts`.
IMPROVEMENTS
• Eliminated duplicated status-parsing logic; single source of truth eases future extension.
• Reduced redundant queries, improved consistency of counts in UI.
• Secured key leakage with `Omit("key")` unchanged; no perf regressions observed.
Closes#1289
Add a `useEffect` hook in `UpstreamRatioSync.js` to automatically set
`currentPage` to `1` whenever `ratioTypeFilter` or `searchKeyword`
updates.
This prevents the table from appearing empty when users switch to the
“model_price” (fixed price) filter or perform a new search while on a
later page.
Additional changes:
- Import `useEffect` from React.
This enhancement delivers a smoother UX by ensuring the first page of
results is always shown after any filtering action.
Introduce the ability to quickly locate models with conflicting billing configurations.
Key points
• Added `hasConflict` flag to detect models that define both a fixed price (`ModelPrice`) and any ratio (`ModelRatio` or `CompletionRatio`).
• Added “Show Only Conflict Rates” `Checkbox` to toolbar; filtering logic now supports keyword + conflict filtering.
• Display a red `Tag` beside the model name when a conflict is detected for immediate visual feedback.
• Kept `hasConflict` state in sync during add, update and delete operations.
• Imported `Checkbox` and `Tag` from **@douyinfe/semi-ui**.
• Minor UI tweaks (circle tag style, margin) for consistency.
This enhancement helps administrators swiftly identify and resolve incompatible pricing rules, addressing the need discussed in issue #1286.
Summary
• Added per-table “Compact / Adaptive” view toggle to all major table components (Tokens, Channels, Logs, MjLogs, TaskLogs, Redemptions, Users).
• Persist user preference in a single localStorage entry (`table_compact_modes`) instead of scattered keys.
Details
1. utils.js
• Re-implemented `getTableCompactMode` / `setTableCompactMode` to read & write a shared JSON object.
• Imported storage-key constant from `constants`.
2. hooks/useTableCompactMode.js
• Hook now consumes the unified helpers and listens to `storage` events via the shared key constant.
3. constants
• Added `TABLE_COMPACT_MODES_KEY` to `common.constant.js` and re-exported via `constants/index.js`.
4. Table components
• Integrated `useTableCompactMode('<tableName>')`.
• Dynamically remove `fixed: 'right'` column and horizontal `scroll` when in compact mode.
• UI: toggle button placed at card title’s right; responsive layout on small screens.
5. UI polish
• Replaced all lucide-react `List`/`ListIcon` usages with Semi UI `IconDescend` for consistency.
• Restored correct icons where `Hash` was intended (TaskLogsTable).
Benefits
• Consistent UX for switching list density across the app.
• Cleaner localStorage footprint with easier future maintenance.
This commit enhances the “Copy Selected Tokens to Clipboard” feature in `TokensTable.js` by introducing a user-friendly modal that lets users choose how they want to copy tokens.
Changes made
• Replaced direct copy logic with a `Modal.info` dialog.
• Modal displays the prompt “Please choose your copy mode”.
• Added two buttons in a custom footer:
– **Name + Secret**: copies `tokenName sk-tokenKey`.
– **Secret Only**: copies `sk-tokenKey`.
• Each button triggers the copy operation and closes the dialog.
• Maintains existing validations (e.g., selection check, clipboard feedback).
Benefits
• Gives users clear control over copy format, reducing manual editing.
• Aligns UI with Semi UI’s best practices via custom modal footer.
No backend/API changes are involved; all updates are limited to the front-end UI logic.
• SettingsAnnouncements.js
– Placeholder now states “Supports Markdown/HTML” for both small & expanded editors
– Success/alert messages unified to use Chinese quotation marks
• SettingsFAQ.js
– Answer textarea placeholder updated with Markdown/HTML support note
– Unified success/alert messages punctuation
These tweaks clarify rich-text support and keep UI copy consistent.
* Added `Tooltip` component and ellipsis style for “question” & “answer” columns
* Keeps table compact while showing full content on hover
* Updated success messages punctuation for consistency
* Added “Expand Edit” button with `Maximize2` icon to open a large modal editor
* Introduced full-screen `TextArea` modal; content syncs back to main form via Form API
* Switched to correct `TextArea` import from Semi UI to fix invalid element error
* Implemented ellipsis & `Tooltip` for “content” and “extra” columns to keep table concise
* Added state management (`showContentModal`, `formApiRef`) and related handlers
* Updated success messages & punctuation for consistency
- Introduced `isNoThinkingRequest` and `trimModelThinking` functions to manage model names and thinking configurations.
- Updated `GeminiHelper` to conditionally adjust the model name based on the thinking budget and request settings.
- Refactored `ThinkingAdaptor` to streamline the integration of thinking capabilities into Gemini requests.
- Cleaned up commented-out code in `FetchUpstreamModels` for clarity.
These changes improve the handling of model configurations and enhance the adaptability of the Gemini relay system.
Backend
- controller/ratio_sync.go
• Parse /api/pricing response and convert to ratio / price maps.
• Introduce confidence heuristic (model_ratio = 37.5 && completion_ratio = 1) to flag unreliable data.
• Include confidence map when building differences and filter “same”/empty entries.
- dto/ratio_sync.go
• Add `ID` to UpstreamDTO, `upstreams` to UpstreamRequest, and `Confidence` to DifferenceItem.
Frontend
- ChannelSelectorModal.js
• Re-implement with table layout, pagination, search, endpoint-type selector and mobile support.
- UpstreamRatioSync.js
• Send full upstream objects, add ratio-type filter, confidence badges/tooltips, retain endpoints.
• Leverage ChannelSelectorModal’s pagination reset.
- ChannelsTable.js – fix tag color for disabled status.
- en.json – add translations for new UI labels.
Motivation
These changes let users sync model ratios / prices from different upstream endpoints and visually identify potentially unreliable data, improving operational safety and flexibility.
* Moved `GroupRatioSettings` component inside the existing Tabs as a new **Group Ratios** tab.
* Removed the standalone `Card` that previously wrapped `GroupRatioSettings`.
* Re-formatted JSX props for `ModelRatioSettings` and `GroupRatioSettings` to improve readability.
* Consolidates all ratio-related settings into a single tabbed view for a cleaner and more consistent UI.
Add reverse-chronological sorting for the announcements list so that the newest
items appear first in the dashboard.
No API changes; this only affects front-end display and user notifications.
• HeaderBar
- Added dynamic unread badge; click now opens NoticeModal on “System Announcements” tab
- Passes `defaultTab` and `unreadKeys` props to NoticeModal for contextual behaviour
• NoticeModal
- Introduced Tabs inside the modal title with Lucide icons (Bell, Megaphone)
- Displays in-app notice (markdown) and system announcements separately
- Highlights unread announcements with “shine” text animation
- Accepts new props `defaultTab`, `unreadKeys` to control initial tab and highlight logic
• CSS (index.css)
- Implemented `sweep-shine` keyframes and `.shine-text` utility for left-to-right glow
- Added dark-mode variant for better contrast
- Ensured cross-browser support with standard `background-clip`
Overall, users now see an unread counter, are directed to new announcements automatically, and benefit from an eye-catching glow effect that works in both light and dark themes.
Restructure payment settings into a separate tab for better organization and user experience. The changes include:
1. Create dedicated Payment components in the Setting directory structure
2. Move payment-related settings from SystemSetting to PaymentSetting
3. Add proper i18n support with useTranslation hook
4. Split payment settings into GeneralPayment and PaymentGateway components
5. Fix internationalization issues in placeholder text
6. Update navigation with CreditCard icon for payment tab
This refactoring improves code maintainability by following the established project pattern of having specialized setting components in their own directories.
This commit relocates the DataDashboard settings component from the Operation section to the Dashboard section for better logical organization. The changes include:
- Remove DataDashboard import and component from OperationSetting.js
- Add DataDashboard component to DashboardSetting.js
- Update import path from Operation to Dashboard directory
- Add DataExport related state management in DashboardSetting
This restructuring improves the application's information architecture by grouping related dashboard visualization settings together.
- Create a new DrawingSetting component for managing drawing-related configurations
- Add a dedicated "Drawing Settings" tab with Palette icon in the settings page
- Remove drawing settings section from the OperationSetting component
- Update import path to use Drawing directory instead of Operation directory
- Improve UI organization by separating drawing settings from general operations
- Add icons to each settings tab to enhance visual recognition
- Import necessary Lucide React icons (Settings, Calculator, Gauge, Shapes, etc.)
- Create consistent tab styling with icons aligned next to text
- Reorder tabs to place "Other Settings" as the last option
- Improve overall settings page UI with better visual hierarchy
- Change message from "已与上游倍率完全一致,无需同步" to "未找到差异化倍率,无需同步"
- Update English translation to "No differential ratio found, no synchronization is required"
- Improve user experience clarity for upstream ratio synchronization status
- Changed response handling from ObjectData to StringData for improved data processing.
- Ensured proper error logging in case of response handling failure.
- Refactored payment method validation to check against available methods.
- Changed payment method types from "zfb" to "alipay" and "wx" to "wxpay" for consistency.
- Updated the purchase request to use the validated payment method directly.
- Added new handlers: AudioHelper, ImageHelper, EmbeddingHelper, and ResponsesHelper to manage respective requests.
- Updated ModelMappedHelper to accept request parameters for better model mapping.
- Enhanced error handling and validation across new handlers to ensure robust request processing.
- Introduced support for new relay formats in relay_info and updated relevant functions accordingly.
- Added status code mapping handling in GeminiHelper to reset status codes based on response.
- Removed redundant candidate check in GeminiTextGenerationHandler to simplify response processing.
Enhance the UI of payment method selection area with responsive layouts:
- Use 2-column grid when exactly 2 payment methods are present
- Use 3-column grid for 3 payment methods
- Use compact card layout for more than 3 payment methods
- Full-width button for single payment method
This improves the visual balance across different device sizes and payment provider configurations, ensuring buttons fill their grid cells appropriately with the w-full class.
WHAT’S NEW
• controller/ratio_sync.go
– Deleted unused local structs (TestResult, DifferenceItem, SyncableChannel).
– Centralised config with constants: defaultTimeoutSeconds, defaultEndpoint, maxConcurrentFetches, ratioTypes.
– Replaced magic numbers; added semaphore-based concurrency limit and shared http.Client (with TLS & Expect-Continue timeouts).
– Added comprehensive error handling and context-aware logging via common.Log* helpers.
– Checked DB errors from GetChannelsByIds; early-return on failures or empty upstream list.
– Removed custom-channel support; logic now relies solely on ChannelIDs.
– Minor clean-ups: import grouping, string trimming, endpoint normalisation.
• dto/ratio_sync.go
– Simplified UpstreamRequest: dropped unused CustomChannels field.
WHY
These improvements harden the ratio-sync endpoint for production use by preventing silent failures, controlling resource usage, and making behaviour configurable and observable.
HOW
No business logic change—only structural refactor, logging, and safeguards—so existing API contracts (aside from removed custom_channels) remain intact.
Summary
1. Add model name search box
• Introduce Semi UI `Input` with `IconSearch` prefix next to the “Apply Sync” button.
• Support case-insensitive fuzzy matching of model names.
• Real-time filtering, pagination and bulk-select logic now work on filtered data.
2. Improve empty state handling
• Add `hasSynced` flag to distinguish “not synced yet” from “synced with no differences”.
• Display messages:
– “Please select sync channels” when no sync has been performed.
– “No differences found” when a sync completed with zero discrepancies.
– “No matching model found” when search yields no results.
3. UI tweaks
• Replace lucide-react `Search` icon with Semi UI `IconSearch` for visual consistency.
• Keep responsive width and clearable input for better usability.
Why
These changes allow admins to quickly locate specific models and provide accurate feedback on the sync status, greatly improving the usability of the Upstream Ratio Sync page.
Summary
1. Consider “both unset” as identical
• When both localValue and upstreamValue are nil, mark upstreamValue as "same" to avoid showing “Not set”.
2. Exclude fully-synced upstream channels from result
• Scan `differences` to detect channels that contain at least one divergent value.
• Remove channels whose every ratio is either `"same"` or `nil`, so the frontend only receives actionable discrepancies.
Why
These changes reduce visual noise in the Upstream Ratio Sync table, making it easier for admins to focus on models requiring attention. No functional regressions or breaking API changes are introduced.
Add visual status indicators and improve user experience for the upstream ratio sync channel selector modal.
Features:
- Add status-based avatar indicators for channels (enabled/disabled/auto-disabled)
- Implement search functionality with text highlighting
- Add endpoint configuration input for each channel
- Optimize component structure with reusable ChannelInfo component
UI Improvements:
- Custom styling for transfer component items
- Hide scrollbars for cleaner appearance in transfer lists
- Responsive layout adjustments for channel information display
- Color-coded avatars: green (enabled), red (disabled), amber (auto-disabled), grey (unknown)
Code Quality:
- Extract channel status configuration to constants
- Create reusable ChannelInfo component to reduce code duplication
- Implement proper search filtering for both channel names and URLs
- Add consistent styling classes for transfer demo components
Files modified:
- web/src/components/settings/ChannelSelectorModal.js
- web/src/pages/Setting/Ratio/UpstreamRatioSync.js
- web/src/index.css
This enhancement provides better visual feedback for channel status and improves the overall user experience when selecting channels for ratio synchronization.
Remove all custom channel functionality from the upstream ratio sync feature to simplify the codebase and focus on database-stored channels only.
Changes:
- Remove custom channel UI components and related state management
- Remove custom channel testing and validation logic
- Simplify ChannelSelectorModal by removing custom channel input fields
- Update API payload to only include channel_ids, removing custom_channels
- Remove custom channel processing logic from backend controller
- Update import path for DEFAULT_ENDPOINT constant
Files modified:
- web/src/pages/Setting/Ratio/UpstreamRatioSync.js
- web/src/components/settings/ChannelSelectorModal.js
- controller/ratio_sync.go
This change streamlines the ratio synchronization workflow by focusing solely on pre-configured database channels, reducing complexity and potential maintenance overhead.
Summary
• Migrated all ratio-related sources into `setting/ratio_setting/`
– `model_ratio.go` (renamed from model-ratio.go)
– `cache_ratio.go`
– `group_ratio.go`
• Changed package name to `ratio_setting` and relocated initialization (`ratio_setting.InitRatioSettings()` in main).
• Updated every import & call site:
– Model / cache / completion / image ratio helpers
– Group ratio helpers (`GetGroupRatio*`, `ContainsGroupRatio`, `CheckGroupRatio`, etc.)
– JSON-serialization & update helpers (`*Ratio2JSONString`, `Update*RatioByJSONString`)
• Adjusted controllers, middleware, relay helpers, services and models to reference the new package.
• Removed obsolete `setting` / `operation_setting` imports; added missing `ratio_setting` imports.
• Adopted idiomatic map iteration (`for key := range m`) where value is unused.
• Ran static checks to ensure clean build.
This commit centralises all ratio configuration (model, cache and group) in one cohesive module, simplifying future maintenance and improving code clarity.
Problem
Semi UI’s Tabs calls `focus()` on the active tab during mount, causing the browser to scroll the page to that element.
Using the bare `preventScroll` shorthand was not picked up reliably, so the page still jumped to the Tabs’ position on first render.
Changes
• Updated both Tabs instances in `web/src/pages/Detail/index.js` to `preventScroll={true}` instead of the shorthand prop.
• Ensures the prop is explicitly interpreted as boolean `true`, converting the internal call to `focus({ preventScroll: true })`.
Result
The `Detail` page now stays at its original scroll position after load, eliminating the unexpected auto-scroll behavior.
The initial render of the `Detail` page was jumping to the first `Tabs` component because Semi UI calls `focus()` on the active tab, which triggers the browser’s default scroll-into-view behavior.
Changes made
• Added `preventScroll` to the chart-selector `Tabs` (type="button").
• Added `preventScroll` to the uptime-monitor `Tabs` (type="card").
These flags convert the internal `focus()` call to `focus({ preventScroll: true })`, allowing the page to stay at its current position after load.
No functional logic is changed other than disabling the unwanted scroll; UI and user interactions remain the same.
frontend(ChannelsTable):
• Do not render type-filter Tabs when `enableTagMode` is true, preventing UI/logic conflicts in tag aggregation view.
• Adjust API query construction:
– Append `type=` param only when NOT in tag mode and selected tab ≠ 'all'.
– Applies to both `loadChannels` and `searchChannels`.
• Result: UI stays clean in tag view, and backend receives correct parameters across modes.
No other functionality affected.
The “Batch Create” secret-key input in Channel Edit previously used a TextArea
with a hard-coded `minHeight`, which caused an extra scrollbar and blank space
on the right side of the field.
This change:
• Removes the fixed `minHeight` in favour of `autosize={{ minRows: 6, maxRows: 6 }}`
• Keeps the field’s rounded appearance while letting it grow/shrink with
content, improving usability on both desktop and mobile
No other components or global styles are affected.
feat(api):
• Add optional `type` query param to `/api/channel` endpoint for type-specific pagination
• Return `type_counts` map with counts for each channel type
• Implement `GetChannelsByType`, `CountChannelsByType`, `CountChannelsGroupByType` in `model/channel.go`
feat(frontend):
• Introduce type Tabs in `ChannelsTable` to switch between channel types
• Tabs show dynamic counts using backend `type_counts`; “All” is computed from sum
• Persist active type, reload data on tab change (with proper query params)
perf(frontend):
• Use a request counter (`useRef`) to discard stale responses when tabs switch quickly
• Move all `useMemo` hooks to top level to satisfy React Hook rules
• Remove redundant local type counting fallback when backend data present
ui:
• Remove icons from response-time tags for cleaner look
• Use Semi-UI native arrow controls for Tabs; custom arrow code deleted
chore:
• Minor refactor & comments for clarity
• Ensure ESLint Hook rules pass
Result: Channel list now supports fast, accurate type filtering with correct counts, improved concurrency safety, and cleaner UI.
Summary
• Added new Ratio tab in Settings for managing all ratio-related configurations (group & model multipliers).
• Created `RatioSetting` component to host GroupRatio, ModelRatio, Visual Editor and Unset-Models panels.
• Moved ratio components to `web/src/pages/Setting/Ratio/` directory:
– `GroupRatioSettings.js`
– `ModelRatioSettings.js`
– `ModelSettingsVisualEditor.js`
– `ModelRationNotSetEditor.js`
• Updated imports in `RatioSetting.js` to use the new path.
• Updated main Settings router (`web/src/pages/Setting/index.js`) to include the new “Ratio Settings” tab.
• Pruned `OperationSetting.js`:
– Removed ratio-specific cards, tabs and unused imports.
– Reduced state to only the keys required by its child components.
– Deleted obsolete fields (`StreamCacheQueueLength`, `CheckSensitiveOnCompletionEnabled`, `StopOnSensitiveEnabled`).
• Added boolean handling simplification in `OperationSetting.js`.
• Adjusted helper import list and removed unused translation hook.
Why
Separating ratio-related settings improves UX clarity, reduces cognitive load in the Operation Settings panel and keeps the codebase modular and easier to maintain.
BREAKING CHANGE
The file paths for ratio components have changed. Any external imports referencing the old `Operation` directory must update to the new `Ratio` path.
Summary
• Added stable, descending sort to `GetAnnouncements()` so that the API always returns the latest announcements first.
• Introduced helper `getPublishTime()` to safely parse `publishDate` (RFC 3339) and fall back to zero value on failure.
• Switched to `sort.SliceStable` for deterministic ordering when timestamps are identical.
• Imported the standard `sort` package and removed redundant, duplicate date parsing.
Impact
Front-end no longer needs to perform client-side sorting; the latest announcement is guaranteed to appear at the top on all platforms and clients.
* backend
- model: add `Remark` field (varchar 255, `json:"remark,omitempty"`); AutoMigrate handles schema change automatically
- controller:
* accept `remark` on user create/update endpoints
* hide remark from regular users (`GetSelf`) by zero-ing the field before JSON marshalling
* clarify inline comment explaining the omitempty behaviour
* frontend (React / Semi UI)
- AddUser.js & EditUser.js: add “Remark” input for admins
- UsersTable.js:
* remove standalone “Remark” column
* show remark as a truncated Tag next to username with Tooltip for full text
* import Tooltip component
- i18n: reuse existing translations where applicable
This commit enables administrators to label users with private notes while ensuring those notes are never exposed to the users themselves.
Improve UX by hiding the vertical scrollbar inside the announcement (NoticeModal)
while keeping the content scrollable.
Changes
• NoticeModal.js
- Introduce `notice-content-scroll` class to the content wrapper.
- Remove inline custom scrollbar styling for cleaner code.
• index.css
- Add `.notice-content-scroll` to the global hidden-scrollbar rules, ensuring
scrollbars are hidden across browsers.
Result
Users can still scroll through long announcements, but no scrollbar is shown,
giving the modal a cleaner and more consistent appearance.
Summary:
Refactored the `Detail` page to deliver a more consistent and compact visual experience when displaying empty states.
Key changes:
1. Introduced a reusable `ILLUSTRATION_SIZE` constant (96 × 96) to ensure all `IllustrationConstruction` / `IllustrationConstructionDark` icons render at a uniform, reduced size.
2. Applied the new size to every `Empty` component instance within the file.
3. Ensured Empty‐state content (title, description, icon) is centrally aligned for better readability.
4. Updated the Uptime panel’s empty description text for greater clarity.
These adjustments improve UI cohesion, reduce visual noise, and make empty messages easier to scan.
* Added migration logic in `controller/console_migrate.go`
* Detects both `UptimeKumaUrl` and `UptimeKumaSlug`
* Creates a single-group JSON array under `console_setting.uptime_kuma_groups`
- Uses `categoryName: "old"` to mark migrated data
- Preserves original `url` and `slug` values
* Clears and removes obsolete `UptimeKumaUrl` and `UptimeKumaSlug` keys
* Removes outdated code paths that wrote to `console_setting.uptime_kuma_url` and `console_setting.uptime_kuma_slug`
* Keeps frontend `DashboardSetting.js` compatible — no additional changes required
* Aligns migration behavior with previous `ApiInfo` refactor for consistent console settings management
Backend
• controller/uptime_kuma.go
- Added Group field to Monitor struct to carry publicGroupList.name.
- Extended status page parsing to capture group Name and inject it into each monitor.
- Re-worked fetchGroupData loop: aggregate all sub-groups, drop unnecessary pre-allocation/breaks.
Frontend
• web/src/pages/Detail/index.js
- renderMonitorList now buckets monitors by the new group field and renders a lightweight header per subgroup.
- Fallback gracefully when group is empty to preserve previous single-list behaviour.
Other
• Expanded anonymous struct definition for statusData.PublicGroupList to include ID/Name, enabling JSON unmarshalling of group names.
Result
Custom CategoryName continues to work while each uptime group’s internal sub-groups are now clearly displayed in the UI, providing finer-grained visibility without impacting performance or existing validation logic.
Backend:
• ConsoleSetting
- Introduce `ApiInfoEnabled`, `UptimeKumaEnabled`, `AnnouncementsEnabled`, `FAQEnabled` (default true).
• misc.GetStatus
- Refactor to build response map dynamically.
- Return the four *_enabled flags.
- Only append `api_info`, `announcements`, `faq` when their respective flags are true.
Frontend:
• Detail page
- Remove all `self_use_mode_enabled` checks.
- Render API, Announcement, FAQ and Uptime panels based on the new *_enabled flags.
• Dashboard → Settings
- Added `Switch` controls in:
· SettingsAPIInfo.js
· SettingsAnnouncements.js
· SettingsFAQ.js
· SettingsUptimeKuma.js
- Each switch persists its state via `/api/option` to the corresponding
`console_setting.<panel>_enabled` key and reflects current status on load.
- DashboardSetting.js now initialises and refreshes the four *_enabled keys so
child components receive accurate panel states.
Fixes:
• Switches previously defaulted to “on” because *_enabled keys were missing.
They are now included, ensuring correct visual state when panels are disabled.
No breaking changes; existing functionality remains untouched aside from the
new per-panel visibility control.
Backend
• Removed the exported function `ValidateApiInfo` from `setting/console_setting/validation.go`; it was only a legacy wrapper and is no longer required.
• Updated `controller/option.go` to call `ValidateConsoleSettings(value, "ApiInfo")` directly when validating `console_setting.api_info`.
• Confirmed there are no remaining references to `ValidateApiInfo` in the codebase.
This commit eliminates the last piece of compatibility code related to the old validation interface, keeping the API surface clean and consistent.
Backend
- Introduce `setting/console_setting` package that defines `ConsoleSetting` struct with JSON tags and validation rules.
- Register the new module with `config.GlobalConfig` to enable automatic injection/export of configuration values.
- Remove legacy `setting/console.go` and the manual `OptionMap` hooks; clean up `model/option.go`.
- Add `controller/console_migrate.go` providing `/api/option/migrate_console_setting` endpoint for one-off data migration.
- Update controllers (`misc`, `option`, `uptime_kuma`) and router to consume namespaced keys `console_setting.*`.
Frontend
- Refactor dashboard pages (`SettingsAPIInfo`, `SettingsAnnouncements`, `SettingsFAQ`, `SettingsUptimeKuma`) and detail page to read/write the new keys.
- Simplify `DashboardSetting.js` state to only include namespaced options.
BREAKING CHANGE: All console-related option keys are now stored under `console_setting.*`. Run the migration endpoint once after deployment to preserve existing data.
Backend
• Introduced `validateExpiredTime` helper in `controller/redemption.go`; reused in both Add & Update endpoints to enforce “expiry time must not be earlier than now”, eliminating duplicated checks
• Removed `RedemptionCodeStatusExpired` constant and all related references – expiry is now determined exclusively by the `expired_time` field for simpler, safer state management
• Simplified `DeleteInvalidRedemptions`: deletes codes that are `used` / `disabled` or `enabled` but already expired, without relying on extra status codes
• Controller no longer mutates `status` when listing or fetching redemption codes; clients derive expiry status from timestamp
Frontend
• Added reusable `isExpired` helper in `RedemptionsTable.js`; leveraged for:
– status rendering (orange “Expired” tag)
– action-menu enable/disable logic
– row styling
• Removed duplicated inline expiry logic, improving readability and performance
• Adjusted toolbar layout: on small screens the “Clear invalid codes” button now wraps onto its own line, while “Add” & “Copy” remain grouped
Result
The codebase is now more maintainable, secure, and performant with no redundant constants, centralized validation, and cleaner UI behaviour across devices.
- Add informative header section to TokensTable with Key icon and description
- Replace generic eye icon with semantic Ticket icon in RedemptionsTable header
- Import additional UI components (Divider, Typography) for better layout structure
- Improve user experience with contextual information about token and redemption functionality
- Maintain consistent styling and layout between both table components
The changes provide users with clear understanding of each table's purpose:
- Tokens: "令牌用于API访问认证,可以设置额度限制和模型权限" with Key icon
- Redemptions: "兑换码可以批量生成和分发,适合用于推广活动或批量充值" with Ticket icon
Front-end enhancements around “Add custom models”:
• EditChannel.js / EditTagModal.js
– Skip models that already exist instead of blocking the action.
– Collect actually inserted items and display:
• Success toast: “Added N models: model1, model2 …”
• Info toast when no new model detected.
– Keeps UX smooth while preserving deduplication logic.
• i18n
– en.json: added keys
• "已新增 {{count}} 个模型:{{list}}"
• "未发现新增模型"
– Fixed a broken JSON string containing smart quotes to maintain valid syntax.
Result:
Users can bulk-paste model names; duplicates are silently ignored and the UI clearly lists what was incrementally appended. All messages are fully internationalised.
Closes#1218
The previous patch lower-cased `group` and `model` when building the
temporary `abilitySet` used to prevent duplicate inserts.
This merged models that differ only by letter case, e.g.
`GPT-3.5-turbo` vs `gpt-3.5-turbo`, causing them to disappear from the
user’s available-models list and pricing page.
Change:
• ability.go – removed all `strings.ToLower` calls when composing the
deduplication key (`group|model`), so duplicates are checked in a
case-sensitive manner while preserving the original data.
Result:
• `GPT-3.5-turbo` and `gpt-3.5-turbo` are now treated as distinct
models throughout the system.
When importing large model lists (≈700+) an attempt to save a channel
could fail with:
Error 1062 (23000): Duplicate entry 'default-DeepSeek-1' for key 'abilities.PRIMARY'
Root cause: AddAbilities / UpdateAbilities inserted the same
(group, model) pair multiple times if the input list contained
duplicates or case-variants (e.g. `default` vs `Default`).
Changes:
• ability.go
– AddAbilities: introduced `abilitySet` to deduplicate by
lower-cased `group|model` key before batch-inserting.
– UpdateAbilities: applied the same deduplication logic when
rebuilding abilities inside a transaction.
Notes:
• The lower-casing is only for set comparison; the original
`group` and `model` values are preserved when persisting to DB,
so case sensitivity of stored data is unchanged.
• Batch chunking logic (lo.Chunk) and performance characteristics
remain unaffected.
Fixes#1215
The User model applies `validate:"max=12"` to the `Username` field, but the
initial setup flow did not validate this constraint. This allowed creation
of a root user with an overly long username (e.g. "Uselessly1344"), which
later caused every update request to fail with:
Field validation for 'Username' failed on the 'max' tag
This patch adds an explicit length check in `controller/setup.go` to reject
usernames longer than 12 characters during setup, keeping validation rules
consistent across the entire application.
Refs: #1214
- Change success message from "通知设置已更新" to "设置保存成功"
- Change error message from "更新通知设置失败" to "设置保存失败"
- Makes messages more generic since the function saves multiple types of settings (notification, pricing, IP logging) not just notification settings
- Add IP field to Log model with database index and default empty value
- Implement conditional IP recording based on user setting in RecordConsumeLog and RecordErrorLog
- Add UserSettingRecordIpLog constant and update user settings API to handle record_ip_log field
- Create dedicated "IP记录" tab in personal settings under "其他设置" section
- Add IP column to logs table with help tooltip explaining recording conditions
- Make IP column visible to all users (not admin-only) with proper filtering for consume/error log types
- Restrict display of use_time and retry columns to consume and error log types only
- Update personal settings UI structure: rename "通知设置" to "其他设置" to accommodate new functionality
- Add proper translation support and maintain consistent styling across components
The IP logging feature is disabled by default and only records client IP addresses
for consume (type 2) and error (type 5) logs when explicitly enabled by users
in their personal settings.
Changes
1. web/src/helpers/token.js
• `fetchTokenKeys` now calls `/api/token/?p=1&size=10` (1-based paging).
• Supports new response shape `{ items, total, page, page_size }`; falls back gracefully if array is returned.
• Filters active tokens from `tokenItems`, not `data` directly.
`useTokenKeys` remains unchanged—its consumer code receives the same list of active keys.
Fix the search button loading state to be consistent with other table components.
The search button now properly shows loading animation when the table data is
being fetched.
Changes:
- Update search button loading prop from `loading={searching}` to
`loading={loading || searching}` in TokensTable.js
- This ensures loading state is shown both when searching with keywords
(searching=true) and when loading default data (loading=true)
- Aligns with the behavior of other table components like ChannelsTable,
UsersTable, and RedemptionsTable
Before: Search button only showed loading when searching with keywords
After: Search button shows loading for all table data fetch operations
- Replace `showTotal` with `formatPageText` in Dashboard table components
- Unify pagination text format to match table components pattern
- Update SettingsAnnouncements.js, SettingsAPIInfo.js, and SettingsFAQ.js
- Change from "共 X 条记录,显示第 Y-Z 条" to "第 Y - Z 条,共 X 条" format
- Ensure consistent user experience across all table components
This change improves UI consistency by standardizing the pagination
text format across Dashboard and table components.
Previously, the uptime status endpoint returned HTTP 400 with
“未配置 Uptime Kuma URL/Slug” when either option was not set, resulting in
frontend error states.
Changes:
• Treat absence of `UptimeKumaUrl` or `UptimeKumaSlug` as a valid scenario.
• Immediately respond with HTTP 200, `success: true`, and an empty `data` array.
• Preserve existing behavior when both options are provided.
This prevents unnecessary error notifications on the dashboard when
Uptime Kuma integration is not configured and improves overall UX.
* Removed `size="middle"` and `centered` props from the column-selector
`Modal` in `ChannelsTable.js` to match the visual style used in
`LogsTable`.
* Re-added `size="middle"` to the main `Table` component to preserve the
original table sizing.
* Ensures consistent UI/UX across both channel and log column settings
modals.
Summary
• Centralized uptime status definition via `uptimeStatusMap`, containing color / label / text for each status.
• Generated `uptimeLegendData`, `getUptimeStatusColor`, `getUptimeStatusText` directly from the map, removing multiple switch-case blocks.
UI Improvements
1. Added statuses 2 (High Latency) & 3 (Maintenance) with dedicated colors.
2. Relocated status legend to a styled footer wrapped in a borderless sub-Card; header now only shows title + refresh button.
3. Footer (and its negative margin) renders only when `uptimeData` is present, preventing empty legend display.
4. Applied rounded, blurred badge style and always-on shadow to legend container for clearer separation.
Maintenance
• Simplified code paths, reduced duplication, and improved readability without breaking existing functionality.
Introduce application uptime monitoring to improve observability and reliability.
• Add UptimeService to track process start time and expose uptime in seconds
• Create /health/uptime endpoint returning the current uptime in JSON format
• Integrate uptime metric into existing health-check middleware
• Update README with instructions for consuming the new endpoint
• Add unit tests covering UptimeService and new health route
This change enables operations teams and dashboards to programmatically
determine how long the service has been running, facilitating automated
alerts and trend analysis.
- Modified returnUrl configuration in RequestEpay function
- Changed payment success redirect path to match updated frontend routing
- Updated controller/topup.go line 116 to use correct callback path
- Add SettingsAnnouncements component with full CRUD operations for system announcements
* Support multiple announcement types (default, ongoing, success, warning, error)
* Include publish date, content, type classification and additional notes
* Implement batch operations and pagination for better data management
* Add real-time preview with relative time display and date formatting
- Add SettingsFAQ component for comprehensive FAQ management
* Support question-answer pairs with rich text content
* Include full editing, deletion and creation capabilities
* Implement batch delete operations and paginated display
* Add validation for complete Q&A information
- Integrate announcement and FAQ modules into DashboardSetting
* Add unified configuration interface in admin console
* Implement auto-refresh functionality for real-time updates
* Add loading states and error handling for better UX
- Enhance backend API support in controller and setting modules
* Add validation functions for console settings
* Include time and sorting utilities for announcement management
* Extend API endpoints for announcement and FAQ data persistence
- Improve frontend infrastructure
* Add new translation keys for internationalization support
* Update utility functions for date/time formatting
* Enhance CSS styles for better component presentation
* Add icons and visual improvements for announcements and FAQ sections
This implementation provides administrators with comprehensive tools to manage
system-wide announcements and user FAQ content through an intuitive console interface.
- Replace IconSearch with Server icon for API info card title to better represent server/API related content
- Add Server imports from lucide-react
This change improves the semantic meaning of icons and provides better visual representation of their respective functionalities.
- Refactor api_info.go to console.go for broader console settings support
- Update URL regex pattern to accept both domain names and IP addresses
- Add support for IPv4 addresses with optional port numbers
- Improve validation to handle formats like http://192.168.1.1:8080
- Add ValidateConsoleSettings function for extensible settings validation
- Maintain backward compatibility with existing ValidateApiInfo function
- Add comprehensive comments explaining supported URL formats
Fixes issue where IP-based URLs were incorrectly rejected as invalid format.
Prepares infrastructure for additional console settings validation.
- Update URL regex pattern to accept both domain names and IP addresses
- Add support for IPv4 addresses with optional port numbers
- Improve validation to handle formats like http://192.168.1.1:8080
- Add comprehensive comments explaining supported URL formats
- Maintain backward compatibility with existing domain-based URLs
Fixes issue where IP-based URLs were incorrectly rejected as invalid format.
Add request deduplication mechanism to prevent duplicate GET requests
to the same endpoint within the same timeframe, significantly reducing
unnecessary network overhead.
**Changes:**
- Add `patchAPIInstance()` function to intercept and deduplicate GET requests
- Implement in-flight request tracking using Map with URL+params as unique keys
- Apply deduplication patch to both initial API instance and `updateAPI()` recreated instances
- Add `disableDuplicate: true` config option to bypass deduplication when needed
**Benefits:**
- Eliminates redundant API calls caused by component re-renders or rapid user interactions
- Reduces server load and improves application performance
- Provides automatic protection against accidental duplicate requests
- Maintains backward compatibility with existing code
**Technical Details:**
- Uses Promise sharing for identical concurrent requests
- Automatically cleans up completed requests from tracking map
- Preserves original axios functionality with minimal overhead
- Zero breaking changes to existing API usage
Addresses the issue observed in EditChannel.js where multiple calls
were made to the same endpoints during component lifecycle.
- Remove IconForward import from @douyinfe/semi-icons
- Add Route icon import from lucide-react
- Update model redirection indicator in LogsTable component
The Route icon better represents the concept of model redirection
compared to the generic forward arrow, providing clearer visual
context for users when models are mapped to different upstream models.
- Hide scrollbars for .semi-layout, .semi-layout-content, and .semi-sider
- Set scrollbar width and height to 0 for webkit browsers
- Add cross-browser scrollbar hiding support (webkit, firefox, IE/Edge)
- Change Content container overflow from 'auto' to 'hidden' on desktop
- Remove redundant scrollbar styling (thumb, hover, track styles)
This ensures that all semi-layout related components have no visible
scrollbars and prevents vertical scrolling functionality entirely.
Files modified:
- web/src/index.css
- web/src/components/layout/PageLayout.js
- Remove system name display from homepage title
- Replace with unified gateway branding: "统一的大模型接口网关"
- Add subtitle highlighting key benefits: price, stability, no subscription
- Implement language-specific title rendering:
- English: Two-line layout ("The Unified" / "LLMs API Gateway")
- Chinese: Single-line layout for better readability
- Increase title font sizes for better visual hierarchy
- Adjust vertical padding for improved centering
- Enhance overall visual appeal and user experience
This update modernizes the homepage presentation and provides better
localization support for different language preferences.
- Convert copy button to Input suffix for cleaner UI design
- Add responsive grid layout for balance cards and preset amounts
- Mobile (< md): single column layout for better readability
- Desktop (>= md): multi-column layout for space efficiency
- Implement bottom fixed payment panel on mobile devices
- Fixed positioning for easy access to payment options
- Includes custom amount input and payment method buttons
- Auto-hide on desktop to maintain original layout
- Improve mobile payment flow with sticky bottom controls
- Add proper spacing to prevent content overlap with fixed elements
- Maintain consistent functionality across all breakpoints
This update significantly improves the mobile user experience by making
payment controls easily accessible without scrolling, while preserving
the desktop layout and functionality.
- Replace local isDarkMode state with global useTheme hook in TopUp component
- Replace local isDarkMode state with global useTheme hook in PersonalSetting component
- Remove redundant theme detection useEffect hooks that caused state inconsistency
- Update theme condition checks from isDarkMode to theme === 'dark'
- Fix issue where components showed dark gradients in light mode due to theme state mismatch
- Clean up trailing commas in import statements
This ensures all components stay synchronized with the global theme system managed by HeaderBar's theme toggle button.
Move validateApiInfo and getApiInfo functions from controller layer to
setting/api_info.go to improve code organization and separation of concerns.
Changes:
- Create setting/api_info.go with ValidateApiInfo() and GetApiInfo() functions
- Remove validateApiInfo function from controller/option.go
- Remove getApiInfo function from controller/misc.go
- Update function calls to use setting package
- Clean up unused imports (net/url, regexp, fmt) in controller/option.go
This refactoring aligns the API info configuration management with the
existing pattern used by other setting modules (chat.go, group_ratio.go,
rate_limit.go, etc.) and improves code reusability and maintainability.
- Add speed test tag with gauge icon for each API route
- Integrate tcptest.cn service for API endpoint performance testing
- Implement handleSpeedTest callback to open speed test in new tab
- Add Tag component import from @douyinfe/semi-ui
- Use Gauge icon with white circular tag styling
- Position speed test tag before API route for better visibility
- URL encoding handles special characters for proper test URL generation
- Remove unused IconTestScoreStroked import and clean up comments
The speed test feature allows users to quickly test API endpoint
performance by clicking a small circular tag that opens the
tcptest.cn speed testing service with the encoded API URL.
- Restructure API info card layout to use two-column design
- Move avatar to separate left column with fixed width
- Align route name, URL, and description text to same starting position
- Remove unnecessary indentation and improve visual hierarchy
- Enhance readability and consistency of API information display
- Add min-w-[120px] class to Form.Select component for log type filtering
- Remove redundant min-width constraint from parent div container
- Ensure consistent dropdown width across different screen sizes
- Improve UI consistency and readability for log type selection
- Move Form.Select (log type selector) from grid layout to action button row
- Position log type selector on the left side of the action button area
- Keep action buttons (Query, Reset, Column Settings) aligned to the right
- Implement responsive design with sm: breakpoint (640px)
- Mobile: vertical stacking with full-width elements
- Desktop: horizontal layout with proper spacing
- Add min-width constraint (140px) for log type selector
- Remove extra padding-top from button area for cleaner spacing
- Maintain accessibility and usability across all screen sizes
This change improves the UI layout by better utilizing horizontal space
and providing a more intuitive grouping of form controls and actions.
- **Code Organization & Architecture:**
- Restructured component with clear sections (Hooks, Constants, Helper Functions, etc.)
- Added comprehensive code organization comments for better maintainability
- Extracted reusable helper functions and constants for better separation of concerns
- **Performance Optimizations:**
- Implemented extensive use of useCallback and useMemo hooks for expensive operations
- Optimized data processing pipeline with dedicated processing functions
- Memoized chart configurations, performance metrics, and grouped stats data
- Cached helper functions like getTrendSpec, handleCopyUrl, and modal handlers
- **UI/UX Enhancements:**
- Added Empty state component with construction illustrations for better UX
- Implemented responsive grid layout with conditional API info section visibility
- Enhanced button styling with consistent rounded design and hover effects
- Added mini trend charts to statistics cards for visual data representation
- Improved form field consistency with reusable createFormField helper
- **Feature Improvements:**
- Added self-use mode detection to conditionally hide/show API information section
- Enhanced chart configurations with centralized CHART_CONFIG constant
- Improved time handling with dedicated helper functions (getTimeInterval, getInitialTimestamp)
- Added comprehensive performance metrics calculation (RPM/TPM trends)
- Implemented advanced data aggregation and processing workflows
- **Code Quality & Maintainability:**
- Extracted complex data processing logic into dedicated functions
- Added proper prop destructuring and state organization
- Implemented consistent naming conventions and helper utilities
- Enhanced error handling and loading states management
- Added comprehensive JSDoc-style comments for better code documentation
- **Technical Debt Reduction:**
- Replaced repetitive form field definitions with reusable components
- Consolidated chart update logic into centralized updateChartSpec function
- Improved data flow with better state management patterns
- Reduced code duplication through strategic use of helper functions
This refactor significantly improves component performance, maintainability, and user experience while maintaining backward compatibility and existing functionality.
- Remove example image and right-side image section for cleaner layout
- Center all content vertically and horizontally on the page
- Implement comprehensive responsive design using Tailwind CSS breakpoints
- Typography scales from text-3xl to xl:text-6xl across screen sizes
- Spacing and padding adjust dynamically (py-12 to lg:py-20)
- Icon grid adapts from gap-3 to lg:gap-8
- Keep action buttons horizontally aligned on all screen sizes
- Add play icon to "Get Started" button for better UX
- Refactor version display logic:
- Show version tag only in demo site mode
- Replace GitHub button text with version number in demo mode
- Add docs button with same logic as HeaderBar when not in demo mode
- Optimize icon layout with consistent 40px size and responsive containers
- Improve overall mobile-first responsive design from 320px to 1280px+ screens
- Remove colorful gradient backgrounds from dashboard panel headers in Detail page
- Replace custom header styling with default Semi-UI card title styling
- Remove background images and gradient overlays from all authentication pages
- Simplify authentication page layouts with clean gray backgrounds
- Update title text colors from white to dark gray for better contrast
- Remove unnecessary z-index layering and complex positioning
- Clean up unused background image imports
This change creates a more professional and consistent visual appearance
across the application by removing distracting visual elements.
Add consistent empty state handling across all table components to improve
user experience when search/filter results are empty.
Changes:
- Import Empty component and IllustrationNoResult/IllustrationNoResultDark from @douyinfe/semi-ui
- Add empty prop to Table components with "搜索无结果" message
- Support both light and dark theme illustrations
- Apply internationalization support for empty state text
Affected files:
- web/src/components/table/MjLogsTable.js
- web/src/components/table/LogsTable.js
- web/src/components/table/ChannelsTable.js
- web/src/components/table/RedemptionsTable.js
- web/src/components/table/TaskLogsTable.js
- web/src/components/table/TokensTable.js
- web/src/components/table/UsersTable.js
- web/src/components/table/ModelPricing.js
This ensures consistent UX across all table components when no data
matches the current search or filter criteria.
Add visual icons to improve user experience and section identification:
- Import lucide-react icons: Wallet, Activity, Zap, Gauge, PieChart
- Add Wallet icon to "Account Data" section
- Add Activity icon to "Usage Statistics" section
- Add Zap icon to "Resource Consumption" section
- Add Gauge icon to "Performance Metrics" section
- Add PieChart icon to "Model Data Analysis" card
All icons are styled with 16px size and proper flex layout with consistent spacing. Icons inherit parent text color for seamless integration with existing gradient headers.
- Replace IconList with Tags icon from lucide-react for better semantic representation
- Update renderTagType function to use Tags icon instead of list icon
- Remove unused IconList import from semi-icons
- Improve visual clarity for tag aggregation feature in channels table
The Tags icon better represents the concept of multiple tags being aggregated
together, providing more intuitive user experience in the channels management
interface.
- Add semantic icons to ChannelsTable.js for channel status, response time, and quota display
- Add status and quota icons to TokensTable.js for better visual distinction
- Add status and quota icons to RedemptionsTable.js for redemption code management
- Add role, status, and statistics icons to UsersTable.js for user management
- Import appropriate lucide-react icons for each table component
- Enhance UI consistency and user experience across all table interfaces
Icons added include:
- Status indicators: CheckCircle, XCircle, AlertCircle, HelpCircle
- Performance metrics: Zap, Timer, Clock, AlertTriangle, TestTube
- Financial data: Coins, DollarSign
- User roles: User, Shield, Crown
- Activity tracking: Activity, Users, UserPlus
This improves visual clarity and makes table data more intuitive to understand.
Fix inconsistent loading state behavior where search buttons in ChannelsTable,
RedemptionsTable, and UsersTable didn't display loading animation when tables
were loading data, unlike LogsTable which handled this correctly.
Changes:
- Fix ChannelsTable searchChannels function to properly manage loading state
- Move setSearching(true) to function start and use try-finally pattern
- Ensure loading state is set for both search and load operations
- Update search button loading prop in ChannelsTable: loading={searching} → loading={loading || searching}
- Update search button loading prop in RedemptionsTable: loading={searching} → loading={loading || searching}
- Update search button loading prop in UsersTable: loading={searching} → loading={loading || searching}
This ensures search buttons show loading state consistently when:
- Table is loading data (initial load, pagination, operations)
- Search operation is in progress
All table components now provide unified UX behavior matching LogsTable,
preventing duplicate clicks and clearly indicating system state to users.
- Refactor LogsTable, MjLogsTable, TokensTable, UsersTable, and ChannelsTable to use Semi-UI Form components
- Replace individual input state management with centralized Form API
- Add form validation and consistent form handling across all tables
- Implement auto-search functionality with proper state update timing
- Add reset functionality to clear all search filters
- Improve responsive layout design for better mobile experience
- Remove duplicate form initial values and consolidate form logic
- Remove column visibility feature from ChannelsTable to simplify UI
- Standardize search form structure and styling across all table components
- Fix state update timing issues in search functionality
- Add proper form submission handling with loading states
BREAKING CHANGE: Form state management has been completely rewritten.
All table components now use Form API instead of individual useState hooks.
Column visibility settings for ChannelsTable have been removed.
- Refactor Form component to use Semi Design best practices
- Remove duplicate initValues configuration for DatePicker
- Add real-time value change monitoring with onValueChange
- Implement auto-search functionality for log type selector changes
- Fix state synchronization issues causing stale values in search requests
- Optimize form layout with proper vertical layout configuration
- Enhance user experience with placeholders, clear buttons, and search icons
- Remove logType parameter passing to prevent async state update conflicts
- Ensure all form controls use latest values from formApi instead of stale state
- Add proper validation triggers and error handling configuration
- Improve reset button logic with proper timing for form state updates
The changes resolve the issue where users needed to select log type twice
for the search request to use the correct value, and ensure all form
interactions provide immediate and accurate results.
Update text link styling in EditTagModal.js to match the consistent design
pattern used in EditChannel.js. Changed className from 'text-blue-500 cursor-pointer'
to '!text-semi-color-primary cursor-pointer' for template-related action links
("填入模板", "清空重定向", "不更改").
This change ensures:
- Visual consistency across channel editing components
- Better theme adaptability using Semi Design color variables
- Adherence to established design patterns in the codebase
Files modified:
- web/src/pages/Channel/EditTagModal.js
When creating tokens, if the user doesn't provide a token name (empty or whitespace-only),
the system will now automatically generate a name using the format "default-xxxxxx" where
"xxxxxx" is a 6-character random alphanumeric string.
This enhancement ensures that all created tokens have meaningful names and improves the
user experience by removing the requirement to manually input token names for quick token
creation scenarios.
Changes:
- Modified token creation logic to detect empty token names
- Added automatic fallback to "default" base name when user input is missing
- Maintained existing behavior for multiple token creation with random suffixes
- Ensured consistent naming pattern across single and batch token creation
- Add rounded-full class to "查看图片" (View Image) button for consistent UI styling
- All other buttons in both MjLogsTable.js and TaskLogsTable.js already have rounded corners applied
- Ensures uniform button styling across the log tables interface
- Add explicit import of '@douyinfe/semi-ui/dist/css/semi.css' in index.js
- Ensures Semi Design components render with proper styling
- Resolves issue where Semi components appeared unstyled after dependency updates
This change addresses the style loading issue that occurred after adding antd
dependency and updating the build configuration. The explicit import ensures
consistent style loading regardless of plugin behavior changes.
- Import IconCopy from semi-icons for copy functionality
- Replace onClick handler with suffix copy button to fix disabled input issue
- Use borderless tertiary button as input suffix for better alignment
- Update notification messages formatting (colon spacing)
- Ensure password copying works even when input field is disabled
- Replace error message div with Semi UI Banner component for better UX
- Add rounded corners to Banner component with !rounded-lg class
- Fix Form.Input not displaying values by implementing proper formApi usage
- Use getFormApi callback to obtain form API instance
- Replace manual value props with formApi.setValues() for dynamic updates
- Set proper initValues for form initialization
- Remove unused Input import and console.log statements
- Clean up debugging code and optimize form state management
This change enhances the visual consistency with Semi Design system
and resolves the issue where email field was not showing URL parameter values.
- Fix input field display issues in password reset confirmation page
* Replace `readOnly` with `disabled={true}` for proper field state
* Improve URL parameter parsing and state management
* Add proper null checks and fallback values
- Enhance user experience and error handling
* Add validation for invalid reset links
* Display appropriate error messages and placeholders
* Add debug logging for troubleshooting
* Improve button states and loading indicators
- Improve password reset form validation
* Add proper email input validation with error messages
* Enhance user feedback for empty email submissions
- Add missing English translations
* Add i18n support for new UI text strings
* Ensure proper internationalization coverage
The password reset confirmation page now correctly displays email addresses
from URL parameters and prevents user input as intended. Error handling
has been improved to provide better user guidance when reset links are
invalid or malformed.
Fixes: Password reset input fields showing empty and allowing user input
when they should display email/password and be read-only.
- Replace inline loading UI in OAuth2Callback with shared Loading component
- Add internationalization support using useTranslation hook
- Translate all hardcoded Chinese strings to support multiple languages
- Remove unused processing state variable
- Maintain consistent loading experience across the application
- Support dynamic text content for retry attempts with parameter interpolation
- Replace Banner with full-screen Spin component for better loading UX
- Add English translation for "正在跳转..." ("Redirecting...")
- Integrate i18next translation hook in Chat page component
- Remove unused useEffect import for cleaner code
The Chat page now shows a centered full-screen loading spinner instead of
a banner when redirecting, providing a more consistent and professional
user experience. The loading text is now properly internationalized and
will display "Redirecting..." in English and "正在跳转..." in Chinese.
**Changes:**
- Unify link color styling across EditChannel.js by replacing `text-blue-500` with consistent primary color scheme
- Apply `!text-semi-color-primary hover:!text-semi-color-primary-hover transition-colors` to all template fill and documentation links
- Update documentation URL from Calcium-Ion repository to QuantumNous repository
- Add smooth hover transitions and consistent visual feedback for all clickable links
**Affected Elements:**
- Model mapping template fill link
- Deployment region template fill link
- Channel settings template fill link
- Channel settings documentation link
- Status code mapping template fill link
**Benefits:**
- Consistent visual design language across the entire application
- Improved user experience with unified link styling
- Better accessibility with clear hover states and transitions
- Correct documentation references pointing to the current project repository
**Technical Details:**
- Maintains existing functionality while improving visual consistency
- Links now match the color scheme used in About page and Footer components
- Smooth color transitions enhance user interaction feedback
Set a minimum width of 200px for progress components in both MjLogsTable.js and TaskLogsTable.js to ensure consistent display and prevent them from becoming too narrow when table resizes.
The Table component in LogsTable.js was previously showing expand icons for all rows, even those without any expandable content. This led to a confusing UX where users could click to expand rows but would see empty content.
This commit adds the `rowExpandable` property to the Table configuration to ensure that only rows with actual expandable content show the expand icon and can be expanded. The function checks if each record has corresponding data in the expandData object before allowing it to be expanded.
Standardize the scrollbar appearance of semi-sidesheet-body to match the existing semi-table-body style. This change:
- Sets scrollbar width to 6px
- Applies light gray color (rgba(var(--semi-grey-2), 0.3))
- Adds subtle hover effect
- Uses 2px border radius for consistency
- Improves overall UI cohesion across components
Previously, the notice modal would automatically show every day even when
the notice content was empty, causing unnecessary user interruption.
This commit modifies the logic to:
- Check notice content before showing the modal
- Only display the modal when notice content exists and is not empty
- Add proper error handling to prevent modal showing on API failures
- Improve user experience by avoiding empty notice interruptions
Changes:
- Modified useEffect in Home component to fetch notice content first
- Added API call to /api/notice before setting noticeVisible state
- Added try-catch block for graceful error handling
- Only show modal when notice data is truthy and non-empty after trimming
Implement rowExpandable property to control which rows can be expanded
in the logs table. Rows are now only expandable when they have actual
expand data content, preventing empty expansion sections from being
displayed to users.
- Add rowExpandable function to check if expandData exists and has content
- Improve user experience by hiding expand functionality for rows without details
- Maintain existing expand behavior for rows with valid expansion data
- Extended OpenAI model filter to include o1, o3, and o4 series models
- Updated model categorization logic to properly classify reasoning models
- Ensures all OpenAI model variants (o1-mini, o1-preview, o3, o4, etc.) are correctly grouped under OpenAI category
- Maintains backward compatibility with existing GPT and other OpenAI model series
Enhance table scrollbar visual design with lighter and thinner styling for better user experience.
Changes:
- Add custom scrollbar styling for .semi-table-body
- Set scrollbar dimensions to 6px width/height
- Apply lighter color using rgba(var(--semi-grey-2), 0.3) with 30% opacity
- Add hover effect with 50% opacity for better interaction feedback
- Use 2px border radius for smoother appearance
- Keep scrollbar track transparent for clean look
- Utilize Semi Design color variables for theme consistency
The new scrollbar design provides a more elegant and less intrusive horizontal scrolling experience across all data tables.
Fix the last column (operation/detail columns) to the right side across all table components to improve user experience and ensure important actions remain visible during horizontal scrolling.
Changes:
- ChannelsTable.js: Fix operation column to right
- UsersTable.js: Fix operation column to right
- TokensTable.js: Fix operation column to right
- RedemptionsTable.js: Fix operation column to right
- LogsTable.js: Fix details column to right
- MjLogsTable.js: Fix fail reason column to right
- TaskLogsTable.js: Fix fail reason column to right
All tables now have their rightmost column fixed using Semi Design's `fixed: 'right'` property, ensuring critical information and actions are always accessible regardless of table scroll position.
Update Footer component to use semantic color variables for better theme integration:
- Replace hardcoded background color with semi-color-bg-2 for theme consistency
- Update text colors to use semantic variables (semi-color-text-0, semi-color-text-1)
- Replace hardcoded link colors with semi-color-primary for brand consistency
- Add hover effects with smooth transitions for better user experience
- Keep logo container background as gray-800 for visual stability
This ensures the footer adapts properly to different theme modes while maintaining
good readability and visual consistency across the application.
Add fallback display value when system_name is not available or empty.
This ensures the homepage title always shows meaningful content instead
of being blank when the system name hasn't been configured or fails to load.
- Update Home component to display "New API" as default when statusState?.status?.system_name is falsy
- Improves user experience by preventing empty title display
Fix dark mode background color rendering issue in the footer component
where the custom dark background color (#1C1F23) was not being applied
consistently across different devices due to missing !important declaration.
Changes:
- Add !important to dark mode background color class in footer
- Change `dark:bg-[#1C1F23]` to `dark:!bg-[#1C1F23]`
- Ensure footer dark mode styling is not overridden by other CSS rules
This resolves visual inconsistencies where the footer would not display
the intended dark background color in dark theme mode on certain devices
or screen configurations.
Fix background color rendering issues for notification bell, theme toggle,
and language switcher buttons in the header bar. These buttons were missing
!important declarations in their CSS classes, causing inconsistent styling
across different devices where other styles could override the intended
background colors.
Changes:
- Add !important to background color classes for notification button
- Add !important to background color classes for theme toggle button
- Add !important to background color classes for language switcher button
- Ensure all header action buttons now have consistent styling matching
the user avatar dropdown button
This resolves visual inconsistencies where these buttons would appear
without proper background colors on certain devices or screen configurations.
- Consolidate 8 individual stat cards into 4 grouped cards:
* Account Data (Current Balance, Historical Consumption)
* Usage Statistics (Request Count, Statistics Count)
* Resource Consumption (Statistics Quota, Statistics Tokens)
* Performance Metrics (Average RPM, Average TPM)
- Add gradient header backgrounds with white text for card titles:
* Blue gradient for Account Data
* Green gradient for Usage Statistics
* Yellow gradient for Resource Consumption
* Pink gradient for Performance Metrics
- Implement mini trend charts using real API data:
* Replace mock data with actual time-series data from API
* Hide x and y axes to show pure trend lines
* Display trends only for metrics with available historical data
* Remove trend charts for Current Balance, Historical Consumption, and Request Count
- Merge model analysis charts into single card:
* Combine "Model Consumption Distribution" and "Model Call Count Ratio"
* Use responsive grid layout (vertical on mobile, horizontal on desktop)
* Update card title to "Model Data Analysis"
- Optimize chart configurations:
* Hide axes, legends, and tooltips for mini trend charts
* Maintain color consistency between metrics and trend lines
* Improve performance by processing all trend data in single API call
This commit improves the codebase structure by:
- Moving all inline styles from SiderBar.js to CSS classes in index.css
- Organizing CSS with clear section comments for better maintainability
- Removing unused imports and components
- Improving sidebar design with cleaner styling and consistent color management
- Restructuring CSS to group related styles together
- Adjusting sidebar width from 200px to 180px
- Replacing Text components with semantic divs for group labels
- Creating a color management function for sidebar icons
Improve the model list section in PersonalSetting component with the following enhancements:
- Add category-based tabs for filtering models by provider (OpenAI, Anthropic, etc.)
- Implement skeleton loading states using Semi UI components
- Add empty state illustrations when no models are available
- Use Semi UI design tokens for consistent styling
- Optimize display for both expanded and collapsed model lists
- Simplify some button text labels for better UI consistency
* feat: support claude cache for upstream [OpenRouter]
* feat: support claude thinking for upstream [OpenRouter]
* feat: reasoning is common params for OpenRouter
Move the Turnstile verification component from the renderOAuthOptions method to the main render function in both LoginForm and RegisterForm components. This ensures the Turnstile verification is globally visible and accessible regardless of which authentication method the user chooses (email login/register or third-party OAuth options).
The change improves UI consistency and ensures the verification mechanism works properly across all authentication flows.
Replace the main card icon in ModelPricing component with IconLayers to better represent the model catalog functionality. Increase icon size from 'large' to 'extra-large' for improved visibility and visual hierarchy.
This change enhances the user interface by using more appropriate iconography and giving the primary navigation elements greater emphasis.
This commit improves the model display interface with several enhancements:
1. Add model count badges to each category tab and dropdown menu item
2. Highlight active category with red badge and use grey for inactive ones
3. Optimize performance by caching category counts with useMemo
4. Standardize model tag rendering across components:
- Replace direct Tag component with centralized renderModelTag function
- Update renderModelTag to use stringToColor for consistent coloring
- Remove redundant color calculations in LogsTable
These changes improve the UI by providing users with visual cues about model distribution across categories while ensuring consistent styling throughout the application.
Refactor model tag rendering to ensure consistency throughout the application:
- Replace direct Tag component in ModelPricing with centralized renderModelTag function
- Update renderModelTag in render.js to use stringToColor for consistent color generation
- Remove redundant stringToColor calls in LogsTable.js renderModelName function
This change improves UI consistency by ensuring all model tags have the same styling, iconography, and color generation logic. Model tags now automatically display appropriate vendor icons based on the model name pattern.
Fix JSON unmarshal error that occurred when copying channels after testing. The JavaScript timestamp (floating point number) in the test_time field was causing type conversion errors in Go backend which expected an int64.
Solution:
- Create deep copy of channel record instead of modifying original
- Remove test_time and response_time fields before sending to backend
- Allow backend to use default values for these fields
Error fixed: "json: cannot unmarshal number into Go struct field Channel.test_time of type int64"
Improve the logs table by implementing brand-specific model icons and better
redirection visualization:
- Replace standard tags with `renderModelTag` to display appropriate brand
icons for each model (OpenAI, Claude, Gemini, etc.)
- Fix background colors by explicitly passing color parameters
- Restore descriptive text for model redirection in popover
- Replace refresh icon with forward icon for better representation of model
redirection
- Clean up unused imports
This change provides a more intuitive visual representation of models and
their relationships, making the logs table easier to understand at a glance.
This commit removes all fixed width constraints from the model pricing table columns, allowing them to naturally expand and adjust based on content. This improves the table's responsiveness and ensures better space utilization across different screen sizes.
This commit refactors the login and registration forms to enhance user experience by conditionally displaying OAuth-related UI elements.
- In `LoginForm.js` and `RegisterForm.js`:
- The "Other login/registration options" button and the "or" divider are now only displayed if at least one OAuth provider is enabled in the system settings.
- This change ensures a cleaner interface when no OAuth options are configured, preventing user confusion.
- In `RegisterForm.js`:
- Changed `div` class from `relative` to `min-h-screen relative` to ensure the registration form an take up the entire screen height.
- Refactored system initialization page using TailwindCSS 3 and SemiUI components
- Changed layout from step navigation to single page display for all configurations
- Modified top area from vertical to more compact horizontal layout
- Updated gradient color scheme from blue/purple to orange/pink
- Fixed form field name duplication issues and optimized Form implementation
- Changed usage mode selection from three-column grid to vertical layout
- Replaced usage mode card icons from settings to more appropriate Layers icon
- Added specific prompts for different database types (SQLite/MySQL/PostgreSQL)
- Removed configuration summary section while keeping the initialization button
- Fixed useSetupCheck issue by using SetupCheck as a direct component for proper redirection
- Added support for multiple platforms (linux/amd64, linux/arm64) in docker-image-alpha.yml.
- Removed outdated docker-image-amd64.yml and docker-image-arm64.yml workflows.
- Deleted linux-release.yml, macos-release.yml, and windows-release.yml as part of workflow cleanup.
Fix ReferenceError caused by undefined `isValidMessage` and `MESSAGE_ROLES`
in the buildApiPayload function within api.js.
Changes:
- Add missing `isValidMessage` import from utils.js
- Add missing `MESSAGE_ROLES` import from playground constants
- Consolidate duplicate `formatMessageForAPI` import
- Clean up import statements organization
Resolves: ReferenceError: isValidMessage is not defined at buildApiPayload (api.js:39:13)
- Remove automatic insertion of "你好" placeholder message in preview payload
- Keep messages array empty when no user messages exist in conversation
- Only process image handling logic when user messages are present
- Ensure preview request body accurately reflects current conversation state
Previously, the preview panel would automatically inject a default "你好"
user message when the conversation was empty, which could be misleading.
This change ensures the preview payload shows exactly what would be sent
based on the current conversation state, improving accuracy and user
understanding of the actual API request structure.
- Add clear context button positioned on the left side of input area
- Create symmetric layout with clear button (left) and send button (right)
- Standardize both buttons to 32x32px size for consistent appearance
- Apply distinct styling: gray background for clear (red on hover), purple for send
- Add smooth transition animations for better user experience
- Align buttons vertically centered for improved visual balance
The clear conversation button provides quick access to context clearing
functionality directly from the input area, matching the design patterns
shown in Semi Design documentation and improving overall user workflow.
- Add onMessageReset reference comparison to OptimizedMessageActions memo
- Force component re-render when model selection changes
- Prevent stale closure issue in retry functionality
- Ensure first retry attempt uses newly selected model
Previously, when changing the model selection, the retry button would
still use the previous model due to React memo optimization preventing
re-renders. By comparing the onMessageReset callback reference, the
component now properly updates when the model changes, ensuring the
retry functionality immediately uses the currently selected model.
- Store editing message object reference using useRef to avoid ID conflicts
- Use object reference comparison first before falling back to ID matching
- Apply fix to both save and cancel operations in message editing
- Clear reference after edit completion to prevent stale object issues
Previously, when editing imported messages that contained duplicate IDs,
the findIndex operation would match the first occurrence rather than the
intended message, causing conversation history truncation when saving
edits. This change stores and uses object references for accurate message
identification during the editing process.
- Use object reference comparison first before falling back to ID matching
- Prevent incorrect message index lookup when duplicate IDs exist
- Apply fix to both handleMessageReset and handleMessageDelete functions
- Maintain backward compatibility with ID-based message identification
Previously, when importing messages that contained duplicate IDs, the
findIndex operation would match the first occurrence rather than the
intended message, causing history truncation on retry. This change uses
object reference comparison as the primary method, ensuring accurate
message identification and preserving conversation history.
- Extend handleMessageReset condition to include 'system' role messages
- Allow system messages to trigger regeneration like assistant messages
- Fix disabled retry button issue when message role is switched to system
- Maintain consistent user experience across different message roles
Previously, when an assistant message was switched to system role,
the retry button became non-functional. This change ensures that
system messages can be regenerated by finding the previous user
message and resending it, maintaining feature parity with assistant
messages.
- Add multi-dimensional animation with translateY, scale, and blur transforms
- Introduce 60% keyframe for smoother animation progression
- Extend animation duration from 0.4s to 0.6s for better visual impact
- Apply cubic-bezier(0.22, 1, 0.36, 1) easing for more natural motion
- Add will-change property to optimize rendering performance
- Improve perceived responsiveness during AI response streaming
The enhanced animation now provides a more polished and engaging user
experience when AI responses are being streamed, with text appearing
smoothly from bottom-up with subtle scaling and blur effects.
**Problem 1: Chat interface not refreshing when resetting imported messages**
- The "reset messages simultaneously" option during config import failed to
update the chat interface properly
- Normal conversation resets worked correctly
**Problem 2: Messages stuck in loading state after page refresh**
- When AI was generating a response and user refreshed the page, the message
remained in loading state indefinitely
- Stop button had no effect on these orphaned loading messages
**Changes Made:**
1. **Fixed config reset message refresh** (`usePlaygroundState.js`):
```javascript
// Clear messages first, then set defaults to force component re-render
setMessage([]);
setTimeout(() => {
setMessage(DEFAULT_MESSAGES);
}, 0);
```
2. **Enhanced stop generator functionality** (`useApiRequest.js`):
```javascript
// Handle orphaned loading messages even without active SSE connection
const onStopGenerator = useCallback(() => {
// Close active SSE if exists
if (sseSourceRef.current) {
sseSourceRef.current.close();
sseSourceRef.current = null;
}
// Always attempt to complete any loading/incomplete messages
// ... processing logic
}, [setMessage, applyAutoCollapseLogic, saveMessages]);
```
3. **Added automatic message state recovery** (`usePlaygroundState.js`):
```javascript
// Auto-fix loading/incomplete messages on page load
useEffect(() => {
const lastMsg = message[message.length - 1];
if (lastMsg.status === MESSAGE_STATUS.LOADING ||
lastMsg.status === MESSAGE_STATUS.INCOMPLETE) {
// Process incomplete content and mark as complete
// Save corrected message state
}
}, []);
```
**Root Cause:**
- Config reset: Direct state assignment didn't trigger component refresh
- Loading state: No recovery mechanism for interrupted SSE connections after refresh
**Impact:**
- ✅ Config reset now properly refreshes chat interface
- ✅ Stop button works on orphaned loading messages
- ✅ Page refresh automatically recovers incomplete messages
- ✅ No more permanently stuck loading states
When using the "reset messages simultaneously" option during config import,
the conversation messages in the chat interface were not being properly reset,
while normal conversation resets worked correctly.
**Changes:**
- Modified `handleConfigReset` in `usePlaygroundState.js` to clear messages
before setting default examples
- Added asynchronous message update to force Chat component re-render
- Ensures immediate UI refresh when resetting imported conversation data
**Root Cause:**
The direct assignment to DEFAULT_MESSAGES didn't trigger a complete
component refresh, causing the chat interface to display stale data.
**Solution:**
```javascript
// Before
setMessage(DEFAULT_MESSAGES);
// After
setMessage([]);
setTimeout(() => {
setMessage(DEFAULT_MESSAGES);
}, 0);
```
This two-step approach forces the Chat component to unmount and remount
with fresh data, resolving the display inconsistency.
- Modify saveMessagesImmediately to accept messages parameter
- Pass updated message list to all save calls instead of relying on closure
- Ensure complete message history is saved including the last message
- Fix timing issue where old message state was being saved
This fixes the issue where the last conversation was not being persisted to localStorage.
- Move useEffect hooks before conditional returns in MessageContent and ThinkingContent
- Ensure hooks are called in the same order every render
- Fix "Rendered fewer hooks than expected" error when API returns non-200 status
- Follow React hooks rules: only call hooks at the top level
This prevents the entire page from crashing when API requests fail.
- Refactor message saving strategy from automatic to manual saving
- Save messages only on key operations: send, complete, edit, delete, role toggle, clear
- Prevent frequent localStorage writes during streaming responses
- Remove excessive console logging
- Remove all console.log statements from save/load operations
- Clean up debug logs to reduce console noise
- Optimize initial state loading with lazy initialization
- Replace useRef with useState lazy initialization for config and messages
- Ensure loadConfig and loadMessages are called only once on mount
- Prevent redundant localStorage reads during re-renders
- Update hooks to support new save strategy
- Pass saveMessages callback through component hierarchy
- Add saveMessagesImmediately to relevant hooks (useApiRequest, useMessageActions, useMessageEdit)
- Trigger saves at appropriate lifecycle points
This significantly improves performance by reducing localStorage I/O operations
from continuous writes during streaming to discrete saves at meaningful points.
Summary
This commit addresses two critical issues affecting the real-time chat experience in the Playground:
1. Optimized re-rendering of reasoning content
• Added `reasoningContent` to the comparison function of `OptimizedMessageContent` (`web/src/components/playground/OptimizedComponents.js`).
• Ensures the component re-renders while reasoning text streams, resolving the bug where only the first characters (“好,”) were shown until the stream finished.
2. Defensive checks for SSE message updates
• Added early-return guards in `streamMessageUpdate` (`web/src/hooks/useApiRequest.js`).
• Skips updates when `lastMessage` is undefined or the last message isn’t from the assistant, preventing `TypeError: Cannot read properties of undefined (reading 'status')` during rapid SSE responses.
Impact
• Real-time reasoning content now appears progressively, enhancing user feedback.
• Eliminates runtime crashes caused by undefined message references, improving overall stability.
- Remove duplicate thinking content rendering logic from MessageContent component
- Import and utilize ThinkingContent component for consistent thinking display
- Clean up unused icon imports (ChevronRight, ChevronUp, Brain)
- Consolidate "思考中..." header text logic into single component
- Reduce code duplication by ~70 lines while maintaining all functionality
- Improve component separation of concerns and maintainability
The MessageContent component now delegates thinking content rendering to the
dedicated ThinkingContent component, eliminating the previously duplicated
UI logic and state management for thinking processes.
- Add consistent title section with gradient icon and heading
- Include close button in mobile view for better UX consistency
- Standardize mobile and desktop ConfigManager styling
- Adjust layout structure and padding for visual alignment
- Use Settings icon with purple-to-pink gradient to match design system
This change ensures both SettingsPanel and DebugPanel have identical
header layouts and interaction patterns across all screen sizes.
## Breaking Changes
- Remove backward compatibility layer for old action types
- StyleContext is no longer exported, use useStyle hook instead
## Major Improvements
- **Architecture**: Replace useState with useReducer for complex state management
- **Performance**: Add debounced resize handling and batch updates via BATCH_UPDATE action
- **DX**: Export useStyle hook and styleActions for type-safe usage
- **Memory**: Use useMemo to cache context value and prevent unnecessary re-renders
## Bug Fixes
- **UI**: Eliminate padding flicker when navigating to /console/chat* and /console/playground routes
- **Logic**: Remove redundant localStorage operations and state synchronization
## Implementation Details
- Define ACTION_TYPES and ROUTE_PATTERNS constants for better maintainability
- Add comprehensive JSDoc documentation for all functions
- Extract custom hooks: useWindowResize, useRouteChange, useMobileSiderAutoHide
- Calculate shouldInnerPadding directly in PageLayout based on pathname to prevent async updates
- Integrate localStorage saving logic into SET_SIDER_COLLAPSED reducer case
- Remove SET_INNER_PADDING action as it's no longer needed
## Updated Components
- PageLayout.js: Direct padding calculation based on route
- HeaderBar.js: Use new useStyle hook and styleActions
- SiderBar.js: Remove redundant localStorage calls
- LogsTable.js: Remove unused StyleContext import
- Playground/index.js: Migrate to new API
## Performance Impact
- Reduced component re-renders through optimized context structure
- Eliminated unnecessary effect dependencies and state updates
- Improved route transition smoothness with synchronous padding calculation
Remove the 5-image upload restriction in playground and enhance UI consistency
Changes:
- Remove 5-image limit constraint from ImageUrlInput component
- Update hint text to remove "maximum 5 images" references
- Add custom scrollbar styling for image list to match site-wide design
- Apply consistent thin scrollbar (6px width) with Semi Design color variables
- Maintain hover effects and rounded corners for better UX
Breaking Changes: None
Files modified:
- web/src/components/playground/ImageUrlInput.js
- web/src/index.css
This change allows users to upload unlimited images in playground mode while
maintaining visual consistency across the application's scrollable elements.
- Move reset settings button to the same row as the last modified timestamp
- Use flexbox layout with justify-between to align timestamp left and reset button right
- Keep export and import buttons on the separate row below
- Improve space utilization and visual hierarchy in the settings panel
This change enhances the user interface by creating a more compact and intuitive layout
for the configuration management controls in the playground component.
- Remove duplicate onRoleToggle prop passing to ChatArea component in Playground/index.js
- Move Toast notification outside setMessage callback in useMessageActions hook
- Prevent multiple event bindings that caused repeated role switch notifications
- Add early return validation for role toggle eligibility
This fixes the issue where users would see multiple success toasts when switching
between Assistant and System roles in the chat interface.
Files changed:
- web/src/pages/Playground/index.js
- web/src/hooks/useMessageActions.js
Hide y-axis scrollbars to provide a cleaner UI experience while maintaining
scroll functionality through mouse wheel and keyboard navigation.
Changes include:
- Hide scrollbars in CustomRequestEditor TextArea component
- Hide scrollbars in chat container and all related chat components
- Hide scrollbars in thinking content areas
- Add cross-browser compatibility for scrollbar hiding
- Maintain scroll functionality while improving visual aesthetics
Components affected:
- CustomRequestEditor.js: Added custom-request-textarea class
- index.css: Updated scrollbar styles for chat, thinking, and editor areas
The interface now provides a more streamlined appearance consistent with
modern UI design patterns while preserving all interactive capabilities.
Fix role toggle functionality where switching message roles (assistant/system)
did not update the UI immediately and required page refresh to see changes.
Changes:
- Add message.role comparison in OptimizedMessageContent memo function
- Add message.role comparison in OptimizedMessageActions memo function
The issue was caused by React.memo optimization that wasn't tracking role
changes, preventing re-renders when only the message role property changed.
Now role switches are reflected immediately in both message content display
and action button states.
Fixes: Role switching requires page refresh to display correctly
- Add CustomRequestEditor component with JSON validation and real-time formatting
- Implement bidirectional sync between chat messages and custom request body
- Add persistent local storage for chat messages (separate from config)
- Remove redundant System Prompt field in custom mode
- Refactor configuration storage to separate messages and settings
New Features:
• Custom request body mode with JSON editor and syntax highlighting
• Real-time bidirectional synchronization between chat UI and custom request body
• Persistent message storage that survives page refresh
• Enhanced configuration export/import including message data
• Improved parameter organization with collapsible sections
Technical Changes:
• Add loadMessages/saveMessages functions in configStorage
• Update usePlaygroundState hook to handle message persistence
• Refactor SettingsPanel to remove System Prompt in custom mode
• Add STORAGE_KEYS constants for better storage key management
• Implement debounced auto-save for both config and messages
• Add hash-based change detection to prevent unnecessary updates
UI/UX Improvements:
• Disabled state styling for parameters in custom mode
• Warning banners and visual feedback for mode switching
• Mobile-responsive design for custom request editor
• Consistent styling with existing design system
- Replace gradient background with purple theme matching EditChannel cards
- Add decorative circle elements for visual consistency
- Update all icons and text to white color for better contrast
- Apply inline styles to ensure proper color rendering
- Maintain hover effects with adjusted opacity values
This change creates visual consistency across the application by adopting
the same modern gradient design pattern used in EditChannel header cards.
- Replace pink-purple gradient with indigo-purple gradient to match PersonalSetting.js color scheme
- Update icon container gradient from purple-indigo to indigo-purple for consistency
- Enhance shadow effects from shadow-sm to shadow-lg to align with card design standards
- Improve hover effects with refined opacity and smoother transitions (duration-300)
- Increase content background opacity from 70% to 80% for better readability
- Update scrollbar color to purple theme (rgba(139, 92, 246, 0.3))
- Standardize border radius to rounded-xl for unified styling
- Apply consistent styling to "thinking in progress" state with matching gradient background
This change ensures visual consistency across the application by adopting the same
purple-blue color palette used in PersonalSetting component, creating a more
cohesive user experience.
- Fix thinking content area scroll functionality in MessageContent.js
* Replace max-h-50 with explicit maxHeight style (200px)
* Add thinking-content-scroll CSS class for proper scrollbar styling
* Ensure scrollbars are visible when content exceeds container height
- Add thinking-content-scroll CSS class in index.css
* Define webkit scrollbar styles with proper dimensions (6px)
* Add hover effects and cross-browser compatibility
* Support both webkit and Firefox scrollbar styling
- Remove unused CSS classes to improve code cleanliness
* Remove .hide-on-mobile class (no usage found in codebase)
* Remove .debug-code class (no longer needed)
- Improve user experience for viewing lengthy thinking content
* Users can now properly scroll through AI reasoning content
* Maintains content visibility with appropriate height constraints
Resolves issue where thinking section had max height but no scrolling capability.
- Add intelligent content truncation for payloads over 50K characters
- Implement tiered performance handling based on content size
- Use useMemo and useCallback for memory optimization and caching
- Add progressive loading with async processing for very large content
- Introduce performance warning indicators and user feedback
- Create expand/collapse functionality with smooth animations
- Skip syntax highlighting for extremely large content (>100K)
- Add loading states and debounce handling for better UX
- Display remaining content size indicators (e.g., +15K)
- Implement chunk-based processing to prevent UI blocking
This optimization ensures that even multi-megabyte JSON responses
won't cause page freezing or performance degradation in the debug
panel, while maintaining full functionality for regular-sized content.
- Change response content language from 'javascript' to 'json' for proper highlighting
- Improve automatic JSON detection to handle both objects and arrays
- Add intelligent content type detection based on string patterns
- Include development environment debug logging for troubleshooting
- Ensure all API responses display with correct JSON syntax coloring
This fix resolves the issue where API response data was not properly
syntax highlighted, ensuring consistent JSON formatting across all
debug panel tabs (preview, request, and response).
- Create new CodeViewer component with VS Code dark theme styling
- Implement custom JSON syntax highlighting with proper color coding
- Add improved copy functionality with hover effects and user feedback
- Refactor DebugPanel to use the new CodeViewer component
- Apply dark background (#1e1e1e) with syntax colors matching VS Code
- Enhance UX with floating copy button and responsive design
- Support automatic JSON formatting and parsing
- Maintain compatibility with existing Semi Design components
The debug panel now displays preview requests, actual requests, and
responses in a professional code editor style, improving readability
and developer experience in the playground interface.
- Replace Semi UI's MarkdownRender with react-markdown library for better performance and features
- Add comprehensive markdown rendering support including:
* Math formulas with KaTeX
* Code syntax highlighting with rehype-highlight
* Mermaid diagrams support
* GitHub Flavored Markdown (tables, task lists, etc.)
* HTML preview for code blocks
* Media file support (audio/video)
- Create new MarkdownRenderer component with enhanced features:
* Copy code button with hover effects
* Code folding for long code blocks
* Responsive design for mobile devices
- Add white text styling for user messages to improve readability on blue backgrounds
- Update all components using markdown rendering:
* MessageContent.js - playground chat messages
* About/index.js - about page content
* Home/index.js - home page content
* NoticeModal.js - system notice modal
* OtherSetting.js - settings page
- Install new dependencies: react-markdown, remark-math, remark-breaks, remark-gfm,
rehype-katex, rehype-highlight, katex, mermaid, use-debounce, clsx
- Add comprehensive CSS styles in markdown.css for better theming and user experience
- Remove unused imports and optimize component imports
Breaking changes: None - maintains backward compatibility with existing markdown content
- Extract common `applyAutoCollapseLogic` function for reasoning panel collapse behavior
- Consolidate duplicated auto-collapse logic across multiple functions
- Simplify conditional expressions using logical OR operator
- Replace repetitive property assignments with object spread syntax
- Update dependency arrays to include new shared function
- Ensure consistent behavior across stream/non-stream/error scenarios
This refactoring improves code maintainability by following DRY principles
and centralizing the auto-collapse logic in a single reusable function.
All message handling functions now use consistent logic for determining
when to auto-collapse the reasoning panel.
Benefits:
- Reduced code duplication from ~20 lines to 6 lines per function
- Single source of truth for auto-collapse behavior
- Improved readability and maintainability
- Easier to modify collapse logic in the future
Files changed:
- web/src/hooks/useApiRequest.js: Refactored message handling functions
- Add `hasAutoCollapsed` flag to track auto-collapse state
- Modify reasoning panel to auto-collapse only once after thinking completion
- Allow users to manually toggle reasoning panel after auto-collapse
- Update message creation, streaming updates, and completion handlers
- Ensure consistent behavior across stream/non-stream requests and error cases
Previously, the reasoning/thinking panel would auto-collapse every time
the AI completed its thinking process, preventing users from reopening
it to review the reasoning content. Now it auto-collapses only once
when thinking is complete, then allows full user control.
Files changed:
- web/src/hooks/useApiRequest.js: Updated all message handling functions
- web/src/utils/messageUtils.js: Added hasAutoCollapsed to initial state
Previously, the "thinking" indicator and loading icon would only disappear
after the entire message generation was complete, which created a poor user
experience where users had to wait for the full response to see that the
reasoning phase had finished.
Changes made:
- Add `isThinkingComplete` field to independently track reasoning state
- Update streaming logic to mark thinking complete when content starts flowing
- Detect closed `<think>` tags to mark reasoning completion
- Modify MessageContent component to use independent thinking state
- Update "思考中..." text and loading icon display conditions
- Ensure thinking state is properly set in all completion scenarios
(non-stream, errors, manual stop)
Now the thinking section immediately shows as complete when reasoning ends,
rather than waiting for the entire message to finish, providing much better
real-time feedback to users.
Files modified:
- web/src/hooks/useApiRequest.js
- web/src/components/playground/MessageContent.js
- web/src/utils/messageUtils.js
Update tooltip messages from "正在生成中,请稍候..." to "操作暂时被禁用"
in MessageActions component to better reflect that actions can be disabled
during both message generation and editing states.
Changes:
- Replace specific "generating" message with generic "temporarily disabled" message
- Applies to retry, edit, role toggle, and delete action tooltips
- Provides more accurate user feedback for disabled states
Files modified:
- web/src/components/playground/MessageActions.js
- Cache initial config using useRef to prevent repeated loadConfig() calls
- Fix useEffect dependencies to only trigger on actual config changes
- Modify debouncedSaveConfig dependency from function reference to actual config values
- Update handleConfigReset to use DEFAULT_CONFIG directly instead of reloading
- Prevent excessive console logging during chat interactions and frequent re-renders
This resolves the issue where console was flooded with:
"配置已从本地存储加载" and "配置已保存到本地存储" messages,
especially during active chat sessions where logs appeared every second.
Fixes: Frequent config load/save operations causing performance issues
Completely restructured the Playground component from a 1437-line monolith
into a maintainable, modular architecture with 62.4% code reduction (540 lines).
**Key Improvements:**
- **Modular Architecture**: Extracted business logic into separate utility files
- `utils/constants.js` - Centralized constant management
- `utils/messageUtils.js` - Message processing utilities
- `utils/apiUtils.js` - API-related helper functions
- **Custom Hooks**: Created specialized hooks for better state management
- `usePlaygroundState.js` - Centralized state management
- `useMessageActions.js` - Message operation handlers
- `useApiRequest.js` - API request management
- **Code Quality**: Applied SOLID principles and functional programming patterns
- **Performance**: Optimized re-renders with useCallback and proper dependency arrays
- **Maintainability**: Implemented single responsibility principle and separation of concerns
**Technical Achievements:**
- Eliminated code duplication and redundancy
- Replaced magic strings with typed constants
- Extracted complex inline logic into pure functions
- Improved error handling and API response processing
- Enhanced code readability and testability
**Breaking Changes:** None - All existing functionality preserved
This refactor transforms the codebase into enterprise-grade quality following
React best practices and modern development standards.
- Add role toggle button in MessageActions component for assistant/system messages
- Implement handleRoleToggle function in Playground component to switch between assistant and system roles
- Add visual distinction for system messages with orange badge indicator
- Update roleInfo configuration to use consistent avatars for assistant and system roles
- Add proper tooltip texts and visual feedback for role switching
- Ensure role toggle is disabled during message generation to prevent conflicts
This feature allows users to easily switch message roles between assistant and system,
providing better control over conversation flow and message categorization in the playground interface.
- Add real-time request body preview that updates when parameters change
- Implement pre-constructed payload generation for debugging without sending requests
- Add support for image URLs in preview payload construction
- Upgrade debug panel to card-style tabs with custom arrow navigation
- Add collapsible functionality and dropdown menu for tab selection
- Integrate image-enabled messages with proper multimodal content structure
- Refactor tab state management with internal useState and external sync
- Remove redundant status labels and clean up component structure
- Set preview tab as default active tab for better UX
- Maintain backward compatibility with existing debug functionality
This enhancement significantly improves the debugging experience by allowing
developers to see exactly what request will be sent before actually sending it,
with real-time updates as they adjust parameters, models, or image settings.
Add a toggle switch to enable/disable image uploads in the playground,
with automatic disabling after message sending to prevent accidental
image inclusion in subsequent messages.
Changes:
- Add `imageEnabled` field to default configuration with false as default
- Enhance ImageUrlInput component with enable/disable toggle switch
- Update UI to show disabled state with opacity and color changes
- Modify message sending logic to only include images when enabled
- Implement auto-disable functionality after message is sent
- Update SettingsPanel to pass through new imageEnabled props
- Maintain backward compatibility with existing configurations
User Experience:
- Images are disabled by default for privacy and intentional usage
- Users must explicitly enable image uploads before adding URLs
- After sending a message with images, the feature auto-disables
- Clear visual feedback shows current enabled/disabled state
- Manual control allows users to re-enable when needed
This improves user control over multimodal conversations and prevents
unintentional image sharing in follow-up messages.
Fix TypeError when processing multimodal messages containing both text and images.
The error "textContent.text.trim is not a function" occurred when textContent
was null or textContent.text was not a string type.
Changes:
- Add comprehensive type checking for textContent.text access
- Implement getTextContent() utility function for unified content extraction
- Enhance error handling to support multimodal content display
- Fix message copy functionality to handle array-format content
- Improve message reset functionality to extract text content for retry
- Add user-friendly warnings when copying messages without text content
Technical improvements:
- Validate textContent existence and text property type before calling trim()
- Extract text content from multimodal messages for operations like copy/retry
- Maintain backward compatibility with string-format content
- Preserve all existing functionality while adding robust error handling
Fixes issues with:
- Image + text message processing
- Message copying from multimodal content
- Message retry with image attachments
- Error display for complex message formats
This ensures the playground component handles multimodal content gracefully
without breaking existing text-only message functionality.
BREAKING CHANGE: Refactor message stream processing and think tag handling logic
- Improve automatic collapse behavior of reasoning panel
- Collapse panel immediately after reasoning content completion
- Add detection for complete think tag pairs
- Remove dependency on full content completion
- Enhance think tag processing
- Unify tag handling logic across stream and stop states
- Add robust handling for unclosed think tags
- Prevent markdown rendering errors from malformed tags
- Simplify state management
- Reduce complexity in collapse condition checks
- Remove redundant state transitions
- Improve code readability by removing unnecessary comments
This commit ensures a more stable and predictable behavior in the chat interface, particularly in handling streaming responses and reasoning content display.
- Modified the `renderCustomChatContent` function to strip `<think>` and `</think>` tags from `finalExtractedThinkingContent` before passing it to the `MarkdownRender` component. This resolves potential parsing errors caused by unclosed or malformed tags.
- Added a conditional check to ensure that the thinking process block is only rendered if `finalExtractedThinkingContent` has actual content and the section is expanded, improving rendering stability.
This commit significantly refactors the handling of <think> tags within the Playground component to improve robustness, prevent Markdown rendering errors, and ensure accurate separation of reasoning and displayable content.
Key changes include:
- Modified `handleNonStreamRequest`, `onStopGenerator`, and `renderCustomChatContent` for more resilient <think> tag parsing.
- Implemented logic to correctly extract content from fully paired `<think>...</think>` tags.
- Added handling for unclosed `<think>` tags, particularly relevant during streaming responses, to capture ongoing thought processes.
- Ensured `reasoningContent` is accurately populated from all sources (API, paired tags, and unclosed streaming tags).
- Thoroughly sanitized the final `currentDisplayableFinalContent` to remove all residual `<think>` and `</think>` string instances, preventing issues with the Markdown renderer.
- Corrected the usage of `thinkTagRegex.lastIndex = 0;` to ensure proper regex state resetting before each use in loops.
Additionally, numerous explanatory comments detailing the "how" of the code (rather than the "why") have been removed to improve code readability and reduce noise.
This commit improves the handling of message generation interruption in the
playground chat interface, ensuring both content and thinking process are
properly preserved.
Key changes:
- Preserve existing content when stopping message generation
- Handle both direct reasoningContent and <think> tag formats
- Extract and merge thinking process from unclosed <think> tags
- Maintain consistent thinking chain format with separators
- Auto-collapse reasoning panel after stopping for cleaner UI
Technical details:
- Modified onStopGenerator to properly handle SSE connection closure
- Added regex pattern to extract thinking content from <think> tags
- Implemented proper state management for incomplete messages
- Ensured all content types are preserved in their respective fields
This fix resolves the issue where thinking chain content would be lost
when stopping message generation mid-stream.
- Add click-to-navigate functionality on balance cards in both Detail and TokensTable components
- Implement navigation to '/console/topup' when clicking on current balance
- Add useNavigate hook and necessary imports
- Keep consistent navigation behavior across components
Components affected:
- web/src/pages/Detail/index.js
- web/src/components/TokensTable.js
This commit introduces the following changes:
- Add i18n support to the Loading component
- Import useTranslation hook from react-i18next
- Replace hardcoded Chinese text with translation keys
- Support dynamic content interpolation for loading prompts
- Use {{name}} variable in translation template
Technical details:
- Added: import { useTranslation } from 'react-i18next'
- Modified: Loading text from static Chinese to i18n keys
- Translation keys added:
- "加载中..."
- "加载{{name}}中..."
File changed: web/src/components/Loading.js
This commit introduces the following changes:
- Create a reusable NoticeModal component to handle system announcements
- Extract notice functionality from Home and HeaderBar components
- Add loading and empty states using Semi UI illustrations
- Implement "close for today" feature with localStorage
- Support both light and dark mode for empty state illustrations
- Add proper error handling and loading states
- Improve code reusability and maintainability
Breaking changes: None
Related components: HeaderBar.js, Home/index.js, NoticeModal.js
- Remove unnecessary undefined status check in readystatechange event
- Only show disconnection message for actual non-200 status codes
- Remove redundant else branch for normal status handling
- Prevent false "Connection lost" messages on successful completion
- Add comprehensive error handling for SSE events
- Implement proper error state UI with Semi Typography
- Prevent white screen issues on non-200 responses
- Add error logging for better debugging
- Enhance message state management for error conditions
- Improve user feedback with i18n error messages
- Ensure UI stability during error states
- Add try-catch blocks for JSON parsing and stream initialization
- Handle connection termination gracefully
- Preserve error states in message stream updates
- Replace emoji icons with Semi Design Avatar components
- Standardize statistics cards layout across TokensTable and LogsTable
- Remove informational text banners for cleaner interface
- Implement consistent grid layout for metric cards
- Add elevated shadow effect to white Avatar for better contrast
Changes include:
- Convert emoji indicators to Semi Icons (MoneyExchangeStroked, Pulse, Typograph)
- Unify card styling with rounded corners and hover shadows
- Implement responsive grid layout (1 column on mobile, 3 columns on desktop)
- Standardize typography and spacing across all stat cards
- Apply Semi Design's elevated shadow to improve white Avatar visibility
- Replace showNotice with Semi Modal component for better UI consistency
- Add "Close Today" and "Close" actions for flexible notice control
- Improve markdown rendering with marked.parse
- Add responsive modal size based on device type
- Implement max height with scrollable content (60vh)
- Style scrollbar to match Semi design system
- Remove old notice caching logic for more reliable notifications
This commit implements a comprehensive UI/UX overhaul of the ModelPricing component,
focusing on improved aesthetics and responsiveness while maintaining existing API logic.
Key improvements:
- Redesigned status card with gradient background and floating elements
- Implemented responsive grid layout for pricing metrics
- Enhanced visual hierarchy with Semi UI components
- Added smooth transitions and hover effects
- Optimized spacing and typography for better readability
- Unified design language with PersonalSettings component
- Integrated Tailwind CSS 3.0 utility classes
- Added decorative elements for visual interest
- Improved mobile responsiveness across all breakpoints
- Enhanced accessibility with proper contrast ratios
The redesign follows modern UI/UX best practices while maintaining consistency
with the application's design system.
This commit standardizes the card header design across multiple edit pages
to create a consistent and modern UI experience.
Changes made:
- Add gradient background colors to card headers
- Implement decorative circular elements for visual appeal
- Update icon colors to white with semi-transparent backgrounds
- Standardize text colors and opacity for better readability
- Add consistent padding and border radius
- Maintain unique color schemes for different functional sections
Modified files:
- EditChannel.js
- EditRedemption.js
- EditToken.js
- EditUser.js
- AddUser.js
The new design features:
- Blue gradient for basic information sections
- Green gradient for quota/permission settings
- Purple gradient for access restrictions
- Orange gradient for binding/group information
- Consistent layout structure across all edit pages
This update improves visual hierarchy and maintains brand consistency
while enhancing the overall user experience.
BREAKING CHANGE: None
- UI Improvements:
- Add gradient backgrounds to card headers
- Enhance visual hierarchy with decorative elements
- Improve button styles with rounded corners and icons
- Standardize input field sizes and styles
- Add consistent border radius to components
- Code Optimizations:
- Remove unused imports (IconHelpCircle, IconKey, IconPlus)
- Remove unused showWarning import
- Remove unused loadChannelModels import
- Remove unused useRef and useParams hooks
- Clean up whitespace and formatting
- Style Enhancements:
- Convert static colors to gradient backgrounds
- Add floating circle decorations for visual interest
- Improve text contrast with white text on gradient backgrounds
- Add semi-transparent white backgrounds to icons
- Standardize card header layouts
- Accessibility:
- Improve text contrast ratios
- Maintain consistent visual hierarchy
- Add relative positioning for better overlay handling
This refactor focuses on modernizing the UI while maintaining all existing functionality. The changes are purely presentational and do not affect the component's behavior.
- Add success notification when testing a single channel
- Only show notification for individual channel test, not for batch model testing
- Include channel name and response time in the notification message
- Keep error notifications for both single and batch testing scenarios
This improves user feedback when manually testing channel connectivity.
This commit improves the ChannelsTable component with enhanced UI and functionality:
UI Improvements:
- Refactor operation column layout with primary actions exposed
- Move secondary actions (delete, copy) to dropdown menu
- Unify button styles with theme='light' and size="small"
- Add !rounded-full design to all buttons
- Add appropriate icons (IconStop, IconPlay etc.)
Column Settings Modal:
- Replace inline styles with Tailwind CSS
- Add rounded corners design
- Optimize button layout and styling
- Improve responsive design
Batch Operations:
- Unify dropdown button styles with !rounded-full
- Replace inline styles with Tailwind w-full
- Maintain semantic button types (warning/secondary/danger)
- Improve visual hierarchy
Model Testing Enhancement:
- Add comprehensive model testing modal
- Implement batch testing functionality
- Add model search and filtering
- Add real-time test status indicators
- Show response time for successful tests
- Add test queue management system
- Implement graceful test cancellation
Other Improvements:
- Optimize responsive layout for mobile devices
- Add i18n support for all new features
- Improve error handling and user feedback
- Enhance performance with optimized state management
- Unify input field styles with size="large" for consistent appearance
- Replace account binding sections with Semi UI Card components for better visual hierarchy
- Redesign invitation statistics cards with responsive layout and Card components
- Enhance security settings with structured Card layout and improved visual design
- Complete i18n internationalization for all text strings and placeholders
- Optimize main profile card responsive design following TopUp page patterns
- Update avatar component to display first two characters with animated border
- Improve user role display with three-tier system (Super Admin/Admin/User)
- Enhance tag visibility with white background for better contrast on purple gradient
- Implement dynamic colors for model tags using stringToColor function
- Add hover effects and improved accessibility across all components
- Maintain consistent design language throughout the interface
This refactor significantly improves the user experience with modern UI patterns,
better responsiveness, and enhanced visual appeal while maintaining all existing
functionality.
- Add paymentLoading state for Alipay and WeChat payment buttons
- Add confirmLoading state for payment confirmation modal
- Implement proper loading management in preTopUp function with try-catch error handling
- Implement proper loading management in onlineTopUp function with comprehensive error handling
- Add loading={paymentLoading} to both payment method buttons to prevent double-clicks
- Add confirmLoading={confirmLoading} to modal confirmation button
- Enhance error handling with user-friendly error messages for failed operations
- Ensure loading states are properly cleared in finally blocks for consistent UX
This update provides immediate visual feedback when users interact with payment buttons,
prevents accidental double-clicks, and improves overall payment flow reliability
with comprehensive error handling and loading state management.
- Replace simple form layout with sophisticated card-based design system
- Implement bank card-style wallet display with gradient backgrounds and decorative elements
- Integrate real user data from UserContext (username, quota, usage stats, user role, group)
- Add personalized color schemes using stringToColor for unique user identification
- Implement comprehensive responsive design for mobile, tablet, and desktop devices
- Add skeleton loading states for all data-dependent components and API calls
- Replace basic Input with InputNumber component for amount input with built-in validation (min: 1)
- Add official brand icons for payment methods (Alipay, WeChat) using react-icons/si
- Integrate Semi UI Banner component for better warning notifications
- Implement real-time data synchronization between local state and UserContext
- Add sophisticated loading states with proper error handling and user feedback
- Clean up all code comments and remove unused imports, functions, and state variables
- Enhance visual hierarchy with proper spacing, shadows, and modern typography
- Add glass-morphism effects and backdrop filters for premium visual experience
- Improve accessibility with proper text truncation and responsive font sizing
This update transforms the TopUp page from a basic form into a professional,
modern payment interface that provides excellent user experience across all devices
while maintaining full functionality and adding comprehensive data validation.
- Refactor EditRedemption.js with card-based layout and modern UI components
- Refactor EditUser.js with three-section card layout (basic info, permissions, bindings)
- Refactor AddUser.js with modern card design and improved user experience
- Replace inline styles with Tailwind CSS 3 classes throughout all components
- Add semantic icons (IconUser, IconKey, IconGift, IconCreditCard, etc.) for better UX
- Implement unified header design with colored tags and consistent typography
- Replace deprecated Title imports with destructured Typography components
- Add proper internationalization support with useTranslation hook
- Standardize form layouts with consistent spacing, rounded corners, and shadows
- Improve button styling with rounded design and loading states
- Fix IconTicket import error by replacing with existing IconGift
- Enhance modal designs with modern styling and icon integration
- Ensure responsive design consistency across all edit/add components
This update brings all user management interfaces in line with the modern
design system established in EditToken.js, providing a cohesive and
professional user experience.
Add loading indicators to improve user experience during authentication processes:
- Implement loading states for all login and registration buttons
- Add try/catch/finally structure to properly handle async operations
- Create wrapper functions for OAuth redirect operations
- Set loading state for verification code submission
- Update modal confirmation buttons with loading state
- Add proper error handling with user feedback
- Split generic loading state into specific state variables
This change enhances user experience by providing clear visual feedback
during authentication actions.
When resizing from medium screens to desktop view in the console section,
the sidebar previously failed to appear automatically. This commit fixes
the issue by simplifying the logic to always show the sidebar when in
desktop mode and in console pages, regardless of previous screen size.
This commit introduces a new component `AuthRedirect` which checks
if a user is already logged in.
If the user is logged in and attempts to access the /login or /register
pages, they will be redirected to the /console page. Otherwise, the
respective authentication form (Login or Register) will be rendered.
The `App.js` file has been updated to utilize this new `AuthRedirect`
component for the /login and /register routes.
Previously, when an unauthenticated user clicked the "Console" navigation
link, the application would first attempt to navigate to '/console'.
This would then trigger a redirect to '/login', causing a brief flicker
between the two pages.
This commit modifies the `renderNavLinks` function in `HeaderBar.js`
to proactively check the user's authentication status. If the user is
not logged in and clicks the "Console" link, the navigation target
is directly set to '/login', avoiding the intermediate redirect and
eliminating the flickering effect.
The `handleNavLinkClick` function in `HeaderBar.js` was previously
forcing the sidebar to be visible for all non-'home' navigation links
on non-mobile devices. This interfered with the intended logic in
`StyleContext` which controls sidebar visibility based on the current
route.
This commit modifies `handleNavLinkClick` to:
- Only apply specific style dispatches (setting inner padding and sider
to false) for the 'home' link, which may have unique layout requirements.
- Remove the logic that unconditionally set sidebar visibility and inner
padding for other navigation links.
- Continue to close the mobile menu загрязнения (`setMobileMenuOpen(false)`) on any nav link click.
This change ensures that `StyleContext` is the single source of truth
for determining sidebar visibility based on the route, resolving an
issue where clicking a non-console link Pferde (e.g., 'Pricing', 'About')
would incorrectly display the sidebar, especially when the link was
clicked Pferde a second time while already on that page.
- Introduced a new constant `AzureNoRemoveDotTime` in `constant/azure.go` to manage model name formatting for channels created after May 10, 2025.
- Updated `distributor.go` to set `channel_create_time` in the context.
- Modified `adaptor.go` to conditionally remove dots from model names based on the channel creation time.
- Enhanced `relay_info.go` to include `ChannelCreateTime` in the `RelayInfo` struct.
- Updated English localization files to reflect changes in model name handling for new channels.
- Introduced a new constant `AzureNoRemoveDotTime` in `constant/azure.go` to manage model name formatting for channels created after May 10, 2025.
- Updated `distributor.go` to set `channel_create_time` in the context.
- Modified `adaptor.go` to conditionally remove dots from model names based on the channel creation time.
- Enhanced `relay_info.go` to include `ChannelCreateTime` in the `RelayInfo` struct.
- Updated English localization files to reflect changes in model name handling for new channels.
These changes ensures SSE ping packets are sent before receiving a response from the upstream. The previous implementation did not send ping packets until after the upstream response, rendering the feature ineffective.
Reason: The original steps 1 and 3 in the redisRateLimitHandler method were not atomic, leading to poor precision under high concurrent requests. For example, with a rate limit set to 60, sending 200 concurrent requests would result in none being blocked, whereas theoretically around 140 should be intercepted.
Solution: I chose not to merge steps 1 and 3 into a single Lua script because a single atomic operation involving read, write, and delete operations could suffer from performance issues under high concurrency. Instead, I implemented a token bucket algorithm to optimize this, reducing the atomic operation to just read and write steps while significantly decreasing the memory footprint.
- Wrapped form sections in Card components for better visual separation
- Added new configuration options for payment settings, email domain whitelist, SMTP, OIDC, GitHub OAuth, Linux DO OAuth, WeChat, and Telegram
- Improved layout with responsive design using Row and Col components
- Updated button actions for saving settings in new sections
Reason: The info parameter already includes the key, so there is no need to retrieve it again from the header.
Solution: Delete the code for obtaining the key and directly use info.ApiKey.
- Added a new GeneralSetting struct to manage configurable docs link
- Removed hardcoded ChatLink and ChatLink2 variables across multiple files
- Updated frontend components to dynamically render docs link from status
- Simplified chat and link-related logic in various components
- Added a warning modal for quota per unit setting in operation settings
- Added github.com/shopspring/decimal for precise floating-point calculations
- Refactored quota and payment calculations in multiple files to use decimal arithmetic
- Updated go.mod and go.sum to include decimal library
- Improved precision in topup, relay, and quota service calculations
- Added support for more OpenAI model variants in cache ratio settings
- Implement a new modal for selecting and testing models per channel
- Add search functionality to filter models by keyword
- Replace dropdown with direct button for model testing
- Introduce new state variables for managing model test modal
- Add version and startup time display in OtherSetting component
- Implement robust GitHub release update checking mechanism
- Add error handling for update check process
- Update Modal component for displaying update information
- Add new translations for version and system information
- Introduce `SelfUseModeEnabled` setting to allow flexible model ratio configuration
- Update error handling to provide more informative messages when model ratios are not set
- Modify pricing and relay logic to support self-use mode
- Add UI toggle for enabling self-use mode in operation settings
- Implement fallback mechanism for model ratios when self-use mode is enabled
- Update error message for missing model ratio to be more user-friendly
- Modify ModelRatioNotSetEditor to filter models without price or ratio
- Enhance model data initialization with fallback values
- Implement `/api/channel/models_enabled` endpoint to retrieve enabled models
- Add `EnabledListModels` handler in controller
- Create new `ModelRatioNotSetEditor` component for managing unset model ratios
- Update router to include new models_enabled route
- Add internationalization support for new model management UI
- Include GPT-4.5 preview model in OpenAI model list
- Replace ThinkingAdapterMaxTokens with a more flexible DefaultMaxTokens map
- Add support for model-specific default max tokens configuration
- Update relay and web interface to use the new configuration approach
- Implement a fallback mechanism for default max tokens
- Update Claude relay to set default MaxTokens dynamically
- Modify web interface to clarify default MaxTokens input purpose
- Improve token configuration logic for thinking adapter models
- Introduce a new configuration management approach for model-specific settings
- Update Gemini settings to use the new config system with more flexible management
- Add support for dynamic configuration updates in option handling
- Modify Claude and Vertex adaptors to use new configuration methods
- Enhance web interface to support namespaced configuration keys
- Enhance channel test to detect more embedding models
- Update Azure OpenAI default API version to 2024-12-01-preview
- Remove redundant default API version setting in channel edit
- Add user cache writing in channel test
- Add new context keys for user-related information
- Modify user cache and authentication middleware to populate context
- Refactor quota and notification services to use context-based user data
- Remove redundant database queries by leveraging context information
- Update various components to use new context-based user retrieval methods
- Remove global `RootUserEmail` variable
- Modify channel testing and user notification methods to use `GetRootUser()`
- Update user cache and notification service to use more consistent user base type
- Add new channel test notification type
- Implement user notification settings with email and webhook options
- Add new user settings for quota warning threshold and notification preferences
- Create backend API and database support for user notification configuration
- Enhance frontend personal settings with notification configuration UI
- Support custom notification email and webhook URL
- Add service layer for sending user notifications
- Introduce AutomaticDisableKeywords setting to dynamically control channel disabling
- Implement AC search for matching error messages against disable keywords
- Add frontend UI for configuring automatic disable keywords
- Update localization with new keyword-based channel disabling feature
- Refactor sensitive word and AC search logic to support multiple keyword lists
- Remove inline channel join in log queries
- Implement separate channel name lookup for logs
- Improve performance by fetching channel names in a single query
- Ensure channel names are correctly associated with logs
- Use alpine-based Golang image for smaller build size
- Simplify Go build command by removing static linking flag
- Improve Docker multi-stage build configuration
- Update EmbeddingRequest DTO to support more flexible input types
- Add input parsing method to handle various input formats
- Implement ConvertEmbeddingRequest for multiple channel adaptors
- Remove relayMode parameter from EmbeddingHelper
- Add input validation for embedding requests
- Simplify embedding request conversion for different channels
- Update channel constants to include Baidu V2 channel
- Create new Baidu V2 adaptor for relay
- Add Baidu V2 models and channel configuration
- Update relay adaptor to support Baidu V2 channel
- Modify web channel constants to include Baidu V2 option
- Add `Prefix` and `ReasoningContent` fields to Message struct
- Add getter and setter methods for `Prefix`
- Make `ToolCall.ID` field optional (fix#749)
- Update user and wechat controllers to use sessions for user ID
- Modify ID retrieval to use `session.Get("id")` instead of `c.GetInt("id")`
- Cast session ID to int when creating user object
- Change `ModelMapping` column type from varchar(1024) to TEXT in channels table
- Add MySQL migration script to alter column type during database initialization
- Improve database schema flexibility for storing complex model mappings
- Enhance `NewProxyHttpClient` to handle SOCKS5 proxy authentication
- Extract username and password from proxy URL for SOCKS5 proxy configuration
- Provide optional authentication for SOCKS5 proxy connections
- Introduce `AZURE_DEFAULT_API_VERSION` environment variable
- Set default Azure API version to `2024-12-01-preview`
- Update README documentation for new environment configuration
- Modify Azure channel relay to use default API version when not specified
- Add `RecodeModelName` to `RelayInfo` struct for more flexible model name tracking
- Update text relay and quota consumption to use `RecodeModelName`
- Move reasoning effort from admin info to other info in log generation
- Ensure consistent model name handling across relay components
- Add `ReasoningEffort` field to `RelayInfo` struct
- Update log generation to include reasoning effort in admin info
- Modify logs table component to display reasoning effort when available
- Preserve reasoning effort information during request processing
- Remove model name suffixes after extracting reasoning effort
- Update upstream model name to reflect the base model
- Ensure clean model name is passed to the upstream service
- Modify model suffix parsing to use hyphen-separated suffixes
- Ensure consistent parsing of `-high`, `-medium`, and `-low` reasoning effort indicators
- Support setting reasoning effort via model name suffix
- Add `-high`, `-medium`, and `-low` suffixes to control reasoning effort
- Update README with new model configuration option
- Modify OpenAI adaptor to handle reasoning effort settings
The issue was caused by the `omitempty` tag in the Go struct, which prevented the `temperature` field from being included in the JSON output when it was set to 0.
Signed-off-by: Butui Hu <hot123tea123@gmail.com>
- Implemented conditional logic to double the streaming timeout for models starting with "o1" or "o3".
- Improved handling of streaming timeout configuration to enhance performance based on model type.
- Changed base image from Node.js to Bun for improved performance.
- Replaced npm install with bun install for dependency management.
- Updated build command to use Bun for building the application.
- Added new bun.lockb file to track Bun dependencies.
- Updated GetAllRedemptions and SearchRedemptions functions to return total count along with paginated results.
- Modified API endpoints to accept page size as a parameter, enhancing flexibility in data retrieval.
- Adjusted RedemptionsTable component to support pagination and display total count, improving user experience.
- Ensured consistent handling of pagination across related components, including LogsTable and UsersTable.
- Updated SearchUsers function to include pagination parameters (startIdx and num) for improved user search results.
- Modified API response structure to return paginated data, including total user count and current page information.
- Adjusted UsersTable component to handle pagination and search parameters, ensuring a seamless user experience.
- Added internationalization support for new search functionality in the UI.
- Updated GetAllUsers function to return total user count along with paginated results, improving data handling in user retrieval.
- Modified GetAllUsers API endpoint to accept page size as a parameter, allowing for dynamic pagination.
- Enhanced UsersTable component to support customizable page sizes and improved pagination logic.
- Added error handling for empty username and password in AddUser component.
- Updated LogsTable component to display pagination information in a user-friendly format.
> This is an open-source project developed based on [One API](https://github.com/songquanpeng/one-api)
> [!IMPORTANT]
> - Users must comply with OpenAI's [Terms of Use](https://openai.com/policies/terms-of-use) and relevant laws and regulations. Not to be used for illegal purposes.
> - This project is for personal learning only. Stability is not guaranteed, and no technical support is provided.
> - This project is for personal learning purposes only, with no guarantee of stability or technical support.
> - Users must comply with OpenAI's [Terms of Use](https://openai.com/policies/terms-of-use) and **applicable laws and regulations**, and must not use it for illegal purposes.
> - According to the [《Interim Measures for the Management of Generative Artificial Intelligence Services》](http://www.cac.gov.cn/2023-07/13/c_1690898327029107.htm), please do not provide any unregistered generative AI services to the public in China.
## 📚 Documentation
For detailed documentation, please visit our official Wiki: [https://docs.newapi.pro/](https://docs.newapi.pro/)
14. 🔄 Support for Rerank models, compatible with Cohere and Jina, can integrate with Dify, [Integration Guide](Rerank.md)
15. ⚡ **[OpenAI Realtime API](https://platform.openai.com/docs/guides/realtime/integration)** - Support for OpenAI's Realtime API, including Azure channels
New API offers a wide range of features, please refer to [Features Introduction](https://docs.newapi.pro/wiki/features-introduction) for details:
1. 🎨 Brand new UI interface
2.🌍 Multi-language support
3. 💰 Online recharge functionality (YiPay)
4. 🔍 Support for querying usage quotas with keys (works with [neko-api-key-tool](https://github.com/Calcium-Ion/neko-api-key-tool))
5. 🔄 Compatible with the original One API database
6.💵 Support for pay-per-use model pricing
7.⚖️ Support for weighted random channel selection
8.📈 Data dashboard (console)
9.🔒 Token grouping and model restrictions
10.🤖 Support for more authorization login methods (LinuxDO, Telegram, OIDC)
11.🔄 Support for Rerank models (Cohere and Jina), [API Documentation](https://docs.newapi.pro/api/jinaai-rerank)
12.⚡ Support for OpenAI Realtime API (including Azure channels), [API Documentation](https://docs.newapi.pro/api/openai-realtime)
13.⚡ Support for Claude Messages format, [API Documentation](https://docs.newapi.pro/api/anthropic-chat)
14. Support for entering chat interface via /chat2link route
15. 🧠 Support for setting reasoning effort through model name suffixes:
1.OpenAI o-series models
- Add `-high` suffix for high reasoning effort (e.g.: `o3-mini-high`)
- Add `-medium` suffix for medium reasoning effort (e.g.: `o3-mini-medium`)
- Add `-low` suffix for low reasoning effort (e.g.: `o3-mini-low`)
2. Claude thinking models
- Add `-thinking` suffix to enable thinking mode (e.g.: `claude-3-7-sonnet-20250219-thinking`)
16. 🔄 Thinking-to-content functionality
17. 🔄 Model rate limiting for users
18. 💰 Cache billing support, which allows billing at a set ratio when cache is hit:
1. Set the `Prompt Cache Ratio` option in `System Settings-Operation Settings`
2. Set `Prompt Cache Ratio` in the channel, range 0-1, e.g., setting to 0.5 means billing at 50% when cache is hit
Channel retry is implemented, configurable in `Settings->Operation Settings->General Settings`. **Cache recommended**.
First retry uses same priority, second retry uses next priority, and so on.
## Channel Retry and Cache
Channel retry functionality has been implemented, you can set the number of retries in `Settings->Operation Settings->General Settings`. It is **recommended to enable caching**.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.