* refactor(playground): streamline chat request state
- extract conversation actions from the page component to keep message flow logic reusable.
- unify streaming and non-streaming generation state, including abort support for non-stream requests.
- simplify message rendering and payload construction while localizing Playground prompts.
* fix(playground): validate persisted chat state
- wrap saved Playground state with a storage version while still reading legacy values.
- validate config, parameter toggles, and messages before restoring them from localStorage.
- cap stored chat history to the latest messages to avoid oversized or stale state.
* refactor(playground): centralize message content access
- route chat rendering, copy actions, and error display through shared message helpers.
- reuse the current-version update helper for non-streaming assistant responses.
- keep message version details behind utility functions to reduce future model churn.
* refactor(playground): split storage schemas
- move Playground storage validation schemas into a dedicated module.
- keep storage read and write logic focused on migration, trimming, and persistence.
- preserve the existing storage envelope and validation behavior.
* refactor(playground): extract options loading hook
- move model and group queries into a dedicated hook so the page component stays focused on layout wiring.
- preserve existing fallback selection and error toast behavior while reusing the hook through the playground barrel export.
* refactor(playground): extract prompt suggestions
- move static prompt suggestion rendering into a focused component so the input stays centered on compose controls.
- preserve translated suggestion submission behavior while isolating icon metadata from the input form.
* refactor(playground): extract input tools
- move attachment and search controls into a dedicated component so the prompt input stays focused on compose state.
- keep existing development toast behavior and disabled handling while centralizing tool metadata.
* refactor(playground): extract input controls
- move model, group, send, and stop controls into a focused component so the input only manages compose state.
- preserve existing disabled states and generation button behavior while isolating control rendering.
* refactor(playground): extract message content display
- move sources, reasoning, loading, error, and response rendering into a dedicated message content component.
- keep the chat list focused on message iteration, edit state, and action wiring without changing display behavior.
* refactor(playground): extract message editor
- move inline message editing controls into a dedicated editor component so the chat list stays focused on rendering flow.
- preserve save, save-and-submit, cancel, and disabled-state behavior for edited messages.
* refactor(playground): extract stream error parsing
- move SSE error payload parsing into a reusable stream utility so the request hook stays focused on lifecycle handling.
- preserve existing error message, error code, and fallback behavior for raw or empty stream errors.
* refactor(playground): extract request error parsing
- move non-stream request error extraction into a shared utility so the chat handler stays focused on request flow.
- preserve the existing response message, error code, and fallback priority for failed chat completions.
* refactor(playground): extract streaming chunk updates
- move reasoning and content chunk application into a message utility so the chat handler only wires stream events.
- preserve error-state skipping, reasoning accumulation, and content streaming behavior for assistant messages.
* refactor(playground): extract message reasoning parser
- move think tag parsing into a dedicated playground message utility.
- export the parser through the shared playground lib barrel for consistent imports.
* refactor(playground): extract message streaming utilities
- move stream chunk application and message finalization into a dedicated utility.
- keep stored message sanitization with the streaming lifecycle helpers.
* refactor(playground): extract message update utilities
- move assistant message update helpers into a focused playground utility.
- keep error-state message updates separate from core message construction helpers.
* refactor(playground): extract completion choice handling
- move non-streaming choice application into the message streaming utilities.
- keep the chat handler focused on request orchestration and message updates.
* refactor(playground): centralize assistant completion state
- add a helper for finalizing assistant messages with complete status.
- reuse the helper in stream completion and stop-generation paths.
* refactor(playground): extract stream message parsing
- move SSE delta parsing into a shared stream utility.
- keep the stream request hook focused on lifecycle handling and update dispatch.
* refactor(playground): extract stream ready state checks
- move SSE ready-state status handling into stream utilities.
- keep weak source status typing outside the stream request hook.
* refactor(playground): extract conversation message helpers
- move send, regenerate, and edit message list construction into focused utilities.
- keep the conversation hook focused on edit state and update dispatch.
* refactor(playground): extract state initialization helpers
- move playground initial state loading into focused utility helpers.
- centralize message state updater resolution outside the React state hook.
* refactor(playground): extract option fallback helpers
- move model and group fallback selection into focused playground utilities.
- keep the options hook focused on query results, toasts, and config updates.
* refactor(playground): extract message action helpers
- move message action state derivation into focused utilities.
- keep the action component focused on guarded handlers and rendering.
* refactor(playground): extract input control state
- move submit, stop, and selector state derivation into a pure helper.
- keep input controls focused on rendering model selectors and action buttons.
* refactor(playground): extract message content state
- move source, reasoning, loader, and body visibility checks into a pure helper.
- use a discriminated state shape so rendered reasoning content stays type-safe.
* refactor(playground): extract message editor state
- move save eligibility and submit visibility checks into a pure helper.
- keep the editor component focused on textarea and button rendering.
* refactor(playground): extract message error state
- move error kind, fallback content, and admin visibility checks into a pure helper.
- centralize the model pricing settings path used by the error action.
* refactor(playground): extract chat render state
- move editing content lookup and per-message render flags into conversation helpers.
- keep the chat component focused on mapping messages to editor and content views.
* refactor(playground): extract suggestion display state
- move suggestion class selection into a pure helper.
- keep the suggestions component focused on translation and rendering.
* refactor(playground): extract assistant message state checks
- move final and pending assistant status checks into streaming utilities.
- keep the chat handler focused on request lifecycle updates.
* refactor(playground): extract input tool state
- move attachment action metadata and development notices into input tool utilities.
- keep the input tools component focused on menu and button rendering.
* refactor(playground): extract stream protocol checks
- move SSE done-message and closed-ready-state checks into stream utilities.
- keep the stream request hook focused on event handling flow.
* refactor(playground): extract message removal helper
- move delete-message filtering into conversation message utilities.
- keep the conversation hook focused on action orchestration.
* refactor(playground): extract option error messages
- move option load error message selection into playground option utilities
- keep the options hook focused on query effects and fallback updates
* refactor(playground): extract input submit text helper
- move prompt submit text validation into input control utilities
- let the input component submit only when a concrete text value is available
* refactor(playground): centralize error message checks
- add a shared helper for identifying error messages
- remove direct status string checks from message content rendering
* refactor(playground): extract message content display checks
- move loader and content visibility decisions into local helper functions
- keep message content state assembly focused on composing render state
* refactor(playground): replace raw message role checks
- use shared message role constants in conversation edit handling
- avoid raw assistant role literals when validating API messages
* refactor(playground): extract non-stream response handling
- move chat completion response choice handling into message streaming utilities
- keep the chat handler focused on request lifecycle and error routing
* refactor(playground): centralize stream cleanup
- reuse one stream cleanup path for completion, errors, startup failures, and manual stops
- preserve the current-source guard when closing SSE streams
* refactor(playground): extract pending assistant check
- centralize pending assistant message detection in streaming utilities
- reuse the helper when sanitizing stored playground messages
* perf(playground): improve mobile input controls
- split mobile input controls into selector and action rows
- keep the desktop input footer compact while reducing mobile control crowding
* perf(playground): add starter empty state
- show starter prompts in the empty playground chat area
- wire empty-state prompt selection into the existing send flow
- add localized copy for the new empty state
* perf(playground): improve mobile message actions
- collapse mobile message actions into a touch-friendly dropdown menu
- keep the desktop hover action strip unchanged for pointer workflows
- share one action list between desktop buttons and the mobile menu
* perf(playground): add error recovery actions
- show retry, edit, and delete actions inside error message alerts
- route edit recovery to the previous user prompt when available
- keep recovery controls touch-friendly on mobile layouts
* perf(playground): refine message editing experience
- present message edits in a focused bordered editor panel
- add unsaved-change state, reset, and cancel confirmation flows
- improve mobile touch targets and keyboard shortcuts for editing
* perf(playground): improve markdown code blocks
- render fenced markdown code with syntax highlighting, line numbers, and fallback plain text
- add copy, download, and collapse controls for playground AI responses
- tighten code block layout and theme token styles for responsive markdown rendering
* fix(playground): constrain markdown code block height
- collapse long playground code blocks after a short preview instead of waiting for very large snippets
- cap expanded code blocks so long responses scroll inside the code block
- keep generic code block usage unconstrained unless a caller opts in
* feat(playground): add chat history clearing
- add a toolbar action that is enabled only when saved playground messages exist.
- confirm destructive clears before removing browser-stored conversation state.
- add localized strings for the action, dialog, and completion toast.
* perf(playground): improve chat markdown rendering
- refine assistant and user message surfaces so chat content matches the app UI.
- normalize markdown typography, tables, images, lists, blockquotes, and details rendering.
- add indentation cues for collapsible reasoning and source sections.
* style: format code block component
* style: format playground frontend files
* feat(playground): render markdown with stream parser
- replace Streamdown with stream-markdown-parser for project-owned markdown rendering and styling.
- split response rendering into focused block, inline, table, alert, details, and footnote modules.
- pass message final state into response parsing so streaming content can be parsed incrementally.
* fix(playground): localize reasoning and chat feedback
- translate reasoning status, message actions, playground errors, and response renderer fallbacks across supported locales.
- keep reasoning duration numeric and tighten the collapsible layout to prevent trigger jitter.
- register dynamic keys so i18n sync keeps runtime labels covered.
* refactor(playground): group files by functional area
- move chat, input, and message components into focused subdirectories to make the UI structure easier to scan.
- split playground helpers into input, message, streaming, storage, options, state, and suggestions modules.
- update barrel exports and imports so existing feature entry points continue to work.
* fix(playground): prevent history replay from freezing page
- defer saved conversation loading so route entry no longer blocks on localStorage parsing and markdown rendering.
- limit initial history rendering and skip expensive markdown parsing for oversized responses.
- normalize corrupted streaming snapshots and cumulative chunks to keep saved playground history bounded.
- add message timing metadata and layout alignment groundwork without introducing live timers.
* feat(playground): allow regenerating from user messages
- show regenerate actions on user messages with saved content.
- truncate following conversation state before starting a fresh assistant response.
* feat(playground): add raw response source view
- add a per-message source toggle for assistant responses.
- render raw response content with the existing code block viewer.
- localize the new source and preview action labels.
* feat(playground): render code with unified editor
- replace Shiki HTML rendering with a read-only CodeMirror view for code blocks and raw responses.
- reuse the same CodeMirror frame for message editing so source and edit modes stay visually aligned.
- add lightweight CodeMirror dependencies while keeping language support scoped to Markdown.
* perf(playground): streamline chat input controls
- combine model and group selection into one compact picker for faster context switching.
- switch playground action buttons to icon-first controls with tooltips to reduce toolbar width.
- refresh input footer styling and submit states so active and destructive actions are clearer.
- bump dompurify lockfile entry to keep the frontend dependency current.
* fix(playground): filter models by selected group
- query user models by the selected playground group instead of reusing the cross-group model union.
- clear unavailable model selections and block sending when the active group has no models.
- align model selector and error action controls with the existing playground interaction style.
* perf(playground): remove input suggestion chips
- remove the prompt suggestion row below the playground input to reduce visual noise.
- delete the now-unused suggestion component and display helper.
* perf(playground): stabilize reasoning trigger layout
- use fixed icon slots around the reasoning label so the left content stays still when toggling.
- limit the open state animation to the chevron rotation for a smoother collapse interaction.
* perf(playground): smooth reasoning expansion
- use the collapsible panel height animation for vertical reasoning reveals.
- sync inner content opacity and position with the panel state.
Resolve verified V1 frontend feedback by improving channel workflows, auth behavior, API key interactions, user filtering, layout persistence, subscription quota handling, i18n text, pricing metadata, and stale frontend cache recovery.
- Add a global frontend cache version cleanup to prevent old frontend localStorage from causing page errors after upgrades.
- Fix channel copy refresh, model mapping input focus loss, create-channel fetch-model title state, upstream model update confirmation, and batch test toast behavior.
- Respect password login settings and improve Turnstile, forgot-password, registration, and invite-link flows.
- Make user role/status filtering server-side and preserve table page size in URLs.
- Improve API key edit validation feedback and prefetch real keys for reliable copy actions.
- Fix rankings access fail-open behavior, double scrollbars, subscription received amount conversion/display, token i18n wording, model deletion confirmation grammar, and Claude pricing context inference.
- Add clearer Playground model/group loading errors.
Validation:
- bun run typecheck
- bun run i18n:sync
- gofmt on modified Go files
- go test ./controller ./model -run '^$'
Admin username/ID was embedded directly into the log Content for
quota changes and forced 2FA disable, leaking the operator's
identity to the target user via their own usage log page.
Move operator info into Other.admin_info so formatUserLogs strips
it for non-admin viewers, and render it in the expand panel only
for admins as "操作管理员".
Closes#4301
When an admin disables/deletes/promotes/demotes a user via ManageUser,
explicitly evict the user cache and all of the user's token caches from
Redis. This prevents a disabled user from continuing to make successful
API requests until the user cache TTL expires, and ensures subsequent
requests reload fresh status from the database.
ValidateAndFill now checks the DB query result and returns sentinel errors
(ErrDatabase, ErrInvalidCredentials, ErrUserEmptyCredentials) instead of
hardcoded Chinese strings. The controller maps each sentinel to the
appropriate i18n message, so users see "please contact admin" on DB errors
instead of a misleading "wrong password" message. Non-DB errors still
return a unified vague response to avoid leaking user existence.
- Refactor token, redemption, and user quota inputs to prioritize monetary
amount entry, with raw quota input collapsed by default
- Add atomic quota adjustment modal for users with add/subtract/override modes,
bypassing batch update queue for immediate DB consistency
- Make user quota fields readonly in edit form; all modifications go through
the dedicated adjust-quota modal via POST /api/user/manage
- Add DecreaseUserQuota `db` parameter for direct DB writes, matching
IncreaseUserQuota behavior
- Support negative quota display in amount conversion helpers
- Add i18n keys for all new UI strings across all locales
- Switch /api/oauth/email/bind and /api/oauth/wechat/bind from GET to
POST with JSON body for better REST semantics
- Normalize password reset endpoint to return consistent responses
- Apply url.QueryEscape to WeChat code parameter for robustness
- Change default language fallback to English instead of Chinese
- Add ErrRedeemFailed typed error for model layer translation
- Migrate remaining hardcoded messages in controller/user.go
- Add translation keys: redeem.failed, user.create_default_token_error, common.uuid_duplicate, common.invalid_input
- Add go-i18n library for internationalization
- Create i18n package with translation keys and YAML locale files (zh/en)
- Implement i18n middleware for language detection from user settings and Accept-Language header
- Add Language field to UserSetting DTO
- Update API response helpers with i18n support (ApiErrorI18n, ApiSuccessI18n)
- Migrate hardcoded messages in token, redemption, and user controllers
- Add frontend language preference settings component
- Sync language preference across header selector and user settings
- Auto-restore user language preference on login
This commit refactors the logging mechanism across the application by replacing direct logger calls with a centralized logging approach using the `common` package. Key changes include:
- Replaced instances of `logger.SysLog` and `logger.FatalLog` with `common.SysLog` and `common.FatalLog` for consistent logging practices.
- Updated resource initialization error handling to utilize the new logging structure, enhancing maintainability and readability.
- Minor adjustments to improve code clarity and organization throughout various modules.
This change aims to streamline logging and improve the overall architecture of the codebase.
This commit introduces a major architectural refactoring to improve quota management, centralize logging, and streamline the relay handling logic.
Key changes:
- **Pre-consume Quota:** Implements a new mechanism to check and reserve user quota *before* making the request to the upstream provider. This ensures more accurate quota deduction and prevents users from exceeding their limits due to concurrent requests.
- **Unified Relay Handlers:** Refactors the relay logic to use generic handlers (e.g., `ChatHandler`, `ImageHandler`) instead of provider-specific implementations. This significantly reduces code duplication and simplifies adding new channels.
- **Centralized Logger:** A new dedicated `logger` package is introduced, and all system logging calls are migrated to use it, moving this responsibility out of the `common` package.
- **Code Reorganization:** DTOs are generalized (e.g., `dalle.go` -> `openai_image.go`) and utility code is moved to more appropriate packages (e.g., `common/http.go` -> `service/http.go`) for better code structure.
* 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.
- 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.
- 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