2025-08-23 20:12:35 +08:00
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
|
use serde_json::Value;
|
|
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
2025-09-04 16:16:51 +08:00
|
|
|
|
// SSOT 模式:不再写供应商副本文件
|
2025-08-23 20:12:35 +08:00
|
|
|
|
|
|
|
|
|
|
/// 供应商结构体
|
|
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
|
|
|
|
pub struct Provider {
|
|
|
|
|
|
pub id: String,
|
|
|
|
|
|
pub name: String,
|
|
|
|
|
|
#[serde(rename = "settingsConfig")]
|
|
|
|
|
|
pub settings_config: Value,
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
#[serde(rename = "websiteUrl")]
|
|
|
|
|
|
pub website_url: Option<String>,
|
2025-09-11 22:33:55 +08:00
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub category: Option<String>,
|
2025-09-22 10:46:18 +08:00
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
#[serde(rename = "createdAt")]
|
|
|
|
|
|
pub created_at: Option<i64>,
|
2025-10-15 22:21:06 +08:00
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
#[serde(rename = "sortIndex")]
|
|
|
|
|
|
pub sort_index: Option<usize>,
|
feat: add model configuration support and fix Gemini deeplink bug (#251)
* feat(providers): add notes field for provider management
- Add notes field to Provider model (backend and frontend)
- Display notes with higher priority than URL in provider card
- Style notes as non-clickable text to differentiate from URLs
- Add notes input field in provider form
- Add i18n support (zh/en) for notes field
* chore: format code and clean up unused props
- Run cargo fmt on Rust backend code
- Format TypeScript imports and code style
- Remove unused appId prop from ProviderPresetSelector
- Clean up unused variables in tests
- Integrate notes field handling in provider dialogs
* feat(deeplink): implement ccswitch:// protocol for provider import
Add deep link support to enable one-click provider configuration import via ccswitch:// URLs.
Backend:
- Implement URL parsing and validation (src-tauri/src/deeplink.rs)
- Add Tauri commands for parse and import (src-tauri/src/commands/deeplink.rs)
- Register ccswitch:// protocol in macOS Info.plist
- Add comprehensive unit tests (src-tauri/tests/deeplink_import.rs)
Frontend:
- Create confirmation dialog with security review UI (src/components/DeepLinkImportDialog.tsx)
- Add API wrapper (src/lib/api/deeplink.ts)
- Integrate event listeners in App.tsx
Configuration:
- Update Tauri config for deep link handling
- Add i18n support for Chinese and English
- Include test page for deep link validation (deeplink-test.html)
Files: 15 changed, 1312 insertions(+)
* chore(deeplink): integrate deep link handling into app lifecycle
Wire up deep link infrastructure with app initialization and event handling.
Backend Integration:
- Register deep link module and commands in mod.rs
- Add URL handling in app setup (src-tauri/src/lib.rs:handle_deeplink_url)
- Handle deep links from single instance callback (Windows/Linux CLI)
- Handle deep links from macOS system events
- Add tauri-plugin-deep-link dependency (Cargo.toml)
Frontend Integration:
- Listen for deeplink-import/deeplink-error events in App.tsx
- Update DeepLinkImportDialog component imports
Configuration:
- Enable deep link plugin in tauri.conf.json
- Update Cargo.lock for new dependencies
Localization:
- Add Chinese translations for deep link UI (zh.json)
- Add English translations for deep link UI (en.json)
Files: 9 changed, 359 insertions(+), 18 deletions(-)
* refactor(deeplink): enhance Codex provider template generation
Align deep link import with UI preset generation logic by:
- Adding complete config.toml template matching frontend defaults
- Generating safe provider name from sanitized input
- Including model_provider, reasoning_effort, and wire_api settings
- Removing minimal template that only contained base_url
- Cleaning up deprecated test file deeplink-test.html
* style: fix clippy uninlined_format_args warnings
Apply clippy --fix to use inline format arguments in:
- src/mcp.rs (8 fixes)
- src/services/env_manager.rs (10 fixes)
* style: apply code formatting and cleanup
- Format TypeScript files with Prettier (App.tsx, EnvWarningBanner.tsx, formatters.ts)
- Organize Rust imports and module order alphabetically
- Add newline at end of JSON files (en.json, zh.json)
- Update Cargo.lock for dependency changes
* feat: add model name configuration support for Codex and fix Gemini model handling
- Add visual model name input field for Codex providers
- Add model name extraction and update utilities in providerConfigUtils
- Implement model name state management in useCodexConfigState hook
- Add conditional model field rendering in CodexFormFields (non-official only)
- Integrate model name sync with TOML config in ProviderForm
- Fix Gemini deeplink model injection bug
- Correct environment variable name from GOOGLE_GEMINI_MODEL to GEMINI_MODEL
- Add test cases for Gemini model injection (with/without model)
- All tests passing (9/9)
- Fix Gemini model field binding in edit mode
- Add geminiModel state to useGeminiConfigState hook
- Extract model value during initialization and reset
- Sync model field with geminiEnv state to prevent data loss on submit
- Fix missing model value display when editing Gemini providers
Changes:
- 6 files changed, 245 insertions(+), 13 deletions(-)
2025-11-19 09:03:18 +08:00
|
|
|
|
/// 备注信息
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub notes: Option<String>,
|
feat: Implement Speed Test Function
* feat: add unified endpoint speed test for API providers
Add a comprehensive endpoint latency testing system that allows users to:
- Test multiple API endpoints concurrently
- Auto-select the fastest endpoint based on latency
- Add/remove custom endpoints dynamically
- View latency results with color-coded indicators
Backend (Rust):
- Implement parallel HTTP HEAD requests with configurable timeout
- Handle various error scenarios (timeout, connection failure, invalid URL)
- Return structured latency data with status codes
Frontend (React):
- Create interactive speed test UI component with auto-sort by latency
- Support endpoint management (add/remove custom endpoints)
- Extract and update Codex base_url from TOML configuration
- Integrate with provider presets for default endpoint candidates
This feature improves user experience when selecting optimal API endpoints,
especially useful for users with multiple provider options or proxy setups.
* refactor: convert endpoint speed test to modal dialog
- Transform EndpointSpeedTest component into a modal dialog
- Add "Advanced" button next to base URL input to open modal
- Support ESC key and backdrop click to close modal
- Apply Linear design principles: minimal styling, clean layout
- Remove unused showBaseUrlInput variable
- Implement same modal pattern for both Claude and Codex
* fix: prevent modal cascade closing when ESC is pressed
- Add state checks to prevent parent modal from closing when child modals (endpoint speed test or template wizard) are open
- Update ESC key handler dependencies to track all modal states
- Ensures only the topmost modal responds to ESC key
* refactor: unify speed test panel UI with project design system
UI improvements:
- Update modal border radius from rounded-lg to rounded-xl
- Unify header padding from px-6 py-4 to p-6
- Change speed test button color to blue theme (bg-blue-500) for consistency
- Update footer background from bg-gray-50 to bg-gray-100
- Style "Done" button as primary action button with blue theme
- Adjust footer button spacing and hover states
Simplify endpoint display:
- Remove endpoint labels (e.g., "Current Address", "Custom 1")
- Display only URL for cleaner interface
- Clean up all label-related logic:
* Remove label field from EndpointCandidate interface
* Remove label generation in buildInitialEntries function
* Remove label handling in useEffect merge logic
* Remove label generation in handleAddEndpoint
* Remove label parameters from claudeSpeedTestEndpoints
* Remove label parameters from codexSpeedTestEndpoints
* refactor: improve endpoint list UI consistency
- Show delete button for all endpoints on hover for uniform UI
- Change selected state to use blue theme matching main interface:
* Blue border (border-blue-500) for selected items
* Light blue background (bg-blue-50/dark:bg-blue-900/20)
* Blue indicator dot (bg-blue-500/dark:bg-blue-400)
- Switch from compact list (space-y-px) to card-based layout (space-y-2)
- Add rounded corners to each endpoint item for better visual separation
* feat: persist custom endpoints to settings.json
- Extend AppSettings to store custom endpoints for Claude and Codex
- Add Tauri commands: get/add/remove/update custom endpoints
- Update frontend API with endpoint persistence methods
- Modify EndpointSpeedTest to load/save custom endpoints via API
- Track endpoint last used time for future sorting/cleanup
- Store endpoints per app type in settings.json instead of localStorage
* - feat(types): add Provider.meta and ProviderMeta (snake_case) with custom_endpoints map
- feat(provider-form): persist custom endpoints on provider create by merging EndpointSpeedTest’s custom URLs into meta.custom_endpoints on submit
- feat(endpoint-speed-test): add onCustomEndpointsChange callback emitting normalized custom URLs; wire it for both Claude/Codex modals
- fix(api): send alias param names (app/appType/app_type and provider_id/providerId) in Tauri invokes to avoid “missing providerId” with older backends
- storage: custom endpoints are stored in ~/.cc-switch/config.json under providers[<id>].meta.custom_endpoints (not in settings.json)
- behavior: edit flow remains immediate writes; create flow now writes once via addProvider, removing the providerId dependency during creation
* feat: add endpoint candidates support and code formatting improvements
- Add endpointCandidates field to ProviderPreset and CodexProviderPreset interfaces
- Integrate preset endpoint candidates into speed test endpoint selection
- Add multiple endpoint options for PackyCode providers (Claude & Codex)
- Apply consistent code formatting (trailing commas, line breaks)
- Improve template value type safety and readability
* refactor: improve endpoint management button UX
Replace ambiguous "Advanced" text with intuitive "Manage & Test" label accompanied by Zap icon, making the endpoint management panel entry point more discoverable and self-explanatory for both Claude and Codex configurations.
* - merge: merge origin/main, resolve conflicts and preserve both feature sets
- feat(tauri): register import/export and file dialogs; keep endpoint speed test and custom endpoints
- feat(api): add updateTrayMenu and onProviderSwitched; wire import/export APIs
- feat(types): extend global API declarations (import/export)
- chore(presets): GLM preset supports both new and legacy model keys
- chore(rust): add chrono dependency; refresh lockfile
---------
Co-authored-by: Jason <farion1231@gmail.com>
2025-10-07 19:14:32 +08:00
|
|
|
|
/// 供应商元数据(不写入 live 配置,仅存于 ~/.cc-switch/config.json)
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub meta: Option<ProviderMeta>,
|
feat(backend): add icon fields to Provider model and default mappings
Extend Rust backend to support provider icon customization:
## Provider Model (src-tauri/src/provider.rs)
- Add `icon: Option<String>` field for icon name
- Add `icon_color: Option<String>` field for hex color
- Use serde rename `iconColor` for frontend compatibility
- Apply skip_serializing_if for clean JSON output
- Update Provider::new() to initialize icon fields as None
## Provider Defaults (src-tauri/src/provider_defaults.rs) [NEW]
- Define ProviderIcon struct with name and color fields
- Create DEFAULT_PROVIDER_ICONS static HashMap with 23 providers:
- AI providers: OpenAI, Anthropic, Claude, Google, Gemini,
DeepSeek, Kimi, Moonshot, Zhipu, MiniMax, Baidu, Alibaba,
Tencent, Meta, Microsoft, Cohere, Perplexity, Mistral, HuggingFace
- Cloud platforms: AWS, Azure, Huawei, Cloudflare
- Implement infer_provider_icon() with exact and fuzzy matching
- Add unit tests for matching logic (exact, fuzzy, case-insensitive)
## Deep Link Support (src-tauri/src/deeplink.rs)
- Initialize icon fields when creating Provider from deep link import
## Module Registration (src-tauri/src/lib.rs)
- Register provider_defaults module
## Dependencies (Cargo.toml)
- Add once_cell for lazy static initialization
This backend support enables icon persistence and future features
like auto-icon inference during provider creation.
2025-11-21 23:22:51 +08:00
|
|
|
|
/// 图标名称(如 "openai", "anthropic")
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub icon: Option<String>,
|
|
|
|
|
|
/// 图标颜色(Hex 格式,如 "#00A67E")
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
#[serde(rename = "iconColor")]
|
|
|
|
|
|
pub icon_color: Option<String>,
|
2025-08-23 20:12:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Provider {
|
|
|
|
|
|
/// 从现有ID创建供应商
|
2025-08-27 11:00:53 +08:00
|
|
|
|
pub fn with_id(
|
|
|
|
|
|
id: String,
|
|
|
|
|
|
name: String,
|
|
|
|
|
|
settings_config: Value,
|
|
|
|
|
|
website_url: Option<String>,
|
|
|
|
|
|
) -> Self {
|
2025-08-23 20:12:35 +08:00
|
|
|
|
Self {
|
|
|
|
|
|
id,
|
|
|
|
|
|
name,
|
|
|
|
|
|
settings_config,
|
|
|
|
|
|
website_url,
|
2025-09-11 22:33:55 +08:00
|
|
|
|
category: None,
|
2025-09-22 10:46:18 +08:00
|
|
|
|
created_at: None,
|
2025-10-15 22:21:06 +08:00
|
|
|
|
sort_index: None,
|
feat: add model configuration support and fix Gemini deeplink bug (#251)
* feat(providers): add notes field for provider management
- Add notes field to Provider model (backend and frontend)
- Display notes with higher priority than URL in provider card
- Style notes as non-clickable text to differentiate from URLs
- Add notes input field in provider form
- Add i18n support (zh/en) for notes field
* chore: format code and clean up unused props
- Run cargo fmt on Rust backend code
- Format TypeScript imports and code style
- Remove unused appId prop from ProviderPresetSelector
- Clean up unused variables in tests
- Integrate notes field handling in provider dialogs
* feat(deeplink): implement ccswitch:// protocol for provider import
Add deep link support to enable one-click provider configuration import via ccswitch:// URLs.
Backend:
- Implement URL parsing and validation (src-tauri/src/deeplink.rs)
- Add Tauri commands for parse and import (src-tauri/src/commands/deeplink.rs)
- Register ccswitch:// protocol in macOS Info.plist
- Add comprehensive unit tests (src-tauri/tests/deeplink_import.rs)
Frontend:
- Create confirmation dialog with security review UI (src/components/DeepLinkImportDialog.tsx)
- Add API wrapper (src/lib/api/deeplink.ts)
- Integrate event listeners in App.tsx
Configuration:
- Update Tauri config for deep link handling
- Add i18n support for Chinese and English
- Include test page for deep link validation (deeplink-test.html)
Files: 15 changed, 1312 insertions(+)
* chore(deeplink): integrate deep link handling into app lifecycle
Wire up deep link infrastructure with app initialization and event handling.
Backend Integration:
- Register deep link module and commands in mod.rs
- Add URL handling in app setup (src-tauri/src/lib.rs:handle_deeplink_url)
- Handle deep links from single instance callback (Windows/Linux CLI)
- Handle deep links from macOS system events
- Add tauri-plugin-deep-link dependency (Cargo.toml)
Frontend Integration:
- Listen for deeplink-import/deeplink-error events in App.tsx
- Update DeepLinkImportDialog component imports
Configuration:
- Enable deep link plugin in tauri.conf.json
- Update Cargo.lock for new dependencies
Localization:
- Add Chinese translations for deep link UI (zh.json)
- Add English translations for deep link UI (en.json)
Files: 9 changed, 359 insertions(+), 18 deletions(-)
* refactor(deeplink): enhance Codex provider template generation
Align deep link import with UI preset generation logic by:
- Adding complete config.toml template matching frontend defaults
- Generating safe provider name from sanitized input
- Including model_provider, reasoning_effort, and wire_api settings
- Removing minimal template that only contained base_url
- Cleaning up deprecated test file deeplink-test.html
* style: fix clippy uninlined_format_args warnings
Apply clippy --fix to use inline format arguments in:
- src/mcp.rs (8 fixes)
- src/services/env_manager.rs (10 fixes)
* style: apply code formatting and cleanup
- Format TypeScript files with Prettier (App.tsx, EnvWarningBanner.tsx, formatters.ts)
- Organize Rust imports and module order alphabetically
- Add newline at end of JSON files (en.json, zh.json)
- Update Cargo.lock for dependency changes
* feat: add model name configuration support for Codex and fix Gemini model handling
- Add visual model name input field for Codex providers
- Add model name extraction and update utilities in providerConfigUtils
- Implement model name state management in useCodexConfigState hook
- Add conditional model field rendering in CodexFormFields (non-official only)
- Integrate model name sync with TOML config in ProviderForm
- Fix Gemini deeplink model injection bug
- Correct environment variable name from GOOGLE_GEMINI_MODEL to GEMINI_MODEL
- Add test cases for Gemini model injection (with/without model)
- All tests passing (9/9)
- Fix Gemini model field binding in edit mode
- Add geminiModel state to useGeminiConfigState hook
- Extract model value during initialization and reset
- Sync model field with geminiEnv state to prevent data loss on submit
- Fix missing model value display when editing Gemini providers
Changes:
- 6 files changed, 245 insertions(+), 13 deletions(-)
2025-11-19 09:03:18 +08:00
|
|
|
|
notes: None,
|
feat: Implement Speed Test Function
* feat: add unified endpoint speed test for API providers
Add a comprehensive endpoint latency testing system that allows users to:
- Test multiple API endpoints concurrently
- Auto-select the fastest endpoint based on latency
- Add/remove custom endpoints dynamically
- View latency results with color-coded indicators
Backend (Rust):
- Implement parallel HTTP HEAD requests with configurable timeout
- Handle various error scenarios (timeout, connection failure, invalid URL)
- Return structured latency data with status codes
Frontend (React):
- Create interactive speed test UI component with auto-sort by latency
- Support endpoint management (add/remove custom endpoints)
- Extract and update Codex base_url from TOML configuration
- Integrate with provider presets for default endpoint candidates
This feature improves user experience when selecting optimal API endpoints,
especially useful for users with multiple provider options or proxy setups.
* refactor: convert endpoint speed test to modal dialog
- Transform EndpointSpeedTest component into a modal dialog
- Add "Advanced" button next to base URL input to open modal
- Support ESC key and backdrop click to close modal
- Apply Linear design principles: minimal styling, clean layout
- Remove unused showBaseUrlInput variable
- Implement same modal pattern for both Claude and Codex
* fix: prevent modal cascade closing when ESC is pressed
- Add state checks to prevent parent modal from closing when child modals (endpoint speed test or template wizard) are open
- Update ESC key handler dependencies to track all modal states
- Ensures only the topmost modal responds to ESC key
* refactor: unify speed test panel UI with project design system
UI improvements:
- Update modal border radius from rounded-lg to rounded-xl
- Unify header padding from px-6 py-4 to p-6
- Change speed test button color to blue theme (bg-blue-500) for consistency
- Update footer background from bg-gray-50 to bg-gray-100
- Style "Done" button as primary action button with blue theme
- Adjust footer button spacing and hover states
Simplify endpoint display:
- Remove endpoint labels (e.g., "Current Address", "Custom 1")
- Display only URL for cleaner interface
- Clean up all label-related logic:
* Remove label field from EndpointCandidate interface
* Remove label generation in buildInitialEntries function
* Remove label handling in useEffect merge logic
* Remove label generation in handleAddEndpoint
* Remove label parameters from claudeSpeedTestEndpoints
* Remove label parameters from codexSpeedTestEndpoints
* refactor: improve endpoint list UI consistency
- Show delete button for all endpoints on hover for uniform UI
- Change selected state to use blue theme matching main interface:
* Blue border (border-blue-500) for selected items
* Light blue background (bg-blue-50/dark:bg-blue-900/20)
* Blue indicator dot (bg-blue-500/dark:bg-blue-400)
- Switch from compact list (space-y-px) to card-based layout (space-y-2)
- Add rounded corners to each endpoint item for better visual separation
* feat: persist custom endpoints to settings.json
- Extend AppSettings to store custom endpoints for Claude and Codex
- Add Tauri commands: get/add/remove/update custom endpoints
- Update frontend API with endpoint persistence methods
- Modify EndpointSpeedTest to load/save custom endpoints via API
- Track endpoint last used time for future sorting/cleanup
- Store endpoints per app type in settings.json instead of localStorage
* - feat(types): add Provider.meta and ProviderMeta (snake_case) with custom_endpoints map
- feat(provider-form): persist custom endpoints on provider create by merging EndpointSpeedTest’s custom URLs into meta.custom_endpoints on submit
- feat(endpoint-speed-test): add onCustomEndpointsChange callback emitting normalized custom URLs; wire it for both Claude/Codex modals
- fix(api): send alias param names (app/appType/app_type and provider_id/providerId) in Tauri invokes to avoid “missing providerId” with older backends
- storage: custom endpoints are stored in ~/.cc-switch/config.json under providers[<id>].meta.custom_endpoints (not in settings.json)
- behavior: edit flow remains immediate writes; create flow now writes once via addProvider, removing the providerId dependency during creation
* feat: add endpoint candidates support and code formatting improvements
- Add endpointCandidates field to ProviderPreset and CodexProviderPreset interfaces
- Integrate preset endpoint candidates into speed test endpoint selection
- Add multiple endpoint options for PackyCode providers (Claude & Codex)
- Apply consistent code formatting (trailing commas, line breaks)
- Improve template value type safety and readability
* refactor: improve endpoint management button UX
Replace ambiguous "Advanced" text with intuitive "Manage & Test" label accompanied by Zap icon, making the endpoint management panel entry point more discoverable and self-explanatory for both Claude and Codex configurations.
* - merge: merge origin/main, resolve conflicts and preserve both feature sets
- feat(tauri): register import/export and file dialogs; keep endpoint speed test and custom endpoints
- feat(api): add updateTrayMenu and onProviderSwitched; wire import/export APIs
- feat(types): extend global API declarations (import/export)
- chore(presets): GLM preset supports both new and legacy model keys
- chore(rust): add chrono dependency; refresh lockfile
---------
Co-authored-by: Jason <farion1231@gmail.com>
2025-10-07 19:14:32 +08:00
|
|
|
|
meta: None,
|
feat(backend): add icon fields to Provider model and default mappings
Extend Rust backend to support provider icon customization:
## Provider Model (src-tauri/src/provider.rs)
- Add `icon: Option<String>` field for icon name
- Add `icon_color: Option<String>` field for hex color
- Use serde rename `iconColor` for frontend compatibility
- Apply skip_serializing_if for clean JSON output
- Update Provider::new() to initialize icon fields as None
## Provider Defaults (src-tauri/src/provider_defaults.rs) [NEW]
- Define ProviderIcon struct with name and color fields
- Create DEFAULT_PROVIDER_ICONS static HashMap with 23 providers:
- AI providers: OpenAI, Anthropic, Claude, Google, Gemini,
DeepSeek, Kimi, Moonshot, Zhipu, MiniMax, Baidu, Alibaba,
Tencent, Meta, Microsoft, Cohere, Perplexity, Mistral, HuggingFace
- Cloud platforms: AWS, Azure, Huawei, Cloudflare
- Implement infer_provider_icon() with exact and fuzzy matching
- Add unit tests for matching logic (exact, fuzzy, case-insensitive)
## Deep Link Support (src-tauri/src/deeplink.rs)
- Initialize icon fields when creating Provider from deep link import
## Module Registration (src-tauri/src/lib.rs)
- Register provider_defaults module
## Dependencies (Cargo.toml)
- Add once_cell for lazy static initialization
This backend support enables icon persistence and future features
like auto-icon inference during provider creation.
2025-11-21 23:22:51 +08:00
|
|
|
|
icon: None,
|
|
|
|
|
|
icon_color: None,
|
2025-08-23 20:12:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 供应商管理器
|
2025-10-12 16:52:32 +08:00
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
2025-08-23 20:12:35 +08:00
|
|
|
|
pub struct ProviderManager {
|
|
|
|
|
|
pub providers: HashMap<String, Provider>,
|
|
|
|
|
|
pub current: String,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-15 09:15:25 +08:00
|
|
|
|
/// 用量查询脚本配置
|
|
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
|
|
|
|
pub struct UsageScript {
|
|
|
|
|
|
pub enabled: bool,
|
|
|
|
|
|
pub language: String,
|
|
|
|
|
|
pub code: String,
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub timeout: Option<u64>,
|
2025-11-10 15:28:09 +08:00
|
|
|
|
/// 用量查询专用的 API Key(通用模板使用)
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
#[serde(rename = "apiKey")]
|
|
|
|
|
|
pub api_key: Option<String>,
|
|
|
|
|
|
/// 用量查询专用的 Base URL(通用和 NewAPI 模板使用)
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
#[serde(rename = "baseUrl")]
|
|
|
|
|
|
pub base_url: Option<String>,
|
|
|
|
|
|
/// 访问令牌(用于需要登录的接口,NewAPI 模板使用)
|
2025-11-04 11:30:14 +08:00
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
#[serde(rename = "accessToken")]
|
|
|
|
|
|
pub access_token: Option<String>,
|
2025-11-10 15:28:09 +08:00
|
|
|
|
/// 用户ID(用于需要用户标识的接口,NewAPI 模板使用)
|
2025-11-04 11:30:14 +08:00
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
#[serde(rename = "userId")]
|
|
|
|
|
|
pub user_id: Option<String>,
|
2025-11-05 15:48:19 +08:00
|
|
|
|
/// 自动查询间隔(单位:分钟,0 表示禁用自动查询)
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
#[serde(rename = "autoQueryInterval")]
|
|
|
|
|
|
pub auto_query_interval: Option<u64>,
|
2025-10-15 09:15:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 用量数据
|
|
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
|
|
|
|
pub struct UsageData {
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
#[serde(rename = "planName")]
|
|
|
|
|
|
pub plan_name: Option<String>,
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub extra: Option<String>,
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
#[serde(rename = "isValid")]
|
|
|
|
|
|
pub is_valid: Option<bool>,
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
#[serde(rename = "invalidMessage")]
|
|
|
|
|
|
pub invalid_message: Option<String>,
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub total: Option<f64>,
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub used: Option<f64>,
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub remaining: Option<f64>,
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub unit: Option<String>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 用量查询结果(支持多套餐)
|
|
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
|
|
|
|
pub struct UsageResult {
|
|
|
|
|
|
pub success: bool,
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub data: Option<Vec<UsageData>>, // 支持返回多个套餐
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub error: Option<String>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: Implement Speed Test Function
* feat: add unified endpoint speed test for API providers
Add a comprehensive endpoint latency testing system that allows users to:
- Test multiple API endpoints concurrently
- Auto-select the fastest endpoint based on latency
- Add/remove custom endpoints dynamically
- View latency results with color-coded indicators
Backend (Rust):
- Implement parallel HTTP HEAD requests with configurable timeout
- Handle various error scenarios (timeout, connection failure, invalid URL)
- Return structured latency data with status codes
Frontend (React):
- Create interactive speed test UI component with auto-sort by latency
- Support endpoint management (add/remove custom endpoints)
- Extract and update Codex base_url from TOML configuration
- Integrate with provider presets for default endpoint candidates
This feature improves user experience when selecting optimal API endpoints,
especially useful for users with multiple provider options or proxy setups.
* refactor: convert endpoint speed test to modal dialog
- Transform EndpointSpeedTest component into a modal dialog
- Add "Advanced" button next to base URL input to open modal
- Support ESC key and backdrop click to close modal
- Apply Linear design principles: minimal styling, clean layout
- Remove unused showBaseUrlInput variable
- Implement same modal pattern for both Claude and Codex
* fix: prevent modal cascade closing when ESC is pressed
- Add state checks to prevent parent modal from closing when child modals (endpoint speed test or template wizard) are open
- Update ESC key handler dependencies to track all modal states
- Ensures only the topmost modal responds to ESC key
* refactor: unify speed test panel UI with project design system
UI improvements:
- Update modal border radius from rounded-lg to rounded-xl
- Unify header padding from px-6 py-4 to p-6
- Change speed test button color to blue theme (bg-blue-500) for consistency
- Update footer background from bg-gray-50 to bg-gray-100
- Style "Done" button as primary action button with blue theme
- Adjust footer button spacing and hover states
Simplify endpoint display:
- Remove endpoint labels (e.g., "Current Address", "Custom 1")
- Display only URL for cleaner interface
- Clean up all label-related logic:
* Remove label field from EndpointCandidate interface
* Remove label generation in buildInitialEntries function
* Remove label handling in useEffect merge logic
* Remove label generation in handleAddEndpoint
* Remove label parameters from claudeSpeedTestEndpoints
* Remove label parameters from codexSpeedTestEndpoints
* refactor: improve endpoint list UI consistency
- Show delete button for all endpoints on hover for uniform UI
- Change selected state to use blue theme matching main interface:
* Blue border (border-blue-500) for selected items
* Light blue background (bg-blue-50/dark:bg-blue-900/20)
* Blue indicator dot (bg-blue-500/dark:bg-blue-400)
- Switch from compact list (space-y-px) to card-based layout (space-y-2)
- Add rounded corners to each endpoint item for better visual separation
* feat: persist custom endpoints to settings.json
- Extend AppSettings to store custom endpoints for Claude and Codex
- Add Tauri commands: get/add/remove/update custom endpoints
- Update frontend API with endpoint persistence methods
- Modify EndpointSpeedTest to load/save custom endpoints via API
- Track endpoint last used time for future sorting/cleanup
- Store endpoints per app type in settings.json instead of localStorage
* - feat(types): add Provider.meta and ProviderMeta (snake_case) with custom_endpoints map
- feat(provider-form): persist custom endpoints on provider create by merging EndpointSpeedTest’s custom URLs into meta.custom_endpoints on submit
- feat(endpoint-speed-test): add onCustomEndpointsChange callback emitting normalized custom URLs; wire it for both Claude/Codex modals
- fix(api): send alias param names (app/appType/app_type and provider_id/providerId) in Tauri invokes to avoid “missing providerId” with older backends
- storage: custom endpoints are stored in ~/.cc-switch/config.json under providers[<id>].meta.custom_endpoints (not in settings.json)
- behavior: edit flow remains immediate writes; create flow now writes once via addProvider, removing the providerId dependency during creation
* feat: add endpoint candidates support and code formatting improvements
- Add endpointCandidates field to ProviderPreset and CodexProviderPreset interfaces
- Integrate preset endpoint candidates into speed test endpoint selection
- Add multiple endpoint options for PackyCode providers (Claude & Codex)
- Apply consistent code formatting (trailing commas, line breaks)
- Improve template value type safety and readability
* refactor: improve endpoint management button UX
Replace ambiguous "Advanced" text with intuitive "Manage & Test" label accompanied by Zap icon, making the endpoint management panel entry point more discoverable and self-explanatory for both Claude and Codex configurations.
* - merge: merge origin/main, resolve conflicts and preserve both feature sets
- feat(tauri): register import/export and file dialogs; keep endpoint speed test and custom endpoints
- feat(api): add updateTrayMenu and onProviderSwitched; wire import/export APIs
- feat(types): extend global API declarations (import/export)
- chore(presets): GLM preset supports both new and legacy model keys
- chore(rust): add chrono dependency; refresh lockfile
---------
Co-authored-by: Jason <farion1231@gmail.com>
2025-10-07 19:14:32 +08:00
|
|
|
|
/// 供应商元数据
|
|
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
|
|
|
|
|
pub struct ProviderMeta {
|
|
|
|
|
|
/// 自定义端点列表(按 URL 去重存储)
|
|
|
|
|
|
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
|
|
|
|
|
|
pub custom_endpoints: HashMap<String, crate::settings::CustomEndpoint>,
|
2025-10-15 09:15:25 +08:00
|
|
|
|
/// 用量查询脚本配置
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub usage_script: Option<UsageScript>,
|
2025-11-12 10:47:34 +08:00
|
|
|
|
/// 合作伙伴标记(前端使用 isPartner,保持字段名一致)
|
|
|
|
|
|
#[serde(rename = "isPartner", skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub is_partner: Option<bool>,
|
|
|
|
|
|
/// 合作伙伴促销 key,用于识别 PackyCode 等特殊供应商
|
|
|
|
|
|
#[serde(
|
|
|
|
|
|
rename = "partnerPromotionKey",
|
|
|
|
|
|
skip_serializing_if = "Option::is_none"
|
|
|
|
|
|
)]
|
|
|
|
|
|
pub partner_promotion_key: Option<String>,
|
feat: Implement Speed Test Function
* feat: add unified endpoint speed test for API providers
Add a comprehensive endpoint latency testing system that allows users to:
- Test multiple API endpoints concurrently
- Auto-select the fastest endpoint based on latency
- Add/remove custom endpoints dynamically
- View latency results with color-coded indicators
Backend (Rust):
- Implement parallel HTTP HEAD requests with configurable timeout
- Handle various error scenarios (timeout, connection failure, invalid URL)
- Return structured latency data with status codes
Frontend (React):
- Create interactive speed test UI component with auto-sort by latency
- Support endpoint management (add/remove custom endpoints)
- Extract and update Codex base_url from TOML configuration
- Integrate with provider presets for default endpoint candidates
This feature improves user experience when selecting optimal API endpoints,
especially useful for users with multiple provider options or proxy setups.
* refactor: convert endpoint speed test to modal dialog
- Transform EndpointSpeedTest component into a modal dialog
- Add "Advanced" button next to base URL input to open modal
- Support ESC key and backdrop click to close modal
- Apply Linear design principles: minimal styling, clean layout
- Remove unused showBaseUrlInput variable
- Implement same modal pattern for both Claude and Codex
* fix: prevent modal cascade closing when ESC is pressed
- Add state checks to prevent parent modal from closing when child modals (endpoint speed test or template wizard) are open
- Update ESC key handler dependencies to track all modal states
- Ensures only the topmost modal responds to ESC key
* refactor: unify speed test panel UI with project design system
UI improvements:
- Update modal border radius from rounded-lg to rounded-xl
- Unify header padding from px-6 py-4 to p-6
- Change speed test button color to blue theme (bg-blue-500) for consistency
- Update footer background from bg-gray-50 to bg-gray-100
- Style "Done" button as primary action button with blue theme
- Adjust footer button spacing and hover states
Simplify endpoint display:
- Remove endpoint labels (e.g., "Current Address", "Custom 1")
- Display only URL for cleaner interface
- Clean up all label-related logic:
* Remove label field from EndpointCandidate interface
* Remove label generation in buildInitialEntries function
* Remove label handling in useEffect merge logic
* Remove label generation in handleAddEndpoint
* Remove label parameters from claudeSpeedTestEndpoints
* Remove label parameters from codexSpeedTestEndpoints
* refactor: improve endpoint list UI consistency
- Show delete button for all endpoints on hover for uniform UI
- Change selected state to use blue theme matching main interface:
* Blue border (border-blue-500) for selected items
* Light blue background (bg-blue-50/dark:bg-blue-900/20)
* Blue indicator dot (bg-blue-500/dark:bg-blue-400)
- Switch from compact list (space-y-px) to card-based layout (space-y-2)
- Add rounded corners to each endpoint item for better visual separation
* feat: persist custom endpoints to settings.json
- Extend AppSettings to store custom endpoints for Claude and Codex
- Add Tauri commands: get/add/remove/update custom endpoints
- Update frontend API with endpoint persistence methods
- Modify EndpointSpeedTest to load/save custom endpoints via API
- Track endpoint last used time for future sorting/cleanup
- Store endpoints per app type in settings.json instead of localStorage
* - feat(types): add Provider.meta and ProviderMeta (snake_case) with custom_endpoints map
- feat(provider-form): persist custom endpoints on provider create by merging EndpointSpeedTest’s custom URLs into meta.custom_endpoints on submit
- feat(endpoint-speed-test): add onCustomEndpointsChange callback emitting normalized custom URLs; wire it for both Claude/Codex modals
- fix(api): send alias param names (app/appType/app_type and provider_id/providerId) in Tauri invokes to avoid “missing providerId” with older backends
- storage: custom endpoints are stored in ~/.cc-switch/config.json under providers[<id>].meta.custom_endpoints (not in settings.json)
- behavior: edit flow remains immediate writes; create flow now writes once via addProvider, removing the providerId dependency during creation
* feat: add endpoint candidates support and code formatting improvements
- Add endpointCandidates field to ProviderPreset and CodexProviderPreset interfaces
- Integrate preset endpoint candidates into speed test endpoint selection
- Add multiple endpoint options for PackyCode providers (Claude & Codex)
- Apply consistent code formatting (trailing commas, line breaks)
- Improve template value type safety and readability
* refactor: improve endpoint management button UX
Replace ambiguous "Advanced" text with intuitive "Manage & Test" label accompanied by Zap icon, making the endpoint management panel entry point more discoverable and self-explanatory for both Claude and Codex configurations.
* - merge: merge origin/main, resolve conflicts and preserve both feature sets
- feat(tauri): register import/export and file dialogs; keep endpoint speed test and custom endpoints
- feat(api): add updateTrayMenu and onProviderSwitched; wire import/export APIs
- feat(types): extend global API declarations (import/export)
- chore(presets): GLM preset supports both new and legacy model keys
- chore(rust): add chrono dependency; refresh lockfile
---------
Co-authored-by: Jason <farion1231@gmail.com>
2025-10-07 19:14:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-23 20:12:35 +08:00
|
|
|
|
impl ProviderManager {
|
|
|
|
|
|
/// 获取所有供应商
|
|
|
|
|
|
pub fn get_all_providers(&self) -> &HashMap<String, Provider> {
|
|
|
|
|
|
&self.providers
|
|
|
|
|
|
}
|
2025-08-24 23:35:44 +08:00
|
|
|
|
}
|