Commit Graph

840 Commits

Author SHA1 Message Date
Calcium-Ion
df1ec4832c Merge branch 'alpha' into main 2025-08-23 15:27:08 +08:00
funnycups
e3473e3c39 fix: prompt calculation
User will correctly get estimated prompt usage when upstream returns either zero or nothing.
2025-08-16 22:54:00 +08:00
CaIon
f8ca8d7cea fix: refactor processChannelError to use goroutine for asynchronous handling 2025-08-16 15:15:19 +08:00
CaIon
64a752a3b4 Merge remote-tracking branch 'origin/alpha' into alpha 2025-08-16 12:28:46 +08:00
Calcium-Ion
0ad918c21d Merge pull request #1584 from feitianbubu/pr/use-proxy-fetch-models
feat: use proxy HTTP client fetch models
2025-08-16 12:27:36 +08:00
CaIon
f70cac54d1 feat: implement concurrent top-up locking mechanism to prevent race conditions 2025-08-15 20:03:38 +08:00
CaIon
f6a48434c1 feat: initialize channel metadata in mjproxy and relay processing 2025-08-15 19:14:29 +08:00
CaIon
28bd31a30b feat: initialize channel metadata in relay processing 2025-08-15 19:00:16 +08:00
CaIon
491013e27a refactor: comment out SetContextKey to prevent token count meta setting 2025-08-15 18:43:08 +08:00
CaIon
0bb43aa464 refactor: update function signatures to include context and improve file handling #1599 2025-08-15 18:40:54 +08:00
CaIon
5fe1ce89ec refactor: improve request type validation and enhance sensitive information masking 2025-08-15 13:20:36 +08:00
CaIon
03fc89da00 refactor: add email masking function and enhance RelayInfo logging
This commit introduces a new function, MaskEmail, to mask user email addresses in logs, preventing PII leakage. Additionally, the RelayInfo logging has been updated to utilize this new masking function, ensuring sensitive information is properly handled. The channel test logic has also been improved to dynamically determine the relay format based on the request path.
2025-08-15 12:50:27 +08:00
CaIon
7f1f368065 refactor: improve channel base URL handling and enhance RelayInfo logging 2025-08-14 22:15:18 +08:00
CaIon
6748b006b7 refactor: centralize logging and update resource initialization
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.
2025-08-14 21:10:04 +08:00
CaIon
e2037ad756 refactor: Introduce pre-consume quota and unify relay handlers
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.
2025-08-14 20:05:06 +08:00
feitianbubu
01cd279f9f feat: use proxy HTTP client fetch models 2025-08-13 18:17:11 +08:00
CaIon
fa2edd9d3f fix(relay): remove unnecessary channel type check for BadRequest 2025-08-12 16:12:47 +08:00
t0ng7u
4ad8eefaec 🚀 perf: optimize model management APIs, unify pricing types as array, and remove redundancies
Backend
- Add GetBoundChannelsByModelsMap to batch-fetch bound channels via a single JOIN (Distinct), compatible with SQLite/MySQL/PostgreSQL
- Replace per-record enrichment with a single-pass enrichModels to avoid N+1 queries; compute unions for prefix/suffix/contains matches in memory
- Change Model.QuotaType to QuotaTypes []int and expose quota_types in responses
- Add GetModelQuotaTypes for cached O(1) lookups; exact models return a single-element array
- Sort quota_types for stable output order
- Remove unused code: GetModelByName, GetBoundChannels, GetBoundChannelsForModels, FindModelByNameWithRule, buildPrefixes, buildSuffixes
- Clean up redundant comments, keeping concise and readable code

Frontend
- Models table: switch to quota_types, render multiple billing modes ([0], [1], [0,1], future values supported)
- Pricing table: switch to quota_types; ratio display now checks quota_types.includes(0); array rendering for billing tags

Compatibility
- SQL uses standard JOIN/IN/Distinct; works across SQLite/MySQL/PostgreSQL
- Lint passes; no DB schema changes (quota_types is a JSON response field only)

Breaking Change
- API field renamed: quota_type -> quota_types (array). Update clients accordingly.
2025-08-11 14:40:01 +08:00
t0ng7u
b97a683bfd Merge remote-tracking branch 'origin/alpha' into alpha 2025-08-10 23:18:16 +08:00
t0ng7u
195be56c46 🏎️ perf: optimize aggregated model look-ups by batching bound-channel queries
Summary
-------
1. **Backend**
   • `model/model_meta.go`
     – Add `GetBoundChannelsForModels([]string)` to retrieve channels for multiple models in a single SQL (`IN (?)`) and deduplicate with `GROUP BY`.

   • `controller/model_meta.go`
     – In non-exact `fillModelExtra`:
       – Remove per-model `GetBoundChannels` calls.
       – Collect matched model names, then call `GetBoundChannelsForModels` once and merge results into `channelSet`.
       – Minor cleanup on loop logic; channel aggregation now happens after quota/group/endpoint processing.

Impact
------
• Eliminates N+1 query pattern for prefix/suffix/contains rules.
• Reduces DB round-trips from *N + 1* to **1**, markedly speeding up the model-management list load.
• Keeps existing `GetBoundChannels` API intact for single-model scenarios; no breaking changes.
2025-08-10 23:11:35 +08:00
Seefs
78662e8194 Merge pull request #1547 from seefs001/feature/model_list
 feat: Enhance model listing and retrieval with support for Anthropic and Gemini models; refactor routes for better API key handling
2025-08-10 22:57:20 +08:00
t0ng7u
c8f7aa76e7 🔍 feat: Show matched model names & counts for non-exact model rules
Summary
-------
1. **Backend**
   • `model/model_meta.go`
     – Add `MatchedModels []string` and `MatchedCount int` (ignored by GORM) to expose matching details in API responses.
   • `controller/model_meta.go`
     – When processing prefix/suffix/contains rules in `fillModelExtra`, collect every matched model name, fill `MatchedModels`, and calculate `MatchedCount`.

2. **Frontend**
   • `web/src/components/table/models/ModelsColumnDefs.js`
     – Import `Tooltip`.
     – Enhance `renderNameRule` to:
       – Display tag text like “前缀 5个模型” for non-exact rules.
       – Show a tooltip listing all matched model names on hover.

Impact
------
Users now see the total number of concrete models aggregated under each prefix/suffix/contains rule and can inspect the exact list via tooltip, improving transparency in model management.
2025-08-10 21:32:18 +08:00
t0ng7u
94bd44d0f2 feat: enhance model billing aggregation & UI display for unknown quota type
Summary
-------
1. **Backend**
   • `controller/model_meta.go`
     – For prefix/suffix/contains rules, aggregate endpoints, bound channels, enable groups, and quota types across all matched models.
     – When mixed billing types are detected, return `quota_type = -1` (unknown) instead of defaulting to volume-based.

2. **Frontend**
   • `web/src/helpers/utils.js`
     – `calculateModelPrice` now handles `quota_type = -1`, returning placeholder `'-'`.

   • `web/src/components/table/model-pricing/view/card/PricingCardView.jsx`
     – Billing tag logic updated: displays “按次计费” (times), “按量计费” (volume), or `'-'` for unknown.

   • `web/src/components/table/model-pricing/view/table/PricingTableColumns.js`
     – `renderQuotaType` shows “未知” for unknown billing type.

   • `web/src/components/table/models/ModelsColumnDefs.js`
     – Unified `renderQuotaType` to return `'-'` when type is unknown.

   • `web/src/components/table/model-pricing/modal/components/ModelPricingTable.jsx`
     – Group price table honors unknown billing type; pricing columns show `'-'` and neutral tag color.

3. **Utilities**
   • Added safe fallback colours/tags for unknown billing type across affected components.

Impact
------
• Ensures correct data aggregation for non-exact model matches.
• Prevents UI from implying volume billing when actual type is ambiguous.
• Provides consistent placeholder display (`'-'` or “未知”) across cards, tables and modals.

No breaking API changes; frontend gracefully handles legacy values.
2025-08-10 21:09:49 +08:00
t0ng7u
1d578b73ce 🖼️ chore: format code file 2025-08-10 12:11:31 +08:00
nekohy
fdb6a3ce16 feat: Enhance model listing and retrieval with support for Anthropic and Gemini models; refactor routes for better API key handling 2025-08-10 11:44:38 +08:00
Calcium-Ion
f942361f7b Merge pull request #1496 from Bliod-Cook/feat-linuxdo-minumum-trust-level
feat: allow admin to restrict the minimum linuxdo trust level to register
2025-08-10 10:27:40 +08:00
RedwindA
03b670971b Merge branch 'alpha' into 'feat/support-native-gemini-embedding' 2025-08-09 18:05:11 +08:00
Calcium-Ion
c7c7229b8b Merge pull request #1458 from simplty/fix/midjourney-field-compatibility
fix(midjourney): 为 Midjourney 任务添加视频 URL 字段
2025-08-09 11:35:22 +08:00
RedwindA
b70d2655ed feat: support native Gemini Embedding 2025-08-09 00:27:33 +08:00
t0ng7u
1690b05629 🚀 feat(pricing): clarify “auto” group routing chain and exclude it from price table
Detailed changes
Backend
• `controller/pricing.go` now includes `auto_groups` in `/api/pricing` response, sourced from `setting.AutoGroups`.

Frontend
• `useModelPricingData.js`
  – Parses `auto_groups` and exposes `autoGroups` state.
• `PricingPage.jsx` → `ModelDetailSideSheet.jsx` → `ModelPricingTable.jsx`
  – Thread `autoGroups` through component tree.
• `ModelPricingTable.jsx`
  – Removes deprecated `getGroupDescription` / `Tooltip`.
  – Filters out `auto` when building price table rows.
  – Renders a descriptive banner: “auto 分组调用链路 → auto → group1 → …”, clarifying fallback order without showing prices.
• Minor i18n tweak: adds `auto分组调用链路` key for the banner text.

Why
Users were confused by the “auto” tag appearing alongside regular groups with no price.
This change:
1. Makes the routing chain explicit.
2. Keeps the pricing table focused on billable groups.

No breaking API changes; existing clients can ignore the new `auto_groups` field.
2025-08-08 14:49:55 +08:00
CaIon
29ec328f46 fix: playground group 2025-08-08 11:59:04 +08:00
t0ng7u
26f44b8d4b Merge remote-tracking branch 'origin/alpha' into refactor/model-pricing 2025-08-08 02:34:44 +08:00
t0ng7u
8fba0017c7 feat(pricing+endpoints+ui): wire custom endpoint mapping end‑to‑end and overhaul visual JSON editor
Backend (Go)
- Include custom endpoints in each model’s SupportedEndpointTypes by parsing Model.Endpoints (JSON) and appending keys alongside native endpoint types.
- Build a global supportedEndpointMap map[string]EndpointInfo{path, method} by:
  - Seeding with native defaults.
  - Overriding/adding from models.endpoints (accepts string path → default POST, or {path, method}).
- Expose supported_endpoint at the top level of /api/pricing (vendors-like), removing per-model duplication.
- Fix default path for EndpointTypeOpenAIResponse to /v1/responses.
- Keep concurrency/caching for pricing retrieval intact.

Frontend (React)
- Fetch supported_endpoint in useModelPricingData and propagate to PricingPage → ModelDetailSideSheet → ModelEndpoints.
- ModelEndpoints
  - Resolve path+method via endpointMap; replace {model} with actual model name.
  - Fix mobile visibility; always show path and HTTP method.
- JSONEditor
  - Wrap with Form.Slot to inherit form layout; simplify visual styles.
  - Use Tabs for “Visual” / “Manual” modes.
  - Unify editors: key-value editor now supports nested JSON:
    - “+” to convert a primitive into an object and add nested fields.
    - Add “Convert to value” for two‑way toggle back from object.
    - Stable key rename without reordering rows; new rows append at bottom.
    - Use Row/Col grid for clean alignment; region editor uses Form.Slot + grid.
- Editing flows
  - EditModelModal / EditPrefillGroupModal use JSONEditor (editorType='object') for endpoint mappings.
  - PrefillGroupManagement renders endpoint group items by JSON keys.

Data expectations / compatibility
- models.endpoints should be a JSON object mapping endpoint type → string path or {path, method}. Strings default to POST.
- No schema changes; existing TEXT field continues to store JSON.

QA
- /api/pricing now returns custom endpoint types and global supported_endpoint.
- UI shows both native and custom endpoints; paths/methods render on mobile; nested editing works and preserves order.
2025-08-08 02:34:15 +08:00
Calcium-Ion
677a02c632 Merge pull request #1517 from RedwindA/fix/gemini-fetch-models
Fix/gemini-fetch-models
2025-08-07 20:44:34 +08:00
IcedTangerine
8a964efbed Merge pull request #1519 from feitianbubu/pr/fix-qwen3-thinking-test
feat: enable thinking mode on ali thinking model
2025-08-07 17:39:27 +08:00
CaIon
d9c1fb5244 feat: update MaxTokens handling 2025-08-07 16:15:59 +08:00
feitianbubu
38067f1ddc feat: enable thinking mode on ali thinking model 2025-08-07 11:59:54 +08:00
RedwindA
ed95a9f2b2 fix a typo in comment 2025-08-07 01:11:01 +08:00
RedwindA
76d71a032a fix: 修复 FetchUpstreamModels 函数中 AuthHeader 的使用,确保正确处理 多key聚合的情况 2025-08-07 01:01:45 +08:00
RedwindA
38bff1a0e0 refactor: 移除 GoogleOpenAI 兼容模型相关结构体,简化 FetchUpstreamModels 函数逻辑 2025-08-07 00:54:48 +08:00
t0ng7u
7c814a5fd9 🚀 refactor: migrate vendor-count aggregation to model layer & align frontend logic
Summary
• Backend
  – Moved duplicate-name validation and total vendor-count aggregation from controllers (`controller/model_meta.go`, `controller/vendor_meta.go`, `controller/prefill_group.go`) to model layer (`model/model_meta.go`, `model/vendor_meta.go`, `model/prefill_group.go`).
  – Added `GetVendorModelCounts()` and `Is*NameDuplicated()` helpers; controllers now call these instead of duplicating queries.
  – API response for `/api/models` now returns `vendor_counts` with per-vendor totals across all pages, plus `all` summary.
  – Removed redundant checks and unused imports, eliminating `go vet` warnings.

• Frontend
  – `useModelsData.js` updated to consume backend-supplied `vendor_counts`, calculate the `all` total once, and drop legacy client-side counting logic.
  – Simplified initial data flow: first render now triggers only one models request.
  – Deleted obsolete `updateVendorCounts` helper and related comments.
  – Ensured search flow also sets `vendorCounts`, keeping tab badges accurate.

Why
This refactor enforces single-responsibility (aggregation in model layer), delivers consistent totals irrespective of pagination, and removes redundant client queries, leading to cleaner code and better performance.
2025-08-06 01:40:08 +08:00
t0ng7u
d61a862fa2 Merge remote-tracking branch 'origin/alpha' into refactor/model-pricing 2025-08-05 23:19:24 +08:00
t0ng7u
327a0ca323 🚀 refactor: refine pricing refresh logic & hide disabled models
Summary
-------
1. Pricing generation
   • `model/pricing.go`: skip any model whose `status != 1` when building
     `pricingMap`, ensuring disabled models are never returned to the
     front-end.

2. Cache refresh placement
   • `controller/model_meta.go`
     – Removed `model.RefreshPricing()` from pure read handlers
       (`GetAllModelsMeta`, `SearchModelsMeta`).
     – Kept refresh only in mutating handlers
       (`Create`, `Update`, `Delete`), guaranteeing data is updated
       immediately after an admin change while avoiding redundant work
       on every read.

Result
------
Front-end no longer receives information about disabled models, and
pricing cache refreshes occur exactly when model data is modified,
improving efficiency and consistency.
2025-08-05 23:18:12 +08:00
Calcium-Ion
306a1a3f57 Merge pull request #1507 from QuantumNous/multi-key-manage
feat: implement channel-specific locking for thread-safe polling
2025-08-05 20:40:26 +08:00
t0ng7u
512850e83d Merge remote-tracking branch 'origin/alpha' into refactor/model-pricing 2025-08-04 21:37:38 +08:00
t0ng7u
0e9c3cde7c 🏗️ refactor: Replace model categories with vendor-based filtering and optimize data structure
- **Backend Changes:**
  - Refactor pricing API to return separate vendors array with ID-based model references
  - Remove redundant vendor_name/vendor_icon fields from pricing records, use vendor_id only
  - Add vendor_description to pricing response for frontend display
  - Maintain 1-minute cache protection for pricing endpoint security

- **Frontend Data Flow:**
  - Update useModelPricingData hook to build vendorsMap from API response
  - Enhance model records with vendor info during data processing
  - Pass vendorsMap through component hierarchy for consistent vendor data access

- **UI Component Replacements:**
  - Replace PricingCategories with PricingVendors component for vendor-based filtering
  - Replace PricingCategoryIntro with PricingVendorIntro in header section
  - Remove all model category related components and logic

- **Header Improvements:**
  - Implement vendor intro with real backend data (name, icon, description)
  - Add text collapsible feature (2-line limit with expand/collapse functionality)
  - Support carousel animation for "All Vendors" view with vendor icon rotation

- **Model Detail Modal Enhancements:**
  - Update ModelHeader to use real vendor icons via getLobeHubIcon()
  - Move tags from header to ModelBasicInfo content area to avoid SideSheet title width constraints
  - Display only custom tags from backend with stringToColor() for consistent styling
  - Use Space component with wrap property for proper tag layout

- **Table View Optimizations:**
  - Integrate RenderUtils for description and tags columns
  - Implement renderLimitedItems for tags (max 3 visible, +x popover for overflow)
  - Use renderDescription for text truncation with tooltip support

- **Filter Logic Updates:**
  - Vendor filter shows disabled options instead of hiding when no models match
  - Include "Unknown Vendor" category for models without vendor information
  - Remove all hardcoded vendor descriptions, use real backend data

- **Code Quality:**
  - Fix import paths after component relocation
  - Remove unused model category utilities and hardcoded mappings
  - Ensure consistent vendor data usage across all pricing views
  - Maintain backward compatibility with existing pricing calculation logic

This refactor provides a more scalable vendor-based architecture while eliminating
data redundancy and improving user experience with real-time backend data integration.
2025-08-04 21:36:31 +08:00
CaIon
8cce3cc84a feat: implement channel-specific locking for thread-safe polling 2025-08-04 20:44:19 +08:00
Calcium-Ion
9c079d04a8 Merge pull request #1487 from seefs001/feature/2fa
feat: implement two-factor authentication (2FA) support with user login and settings integration
2025-08-04 19:54:31 +08:00
CaIon
12b4e80d4b feat: add status filtering and bulk enable/disable functionality in multi-key management 2025-08-04 19:51:58 +08:00
Bliod-Cook
3feeca627c feat: allow admin to restrict the minimum linuxdo trust level to register 2025-08-04 17:19:38 +08:00