@tombcato/ai-selector-core 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +354 -13
- package/dist/index.js +784 -19
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/package.json +6 -4
- package/src/styles.css +2 -0
- package/dist/api.d.ts +0 -14
- package/dist/api.d.ts.map +0 -1
- package/dist/api.js +0 -139
- package/dist/api.js.map +0 -1
- package/dist/config.d.ts +0 -18
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -85
- package/dist/config.js.map +0 -1
- package/dist/i18n.d.ts +0 -53
- package/dist/i18n.d.ts.map +0 -1
- package/dist/i18n.js +0 -51
- package/dist/i18n.js.map +0 -1
- package/dist/icons.d.ts +0 -10
- package/dist/icons.d.ts.map +0 -1
- package/dist/icons.js +0 -22
- package/dist/icons.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/models.d.ts +0 -11
- package/dist/models.d.ts.map +0 -1
- package/dist/models.js +0 -199
- package/dist/models.js.map +0 -1
- package/dist/providers.d.ts +0 -42
- package/dist/providers.d.ts.map +0 -1
- package/dist/providers.js +0 -229
- package/dist/providers.js.map +0 -1
- package/dist/storage.d.ts +0 -31
- package/dist/storage.d.ts.map +0 -1
- package/dist/storage.js +0 -65
- package/dist/storage.js.map +0 -1
- package/dist/strategies.d.ts +0 -54
- package/dist/strategies.d.ts.map +0 -1
- package/dist/strategies.js +0 -184
- package/dist/strategies.js.map +0 -1
- package/dist/types.d.ts +0 -122
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -6
- package/dist/types.js.map +0 -1
- package/dist/utils.d.ts +0 -2
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -4
- package/dist/utils.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO;AACP,cAAc,QAAQ,CAAC;AAuBvB,YAAY;AACZ,OAAO,EACH,SAAS,EACT,WAAW,EAEX,WAAW,EACX,eAAe,EACf,oBAAoB,EACvB,MAAM,aAAa,CAAC;AAErB,SAAS;AACT,OAAO,EACH,aAAa,EACb,eAAe,EAClB,MAAM,UAAU,CAAC;AAElB,MAAM;AACN,OAAO,EACH,cAAc,EACd,WAAW,EACd,MAAM,OAAO,CAAC;AAEf,UAAU;AACV,OAAO,EACH,mBAAmB,EACnB,mBAAmB,EACtB,MAAM,WAAW,CAAC;AAInB,oBAAoB;AACpB,OAAO,EACH,qBAAqB,EACrB,qBAAqB,EAExB,MAAM,UAAU,CAAC;AAElB,aAAa;AACb,OAAO,EAEH,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,oBAAoB,GAGvB,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/i18n.ts","../src/providers.ts","../src/models.ts","../src/strategies.ts","../src/api.ts","../src/storage.ts","../src/config.ts"],"sourcesContent":["export const I18N = {\n zh: {\n save: '保存配置',\n saved: '保存成功',\n providerLabel: 'Provider',\n modelLabel: 'Model',\n selectProvider: '选择 Provider...',\n customBaseUrl: '自定义 Base URL',\n apiKeyLabel: 'API Key',\n apiKeyPlaceholder: '输入 API Key...',\n testConnection: '测试模型连接',\n testing: '测试中...',\n testSuccess: '连接成功',\n testFailed: '测试连通性失败',\n selectModel: '选择 Model...',\n searchModel: '搜索或自定义模型...',\n useCustom: '使用自定义',\n noModels: '暂无模型数据',\n apiKeyTip: '输入 API Key 后可获取完整模型列表',\n fetchModelsFailed: '拉取模型列表失败,已使用离线模型列表',\n refreshingModels: '列表刷新中...',\n modelListUpdated: '模型列表已刷新',\n preview: '配置预览',\n unselected: '(未选择)',\n },\n en: {\n save: 'Save Config',\n saved: 'Saved',\n providerLabel: 'Provider',\n modelLabel: 'Model',\n selectProvider: 'Select Provider...',\n customBaseUrl: 'Custom Base URL',\n apiKeyLabel: 'API Key',\n apiKeyPlaceholder: 'Enter API Key...',\n testConnection: 'Test Model Connection',\n testing: 'Testing...',\n testSuccess: 'Connection Successful',\n testFailed: 'Connection Failed',\n selectModel: 'Select Model...',\n searchModel: 'Search or custom models...',\n useCustom: 'Use custom',\n noModels: 'No models found',\n apiKeyTip: 'Enter API Key to fetch full model list',\n fetchModelsFailed: 'Failed to fetch model list, using offline models',\n refreshingModels: 'Refreshing models...',\n modelListUpdated: 'Model list updated',\n preview: 'Config Preview',\n unselected: '(Unselected)',\n }\n} as const;\n\nexport type Language = keyof typeof I18N;\nexport type I18NKeys = keyof typeof I18N['zh'];\n\n","/**\r\n * AI Provider Selector - Provider Definitions\r\n * All supported AI providers metadata\r\n */\r\n\r\nimport type { Provider } from './types';\r\n\r\nconst ICON_CDN_BASE = 'https://registry.npmmirror.com/@lobehub/icons-static-svg/1.77.0/files/icons';\r\n\r\n// Provider IDs\r\nexport const PROVIDER_ID = {\r\n OPENAI: 'openai',\r\n ANTHROPIC: 'anthropic',\r\n GEMINI: 'gemini',\r\n DEEPSEEK: 'deepseek',\r\n OPENROUTER: 'openrouter',\r\n GROQ: 'groq',\r\n MISTRAL: 'mistral',\r\n MOONSHOT: 'moonshot',\r\n QWEN: 'qwen',\r\n ZHIPU: 'zhipu',\r\n SILICONFLOW: 'siliconflow',\r\n XAI: 'xai',\r\n TOGETHER: 'together',\r\n FIREWORKS: 'fireworks',\r\n DEEPINFRA: 'deepinfra',\r\n PERPLEXITY: 'perplexity',\r\n COHERE: 'cohere',\r\n OLLAMA: 'ollama',\r\n DOUBAO: 'doubao',\r\n MINIMAX: 'minimax',\r\n} as const;\r\n\r\nexport type ProviderId = typeof PROVIDER_ID[keyof typeof PROVIDER_ID];\r\n\r\nexport const PROVIDERS: Record<string, Provider> = {\r\n [PROVIDER_ID.OPENAI]: {\r\n id: PROVIDER_ID.OPENAI,\r\n name: 'OpenAI',\r\n baseUrl: 'https://api.openai.com/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/openai.svg`,\r\n },\r\n [PROVIDER_ID.ANTHROPIC]: {\r\n id: PROVIDER_ID.ANTHROPIC,\r\n name: 'Anthropic (Claude)',\r\n baseUrl: 'https://api.anthropic.com/v1',\r\n needsApiKey: true,\r\n apiFormat: 'anthropic',\r\n supportsModelsApi: false,\r\n icon: `${ICON_CDN_BASE}/anthropic.svg`,\r\n },\r\n [PROVIDER_ID.GEMINI]: {\r\n id: PROVIDER_ID.GEMINI,\r\n name: 'Google Gemini',\r\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\r\n needsApiKey: true,\r\n apiFormat: 'gemini',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/gemini.svg`,\r\n },\r\n [PROVIDER_ID.OPENROUTER]: {\r\n id: PROVIDER_ID.OPENROUTER,\r\n name: 'OpenRouter',\r\n baseUrl: 'https://openrouter.ai/api/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/openrouter.svg`,\r\n },\r\n [PROVIDER_ID.DEEPSEEK]: {\r\n id: PROVIDER_ID.DEEPSEEK,\r\n name: 'DeepSeek',\r\n baseUrl: 'https://api.deepseek.com',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/deepseek.svg`,\r\n },\r\n [PROVIDER_ID.MOONSHOT]: {\r\n id: PROVIDER_ID.MOONSHOT,\r\n name: 'Moonshot (Kimi)',\r\n baseUrl: 'https://api.moonshot.cn/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/moonshot.svg`,\r\n },\r\n [PROVIDER_ID.QWEN]: {\r\n id: PROVIDER_ID.QWEN,\r\n name: '通义千问 (Qwen)',\r\n baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/qwen.svg`,\r\n },\r\n [PROVIDER_ID.ZHIPU]: {\r\n id: PROVIDER_ID.ZHIPU,\r\n name: '智谱 AI (GLM)',\r\n baseUrl: 'https://open.bigmodel.cn/api/paas/v4',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/zhipu.svg`,\r\n },\r\n [PROVIDER_ID.SILICONFLOW]: {\r\n id: PROVIDER_ID.SILICONFLOW,\r\n name: '硅基流动 (siliconflow)',\r\n baseUrl: 'https://api.siliconflow.cn/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/siliconcloud.svg`,\r\n },\r\n\r\n [PROVIDER_ID.DOUBAO]: {\r\n id: PROVIDER_ID.DOUBAO,\r\n name: '火山方舟 (Doubao)',\r\n baseUrl: 'https://ark.cn-beijing.volces.com/api/v3',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/doubao.svg`,\r\n },\r\n [PROVIDER_ID.MINIMAX]: {\r\n id: PROVIDER_ID.MINIMAX,\r\n name: 'MiniMax',\r\n baseUrl: 'https://api.minimax.io/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: false,\r\n icon: `${ICON_CDN_BASE}/minimax.svg`,\r\n },\r\n [PROVIDER_ID.XAI]: {\r\n id: PROVIDER_ID.XAI,\r\n name: 'xAI (Grok)',\r\n baseUrl: 'https://api.x.ai/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/grok.svg`,\r\n },\r\n [PROVIDER_ID.GROQ]: {\r\n id: PROVIDER_ID.GROQ,\r\n name: 'Groq',\r\n baseUrl: 'https://api.groq.com/openai/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/groq.svg`,\r\n },\r\n [PROVIDER_ID.MISTRAL]: {\r\n id: PROVIDER_ID.MISTRAL,\r\n name: 'Mistral AI',\r\n baseUrl: 'https://api.mistral.ai/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/mistral.svg`,\r\n },\r\n [PROVIDER_ID.TOGETHER]: {\r\n id: PROVIDER_ID.TOGETHER,\r\n name: 'Together AI',\r\n baseUrl: 'https://api.together.xyz/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/together.svg`,\r\n },\r\n [PROVIDER_ID.FIREWORKS]: {\r\n id: PROVIDER_ID.FIREWORKS,\r\n name: 'Fireworks AI',\r\n baseUrl: 'https://api.fireworks.ai/inference/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/fireworks.svg`,\r\n },\r\n [PROVIDER_ID.DEEPINFRA]: {\r\n id: PROVIDER_ID.DEEPINFRA,\r\n name: 'DeepInfra',\r\n baseUrl: 'https://api.deepinfra.com/v1/openai',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/deepinfra.svg`,\r\n },\r\n [PROVIDER_ID.PERPLEXITY]: {\r\n id: PROVIDER_ID.PERPLEXITY,\r\n name: 'Perplexity',\r\n baseUrl: 'https://api.perplexity.ai',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: false,\r\n icon: `${ICON_CDN_BASE}/perplexity.svg`,\r\n },\r\n [PROVIDER_ID.COHERE]: {\r\n id: PROVIDER_ID.COHERE,\r\n name: 'Cohere',\r\n baseUrl: 'https://api.cohere.com/v2',\r\n needsApiKey: true,\r\n apiFormat: 'cohere',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/cohere.svg`,\r\n },\r\n [PROVIDER_ID.OLLAMA]: {\r\n id: PROVIDER_ID.OLLAMA,\r\n name: 'Ollama (Local)',\r\n baseUrl: 'http://localhost:11434/v1',\r\n needsApiKey: false,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/ollama.svg`,\r\n },\r\n};\r\n\r\n/**\r\n * Get a provider by ID\r\n */\r\nexport function getProvider(id: string): Provider | undefined {\r\n return PROVIDERS[id];\r\n}\r\n\r\n/**\r\n * Get all providers as an array\r\n */\r\nexport function getAllProviders(): Provider[] {\r\n return Object.values(PROVIDERS);\r\n}\r\n\r\n/**\r\n * Get providers by API format\r\n */\r\nexport function getProvidersByFormat(format: Provider['apiFormat']): Provider[] {\r\n return getAllProviders().filter(p => p.apiFormat === format);\r\n}\r\n","/**\r\n * AI Provider Selector - Static Model Definitions\r\n * Models data when API doesn't support /models endpoint\r\n */\r\n\r\nimport type { Model } from './types';\r\nimport { PROVIDER_ID } from './providers';\r\n\r\nexport const STATIC_MODELS: Record<string, Model[]> = {\r\n [PROVIDER_ID.OPENAI]: [\r\n { id: 'gpt-5.2-pro', name: 'GPT-5.2 Pro' },\r\n { id: 'gpt-5.2', name: 'GPT-5.2' },\r\n { id: 'gpt-5', name: 'GPT-5' },\r\n { id: 'gpt-5-mini', name: 'GPT-5 Mini' },\r\n { id: 'gpt-5-nano', name: 'GPT-5 Nano' },\r\n { id: 'gpt-4.1', name: 'GPT-4.1' },\r\n ],\r\n [PROVIDER_ID.ANTHROPIC]: [\r\n { id: 'claude-opus-4.5-20251101', name: 'Claude Opus 4.5' },\r\n { id: 'claude-opus-4.5-20251101-thinking', name: 'Claude Opus 4.5 Thinking' },\r\n { id: 'claude-sonnet-4.5-20250929', name: 'Claude Sonnet 4.5' },\r\n { id: 'claude-sonnet-4.5-20250929-thinking', name: 'Claude Sonnet 4.5 Thinking' },\r\n { id: 'claude-haiku-4.5-20251001', name: 'Claude Haiku 4.5' },\r\n { id: 'claude-haiku-4.5-20251001-thinking', name: 'Claude Haiku 4.5 Thinking' },\r\n { id: 'claude-opus-4.1-20250805', name: 'Claude Opus 4.1' },\r\n { id: 'claude-opus-4.1-20250805-thinking', name: 'Claude Opus 4.1 Thinking' },\r\n ],\r\n [PROVIDER_ID.GEMINI]: [\r\n { id: 'gemini-3-flash-preview', name: 'Gemini 3 Flash Preview' },\r\n { id: 'gemini-3-pro-preview', name: 'Gemini 3 Pro Preview' },\r\n { id: 'gemini-2.5-pro', name: 'Gemini 2.5 Pro' },\r\n { id: 'gemini-2.5-flash', name: 'Gemini 2.5 Flash' },\r\n { id: 'gemini-2.5-flash-lite', name: 'Gemini 2.5 Flash-Lite' },\r\n ],\r\n [PROVIDER_ID.DEEPSEEK]: [\r\n { id: 'deepseek-chat', name: 'Deepseek Chat' },\r\n { id: 'deepseek-reasoner', name: 'Deepseek Reasoner' },\r\n ],\r\n [PROVIDER_ID.MISTRAL]: [\r\n { id: 'mistral-large-latest', name: 'Mistral Large' },\r\n { id: 'mistral-medium-latest', name: 'Mistral Medium' },\r\n { id: 'mistral-small-latest', name: 'Mistral Small' },\r\n { id: 'codestral-latest', name: 'Codestral' },\r\n { id: 'devstral-latest', name: 'Devstral' },\r\n { id: 'magistral-medium-latest', name: 'Magistral Medium' },\r\n { id: 'pixtral-large-latest', name: 'Pixtral Large' },\r\n { id: 'pixtral-12b-latest', name: 'Pixtral 12B' },\r\n { id: 'ministral-8b-latest', name: 'Ministral 8B' },\r\n { id: 'ministral-3b-latest', name: 'Ministral 3B' },\r\n ],\r\n [PROVIDER_ID.GROQ]: [\r\n { id: 'canopylabs/orpheus-v1-english', name: 'Orpheus V1 English' },\r\n { id: 'canopylabs/orpheus-arabic-saudi', name: 'Orpheus Arabic Saudi' },\r\n { id: 'moonshotai/kimi-k2-instruct', name: 'Kimi K2 Instruct' },\r\n { id: 'groq/compound-mini', name: 'Compound Mini' },\r\n { id: 'llama-3.3-70b-versatile', name: 'Llama 3.3 70B Versatile' },\r\n { id: 'openai/gpt-oss-120b', name: 'Gpt Oss 120B' },\r\n { id: 'qwen/qwen3-32b', name: 'Qwen3 32B' },\r\n { id: 'groq/compound', name: 'Compound' },\r\n { id: 'meta-llama/llama-4-maverick-17b-128e-instruct', name: 'Llama 4 Maverick 17B 128E Instruct' },\r\n ],\r\n [PROVIDER_ID.XAI]: [\r\n { id: 'grok-4', name: 'Grok 4' },\r\n { id: 'grok-4-fast', name: 'Grok 4 Fast' },\r\n { id: 'grok-3-latest', name: 'Grok 3' },\r\n { id: 'grok-3-fast', name: 'Grok 3 Fast' },\r\n { id: 'grok-3-mini-latest', name: 'Grok 3 Mini' },\r\n { id: 'grok-3-mini-fast', name: 'Grok 3 Mini Fast' },\r\n { id: 'grok-vision-beta', name: 'Grok Vision (Beta)' },\r\n ],\r\n [PROVIDER_ID.TOGETHER]: [\r\n { id: 'Qwen/Qwen2.5-72B-Instruct-Turbo', name: 'Qwen2.5 72B Instruct Turbo' },\r\n { id: 'Qwen/Qwen3-235B-A22B-Thinking-2507', name: 'Qwen3 235B A22B Thinking 2507' },\r\n { id: 'deepseek-ai/DeepSeek-R1', name: 'Deepseek R1' },\r\n { id: 'deepseek-ai/DeepSeek-V3.1', name: 'Deepseek V3.1' },\r\n { id: 'meta-llama/Llama-3.2-3B-Instruct-Turbo', name: 'Llama 3.2 3B Instruct Turbo' },\r\n { id: 'meta-llama/Llama-3.3-70B-Instruct-Turbo', name: 'Llama 3.3 70B Instruct Turbo' },\r\n { id: 'meta-llama/Llama-3.3-70B-Instruct-Turbo-Free', name: 'Llama 3.3 70B Instruct Turbo Free' },\r\n ],\r\n [PROVIDER_ID.FIREWORKS]: [\r\n { id: 'accounts/fireworks/models/llama4-scout-instruct-basic', name: 'Llama4 Scout Instruct Basic' },\r\n { id: 'accounts/fireworks/models/qwen3-vl-235b-a22b-thinking', name: 'Qwen3 Vl 235B A22B Thinking' },\r\n { id: 'accounts/fireworks/models/deepseek-v3p2', name: 'Deepseek V3P2' },\r\n { id: 'accounts/fireworks/models/qwen3-vl-30b-a3b-thinking', name: 'Qwen3 Vl 30B A3B Thinking' },\r\n { id: 'accounts/fireworks/models/qwen3-8b', name: 'Qwen3 8B' },\r\n { id: 'accounts/fireworks/models/qwen3-vl-30b-a3b-instruct', name: 'Qwen3 Vl 30B A3B Instruct' },\r\n { id: 'accounts/fireworks/models/qwen2p5-vl-32b-instruct', name: 'Qwen2P5 Vl 32B Instruct' },\r\n { id: 'accounts/fireworks/models/llama4-maverick-instruct-basic', name: 'Llama4 Maverick Instruct Basic' },\r\n { id: 'accounts/fireworks/models/qwen3-235b-a22b-thinking-2507', name: 'Qwen3 235B A22B Thinking 2507' },\r\n { id: 'accounts/fireworks/models/qwen3-coder-480b-a35b-instruct', name: 'Qwen3 Coder 480B A35B Instruct' },\r\n ],\r\n [PROVIDER_ID.DEEPINFRA]: [\r\n { id: 'meta-llama/Llama-3.2-11B-Vision-Instruct', name: 'Llama 3.2 11B Vision Instruct' },\r\n { id: 'Qwen/Qwen3-32B', name: 'Qwen3 32B' },\r\n { id: 'NousResearch/Hermes-3-Llama-3.1-70B', name: 'Hermes 3 Llama 3.1 70B' },\r\n { id: 'Qwen/Qwen2.5-72B-Instruct', name: 'Qwen2.5 72B Instruct' },\r\n { id: 'deepseek-ai/DeepSeek-V3-0324', name: 'Deepseek V3 0324' },\r\n { id: 'Qwen/Qwen3-VL-235B-A22B-Instruct', name: 'Qwen3 Vl 235B A22B Instruct' },\r\n { id: 'meta-llama/Llama-3.2-3B-Instruct', name: 'Llama 3.2 3B Instruct' },\r\n { id: 'Qwen/Qwen2.5-VL-32B-Instruct', name: 'Qwen2.5 Vl 32B Instruct' },\r\n { id: 'meta-llama/Meta-Llama-3.1-8B-Instruct', name: 'Meta Llama 3.1 8B Instruct' },\r\n { id: 'Qwen/Qwen3-Coder-480B-A35B-Instruct-Turbo', name: 'Qwen3 Coder 480B A35B Instruct Turbo' },\r\n ],\r\n [PROVIDER_ID.OPENROUTER]: [\r\n { id: 'google/gemini-3-flash-preview', name: 'Gemini 3 Flash Preview' },\r\n { id: 'mistralai/mistral-small-creative', name: 'Mistral Small Creative' },\r\n { id: 'openai/gpt-5.2-chat', name: 'Gpt 5.2 Chat' },\r\n { id: 'openai/gpt-5.2-pro', name: 'Gpt 5.2 Pro' },\r\n { id: 'openai/gpt-5.2', name: 'Gpt 5.2' },\r\n { id: 'mistralai/devstral-2512', name: 'Devstral 2512' },\r\n { id: 'openai/gpt-5.1-codex-max', name: 'Gpt 5.1 Codex Max' },\r\n { id: 'mistralai/ministral-14b-2512', name: 'Ministral 14B 2512' },\r\n { id: 'mistralai/ministral-8b-2512', name: 'Ministral 8B 2512' },\r\n { id: 'mistralai/ministral-3b-2512', name: 'Ministral 3B 2512' },\r\n { id: 'mistralai/mistral-large-2512', name: 'Mistral Large 2512' },\r\n { id: 'deepseek/deepseek-v3.2-speciale', name: 'Deepseek V3.2 Speciale' },\r\n ],\r\n [PROVIDER_ID.PERPLEXITY]: [\r\n { id: 'codellama-34b-instruct', name: 'Codellama 34B Instruct' },\r\n { id: 'codellama-70b-instruct', name: 'Codellama 70B Instruct' },\r\n { id: 'llama-2-70b-chat', name: 'Llama 2 70B Chat' },\r\n { id: 'llama-3.1-70b-instruct', name: 'Llama 3.1 70B Instruct' },\r\n { id: 'llama-3.1-8b-instruct', name: 'Llama 3.1 8B Instruct' },\r\n { id: 'llama-3.1-sonar-huge-128k-online', name: 'Llama 3.1 Sonar Huge 128K Online' },\r\n { id: 'llama-3.1-sonar-large-128k-chat', name: 'Llama 3.1 Sonar Large 128K Chat' },\r\n { id: 'llama-3.1-sonar-large-128k-online', name: 'Llama 3.1 Sonar Large 128K Online' },\r\n { id: 'llama-3.1-sonar-small-128k-chat', name: 'Llama 3.1 Sonar Small 128K Chat' },\r\n ],\r\n [PROVIDER_ID.COHERE]: [\r\n { id: 'command-a-vision-07-2025', name: 'Command A Vision 07 2025' },\r\n { id: 'command-a-reasoning-08-2025', name: 'Command A Reasoning 08 2025' },\r\n { id: 'command-r-08-2024', name: 'Command R 08 2024' },\r\n { id: 'command-r7b-arabic-02-2025', name: 'Command R7B Arabic 02 2025' },\r\n { id: 'command-r7b-12-2024', name: 'Command R7B 12 2024' },\r\n ],\r\n [PROVIDER_ID.MOONSHOT]: [\r\n { id: 'moonshot-v1-128k', name: 'Moonshot 128K' },\r\n { id: 'moonshot-v1-32k', name: 'Moonshot 32K' },\r\n { id: 'moonshot-v1-8k', name: 'Moonshot 8K' },\r\n { id: 'kimi-k2-0711-chat', name: 'Kimi K2 Chat' },\r\n { id: 'moonshot-v1-auto', name: 'Moonshot Auto' },\r\n ],\r\n [PROVIDER_ID.QWEN]: [\r\n { id: 'qwen-flash', name: 'Qwen Flash' },\r\n { id: 'qwen3-vl-plus-2025-12-19', name: 'Qwen3 Vl Plus 2025 12 19' },\r\n { id: 'qwen3-tts-vd-realtime-2025-12-16', name: 'Qwen3 Tts Vd Realtime 2025 12 16' },\r\n { id: 'qwen-image-edit-plus-2025-12-15', name: 'Qwen Image Edit Plus 2025 12 15' },\r\n { id: 'qwen3-omni-flash-2025-12-01', name: 'Qwen3 Omni Flash 2025 12 01' },\r\n { id: 'qwen3-omni-flash-realtime-2025-12-01', name: 'Qwen3 Omni Flash Realtime 2025 12 01' },\r\n { id: 'qwen3-livetranslate-flash-2025-12-01', name: 'Qwen3 Livetranslate Flash 2025 12 01' },\r\n { id: 'qwen3-livetranslate-flash', name: 'Qwen3 Livetranslate Flash' },\r\n { id: 'qwen-plus-2025-12-01', name: 'Qwen Plus 2025 12 01' },\r\n { id: 'qwen3-tts-vc-realtime-2025-11-27', name: 'Qwen3 Tts Vc Realtime 2025 11 27' },\r\n ],\r\n [PROVIDER_ID.ZHIPU]: [\r\n { id: 'glm-4.5', name: 'Glm 4.5' },\r\n { id: 'glm-4.5-air', name: 'Glm 4.5 Air' },\r\n { id: 'glm-4.6', name: 'Glm 4.6' },\r\n { id: 'glm-4.7', name: 'Glm 4.7' },\r\n ],\r\n [PROVIDER_ID.SILICONFLOW]: [\r\n { id: 'deepseek-ai/DeepSeek-V3.2', name: 'Deepseek V3.2' },\r\n { id: 'deepseek-ai/DeepSeek-V3.1-Terminus', name: 'Deepseek V3.1 Terminus' },\r\n { id: 'deepseek-ai/DeepSeek-R1', name: 'Deepseek R1' },\r\n { id: 'deepseek-ai/DeepSeek-V3', name: 'Deepseek V3' },\r\n { id: 'zai-org/GLM-4.6V', name: 'Glm 4.6V' },\r\n { id: 'zai-org/GLM-4.6', name: 'Glm 4.6' },\r\n { id: 'Pro/zai-org/GLM-4.7', name: 'Glm 4.7' },\r\n { id: 'Qwen/Qwen3-VL-32B-Instruct', name: 'Qwen3 Vl 32B Instruct' },\r\n ],\r\n [PROVIDER_ID.OLLAMA]: [\r\n { id: 'llama3.3', name: 'Llama 3.3' },\r\n { id: 'llama3.2', name: 'Llama 3.2' },\r\n { id: 'qwq', name: 'QwQ (推理)' },\r\n { id: 'qwen3:32b', name: 'Qwen3 32B' },\r\n { id: 'deepseek-r1:32b', name: 'DeepSeek R1 32B' },\r\n { id: 'deepseek-coder-v2', name: 'DeepSeek Coder V2' },\r\n { id: 'gemma3:27b', name: 'Gemma 3 27B' },\r\n { id: 'mistral:7b', name: 'Mistral 7B' },\r\n { id: 'phi4', name: 'Phi 4' },\r\n { id: 'codellama', name: 'Code Llama' },\r\n ],\r\n [PROVIDER_ID.DOUBAO]: [\r\n { id: 'doubao-seed-1-8-251215', name: 'Doubao 1.8' },\r\n { id: \"doubao-seed-1-6-251015\",name: \"Doubao 1.6\"},\r\n { id: 'doubao-seed-1-6-lite-251015', name: 'Doubao 1.6 Lite' },\r\n { id: 'doubao-seed-1-6-flash-250828', name: 'Doubao 1.6 Flash' },\r\n { id: 'doubao-seed-1-6-thinking-250615', name: 'Doubao 1.6 Thinking' },\r\n ],\r\n [PROVIDER_ID.MINIMAX]: [\r\n { id: 'MiniMax-M2.1', name: 'MiniMax M2.1' },\r\n { id: 'MiniMax-M2.1-lightning', name: 'MiniMax M2.1 Lightning' },\r\n { id: 'MiniMax-M2', name: 'MiniMax M2' },\r\n ],\r\n};\r\n\r\n/**\r\n * Get static models for a provider\r\n */\r\nexport function getStaticModels(providerId: string): Model[] {\r\n return STATIC_MODELS[providerId] || [];\r\n}\r\n","import type { Provider, Model } from './types';\r\n\r\nexport interface ProviderStrategy {\r\n format: string;\r\n // 模型列表\r\n getModelsEndpoint?: (baseUrl: string, apiKey: string) => string;\r\n parseModelsResponse?: (data: any) => Model[];\r\n // 聊天 (也用于连接测试)\r\n getChatEndpoint: (baseUrl: string, apiKey: string, model: string) => string;\r\n buildChatPayload: (model: string, messages: Array<{ role: string; content: string }>, maxTokens: number) => Record<string, unknown>;\r\n parseChatResponse: (data: any) => string;\r\n // Headers\r\n buildHeaders: (apiKey: string) => Record<string, string>;\r\n}\r\n\r\nexport const defaultParseModelsResponse = (data: any): Model[] => {\r\n if (Array.isArray(data?.data)) {\r\n return data.data\r\n .filter((m: any) => m.id)\r\n .map((m: any) => {\r\n const name =\r\n m.name ||\r\n (m.id.split('/').pop() ?? '')\r\n .replace(/[-_]/g, ' ')\r\n .replace(/\\b\\w/g, (c: string) => c.toUpperCase());\r\n return {\r\n id: m.id,\r\n name,\r\n created: m.created || 0,\r\n } as any;\r\n })\r\n .sort((a: any, b: any) => (b.created || 0) - (a.created || 0)); // 最新的排在前面\r\n }\r\n return [];\r\n};\r\n\r\nconst openaiStrategy: ProviderStrategy = {\r\n format: 'openai',\r\n getModelsEndpoint: (baseUrl) => `${baseUrl}/models`,\r\n getChatEndpoint: (baseUrl) => `${baseUrl}/chat/completions`,\r\n buildHeaders: (apiKey) => ({\r\n 'Content-Type': 'application/json',\r\n 'Authorization': `Bearer ${apiKey}`,\r\n }),\r\n buildChatPayload: (model, messages, maxTokens) => ({\r\n model,\r\n messages,\r\n max_tokens: maxTokens,\r\n }),\r\n parseChatResponse: (data) => {\r\n return data.choices?.[0]?.message?.content || '';\r\n },\r\n};\r\n\r\nconst anthropicStrategy: ProviderStrategy = {\r\n format: 'anthropic',\r\n getChatEndpoint: (baseUrl) => `${baseUrl}/messages`,\r\n buildHeaders: (apiKey) => ({\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': apiKey,\r\n 'anthropic-version': '2023-06-01',\r\n }),\r\n buildChatPayload: (model, messages, maxTokens) => ({\r\n model,\r\n messages,\r\n max_tokens: maxTokens,\r\n }),\r\n parseChatResponse: (data) => {\r\n return data.content?.[0]?.text || '';\r\n },\r\n};\r\n\r\nconst geminiStrategy: ProviderStrategy = {\r\n format: 'gemini',\r\n getModelsEndpoint: (baseUrl, apiKey) => `${baseUrl}/models?key=${apiKey}`,\r\n getChatEndpoint: (baseUrl, apiKey, model) => `${baseUrl}/models/${model}:generateContent?key=${apiKey}`,\r\n buildHeaders: () => ({\r\n 'Content-Type': 'application/json',\r\n }),\r\n buildChatPayload: (_model, messages, maxTokens) => {\r\n // 转换 OpenAI 格式的 messages 为 Gemini 格式\r\n const contents = messages.map(m => ({\r\n role: m.role === 'assistant' ? 'model' : 'user',\r\n parts: [{ text: m.content }],\r\n }));\r\n return {\r\n contents,\r\n generationConfig: { maxOutputTokens: maxTokens },\r\n };\r\n },\r\n parseChatResponse: (data) => {\r\n return data.candidates?.[0]?.content?.parts?.[0]?.text || '';\r\n },\r\n // Gemini 返回格式: { models: [{ name: \"models/gemini-pro\", ... }] }\r\n parseModelsResponse: (data) => {\r\n if (Array.isArray(data.models)) {\r\n return data.models\r\n .filter((m: any) => m.supportedGenerationMethods?.includes('generateContent'))\r\n .map((m: any) => ({\r\n id: m.name.replace('models/', ''), // \"models/gemini-pro\" -> \"gemini-pro\"\r\n name: m.displayName || m.name.replace('models/', ''),\r\n created: m.created || 0,\r\n }))\r\n .sort((a: any, b: any) => (b.created || 0) - (a.created || 0));\r\n }\r\n return [];\r\n },\r\n};\r\n\r\nconst cohereStrategy: ProviderStrategy = {\r\n format: 'cohere',\r\n getModelsEndpoint: (baseUrl) => `${baseUrl}/models`,\r\n getChatEndpoint: (baseUrl) => `${baseUrl}/chat`,\r\n buildHeaders: (apiKey) => ({\r\n 'Content-Type': 'application/json',\r\n 'Authorization': `Bearer ${apiKey}`,\r\n }),\r\n buildChatPayload: (model, messages, maxTokens) => {\r\n // Cohere 使用不同的格式: message 是当前消息, chat_history 是历史\r\n const lastMessage = messages[messages.length - 1];\r\n const chatHistory = messages.slice(0, -1).map(m => ({\r\n role: m.role === 'assistant' ? 'CHATBOT' : 'USER',\r\n message: m.content,\r\n }));\r\n return {\r\n model,\r\n message: lastMessage.content,\r\n chat_history: chatHistory,\r\n max_tokens: maxTokens,\r\n };\r\n },\r\n parseChatResponse: (data) => {\r\n return data.text || '';\r\n },\r\n};\r\n\r\nexport const strategyRegistry: Record<string, ProviderStrategy> = {\r\n openai: openaiStrategy,\r\n anthropic: anthropicStrategy,\r\n gemini: geminiStrategy,\r\n cohere: cohereStrategy,\r\n};\r\n\r\nexport function getStrategy(format: string): ProviderStrategy {\r\n return strategyRegistry[format] || openaiStrategy;\r\n}\r\n\r\n// ============================================================================\r\n// 纯前端直连聊天函数\r\n// ============================================================================\r\n\r\nexport interface DirectChatOptions {\r\n apiFormat: string;\r\n baseUrl: string;\r\n apiKey: string;\r\n model: string;\r\n messages: Array<{ role: string; content: string }>;\r\n maxTokens?: number;\r\n}\r\n\r\nexport interface DirectChatResult {\r\n success: boolean;\r\n content?: string;\r\n message?: string;\r\n latencyMs?: number;\r\n}\r\n\r\n/**\r\n * 纯前端直连 AI 厂商进行聊天\r\n * 注意: 这会将 API Key 暴露在浏览器中,仅适用于 Demo/测试场景\r\n */\r\nexport async function sendDirectChat(options: DirectChatOptions): Promise<DirectChatResult> {\r\n const { apiFormat, baseUrl, apiKey, model, messages, maxTokens = 2048 } = options;\r\n const strategy = getStrategy(apiFormat);\r\n\r\n const endpoint = strategy.getChatEndpoint(baseUrl, apiKey, model);\r\n const headers = strategy.buildHeaders(apiKey);\r\n const payload = strategy.buildChatPayload(model, messages, maxTokens);\r\n\r\n const startTime = performance.now();\r\n\r\n try {\r\n const response = await fetch(endpoint, {\r\n method: 'POST',\r\n headers,\r\n body: JSON.stringify(payload),\r\n });\r\n\r\n const latencyMs = Math.round(performance.now() - startTime);\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n return {\r\n success: false,\r\n message: errorData.error?.message || `HTTP ${response.status}: ${response.statusText}`,\r\n latencyMs,\r\n };\r\n }\r\n\r\n const data = await response.json();\r\n const content = strategy.parseChatResponse(data);\r\n\r\n return {\r\n success: true,\r\n content,\r\n latencyMs,\r\n };\r\n } catch (e) {\r\n return {\r\n success: false,\r\n message: e instanceof Error ? e.message : '网络错误',\r\n };\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// 连接测试函数 (复用聊天接口)\r\n// ============================================================================\r\n\r\nexport interface TestConnectionOptions {\r\n apiFormat: string;\r\n baseUrl: string;\r\n apiKey: string;\r\n model: string;\r\n}\r\n\r\nexport interface TestConnectionResult {\r\n success: boolean;\r\n latencyMs?: number;\r\n message?: string;\r\n}\r\n\r\n/**\r\n * 测试 AI 厂商连接 (通过发送一个简单的聊天请求)\r\n */\r\nexport async function testDirectConnection(options: TestConnectionOptions): Promise<TestConnectionResult> {\r\n const result = await sendDirectChat({\r\n apiFormat: options.apiFormat,\r\n baseUrl: options.baseUrl,\r\n apiKey: options.apiKey,\r\n model: options.model,\r\n messages: [{ role: 'user', content: 'Hi' }],\r\n maxTokens: 5, // 最小 token 数,节省成本\r\n });\r\n\r\n return {\r\n success: result.success,\r\n latencyMs: result.latencyMs,\r\n message: result.success ? undefined : result.message,\r\n };\r\n}\r\n","/**\r\n * AI Provider Selector - API Functions\r\n * Connection testing and model fetching logic\r\n */\r\n\r\nimport type {\r\n Provider,\r\n Model,\r\n TestConnectionOptions,\r\n TestConnectionResult,\r\n FetchModelsOptions\r\n} from './types';\r\nimport { getStaticModels } from './models';\r\nimport { getStrategy, defaultParseModelsResponse } from './strategies';\r\n\r\nconst DEFAULT_TIMEOUT = 30000;\r\n\r\n/**\r\n * Test connection to an AI provider\r\n */\r\nexport async function testConnection(options: TestConnectionOptions): Promise<TestConnectionResult> {\r\n const { provider, apiKey, model, baseUrl, proxyUrl } = options;\r\n const actualBaseUrl = baseUrl || provider.baseUrl;\r\n const startTime = Date.now();\r\n\r\n try {\r\n // If proxy URL is provided, use it\r\n if (proxyUrl) {\r\n const response = await fetch(`${proxyUrl}/test`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n provider_id: provider.id,\r\n api_key: apiKey,\r\n model: model || '',\r\n base_url: baseUrl || provider.baseUrl,\r\n api_format: provider.apiFormat,\r\n }),\r\n });\r\n const data = await response.json();\r\n return {\r\n success: data.success,\r\n latencyMs: data.latency_ms || (Date.now() - startTime),\r\n message: data.message,\r\n };\r\n }\r\n\r\n // Direct API call (for browser-compatible providers)\r\n const strategy = getStrategy(provider.apiFormat);\r\n const targetModel = model || '';\r\n\r\n // If no model provided, we cannot test (user must select model first)\r\n if (!targetModel) {\r\n return {\r\n success: false,\r\n latencyMs: 0,\r\n message: '请先选择模型 (Please select a model)'\r\n };\r\n }\r\n\r\n const headers = strategy.buildHeaders(apiKey);\r\n // 使用聊天接口进行测试,发送最简单的请求\r\n const testPayload = strategy.buildChatPayload(targetModel, [{ role: 'user', content: 'Hi' }], 5);\r\n const endpoint = strategy.getChatEndpoint(actualBaseUrl, apiKey, targetModel);\r\n\r\n const response = await fetch(endpoint, {\r\n method: 'POST',\r\n headers,\r\n body: JSON.stringify(testPayload),\r\n });\r\n\r\n const latencyMs = Date.now() - startTime;\r\n\r\n if (response.ok) {\r\n return { success: true, latencyMs, message: '连接成功' };\r\n } else {\r\n const errorText = await response.text();\r\n return {\r\n success: false,\r\n latencyMs,\r\n message: `HTTP ${response.status}: ${errorText.slice(0, 200)}`\r\n };\r\n }\r\n } catch (error) {\r\n return {\r\n success: false,\r\n latencyMs: Date.now() - startTime,\r\n message: error instanceof Error ? error.message : String(error),\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Fetch available models from a provider\r\n */\r\nexport async function fetchModels(options: FetchModelsOptions): Promise<Model[]> {\r\n const { provider, apiKey, baseUrl, proxyUrl, fallbackToStatic = true } = options;\r\n\r\n // If proxy URL is provided, use it\r\n if (proxyUrl) {\r\n try {\r\n const response = await fetch(`${proxyUrl}/models`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n provider_id: provider.id,\r\n api_key: apiKey || undefined,\r\n base_url: baseUrl || provider.baseUrl,\r\n }),\r\n });\r\n const data = await response.json();\r\n if (data.success && data.models?.length > 0) {\r\n return data.models;\r\n }\r\n } catch (error) {\r\n console.warn('Failed to fetch models via proxy:', error);\r\n if (!fallbackToStatic) throw error;\r\n }\r\n }\r\n\r\n // Direct API call\r\n if (!proxyUrl && provider.supportsModelsApi) {\r\n try {\r\n const strategy = getStrategy(provider.apiFormat);\r\n if (strategy.getModelsEndpoint) {\r\n const endpoint = strategy.getModelsEndpoint(baseUrl || provider.baseUrl, apiKey || '');\r\n const headers = strategy.buildHeaders(apiKey || '');\r\n\r\n const response = await fetch(endpoint, {\r\n method: 'GET',\r\n headers\r\n });\r\n\r\n if (response.ok) {\r\n const data = await response.json();\r\n const parser = strategy.parseModelsResponse || defaultParseModelsResponse;\r\n return parser(data);\r\n } else {\r\n if (!fallbackToStatic) throw new Error(`HTTP ${response.status}`);\r\n }\r\n }\r\n } catch (e) {\r\n console.warn('Failed to fetch models directly:', e);\r\n if (!fallbackToStatic) throw e;\r\n }\r\n }\r\n\r\n if (!fallbackToStatic && provider.supportsModelsApi) {\r\n throw new Error('Failed to fetch models');\r\n }\r\n\r\n // Fallback to static models\r\n return getStaticModels(provider.id);\r\n}\r\n","/**\r\n * AI Provider Selector - Storage Utilities\r\n * Abstraction layer for config persistence\r\n */\r\n\r\nimport type { AIConfig, StorageAdapter } from './types';\r\n\r\nconst STORAGE_KEY = 'ai_provider_config';\r\n\r\n/**\r\n * Default localStorage adapter\r\n */\r\nexport const localStorageAdapter: StorageAdapter = {\r\n get: (key: string) => {\r\n if (typeof window === 'undefined') return null;\r\n return localStorage.getItem(key);\r\n },\r\n set: (key: string, value: string) => {\r\n if (typeof window === 'undefined') return;\r\n localStorage.setItem(key, value);\r\n },\r\n remove: (key: string) => {\r\n if (typeof window === 'undefined') return;\r\n localStorage.removeItem(key);\r\n },\r\n};\r\n\r\n/**\r\n * Create a config storage instance\r\n */\r\nexport interface StorageOptions {\r\n serialize?: (data: any) => string;\r\n deserialize?: (data: string) => any;\r\n}\r\n\r\nexport function createConfigStorage(\r\n adapter: StorageAdapter = localStorageAdapter,\r\n options: StorageOptions = {}\r\n) {\r\n const serialize = options.serialize || JSON.stringify;\r\n const deserialize = options.deserialize || JSON.parse;\r\n\r\n return {\r\n /**\r\n * Save AI config\r\n */\r\n save(config: AIConfig): void {\r\n try {\r\n const serialized = serialize(config);\r\n adapter.set(STORAGE_KEY, serialized);\r\n } catch (e) {\r\n console.error('Failed to save config:', e);\r\n }\r\n },\r\n\r\n /**\r\n * Load AI config\r\n */\r\n load(): AIConfig | null {\r\n const raw = adapter.get(STORAGE_KEY);\r\n if (!raw) return null;\r\n try {\r\n return deserialize(raw) as AIConfig;\r\n } catch (e) {\r\n console.error('Failed to load config:', e);\r\n return null;\r\n }\r\n },\r\n\r\n /**\r\n * Clear AI config\r\n */\r\n clear(): void {\r\n adapter.remove(STORAGE_KEY);\r\n },\r\n };\r\n}\r\n\r\n","/**\r\n * AI Provider Selector - Config Resolution\r\n * Resolves ProviderConfig into a list of providers and models\r\n */\r\n\r\nimport type { Provider, Model, ProviderConfig, CustomProviderDefinition } from './types';\r\nimport { PROVIDERS } from './providers';\r\nimport { getStaticModels } from './models';\r\n\r\nexport interface ResolvedConfig {\r\n providers: Provider[];\r\n getModels: (providerId: string) => Model[];\r\n}\r\n\r\n/**\r\n * Resolve a ProviderConfig into usable providers and models\r\n */\r\nexport function resolveProviderConfig(config?: ProviderConfig): ResolvedConfig {\r\n // Default config: use all built-in providers\r\n if (!config) {\r\n return {\r\n providers: Object.values(PROVIDERS),\r\n getModels: (providerId: string) => getStaticModels(providerId),\r\n };\r\n }\r\n\r\n const { mode, include, exclude, custom } = config;\r\n let providers: Provider[] = [];\r\n\r\n // Handle built-in providers based on mode\r\n if (mode === 'default') {\r\n let builtInProviders = Object.values(PROVIDERS);\r\n\r\n // Apply include filter\r\n if (include && include.length > 0) {\r\n builtInProviders = builtInProviders.filter(p => include.includes(p.id));\r\n }\r\n\r\n // Apply exclude filter\r\n if (exclude && exclude.length > 0) {\r\n builtInProviders = builtInProviders.filter(p => !exclude.includes(p.id));\r\n }\r\n\r\n providers = [...builtInProviders];\r\n }\r\n\r\n // Handle custom providers\r\n const customModelsMap: Record<string, Model[]> = {};\r\n\r\n if (custom) {\r\n for (const [id, def] of Object.entries(custom)) {\r\n const customProvider: Provider = {\r\n id,\r\n name: def.name,\r\n baseUrl: def.baseUrl,\r\n needsApiKey: def.needsApiKey,\r\n apiFormat: def.apiFormat,\r\n supportsModelsApi: def.supportsModelsApi ?? false,\r\n icon: def.icon,\r\n };\r\n\r\n // Check if provider already exists (for override)\r\n const existingIndex = providers.findIndex(p => p.id === id);\r\n\r\n if (existingIndex >= 0) {\r\n // Merge/Override existing provider\r\n // We keep the original icon if custom doesn't provide one\r\n providers[existingIndex] = {\r\n ...providers[existingIndex],\r\n ...customProvider,\r\n icon: customProvider.icon || providers[existingIndex].icon\r\n };\r\n } else {\r\n // Add new provider\r\n providers.push(customProvider);\r\n }\r\n\r\n // Store custom models if provided\r\n if (def.models && def.models.length > 0) {\r\n customModelsMap[id] = def.models;\r\n }\r\n }\r\n }\r\n\r\n // Create getModels function that checks custom models first\r\n const getModels = (providerId: string): Model[] => {\r\n // Check custom models first\r\n if (customModelsMap[providerId]) {\r\n return customModelsMap[providerId];\r\n }\r\n // Fall back to static models\r\n return getStaticModels(providerId);\r\n };\r\n\r\n return { providers, getModels };\r\n}\r\n\r\n/**\r\n * Get a single provider by ID from config\r\n */\r\nexport function getProviderFromConfig(providerId: string, config?: ProviderConfig): Provider | null {\r\n const { providers } = resolveProviderConfig(config);\r\n return providers.find(p => p.id === providerId) || null;\r\n}\r\n"],"names":["I18N","ICON_CDN_BASE","PROVIDER_ID","PROVIDERS","getProvider","id","getAllProviders","getProvidersByFormat","format","p","STATIC_MODELS","getStaticModels","providerId","defaultParseModelsResponse","data","m","name","c","b","openaiStrategy","baseUrl","apiKey","model","messages","maxTokens","_a","_b","_c","anthropicStrategy","geminiStrategy","_model","_d","_e","cohereStrategy","lastMessage","chatHistory","strategyRegistry","getStrategy","sendDirectChat","options","apiFormat","strategy","endpoint","headers","payload","startTime","response","latencyMs","e","testDirectConnection","result","testConnection","provider","proxyUrl","actualBaseUrl","targetModel","testPayload","errorText","error","fetchModels","fallbackToStatic","STORAGE_KEY","localStorageAdapter","key","value","createConfigStorage","adapter","serialize","deserialize","config","serialized","raw","resolveProviderConfig","mode","include","exclude","custom","providers","builtInProviders","customModelsMap","def","customProvider","existingIndex","getProviderFromConfig"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(function(l,M){typeof exports=="object"&&typeof module<"u"?M(exports):typeof define=="function"&&define.amd?define(["exports"],M):(l=typeof globalThis<"u"?globalThis:l||self,M(l.AISelectorCore={}))})(this,(function(l){"use strict";const M={zh:{save:"保存配置",saved:"保存成功",providerLabel:"Provider",modelLabel:"Model",selectProvider:"选择 Provider...",customBaseUrl:"自定义 Base URL",apiKeyLabel:"API Key",apiKeyPlaceholder:"输入 API Key...",testConnection:"测试模型连接",testing:"测试中...",testSuccess:"连接成功",testFailed:"测试连通性失败",selectModel:"选择 Model...",searchModel:"搜索或自定义模型...",useCustom:"使用自定义",noModels:"暂无模型数据",apiKeyTip:"输入 API Key 后可获取完整模型列表",fetchModelsFailed:"拉取模型列表失败,已使用离线模型列表",refreshingModels:"列表刷新中...",modelListUpdated:"模型列表已刷新",preview:"配置预览",unselected:"(未选择)"},en:{save:"Save Config",saved:"Saved",providerLabel:"Provider",modelLabel:"Model",selectProvider:"Select Provider...",customBaseUrl:"Custom Base URL",apiKeyLabel:"API Key",apiKeyPlaceholder:"Enter API Key...",testConnection:"Test Model Connection",testing:"Testing...",testSuccess:"Connection Successful",testFailed:"Connection Failed",selectModel:"Select Model...",searchModel:"Search or custom models...",useCustom:"Use custom",noModels:"No models found",apiKeyTip:"Enter API Key to fetch full model list",fetchModelsFailed:"Failed to fetch model list, using offline models",refreshingModels:"Refreshing models...",modelListUpdated:"Model list updated",preview:"Config Preview",unselected:"(Unselected)"}},c="https://registry.npmmirror.com/@lobehub/icons-static-svg/1.77.0/files/icons",t={OPENAI:"openai",ANTHROPIC:"anthropic",GEMINI:"gemini",DEEPSEEK:"deepseek",OPENROUTER:"openrouter",GROQ:"groq",MISTRAL:"mistral",MOONSHOT:"moonshot",QWEN:"qwen",ZHIPU:"zhipu",SILICONFLOW:"siliconflow",XAI:"xai",TOGETHER:"together",FIREWORKS:"fireworks",DEEPINFRA:"deepinfra",PERPLEXITY:"perplexity",COHERE:"cohere",OLLAMA:"ollama",DOUBAO:"doubao",MINIMAX:"minimax"},b={[t.OPENAI]:{id:t.OPENAI,name:"OpenAI",baseUrl:"https://api.openai.com/v1",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!0,icon:`${c}/openai.svg`},[t.ANTHROPIC]:{id:t.ANTHROPIC,name:"Anthropic (Claude)",baseUrl:"https://api.anthropic.com/v1",needsApiKey:!0,apiFormat:"anthropic",supportsModelsApi:!1,icon:`${c}/anthropic.svg`},[t.GEMINI]:{id:t.GEMINI,name:"Google Gemini",baseUrl:"https://generativelanguage.googleapis.com/v1beta",needsApiKey:!0,apiFormat:"gemini",supportsModelsApi:!0,icon:`${c}/gemini.svg`},[t.OPENROUTER]:{id:t.OPENROUTER,name:"OpenRouter",baseUrl:"https://openrouter.ai/api/v1",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!0,icon:`${c}/openrouter.svg`},[t.DEEPSEEK]:{id:t.DEEPSEEK,name:"DeepSeek",baseUrl:"https://api.deepseek.com",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!0,icon:`${c}/deepseek.svg`},[t.MOONSHOT]:{id:t.MOONSHOT,name:"Moonshot (Kimi)",baseUrl:"https://api.moonshot.cn/v1",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!0,icon:`${c}/moonshot.svg`},[t.QWEN]:{id:t.QWEN,name:"通义千问 (Qwen)",baseUrl:"https://dashscope.aliyuncs.com/compatible-mode/v1",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!0,icon:`${c}/qwen.svg`},[t.ZHIPU]:{id:t.ZHIPU,name:"智谱 AI (GLM)",baseUrl:"https://open.bigmodel.cn/api/paas/v4",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!0,icon:`${c}/zhipu.svg`},[t.SILICONFLOW]:{id:t.SILICONFLOW,name:"硅基流动 (siliconflow)",baseUrl:"https://api.siliconflow.cn/v1",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!0,icon:`${c}/siliconcloud.svg`},[t.DOUBAO]:{id:t.DOUBAO,name:"火山方舟 (Doubao)",baseUrl:"https://ark.cn-beijing.volces.com/api/v3",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!0,icon:`${c}/doubao.svg`},[t.MINIMAX]:{id:t.MINIMAX,name:"MiniMax",baseUrl:"https://api.minimax.io/v1",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!1,icon:`${c}/minimax.svg`},[t.XAI]:{id:t.XAI,name:"xAI (Grok)",baseUrl:"https://api.x.ai/v1",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!0,icon:`${c}/grok.svg`},[t.GROQ]:{id:t.GROQ,name:"Groq",baseUrl:"https://api.groq.com/openai/v1",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!0,icon:`${c}/groq.svg`},[t.MISTRAL]:{id:t.MISTRAL,name:"Mistral AI",baseUrl:"https://api.mistral.ai/v1",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!0,icon:`${c}/mistral.svg`},[t.TOGETHER]:{id:t.TOGETHER,name:"Together AI",baseUrl:"https://api.together.xyz/v1",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!0,icon:`${c}/together.svg`},[t.FIREWORKS]:{id:t.FIREWORKS,name:"Fireworks AI",baseUrl:"https://api.fireworks.ai/inference/v1",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!0,icon:`${c}/fireworks.svg`},[t.DEEPINFRA]:{id:t.DEEPINFRA,name:"DeepInfra",baseUrl:"https://api.deepinfra.com/v1/openai",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!0,icon:`${c}/deepinfra.svg`},[t.PERPLEXITY]:{id:t.PERPLEXITY,name:"Perplexity",baseUrl:"https://api.perplexity.ai",needsApiKey:!0,apiFormat:"openai",supportsModelsApi:!1,icon:`${c}/perplexity.svg`},[t.COHERE]:{id:t.COHERE,name:"Cohere",baseUrl:"https://api.cohere.com/v2",needsApiKey:!0,apiFormat:"cohere",supportsModelsApi:!0,icon:`${c}/cohere.svg`},[t.OLLAMA]:{id:t.OLLAMA,name:"Ollama (Local)",baseUrl:"http://localhost:11434/v1",needsApiKey:!1,apiFormat:"openai",supportsModelsApi:!0,icon:`${c}/ollama.svg`}};function L(e){return b[e]}function E(){return Object.values(b)}function R(e){return E().filter(a=>a.apiFormat===e)}const O={[t.OPENAI]:[{id:"gpt-5.2-pro",name:"GPT-5.2 Pro"},{id:"gpt-5.2",name:"GPT-5.2"},{id:"gpt-5",name:"GPT-5"},{id:"gpt-5-mini",name:"GPT-5 Mini"},{id:"gpt-5-nano",name:"GPT-5 Nano"},{id:"gpt-4.1",name:"GPT-4.1"}],[t.ANTHROPIC]:[{id:"claude-opus-4.5-20251101",name:"Claude Opus 4.5"},{id:"claude-opus-4.5-20251101-thinking",name:"Claude Opus 4.5 Thinking"},{id:"claude-sonnet-4.5-20250929",name:"Claude Sonnet 4.5"},{id:"claude-sonnet-4.5-20250929-thinking",name:"Claude Sonnet 4.5 Thinking"},{id:"claude-haiku-4.5-20251001",name:"Claude Haiku 4.5"},{id:"claude-haiku-4.5-20251001-thinking",name:"Claude Haiku 4.5 Thinking"},{id:"claude-opus-4.1-20250805",name:"Claude Opus 4.1"},{id:"claude-opus-4.1-20250805-thinking",name:"Claude Opus 4.1 Thinking"}],[t.GEMINI]:[{id:"gemini-3-flash-preview",name:"Gemini 3 Flash Preview"},{id:"gemini-3-pro-preview",name:"Gemini 3 Pro Preview"},{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro"},{id:"gemini-2.5-flash",name:"Gemini 2.5 Flash"},{id:"gemini-2.5-flash-lite",name:"Gemini 2.5 Flash-Lite"}],[t.DEEPSEEK]:[{id:"deepseek-chat",name:"Deepseek Chat"},{id:"deepseek-reasoner",name:"Deepseek Reasoner"}],[t.MISTRAL]:[{id:"mistral-large-latest",name:"Mistral Large"},{id:"mistral-medium-latest",name:"Mistral Medium"},{id:"mistral-small-latest",name:"Mistral Small"},{id:"codestral-latest",name:"Codestral"},{id:"devstral-latest",name:"Devstral"},{id:"magistral-medium-latest",name:"Magistral Medium"},{id:"pixtral-large-latest",name:"Pixtral Large"},{id:"pixtral-12b-latest",name:"Pixtral 12B"},{id:"ministral-8b-latest",name:"Ministral 8B"},{id:"ministral-3b-latest",name:"Ministral 3B"}],[t.GROQ]:[{id:"canopylabs/orpheus-v1-english",name:"Orpheus V1 English"},{id:"canopylabs/orpheus-arabic-saudi",name:"Orpheus Arabic Saudi"},{id:"moonshotai/kimi-k2-instruct",name:"Kimi K2 Instruct"},{id:"groq/compound-mini",name:"Compound Mini"},{id:"llama-3.3-70b-versatile",name:"Llama 3.3 70B Versatile"},{id:"openai/gpt-oss-120b",name:"Gpt Oss 120B"},{id:"qwen/qwen3-32b",name:"Qwen3 32B"},{id:"groq/compound",name:"Compound"},{id:"meta-llama/llama-4-maverick-17b-128e-instruct",name:"Llama 4 Maverick 17B 128E Instruct"}],[t.XAI]:[{id:"grok-4",name:"Grok 4"},{id:"grok-4-fast",name:"Grok 4 Fast"},{id:"grok-3-latest",name:"Grok 3"},{id:"grok-3-fast",name:"Grok 3 Fast"},{id:"grok-3-mini-latest",name:"Grok 3 Mini"},{id:"grok-3-mini-fast",name:"Grok 3 Mini Fast"},{id:"grok-vision-beta",name:"Grok Vision (Beta)"}],[t.TOGETHER]:[{id:"Qwen/Qwen2.5-72B-Instruct-Turbo",name:"Qwen2.5 72B Instruct Turbo"},{id:"Qwen/Qwen3-235B-A22B-Thinking-2507",name:"Qwen3 235B A22B Thinking 2507"},{id:"deepseek-ai/DeepSeek-R1",name:"Deepseek R1"},{id:"deepseek-ai/DeepSeek-V3.1",name:"Deepseek V3.1"},{id:"meta-llama/Llama-3.2-3B-Instruct-Turbo",name:"Llama 3.2 3B Instruct Turbo"},{id:"meta-llama/Llama-3.3-70B-Instruct-Turbo",name:"Llama 3.3 70B Instruct Turbo"},{id:"meta-llama/Llama-3.3-70B-Instruct-Turbo-Free",name:"Llama 3.3 70B Instruct Turbo Free"}],[t.FIREWORKS]:[{id:"accounts/fireworks/models/llama4-scout-instruct-basic",name:"Llama4 Scout Instruct Basic"},{id:"accounts/fireworks/models/qwen3-vl-235b-a22b-thinking",name:"Qwen3 Vl 235B A22B Thinking"},{id:"accounts/fireworks/models/deepseek-v3p2",name:"Deepseek V3P2"},{id:"accounts/fireworks/models/qwen3-vl-30b-a3b-thinking",name:"Qwen3 Vl 30B A3B Thinking"},{id:"accounts/fireworks/models/qwen3-8b",name:"Qwen3 8B"},{id:"accounts/fireworks/models/qwen3-vl-30b-a3b-instruct",name:"Qwen3 Vl 30B A3B Instruct"},{id:"accounts/fireworks/models/qwen2p5-vl-32b-instruct",name:"Qwen2P5 Vl 32B Instruct"},{id:"accounts/fireworks/models/llama4-maverick-instruct-basic",name:"Llama4 Maverick Instruct Basic"},{id:"accounts/fireworks/models/qwen3-235b-a22b-thinking-2507",name:"Qwen3 235B A22B Thinking 2507"},{id:"accounts/fireworks/models/qwen3-coder-480b-a35b-instruct",name:"Qwen3 Coder 480B A35B Instruct"}],[t.DEEPINFRA]:[{id:"meta-llama/Llama-3.2-11B-Vision-Instruct",name:"Llama 3.2 11B Vision Instruct"},{id:"Qwen/Qwen3-32B",name:"Qwen3 32B"},{id:"NousResearch/Hermes-3-Llama-3.1-70B",name:"Hermes 3 Llama 3.1 70B"},{id:"Qwen/Qwen2.5-72B-Instruct",name:"Qwen2.5 72B Instruct"},{id:"deepseek-ai/DeepSeek-V3-0324",name:"Deepseek V3 0324"},{id:"Qwen/Qwen3-VL-235B-A22B-Instruct",name:"Qwen3 Vl 235B A22B Instruct"},{id:"meta-llama/Llama-3.2-3B-Instruct",name:"Llama 3.2 3B Instruct"},{id:"Qwen/Qwen2.5-VL-32B-Instruct",name:"Qwen2.5 Vl 32B Instruct"},{id:"meta-llama/Meta-Llama-3.1-8B-Instruct",name:"Meta Llama 3.1 8B Instruct"},{id:"Qwen/Qwen3-Coder-480B-A35B-Instruct-Turbo",name:"Qwen3 Coder 480B A35B Instruct Turbo"}],[t.OPENROUTER]:[{id:"google/gemini-3-flash-preview",name:"Gemini 3 Flash Preview"},{id:"mistralai/mistral-small-creative",name:"Mistral Small Creative"},{id:"openai/gpt-5.2-chat",name:"Gpt 5.2 Chat"},{id:"openai/gpt-5.2-pro",name:"Gpt 5.2 Pro"},{id:"openai/gpt-5.2",name:"Gpt 5.2"},{id:"mistralai/devstral-2512",name:"Devstral 2512"},{id:"openai/gpt-5.1-codex-max",name:"Gpt 5.1 Codex Max"},{id:"mistralai/ministral-14b-2512",name:"Ministral 14B 2512"},{id:"mistralai/ministral-8b-2512",name:"Ministral 8B 2512"},{id:"mistralai/ministral-3b-2512",name:"Ministral 3B 2512"},{id:"mistralai/mistral-large-2512",name:"Mistral Large 2512"},{id:"deepseek/deepseek-v3.2-speciale",name:"Deepseek V3.2 Speciale"}],[t.PERPLEXITY]:[{id:"codellama-34b-instruct",name:"Codellama 34B Instruct"},{id:"codellama-70b-instruct",name:"Codellama 70B Instruct"},{id:"llama-2-70b-chat",name:"Llama 2 70B Chat"},{id:"llama-3.1-70b-instruct",name:"Llama 3.1 70B Instruct"},{id:"llama-3.1-8b-instruct",name:"Llama 3.1 8B Instruct"},{id:"llama-3.1-sonar-huge-128k-online",name:"Llama 3.1 Sonar Huge 128K Online"},{id:"llama-3.1-sonar-large-128k-chat",name:"Llama 3.1 Sonar Large 128K Chat"},{id:"llama-3.1-sonar-large-128k-online",name:"Llama 3.1 Sonar Large 128K Online"},{id:"llama-3.1-sonar-small-128k-chat",name:"Llama 3.1 Sonar Small 128K Chat"}],[t.COHERE]:[{id:"command-a-vision-07-2025",name:"Command A Vision 07 2025"},{id:"command-a-reasoning-08-2025",name:"Command A Reasoning 08 2025"},{id:"command-r-08-2024",name:"Command R 08 2024"},{id:"command-r7b-arabic-02-2025",name:"Command R7B Arabic 02 2025"},{id:"command-r7b-12-2024",name:"Command R7B 12 2024"}],[t.MOONSHOT]:[{id:"moonshot-v1-128k",name:"Moonshot 128K"},{id:"moonshot-v1-32k",name:"Moonshot 32K"},{id:"moonshot-v1-8k",name:"Moonshot 8K"},{id:"kimi-k2-0711-chat",name:"Kimi K2 Chat"},{id:"moonshot-v1-auto",name:"Moonshot Auto"}],[t.QWEN]:[{id:"qwen-flash",name:"Qwen Flash"},{id:"qwen3-vl-plus-2025-12-19",name:"Qwen3 Vl Plus 2025 12 19"},{id:"qwen3-tts-vd-realtime-2025-12-16",name:"Qwen3 Tts Vd Realtime 2025 12 16"},{id:"qwen-image-edit-plus-2025-12-15",name:"Qwen Image Edit Plus 2025 12 15"},{id:"qwen3-omni-flash-2025-12-01",name:"Qwen3 Omni Flash 2025 12 01"},{id:"qwen3-omni-flash-realtime-2025-12-01",name:"Qwen3 Omni Flash Realtime 2025 12 01"},{id:"qwen3-livetranslate-flash-2025-12-01",name:"Qwen3 Livetranslate Flash 2025 12 01"},{id:"qwen3-livetranslate-flash",name:"Qwen3 Livetranslate Flash"},{id:"qwen-plus-2025-12-01",name:"Qwen Plus 2025 12 01"},{id:"qwen3-tts-vc-realtime-2025-11-27",name:"Qwen3 Tts Vc Realtime 2025 11 27"}],[t.ZHIPU]:[{id:"glm-4.5",name:"Glm 4.5"},{id:"glm-4.5-air",name:"Glm 4.5 Air"},{id:"glm-4.6",name:"Glm 4.6"},{id:"glm-4.7",name:"Glm 4.7"}],[t.SILICONFLOW]:[{id:"deepseek-ai/DeepSeek-V3.2",name:"Deepseek V3.2"},{id:"deepseek-ai/DeepSeek-V3.1-Terminus",name:"Deepseek V3.1 Terminus"},{id:"deepseek-ai/DeepSeek-R1",name:"Deepseek R1"},{id:"deepseek-ai/DeepSeek-V3",name:"Deepseek V3"},{id:"zai-org/GLM-4.6V",name:"Glm 4.6V"},{id:"zai-org/GLM-4.6",name:"Glm 4.6"},{id:"Pro/zai-org/GLM-4.7",name:"Glm 4.7"},{id:"Qwen/Qwen3-VL-32B-Instruct",name:"Qwen3 Vl 32B Instruct"}],[t.OLLAMA]:[{id:"llama3.3",name:"Llama 3.3"},{id:"llama3.2",name:"Llama 3.2"},{id:"qwq",name:"QwQ (推理)"},{id:"qwen3:32b",name:"Qwen3 32B"},{id:"deepseek-r1:32b",name:"DeepSeek R1 32B"},{id:"deepseek-coder-v2",name:"DeepSeek Coder V2"},{id:"gemma3:27b",name:"Gemma 3 27B"},{id:"mistral:7b",name:"Mistral 7B"},{id:"phi4",name:"Phi 4"},{id:"codellama",name:"Code Llama"}],[t.DOUBAO]:[{id:"doubao-seed-1-8-251215",name:"Doubao 1.8"},{id:"doubao-seed-1-6-251015",name:"Doubao 1.6"},{id:"doubao-seed-1-6-lite-251015",name:"Doubao 1.6 Lite"},{id:"doubao-seed-1-6-flash-250828",name:"Doubao 1.6 Flash"},{id:"doubao-seed-1-6-thinking-250615",name:"Doubao 1.6 Thinking"}],[t.MINIMAX]:[{id:"MiniMax-M2.1",name:"MiniMax M2.1"},{id:"MiniMax-M2.1-lightning",name:"MiniMax M2.1 Lightning"},{id:"MiniMax-M2",name:"MiniMax M2"}]};function v(e){return O[e]||[]}const F=e=>Array.isArray(e==null?void 0:e.data)?e.data.filter(a=>a.id).map(a=>{const n=a.name||(a.id.split("/").pop()??"").replace(/[-_]/g," ").replace(/\b\w/g,o=>o.toUpperCase());return{id:a.id,name:n,created:a.created||0}}).sort((a,n)=>(n.created||0)-(a.created||0)):[],P={format:"openai",getModelsEndpoint:e=>`${e}/models`,getChatEndpoint:e=>`${e}/chat/completions`,buildHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),buildChatPayload:(e,a,n)=>({model:e,messages:a,max_tokens:n}),parseChatResponse:e=>{var a,n,o;return((o=(n=(a=e.choices)==null?void 0:a[0])==null?void 0:n.message)==null?void 0:o.content)||""}},C={openai:P,anthropic:{format:"anthropic",getChatEndpoint:e=>`${e}/messages`,buildHeaders:e=>({"Content-Type":"application/json","x-api-key":e,"anthropic-version":"2023-06-01"}),buildChatPayload:(e,a,n)=>({model:e,messages:a,max_tokens:n}),parseChatResponse:e=>{var a,n;return((n=(a=e.content)==null?void 0:a[0])==null?void 0:n.text)||""}},gemini:{format:"gemini",getModelsEndpoint:(e,a)=>`${e}/models?key=${a}`,getChatEndpoint:(e,a,n)=>`${e}/models/${n}:generateContent?key=${a}`,buildHeaders:()=>({"Content-Type":"application/json"}),buildChatPayload:(e,a,n)=>({contents:a.map(r=>({role:r.role==="assistant"?"model":"user",parts:[{text:r.content}]})),generationConfig:{maxOutputTokens:n}}),parseChatResponse:e=>{var a,n,o,r,s;return((s=(r=(o=(n=(a=e.candidates)==null?void 0:a[0])==null?void 0:n.content)==null?void 0:o.parts)==null?void 0:r[0])==null?void 0:s.text)||""},parseModelsResponse:e=>Array.isArray(e.models)?e.models.filter(a=>{var n;return(n=a.supportedGenerationMethods)==null?void 0:n.includes("generateContent")}).map(a=>({id:a.name.replace("models/",""),name:a.displayName||a.name.replace("models/",""),created:a.created||0})).sort((a,n)=>(n.created||0)-(a.created||0)):[]},cohere:{format:"cohere",getModelsEndpoint:e=>`${e}/models`,getChatEndpoint:e=>`${e}/chat`,buildHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),buildChatPayload:(e,a,n)=>{const o=a[a.length-1],r=a.slice(0,-1).map(s=>({role:s.role==="assistant"?"CHATBOT":"USER",message:s.content}));return{model:e,message:o.content,chat_history:r,max_tokens:n}},parseChatResponse:e=>e.text||""}};function w(e){return C[e]||P}async function T(e){var f;const{apiFormat:a,baseUrl:n,apiKey:o,model:r,messages:s,maxTokens:g=2048}=e,d=w(a),i=d.getChatEndpoint(n,o,r),m=d.buildHeaders(o),u=d.buildChatPayload(r,s,g),h=performance.now();try{const p=await fetch(i,{method:"POST",headers:m,body:JSON.stringify(u)}),y=Math.round(performance.now()-h);if(!p.ok)return{success:!1,message:((f=(await p.json().catch(()=>({}))).error)==null?void 0:f.message)||`HTTP ${p.status}: ${p.statusText}`,latencyMs:y};const A=await p.json();return{success:!0,content:d.parseChatResponse(A),latencyMs:y}}catch(p){return{success:!1,message:p instanceof Error?p.message:"网络错误"}}}async function D(e){const a=await T({apiFormat:e.apiFormat,baseUrl:e.baseUrl,apiKey:e.apiKey,model:e.model,messages:[{role:"user",content:"Hi"}],maxTokens:5});return{success:a.success,latencyMs:a.latencyMs,message:a.success?void 0:a.message}}async function K(e){const{provider:a,apiKey:n,model:o,baseUrl:r,proxyUrl:s}=e,g=r||a.baseUrl,d=Date.now();try{if(s){const k=await(await fetch(`${s}/test`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider_id:a.id,api_key:n,model:o||"",base_url:r||a.baseUrl,api_format:a.apiFormat})})).json();return{success:k.success,latencyMs:k.latency_ms||Date.now()-d,message:k.message}}const i=w(a.apiFormat),m=o||"";if(!m)return{success:!1,latencyMs:0,message:"请先选择模型 (Please select a model)"};const u=i.buildHeaders(n),h=i.buildChatPayload(m,[{role:"user",content:"Hi"}],5),f=i.getChatEndpoint(g,n,m),p=await fetch(f,{method:"POST",headers:u,body:JSON.stringify(h)}),y=Date.now()-d;if(p.ok)return{success:!0,latencyMs:y,message:"连接成功"};{const A=await p.text();return{success:!1,latencyMs:y,message:`HTTP ${p.status}: ${A.slice(0,200)}`}}}catch(i){return{success:!1,latencyMs:Date.now()-d,message:i instanceof Error?i.message:String(i)}}}async function U(e){var g;const{provider:a,apiKey:n,baseUrl:o,proxyUrl:r,fallbackToStatic:s=!0}=e;if(r)try{const i=await(await fetch(`${r}/models`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider_id:a.id,api_key:n||void 0,base_url:o||a.baseUrl})})).json();if(i.success&&((g=i.models)==null?void 0:g.length)>0)return i.models}catch(d){if(console.warn("Failed to fetch models via proxy:",d),!s)throw d}if(!r&&a.supportsModelsApi)try{const d=w(a.apiFormat);if(d.getModelsEndpoint){const i=d.getModelsEndpoint(o||a.baseUrl,n||""),m=d.buildHeaders(n||""),u=await fetch(i,{method:"GET",headers:m});if(u.ok){const h=await u.json();return(d.parseModelsResponse||F)(h)}else if(!s)throw new Error(`HTTP ${u.status}`)}}catch(d){if(console.warn("Failed to fetch models directly:",d),!s)throw d}if(!s&&a.supportsModelsApi)throw new Error("Failed to fetch models");return v(a.id)}const I="ai_provider_config",S={get:e=>typeof window>"u"?null:localStorage.getItem(e),set:(e,a)=>{typeof window>"u"||localStorage.setItem(e,a)},remove:e=>{typeof window>"u"||localStorage.removeItem(e)}};function G(e=S,a={}){const n=a.serialize||JSON.stringify,o=a.deserialize||JSON.parse;return{save(r){try{const s=n(r);e.set(I,s)}catch(s){console.error("Failed to save config:",s)}},load(){const r=e.get(I);if(!r)return null;try{return o(r)}catch(s){return console.error("Failed to load config:",s),null}},clear(){e.remove(I)}}}function B(e){if(!e)return{providers:Object.values(b),getModels:i=>v(i)};const{mode:a,include:n,exclude:o,custom:r}=e;let s=[];if(a==="default"){let i=Object.values(b);n&&n.length>0&&(i=i.filter(m=>n.includes(m.id))),o&&o.length>0&&(i=i.filter(m=>!o.includes(m.id))),s=[...i]}const g={};if(r)for(const[i,m]of Object.entries(r)){const u={id:i,name:m.name,baseUrl:m.baseUrl,needsApiKey:m.needsApiKey,apiFormat:m.apiFormat,supportsModelsApi:m.supportsModelsApi??!1,icon:m.icon},h=s.findIndex(f=>f.id===i);h>=0?s[h]={...s[h],...u,icon:u.icon||s[h].icon}:s.push(u),m.models&&m.models.length>0&&(g[i]=m.models)}return{providers:s,getModels:i=>g[i]?g[i]:v(i)}}function Q(e,a){const{providers:n}=B(a);return n.find(o=>o.id===e)||null}l.I18N=M,l.PROVIDERS=b,l.PROVIDER_ID=t,l.STATIC_MODELS=O,l.createConfigStorage=G,l.fetchModels=U,l.getAllProviders=E,l.getProvider=L,l.getProviderFromConfig=Q,l.getProvidersByFormat=R,l.getStaticModels=v,l.getStrategy=w,l.localStorageAdapter=S,l.resolveProviderConfig=B,l.sendDirectChat=T,l.strategyRegistry=C,l.testConnection=K,l.testDirectConnection=D,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})}));
|
|
2
|
+
//# sourceMappingURL=index.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.umd.js","sources":["../src/i18n.ts","../src/providers.ts","../src/models.ts","../src/strategies.ts","../src/api.ts","../src/storage.ts","../src/config.ts"],"sourcesContent":["export const I18N = {\n zh: {\n save: '保存配置',\n saved: '保存成功',\n providerLabel: 'Provider',\n modelLabel: 'Model',\n selectProvider: '选择 Provider...',\n customBaseUrl: '自定义 Base URL',\n apiKeyLabel: 'API Key',\n apiKeyPlaceholder: '输入 API Key...',\n testConnection: '测试模型连接',\n testing: '测试中...',\n testSuccess: '连接成功',\n testFailed: '测试连通性失败',\n selectModel: '选择 Model...',\n searchModel: '搜索或自定义模型...',\n useCustom: '使用自定义',\n noModels: '暂无模型数据',\n apiKeyTip: '输入 API Key 后可获取完整模型列表',\n fetchModelsFailed: '拉取模型列表失败,已使用离线模型列表',\n refreshingModels: '列表刷新中...',\n modelListUpdated: '模型列表已刷新',\n preview: '配置预览',\n unselected: '(未选择)',\n },\n en: {\n save: 'Save Config',\n saved: 'Saved',\n providerLabel: 'Provider',\n modelLabel: 'Model',\n selectProvider: 'Select Provider...',\n customBaseUrl: 'Custom Base URL',\n apiKeyLabel: 'API Key',\n apiKeyPlaceholder: 'Enter API Key...',\n testConnection: 'Test Model Connection',\n testing: 'Testing...',\n testSuccess: 'Connection Successful',\n testFailed: 'Connection Failed',\n selectModel: 'Select Model...',\n searchModel: 'Search or custom models...',\n useCustom: 'Use custom',\n noModels: 'No models found',\n apiKeyTip: 'Enter API Key to fetch full model list',\n fetchModelsFailed: 'Failed to fetch model list, using offline models',\n refreshingModels: 'Refreshing models...',\n modelListUpdated: 'Model list updated',\n preview: 'Config Preview',\n unselected: '(Unselected)',\n }\n} as const;\n\nexport type Language = keyof typeof I18N;\nexport type I18NKeys = keyof typeof I18N['zh'];\n\n","/**\r\n * AI Provider Selector - Provider Definitions\r\n * All supported AI providers metadata\r\n */\r\n\r\nimport type { Provider } from './types';\r\n\r\nconst ICON_CDN_BASE = 'https://registry.npmmirror.com/@lobehub/icons-static-svg/1.77.0/files/icons';\r\n\r\n// Provider IDs\r\nexport const PROVIDER_ID = {\r\n OPENAI: 'openai',\r\n ANTHROPIC: 'anthropic',\r\n GEMINI: 'gemini',\r\n DEEPSEEK: 'deepseek',\r\n OPENROUTER: 'openrouter',\r\n GROQ: 'groq',\r\n MISTRAL: 'mistral',\r\n MOONSHOT: 'moonshot',\r\n QWEN: 'qwen',\r\n ZHIPU: 'zhipu',\r\n SILICONFLOW: 'siliconflow',\r\n XAI: 'xai',\r\n TOGETHER: 'together',\r\n FIREWORKS: 'fireworks',\r\n DEEPINFRA: 'deepinfra',\r\n PERPLEXITY: 'perplexity',\r\n COHERE: 'cohere',\r\n OLLAMA: 'ollama',\r\n DOUBAO: 'doubao',\r\n MINIMAX: 'minimax',\r\n} as const;\r\n\r\nexport type ProviderId = typeof PROVIDER_ID[keyof typeof PROVIDER_ID];\r\n\r\nexport const PROVIDERS: Record<string, Provider> = {\r\n [PROVIDER_ID.OPENAI]: {\r\n id: PROVIDER_ID.OPENAI,\r\n name: 'OpenAI',\r\n baseUrl: 'https://api.openai.com/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/openai.svg`,\r\n },\r\n [PROVIDER_ID.ANTHROPIC]: {\r\n id: PROVIDER_ID.ANTHROPIC,\r\n name: 'Anthropic (Claude)',\r\n baseUrl: 'https://api.anthropic.com/v1',\r\n needsApiKey: true,\r\n apiFormat: 'anthropic',\r\n supportsModelsApi: false,\r\n icon: `${ICON_CDN_BASE}/anthropic.svg`,\r\n },\r\n [PROVIDER_ID.GEMINI]: {\r\n id: PROVIDER_ID.GEMINI,\r\n name: 'Google Gemini',\r\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\r\n needsApiKey: true,\r\n apiFormat: 'gemini',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/gemini.svg`,\r\n },\r\n [PROVIDER_ID.OPENROUTER]: {\r\n id: PROVIDER_ID.OPENROUTER,\r\n name: 'OpenRouter',\r\n baseUrl: 'https://openrouter.ai/api/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/openrouter.svg`,\r\n },\r\n [PROVIDER_ID.DEEPSEEK]: {\r\n id: PROVIDER_ID.DEEPSEEK,\r\n name: 'DeepSeek',\r\n baseUrl: 'https://api.deepseek.com',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/deepseek.svg`,\r\n },\r\n [PROVIDER_ID.MOONSHOT]: {\r\n id: PROVIDER_ID.MOONSHOT,\r\n name: 'Moonshot (Kimi)',\r\n baseUrl: 'https://api.moonshot.cn/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/moonshot.svg`,\r\n },\r\n [PROVIDER_ID.QWEN]: {\r\n id: PROVIDER_ID.QWEN,\r\n name: '通义千问 (Qwen)',\r\n baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/qwen.svg`,\r\n },\r\n [PROVIDER_ID.ZHIPU]: {\r\n id: PROVIDER_ID.ZHIPU,\r\n name: '智谱 AI (GLM)',\r\n baseUrl: 'https://open.bigmodel.cn/api/paas/v4',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/zhipu.svg`,\r\n },\r\n [PROVIDER_ID.SILICONFLOW]: {\r\n id: PROVIDER_ID.SILICONFLOW,\r\n name: '硅基流动 (siliconflow)',\r\n baseUrl: 'https://api.siliconflow.cn/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/siliconcloud.svg`,\r\n },\r\n\r\n [PROVIDER_ID.DOUBAO]: {\r\n id: PROVIDER_ID.DOUBAO,\r\n name: '火山方舟 (Doubao)',\r\n baseUrl: 'https://ark.cn-beijing.volces.com/api/v3',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/doubao.svg`,\r\n },\r\n [PROVIDER_ID.MINIMAX]: {\r\n id: PROVIDER_ID.MINIMAX,\r\n name: 'MiniMax',\r\n baseUrl: 'https://api.minimax.io/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: false,\r\n icon: `${ICON_CDN_BASE}/minimax.svg`,\r\n },\r\n [PROVIDER_ID.XAI]: {\r\n id: PROVIDER_ID.XAI,\r\n name: 'xAI (Grok)',\r\n baseUrl: 'https://api.x.ai/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/grok.svg`,\r\n },\r\n [PROVIDER_ID.GROQ]: {\r\n id: PROVIDER_ID.GROQ,\r\n name: 'Groq',\r\n baseUrl: 'https://api.groq.com/openai/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/groq.svg`,\r\n },\r\n [PROVIDER_ID.MISTRAL]: {\r\n id: PROVIDER_ID.MISTRAL,\r\n name: 'Mistral AI',\r\n baseUrl: 'https://api.mistral.ai/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/mistral.svg`,\r\n },\r\n [PROVIDER_ID.TOGETHER]: {\r\n id: PROVIDER_ID.TOGETHER,\r\n name: 'Together AI',\r\n baseUrl: 'https://api.together.xyz/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/together.svg`,\r\n },\r\n [PROVIDER_ID.FIREWORKS]: {\r\n id: PROVIDER_ID.FIREWORKS,\r\n name: 'Fireworks AI',\r\n baseUrl: 'https://api.fireworks.ai/inference/v1',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/fireworks.svg`,\r\n },\r\n [PROVIDER_ID.DEEPINFRA]: {\r\n id: PROVIDER_ID.DEEPINFRA,\r\n name: 'DeepInfra',\r\n baseUrl: 'https://api.deepinfra.com/v1/openai',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/deepinfra.svg`,\r\n },\r\n [PROVIDER_ID.PERPLEXITY]: {\r\n id: PROVIDER_ID.PERPLEXITY,\r\n name: 'Perplexity',\r\n baseUrl: 'https://api.perplexity.ai',\r\n needsApiKey: true,\r\n apiFormat: 'openai',\r\n supportsModelsApi: false,\r\n icon: `${ICON_CDN_BASE}/perplexity.svg`,\r\n },\r\n [PROVIDER_ID.COHERE]: {\r\n id: PROVIDER_ID.COHERE,\r\n name: 'Cohere',\r\n baseUrl: 'https://api.cohere.com/v2',\r\n needsApiKey: true,\r\n apiFormat: 'cohere',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/cohere.svg`,\r\n },\r\n [PROVIDER_ID.OLLAMA]: {\r\n id: PROVIDER_ID.OLLAMA,\r\n name: 'Ollama (Local)',\r\n baseUrl: 'http://localhost:11434/v1',\r\n needsApiKey: false,\r\n apiFormat: 'openai',\r\n supportsModelsApi: true,\r\n icon: `${ICON_CDN_BASE}/ollama.svg`,\r\n },\r\n};\r\n\r\n/**\r\n * Get a provider by ID\r\n */\r\nexport function getProvider(id: string): Provider | undefined {\r\n return PROVIDERS[id];\r\n}\r\n\r\n/**\r\n * Get all providers as an array\r\n */\r\nexport function getAllProviders(): Provider[] {\r\n return Object.values(PROVIDERS);\r\n}\r\n\r\n/**\r\n * Get providers by API format\r\n */\r\nexport function getProvidersByFormat(format: Provider['apiFormat']): Provider[] {\r\n return getAllProviders().filter(p => p.apiFormat === format);\r\n}\r\n","/**\r\n * AI Provider Selector - Static Model Definitions\r\n * Models data when API doesn't support /models endpoint\r\n */\r\n\r\nimport type { Model } from './types';\r\nimport { PROVIDER_ID } from './providers';\r\n\r\nexport const STATIC_MODELS: Record<string, Model[]> = {\r\n [PROVIDER_ID.OPENAI]: [\r\n { id: 'gpt-5.2-pro', name: 'GPT-5.2 Pro' },\r\n { id: 'gpt-5.2', name: 'GPT-5.2' },\r\n { id: 'gpt-5', name: 'GPT-5' },\r\n { id: 'gpt-5-mini', name: 'GPT-5 Mini' },\r\n { id: 'gpt-5-nano', name: 'GPT-5 Nano' },\r\n { id: 'gpt-4.1', name: 'GPT-4.1' },\r\n ],\r\n [PROVIDER_ID.ANTHROPIC]: [\r\n { id: 'claude-opus-4.5-20251101', name: 'Claude Opus 4.5' },\r\n { id: 'claude-opus-4.5-20251101-thinking', name: 'Claude Opus 4.5 Thinking' },\r\n { id: 'claude-sonnet-4.5-20250929', name: 'Claude Sonnet 4.5' },\r\n { id: 'claude-sonnet-4.5-20250929-thinking', name: 'Claude Sonnet 4.5 Thinking' },\r\n { id: 'claude-haiku-4.5-20251001', name: 'Claude Haiku 4.5' },\r\n { id: 'claude-haiku-4.5-20251001-thinking', name: 'Claude Haiku 4.5 Thinking' },\r\n { id: 'claude-opus-4.1-20250805', name: 'Claude Opus 4.1' },\r\n { id: 'claude-opus-4.1-20250805-thinking', name: 'Claude Opus 4.1 Thinking' },\r\n ],\r\n [PROVIDER_ID.GEMINI]: [\r\n { id: 'gemini-3-flash-preview', name: 'Gemini 3 Flash Preview' },\r\n { id: 'gemini-3-pro-preview', name: 'Gemini 3 Pro Preview' },\r\n { id: 'gemini-2.5-pro', name: 'Gemini 2.5 Pro' },\r\n { id: 'gemini-2.5-flash', name: 'Gemini 2.5 Flash' },\r\n { id: 'gemini-2.5-flash-lite', name: 'Gemini 2.5 Flash-Lite' },\r\n ],\r\n [PROVIDER_ID.DEEPSEEK]: [\r\n { id: 'deepseek-chat', name: 'Deepseek Chat' },\r\n { id: 'deepseek-reasoner', name: 'Deepseek Reasoner' },\r\n ],\r\n [PROVIDER_ID.MISTRAL]: [\r\n { id: 'mistral-large-latest', name: 'Mistral Large' },\r\n { id: 'mistral-medium-latest', name: 'Mistral Medium' },\r\n { id: 'mistral-small-latest', name: 'Mistral Small' },\r\n { id: 'codestral-latest', name: 'Codestral' },\r\n { id: 'devstral-latest', name: 'Devstral' },\r\n { id: 'magistral-medium-latest', name: 'Magistral Medium' },\r\n { id: 'pixtral-large-latest', name: 'Pixtral Large' },\r\n { id: 'pixtral-12b-latest', name: 'Pixtral 12B' },\r\n { id: 'ministral-8b-latest', name: 'Ministral 8B' },\r\n { id: 'ministral-3b-latest', name: 'Ministral 3B' },\r\n ],\r\n [PROVIDER_ID.GROQ]: [\r\n { id: 'canopylabs/orpheus-v1-english', name: 'Orpheus V1 English' },\r\n { id: 'canopylabs/orpheus-arabic-saudi', name: 'Orpheus Arabic Saudi' },\r\n { id: 'moonshotai/kimi-k2-instruct', name: 'Kimi K2 Instruct' },\r\n { id: 'groq/compound-mini', name: 'Compound Mini' },\r\n { id: 'llama-3.3-70b-versatile', name: 'Llama 3.3 70B Versatile' },\r\n { id: 'openai/gpt-oss-120b', name: 'Gpt Oss 120B' },\r\n { id: 'qwen/qwen3-32b', name: 'Qwen3 32B' },\r\n { id: 'groq/compound', name: 'Compound' },\r\n { id: 'meta-llama/llama-4-maverick-17b-128e-instruct', name: 'Llama 4 Maverick 17B 128E Instruct' },\r\n ],\r\n [PROVIDER_ID.XAI]: [\r\n { id: 'grok-4', name: 'Grok 4' },\r\n { id: 'grok-4-fast', name: 'Grok 4 Fast' },\r\n { id: 'grok-3-latest', name: 'Grok 3' },\r\n { id: 'grok-3-fast', name: 'Grok 3 Fast' },\r\n { id: 'grok-3-mini-latest', name: 'Grok 3 Mini' },\r\n { id: 'grok-3-mini-fast', name: 'Grok 3 Mini Fast' },\r\n { id: 'grok-vision-beta', name: 'Grok Vision (Beta)' },\r\n ],\r\n [PROVIDER_ID.TOGETHER]: [\r\n { id: 'Qwen/Qwen2.5-72B-Instruct-Turbo', name: 'Qwen2.5 72B Instruct Turbo' },\r\n { id: 'Qwen/Qwen3-235B-A22B-Thinking-2507', name: 'Qwen3 235B A22B Thinking 2507' },\r\n { id: 'deepseek-ai/DeepSeek-R1', name: 'Deepseek R1' },\r\n { id: 'deepseek-ai/DeepSeek-V3.1', name: 'Deepseek V3.1' },\r\n { id: 'meta-llama/Llama-3.2-3B-Instruct-Turbo', name: 'Llama 3.2 3B Instruct Turbo' },\r\n { id: 'meta-llama/Llama-3.3-70B-Instruct-Turbo', name: 'Llama 3.3 70B Instruct Turbo' },\r\n { id: 'meta-llama/Llama-3.3-70B-Instruct-Turbo-Free', name: 'Llama 3.3 70B Instruct Turbo Free' },\r\n ],\r\n [PROVIDER_ID.FIREWORKS]: [\r\n { id: 'accounts/fireworks/models/llama4-scout-instruct-basic', name: 'Llama4 Scout Instruct Basic' },\r\n { id: 'accounts/fireworks/models/qwen3-vl-235b-a22b-thinking', name: 'Qwen3 Vl 235B A22B Thinking' },\r\n { id: 'accounts/fireworks/models/deepseek-v3p2', name: 'Deepseek V3P2' },\r\n { id: 'accounts/fireworks/models/qwen3-vl-30b-a3b-thinking', name: 'Qwen3 Vl 30B A3B Thinking' },\r\n { id: 'accounts/fireworks/models/qwen3-8b', name: 'Qwen3 8B' },\r\n { id: 'accounts/fireworks/models/qwen3-vl-30b-a3b-instruct', name: 'Qwen3 Vl 30B A3B Instruct' },\r\n { id: 'accounts/fireworks/models/qwen2p5-vl-32b-instruct', name: 'Qwen2P5 Vl 32B Instruct' },\r\n { id: 'accounts/fireworks/models/llama4-maverick-instruct-basic', name: 'Llama4 Maverick Instruct Basic' },\r\n { id: 'accounts/fireworks/models/qwen3-235b-a22b-thinking-2507', name: 'Qwen3 235B A22B Thinking 2507' },\r\n { id: 'accounts/fireworks/models/qwen3-coder-480b-a35b-instruct', name: 'Qwen3 Coder 480B A35B Instruct' },\r\n ],\r\n [PROVIDER_ID.DEEPINFRA]: [\r\n { id: 'meta-llama/Llama-3.2-11B-Vision-Instruct', name: 'Llama 3.2 11B Vision Instruct' },\r\n { id: 'Qwen/Qwen3-32B', name: 'Qwen3 32B' },\r\n { id: 'NousResearch/Hermes-3-Llama-3.1-70B', name: 'Hermes 3 Llama 3.1 70B' },\r\n { id: 'Qwen/Qwen2.5-72B-Instruct', name: 'Qwen2.5 72B Instruct' },\r\n { id: 'deepseek-ai/DeepSeek-V3-0324', name: 'Deepseek V3 0324' },\r\n { id: 'Qwen/Qwen3-VL-235B-A22B-Instruct', name: 'Qwen3 Vl 235B A22B Instruct' },\r\n { id: 'meta-llama/Llama-3.2-3B-Instruct', name: 'Llama 3.2 3B Instruct' },\r\n { id: 'Qwen/Qwen2.5-VL-32B-Instruct', name: 'Qwen2.5 Vl 32B Instruct' },\r\n { id: 'meta-llama/Meta-Llama-3.1-8B-Instruct', name: 'Meta Llama 3.1 8B Instruct' },\r\n { id: 'Qwen/Qwen3-Coder-480B-A35B-Instruct-Turbo', name: 'Qwen3 Coder 480B A35B Instruct Turbo' },\r\n ],\r\n [PROVIDER_ID.OPENROUTER]: [\r\n { id: 'google/gemini-3-flash-preview', name: 'Gemini 3 Flash Preview' },\r\n { id: 'mistralai/mistral-small-creative', name: 'Mistral Small Creative' },\r\n { id: 'openai/gpt-5.2-chat', name: 'Gpt 5.2 Chat' },\r\n { id: 'openai/gpt-5.2-pro', name: 'Gpt 5.2 Pro' },\r\n { id: 'openai/gpt-5.2', name: 'Gpt 5.2' },\r\n { id: 'mistralai/devstral-2512', name: 'Devstral 2512' },\r\n { id: 'openai/gpt-5.1-codex-max', name: 'Gpt 5.1 Codex Max' },\r\n { id: 'mistralai/ministral-14b-2512', name: 'Ministral 14B 2512' },\r\n { id: 'mistralai/ministral-8b-2512', name: 'Ministral 8B 2512' },\r\n { id: 'mistralai/ministral-3b-2512', name: 'Ministral 3B 2512' },\r\n { id: 'mistralai/mistral-large-2512', name: 'Mistral Large 2512' },\r\n { id: 'deepseek/deepseek-v3.2-speciale', name: 'Deepseek V3.2 Speciale' },\r\n ],\r\n [PROVIDER_ID.PERPLEXITY]: [\r\n { id: 'codellama-34b-instruct', name: 'Codellama 34B Instruct' },\r\n { id: 'codellama-70b-instruct', name: 'Codellama 70B Instruct' },\r\n { id: 'llama-2-70b-chat', name: 'Llama 2 70B Chat' },\r\n { id: 'llama-3.1-70b-instruct', name: 'Llama 3.1 70B Instruct' },\r\n { id: 'llama-3.1-8b-instruct', name: 'Llama 3.1 8B Instruct' },\r\n { id: 'llama-3.1-sonar-huge-128k-online', name: 'Llama 3.1 Sonar Huge 128K Online' },\r\n { id: 'llama-3.1-sonar-large-128k-chat', name: 'Llama 3.1 Sonar Large 128K Chat' },\r\n { id: 'llama-3.1-sonar-large-128k-online', name: 'Llama 3.1 Sonar Large 128K Online' },\r\n { id: 'llama-3.1-sonar-small-128k-chat', name: 'Llama 3.1 Sonar Small 128K Chat' },\r\n ],\r\n [PROVIDER_ID.COHERE]: [\r\n { id: 'command-a-vision-07-2025', name: 'Command A Vision 07 2025' },\r\n { id: 'command-a-reasoning-08-2025', name: 'Command A Reasoning 08 2025' },\r\n { id: 'command-r-08-2024', name: 'Command R 08 2024' },\r\n { id: 'command-r7b-arabic-02-2025', name: 'Command R7B Arabic 02 2025' },\r\n { id: 'command-r7b-12-2024', name: 'Command R7B 12 2024' },\r\n ],\r\n [PROVIDER_ID.MOONSHOT]: [\r\n { id: 'moonshot-v1-128k', name: 'Moonshot 128K' },\r\n { id: 'moonshot-v1-32k', name: 'Moonshot 32K' },\r\n { id: 'moonshot-v1-8k', name: 'Moonshot 8K' },\r\n { id: 'kimi-k2-0711-chat', name: 'Kimi K2 Chat' },\r\n { id: 'moonshot-v1-auto', name: 'Moonshot Auto' },\r\n ],\r\n [PROVIDER_ID.QWEN]: [\r\n { id: 'qwen-flash', name: 'Qwen Flash' },\r\n { id: 'qwen3-vl-plus-2025-12-19', name: 'Qwen3 Vl Plus 2025 12 19' },\r\n { id: 'qwen3-tts-vd-realtime-2025-12-16', name: 'Qwen3 Tts Vd Realtime 2025 12 16' },\r\n { id: 'qwen-image-edit-plus-2025-12-15', name: 'Qwen Image Edit Plus 2025 12 15' },\r\n { id: 'qwen3-omni-flash-2025-12-01', name: 'Qwen3 Omni Flash 2025 12 01' },\r\n { id: 'qwen3-omni-flash-realtime-2025-12-01', name: 'Qwen3 Omni Flash Realtime 2025 12 01' },\r\n { id: 'qwen3-livetranslate-flash-2025-12-01', name: 'Qwen3 Livetranslate Flash 2025 12 01' },\r\n { id: 'qwen3-livetranslate-flash', name: 'Qwen3 Livetranslate Flash' },\r\n { id: 'qwen-plus-2025-12-01', name: 'Qwen Plus 2025 12 01' },\r\n { id: 'qwen3-tts-vc-realtime-2025-11-27', name: 'Qwen3 Tts Vc Realtime 2025 11 27' },\r\n ],\r\n [PROVIDER_ID.ZHIPU]: [\r\n { id: 'glm-4.5', name: 'Glm 4.5' },\r\n { id: 'glm-4.5-air', name: 'Glm 4.5 Air' },\r\n { id: 'glm-4.6', name: 'Glm 4.6' },\r\n { id: 'glm-4.7', name: 'Glm 4.7' },\r\n ],\r\n [PROVIDER_ID.SILICONFLOW]: [\r\n { id: 'deepseek-ai/DeepSeek-V3.2', name: 'Deepseek V3.2' },\r\n { id: 'deepseek-ai/DeepSeek-V3.1-Terminus', name: 'Deepseek V3.1 Terminus' },\r\n { id: 'deepseek-ai/DeepSeek-R1', name: 'Deepseek R1' },\r\n { id: 'deepseek-ai/DeepSeek-V3', name: 'Deepseek V3' },\r\n { id: 'zai-org/GLM-4.6V', name: 'Glm 4.6V' },\r\n { id: 'zai-org/GLM-4.6', name: 'Glm 4.6' },\r\n { id: 'Pro/zai-org/GLM-4.7', name: 'Glm 4.7' },\r\n { id: 'Qwen/Qwen3-VL-32B-Instruct', name: 'Qwen3 Vl 32B Instruct' },\r\n ],\r\n [PROVIDER_ID.OLLAMA]: [\r\n { id: 'llama3.3', name: 'Llama 3.3' },\r\n { id: 'llama3.2', name: 'Llama 3.2' },\r\n { id: 'qwq', name: 'QwQ (推理)' },\r\n { id: 'qwen3:32b', name: 'Qwen3 32B' },\r\n { id: 'deepseek-r1:32b', name: 'DeepSeek R1 32B' },\r\n { id: 'deepseek-coder-v2', name: 'DeepSeek Coder V2' },\r\n { id: 'gemma3:27b', name: 'Gemma 3 27B' },\r\n { id: 'mistral:7b', name: 'Mistral 7B' },\r\n { id: 'phi4', name: 'Phi 4' },\r\n { id: 'codellama', name: 'Code Llama' },\r\n ],\r\n [PROVIDER_ID.DOUBAO]: [\r\n { id: 'doubao-seed-1-8-251215', name: 'Doubao 1.8' },\r\n { id: \"doubao-seed-1-6-251015\",name: \"Doubao 1.6\"},\r\n { id: 'doubao-seed-1-6-lite-251015', name: 'Doubao 1.6 Lite' },\r\n { id: 'doubao-seed-1-6-flash-250828', name: 'Doubao 1.6 Flash' },\r\n { id: 'doubao-seed-1-6-thinking-250615', name: 'Doubao 1.6 Thinking' },\r\n ],\r\n [PROVIDER_ID.MINIMAX]: [\r\n { id: 'MiniMax-M2.1', name: 'MiniMax M2.1' },\r\n { id: 'MiniMax-M2.1-lightning', name: 'MiniMax M2.1 Lightning' },\r\n { id: 'MiniMax-M2', name: 'MiniMax M2' },\r\n ],\r\n};\r\n\r\n/**\r\n * Get static models for a provider\r\n */\r\nexport function getStaticModels(providerId: string): Model[] {\r\n return STATIC_MODELS[providerId] || [];\r\n}\r\n","import type { Provider, Model } from './types';\r\n\r\nexport interface ProviderStrategy {\r\n format: string;\r\n // 模型列表\r\n getModelsEndpoint?: (baseUrl: string, apiKey: string) => string;\r\n parseModelsResponse?: (data: any) => Model[];\r\n // 聊天 (也用于连接测试)\r\n getChatEndpoint: (baseUrl: string, apiKey: string, model: string) => string;\r\n buildChatPayload: (model: string, messages: Array<{ role: string; content: string }>, maxTokens: number) => Record<string, unknown>;\r\n parseChatResponse: (data: any) => string;\r\n // Headers\r\n buildHeaders: (apiKey: string) => Record<string, string>;\r\n}\r\n\r\nexport const defaultParseModelsResponse = (data: any): Model[] => {\r\n if (Array.isArray(data?.data)) {\r\n return data.data\r\n .filter((m: any) => m.id)\r\n .map((m: any) => {\r\n const name =\r\n m.name ||\r\n (m.id.split('/').pop() ?? '')\r\n .replace(/[-_]/g, ' ')\r\n .replace(/\\b\\w/g, (c: string) => c.toUpperCase());\r\n return {\r\n id: m.id,\r\n name,\r\n created: m.created || 0,\r\n } as any;\r\n })\r\n .sort((a: any, b: any) => (b.created || 0) - (a.created || 0)); // 最新的排在前面\r\n }\r\n return [];\r\n};\r\n\r\nconst openaiStrategy: ProviderStrategy = {\r\n format: 'openai',\r\n getModelsEndpoint: (baseUrl) => `${baseUrl}/models`,\r\n getChatEndpoint: (baseUrl) => `${baseUrl}/chat/completions`,\r\n buildHeaders: (apiKey) => ({\r\n 'Content-Type': 'application/json',\r\n 'Authorization': `Bearer ${apiKey}`,\r\n }),\r\n buildChatPayload: (model, messages, maxTokens) => ({\r\n model,\r\n messages,\r\n max_tokens: maxTokens,\r\n }),\r\n parseChatResponse: (data) => {\r\n return data.choices?.[0]?.message?.content || '';\r\n },\r\n};\r\n\r\nconst anthropicStrategy: ProviderStrategy = {\r\n format: 'anthropic',\r\n getChatEndpoint: (baseUrl) => `${baseUrl}/messages`,\r\n buildHeaders: (apiKey) => ({\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': apiKey,\r\n 'anthropic-version': '2023-06-01',\r\n }),\r\n buildChatPayload: (model, messages, maxTokens) => ({\r\n model,\r\n messages,\r\n max_tokens: maxTokens,\r\n }),\r\n parseChatResponse: (data) => {\r\n return data.content?.[0]?.text || '';\r\n },\r\n};\r\n\r\nconst geminiStrategy: ProviderStrategy = {\r\n format: 'gemini',\r\n getModelsEndpoint: (baseUrl, apiKey) => `${baseUrl}/models?key=${apiKey}`,\r\n getChatEndpoint: (baseUrl, apiKey, model) => `${baseUrl}/models/${model}:generateContent?key=${apiKey}`,\r\n buildHeaders: () => ({\r\n 'Content-Type': 'application/json',\r\n }),\r\n buildChatPayload: (_model, messages, maxTokens) => {\r\n // 转换 OpenAI 格式的 messages 为 Gemini 格式\r\n const contents = messages.map(m => ({\r\n role: m.role === 'assistant' ? 'model' : 'user',\r\n parts: [{ text: m.content }],\r\n }));\r\n return {\r\n contents,\r\n generationConfig: { maxOutputTokens: maxTokens },\r\n };\r\n },\r\n parseChatResponse: (data) => {\r\n return data.candidates?.[0]?.content?.parts?.[0]?.text || '';\r\n },\r\n // Gemini 返回格式: { models: [{ name: \"models/gemini-pro\", ... }] }\r\n parseModelsResponse: (data) => {\r\n if (Array.isArray(data.models)) {\r\n return data.models\r\n .filter((m: any) => m.supportedGenerationMethods?.includes('generateContent'))\r\n .map((m: any) => ({\r\n id: m.name.replace('models/', ''), // \"models/gemini-pro\" -> \"gemini-pro\"\r\n name: m.displayName || m.name.replace('models/', ''),\r\n created: m.created || 0,\r\n }))\r\n .sort((a: any, b: any) => (b.created || 0) - (a.created || 0));\r\n }\r\n return [];\r\n },\r\n};\r\n\r\nconst cohereStrategy: ProviderStrategy = {\r\n format: 'cohere',\r\n getModelsEndpoint: (baseUrl) => `${baseUrl}/models`,\r\n getChatEndpoint: (baseUrl) => `${baseUrl}/chat`,\r\n buildHeaders: (apiKey) => ({\r\n 'Content-Type': 'application/json',\r\n 'Authorization': `Bearer ${apiKey}`,\r\n }),\r\n buildChatPayload: (model, messages, maxTokens) => {\r\n // Cohere 使用不同的格式: message 是当前消息, chat_history 是历史\r\n const lastMessage = messages[messages.length - 1];\r\n const chatHistory = messages.slice(0, -1).map(m => ({\r\n role: m.role === 'assistant' ? 'CHATBOT' : 'USER',\r\n message: m.content,\r\n }));\r\n return {\r\n model,\r\n message: lastMessage.content,\r\n chat_history: chatHistory,\r\n max_tokens: maxTokens,\r\n };\r\n },\r\n parseChatResponse: (data) => {\r\n return data.text || '';\r\n },\r\n};\r\n\r\nexport const strategyRegistry: Record<string, ProviderStrategy> = {\r\n openai: openaiStrategy,\r\n anthropic: anthropicStrategy,\r\n gemini: geminiStrategy,\r\n cohere: cohereStrategy,\r\n};\r\n\r\nexport function getStrategy(format: string): ProviderStrategy {\r\n return strategyRegistry[format] || openaiStrategy;\r\n}\r\n\r\n// ============================================================================\r\n// 纯前端直连聊天函数\r\n// ============================================================================\r\n\r\nexport interface DirectChatOptions {\r\n apiFormat: string;\r\n baseUrl: string;\r\n apiKey: string;\r\n model: string;\r\n messages: Array<{ role: string; content: string }>;\r\n maxTokens?: number;\r\n}\r\n\r\nexport interface DirectChatResult {\r\n success: boolean;\r\n content?: string;\r\n message?: string;\r\n latencyMs?: number;\r\n}\r\n\r\n/**\r\n * 纯前端直连 AI 厂商进行聊天\r\n * 注意: 这会将 API Key 暴露在浏览器中,仅适用于 Demo/测试场景\r\n */\r\nexport async function sendDirectChat(options: DirectChatOptions): Promise<DirectChatResult> {\r\n const { apiFormat, baseUrl, apiKey, model, messages, maxTokens = 2048 } = options;\r\n const strategy = getStrategy(apiFormat);\r\n\r\n const endpoint = strategy.getChatEndpoint(baseUrl, apiKey, model);\r\n const headers = strategy.buildHeaders(apiKey);\r\n const payload = strategy.buildChatPayload(model, messages, maxTokens);\r\n\r\n const startTime = performance.now();\r\n\r\n try {\r\n const response = await fetch(endpoint, {\r\n method: 'POST',\r\n headers,\r\n body: JSON.stringify(payload),\r\n });\r\n\r\n const latencyMs = Math.round(performance.now() - startTime);\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n return {\r\n success: false,\r\n message: errorData.error?.message || `HTTP ${response.status}: ${response.statusText}`,\r\n latencyMs,\r\n };\r\n }\r\n\r\n const data = await response.json();\r\n const content = strategy.parseChatResponse(data);\r\n\r\n return {\r\n success: true,\r\n content,\r\n latencyMs,\r\n };\r\n } catch (e) {\r\n return {\r\n success: false,\r\n message: e instanceof Error ? e.message : '网络错误',\r\n };\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// 连接测试函数 (复用聊天接口)\r\n// ============================================================================\r\n\r\nexport interface TestConnectionOptions {\r\n apiFormat: string;\r\n baseUrl: string;\r\n apiKey: string;\r\n model: string;\r\n}\r\n\r\nexport interface TestConnectionResult {\r\n success: boolean;\r\n latencyMs?: number;\r\n message?: string;\r\n}\r\n\r\n/**\r\n * 测试 AI 厂商连接 (通过发送一个简单的聊天请求)\r\n */\r\nexport async function testDirectConnection(options: TestConnectionOptions): Promise<TestConnectionResult> {\r\n const result = await sendDirectChat({\r\n apiFormat: options.apiFormat,\r\n baseUrl: options.baseUrl,\r\n apiKey: options.apiKey,\r\n model: options.model,\r\n messages: [{ role: 'user', content: 'Hi' }],\r\n maxTokens: 5, // 最小 token 数,节省成本\r\n });\r\n\r\n return {\r\n success: result.success,\r\n latencyMs: result.latencyMs,\r\n message: result.success ? undefined : result.message,\r\n };\r\n}\r\n","/**\r\n * AI Provider Selector - API Functions\r\n * Connection testing and model fetching logic\r\n */\r\n\r\nimport type {\r\n Provider,\r\n Model,\r\n TestConnectionOptions,\r\n TestConnectionResult,\r\n FetchModelsOptions\r\n} from './types';\r\nimport { getStaticModels } from './models';\r\nimport { getStrategy, defaultParseModelsResponse } from './strategies';\r\n\r\nconst DEFAULT_TIMEOUT = 30000;\r\n\r\n/**\r\n * Test connection to an AI provider\r\n */\r\nexport async function testConnection(options: TestConnectionOptions): Promise<TestConnectionResult> {\r\n const { provider, apiKey, model, baseUrl, proxyUrl } = options;\r\n const actualBaseUrl = baseUrl || provider.baseUrl;\r\n const startTime = Date.now();\r\n\r\n try {\r\n // If proxy URL is provided, use it\r\n if (proxyUrl) {\r\n const response = await fetch(`${proxyUrl}/test`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n provider_id: provider.id,\r\n api_key: apiKey,\r\n model: model || '',\r\n base_url: baseUrl || provider.baseUrl,\r\n api_format: provider.apiFormat,\r\n }),\r\n });\r\n const data = await response.json();\r\n return {\r\n success: data.success,\r\n latencyMs: data.latency_ms || (Date.now() - startTime),\r\n message: data.message,\r\n };\r\n }\r\n\r\n // Direct API call (for browser-compatible providers)\r\n const strategy = getStrategy(provider.apiFormat);\r\n const targetModel = model || '';\r\n\r\n // If no model provided, we cannot test (user must select model first)\r\n if (!targetModel) {\r\n return {\r\n success: false,\r\n latencyMs: 0,\r\n message: '请先选择模型 (Please select a model)'\r\n };\r\n }\r\n\r\n const headers = strategy.buildHeaders(apiKey);\r\n // 使用聊天接口进行测试,发送最简单的请求\r\n const testPayload = strategy.buildChatPayload(targetModel, [{ role: 'user', content: 'Hi' }], 5);\r\n const endpoint = strategy.getChatEndpoint(actualBaseUrl, apiKey, targetModel);\r\n\r\n const response = await fetch(endpoint, {\r\n method: 'POST',\r\n headers,\r\n body: JSON.stringify(testPayload),\r\n });\r\n\r\n const latencyMs = Date.now() - startTime;\r\n\r\n if (response.ok) {\r\n return { success: true, latencyMs, message: '连接成功' };\r\n } else {\r\n const errorText = await response.text();\r\n return {\r\n success: false,\r\n latencyMs,\r\n message: `HTTP ${response.status}: ${errorText.slice(0, 200)}`\r\n };\r\n }\r\n } catch (error) {\r\n return {\r\n success: false,\r\n latencyMs: Date.now() - startTime,\r\n message: error instanceof Error ? error.message : String(error),\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Fetch available models from a provider\r\n */\r\nexport async function fetchModels(options: FetchModelsOptions): Promise<Model[]> {\r\n const { provider, apiKey, baseUrl, proxyUrl, fallbackToStatic = true } = options;\r\n\r\n // If proxy URL is provided, use it\r\n if (proxyUrl) {\r\n try {\r\n const response = await fetch(`${proxyUrl}/models`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n provider_id: provider.id,\r\n api_key: apiKey || undefined,\r\n base_url: baseUrl || provider.baseUrl,\r\n }),\r\n });\r\n const data = await response.json();\r\n if (data.success && data.models?.length > 0) {\r\n return data.models;\r\n }\r\n } catch (error) {\r\n console.warn('Failed to fetch models via proxy:', error);\r\n if (!fallbackToStatic) throw error;\r\n }\r\n }\r\n\r\n // Direct API call\r\n if (!proxyUrl && provider.supportsModelsApi) {\r\n try {\r\n const strategy = getStrategy(provider.apiFormat);\r\n if (strategy.getModelsEndpoint) {\r\n const endpoint = strategy.getModelsEndpoint(baseUrl || provider.baseUrl, apiKey || '');\r\n const headers = strategy.buildHeaders(apiKey || '');\r\n\r\n const response = await fetch(endpoint, {\r\n method: 'GET',\r\n headers\r\n });\r\n\r\n if (response.ok) {\r\n const data = await response.json();\r\n const parser = strategy.parseModelsResponse || defaultParseModelsResponse;\r\n return parser(data);\r\n } else {\r\n if (!fallbackToStatic) throw new Error(`HTTP ${response.status}`);\r\n }\r\n }\r\n } catch (e) {\r\n console.warn('Failed to fetch models directly:', e);\r\n if (!fallbackToStatic) throw e;\r\n }\r\n }\r\n\r\n if (!fallbackToStatic && provider.supportsModelsApi) {\r\n throw new Error('Failed to fetch models');\r\n }\r\n\r\n // Fallback to static models\r\n return getStaticModels(provider.id);\r\n}\r\n","/**\r\n * AI Provider Selector - Storage Utilities\r\n * Abstraction layer for config persistence\r\n */\r\n\r\nimport type { AIConfig, StorageAdapter } from './types';\r\n\r\nconst STORAGE_KEY = 'ai_provider_config';\r\n\r\n/**\r\n * Default localStorage adapter\r\n */\r\nexport const localStorageAdapter: StorageAdapter = {\r\n get: (key: string) => {\r\n if (typeof window === 'undefined') return null;\r\n return localStorage.getItem(key);\r\n },\r\n set: (key: string, value: string) => {\r\n if (typeof window === 'undefined') return;\r\n localStorage.setItem(key, value);\r\n },\r\n remove: (key: string) => {\r\n if (typeof window === 'undefined') return;\r\n localStorage.removeItem(key);\r\n },\r\n};\r\n\r\n/**\r\n * Create a config storage instance\r\n */\r\nexport interface StorageOptions {\r\n serialize?: (data: any) => string;\r\n deserialize?: (data: string) => any;\r\n}\r\n\r\nexport function createConfigStorage(\r\n adapter: StorageAdapter = localStorageAdapter,\r\n options: StorageOptions = {}\r\n) {\r\n const serialize = options.serialize || JSON.stringify;\r\n const deserialize = options.deserialize || JSON.parse;\r\n\r\n return {\r\n /**\r\n * Save AI config\r\n */\r\n save(config: AIConfig): void {\r\n try {\r\n const serialized = serialize(config);\r\n adapter.set(STORAGE_KEY, serialized);\r\n } catch (e) {\r\n console.error('Failed to save config:', e);\r\n }\r\n },\r\n\r\n /**\r\n * Load AI config\r\n */\r\n load(): AIConfig | null {\r\n const raw = adapter.get(STORAGE_KEY);\r\n if (!raw) return null;\r\n try {\r\n return deserialize(raw) as AIConfig;\r\n } catch (e) {\r\n console.error('Failed to load config:', e);\r\n return null;\r\n }\r\n },\r\n\r\n /**\r\n * Clear AI config\r\n */\r\n clear(): void {\r\n adapter.remove(STORAGE_KEY);\r\n },\r\n };\r\n}\r\n\r\n","/**\r\n * AI Provider Selector - Config Resolution\r\n * Resolves ProviderConfig into a list of providers and models\r\n */\r\n\r\nimport type { Provider, Model, ProviderConfig, CustomProviderDefinition } from './types';\r\nimport { PROVIDERS } from './providers';\r\nimport { getStaticModels } from './models';\r\n\r\nexport interface ResolvedConfig {\r\n providers: Provider[];\r\n getModels: (providerId: string) => Model[];\r\n}\r\n\r\n/**\r\n * Resolve a ProviderConfig into usable providers and models\r\n */\r\nexport function resolveProviderConfig(config?: ProviderConfig): ResolvedConfig {\r\n // Default config: use all built-in providers\r\n if (!config) {\r\n return {\r\n providers: Object.values(PROVIDERS),\r\n getModels: (providerId: string) => getStaticModels(providerId),\r\n };\r\n }\r\n\r\n const { mode, include, exclude, custom } = config;\r\n let providers: Provider[] = [];\r\n\r\n // Handle built-in providers based on mode\r\n if (mode === 'default') {\r\n let builtInProviders = Object.values(PROVIDERS);\r\n\r\n // Apply include filter\r\n if (include && include.length > 0) {\r\n builtInProviders = builtInProviders.filter(p => include.includes(p.id));\r\n }\r\n\r\n // Apply exclude filter\r\n if (exclude && exclude.length > 0) {\r\n builtInProviders = builtInProviders.filter(p => !exclude.includes(p.id));\r\n }\r\n\r\n providers = [...builtInProviders];\r\n }\r\n\r\n // Handle custom providers\r\n const customModelsMap: Record<string, Model[]> = {};\r\n\r\n if (custom) {\r\n for (const [id, def] of Object.entries(custom)) {\r\n const customProvider: Provider = {\r\n id,\r\n name: def.name,\r\n baseUrl: def.baseUrl,\r\n needsApiKey: def.needsApiKey,\r\n apiFormat: def.apiFormat,\r\n supportsModelsApi: def.supportsModelsApi ?? false,\r\n icon: def.icon,\r\n };\r\n\r\n // Check if provider already exists (for override)\r\n const existingIndex = providers.findIndex(p => p.id === id);\r\n\r\n if (existingIndex >= 0) {\r\n // Merge/Override existing provider\r\n // We keep the original icon if custom doesn't provide one\r\n providers[existingIndex] = {\r\n ...providers[existingIndex],\r\n ...customProvider,\r\n icon: customProvider.icon || providers[existingIndex].icon\r\n };\r\n } else {\r\n // Add new provider\r\n providers.push(customProvider);\r\n }\r\n\r\n // Store custom models if provided\r\n if (def.models && def.models.length > 0) {\r\n customModelsMap[id] = def.models;\r\n }\r\n }\r\n }\r\n\r\n // Create getModels function that checks custom models first\r\n const getModels = (providerId: string): Model[] => {\r\n // Check custom models first\r\n if (customModelsMap[providerId]) {\r\n return customModelsMap[providerId];\r\n }\r\n // Fall back to static models\r\n return getStaticModels(providerId);\r\n };\r\n\r\n return { providers, getModels };\r\n}\r\n\r\n/**\r\n * Get a single provider by ID from config\r\n */\r\nexport function getProviderFromConfig(providerId: string, config?: ProviderConfig): Provider | null {\r\n const { providers } = resolveProviderConfig(config);\r\n return providers.find(p => p.id === providerId) || null;\r\n}\r\n"],"names":["I18N","ICON_CDN_BASE","PROVIDER_ID","PROVIDERS","getProvider","id","getAllProviders","getProvidersByFormat","format","p","STATIC_MODELS","getStaticModels","providerId","defaultParseModelsResponse","data","m","name","c","b","openaiStrategy","baseUrl","apiKey","model","messages","maxTokens","_c","_b","_a","strategyRegistry","_model","_e","_d","lastMessage","chatHistory","getStrategy","sendDirectChat","options","apiFormat","strategy","endpoint","headers","payload","startTime","response","latencyMs","e","testDirectConnection","result","testConnection","provider","proxyUrl","actualBaseUrl","targetModel","testPayload","errorText","error","fetchModels","fallbackToStatic","STORAGE_KEY","localStorageAdapter","key","value","createConfigStorage","adapter","serialize","deserialize","config","serialized","raw","resolveProviderConfig","mode","include","exclude","custom","providers","builtInProviders","customModelsMap","def","customProvider","existingIndex","getProviderFromConfig"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tombcato/ai-selector-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Framework-agnostic AI Provider Selector core utilities",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -15,11 +15,13 @@
|
|
|
15
15
|
"src"
|
|
16
16
|
],
|
|
17
17
|
"scripts": {
|
|
18
|
-
"build": "
|
|
19
|
-
"dev": "
|
|
18
|
+
"build": "vite build",
|
|
19
|
+
"dev": "vite build --watch"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"typescript": "^5.3.0"
|
|
22
|
+
"typescript": "^5.3.0",
|
|
23
|
+
"vite": "^6.4.1",
|
|
24
|
+
"vite-plugin-dts": "^3.9.1"
|
|
23
25
|
},
|
|
24
26
|
"keywords": [
|
|
25
27
|
"ai",
|
package/src/styles.css
CHANGED
|
@@ -61,6 +61,8 @@
|
|
|
61
61
|
.apmsu-dropdown {
|
|
62
62
|
@apply absolute z-50 mt-1 w-full overflow-hidden rounded-md border border-gray-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 shadow-xl;
|
|
63
63
|
border-width: 1px;
|
|
64
|
+
/* Hack to fix rendering glitch where dropdown content is white/hidden until scroll */
|
|
65
|
+
transform: translateZ(0);
|
|
64
66
|
|
|
65
67
|
/* 动画初始状态 */
|
|
66
68
|
max-height: 0;
|
package/dist/api.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AI Provider Selector - API Functions
|
|
3
|
-
* Connection testing and model fetching logic
|
|
4
|
-
*/
|
|
5
|
-
import type { Model, TestConnectionOptions, TestConnectionResult, FetchModelsOptions } from './types';
|
|
6
|
-
/**
|
|
7
|
-
* Test connection to an AI provider
|
|
8
|
-
*/
|
|
9
|
-
export declare function testConnection(options: TestConnectionOptions): Promise<TestConnectionResult>;
|
|
10
|
-
/**
|
|
11
|
-
* Fetch available models from a provider
|
|
12
|
-
*/
|
|
13
|
-
export declare function fetchModels(options: FetchModelsOptions): Promise<Model[]>;
|
|
14
|
-
//# sourceMappingURL=api.d.ts.map
|
package/dist/api.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAER,KAAK,EACL,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EACrB,MAAM,SAAS,CAAC;AAMjB;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAsElG;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CA0D/E"}
|
package/dist/api.js
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AI Provider Selector - API Functions
|
|
3
|
-
* Connection testing and model fetching logic
|
|
4
|
-
*/
|
|
5
|
-
import { getStaticModels } from './models';
|
|
6
|
-
import { getStrategy, defaultParseModelsResponse } from './strategies';
|
|
7
|
-
const DEFAULT_TIMEOUT = 30000;
|
|
8
|
-
/**
|
|
9
|
-
* Test connection to an AI provider
|
|
10
|
-
*/
|
|
11
|
-
export async function testConnection(options) {
|
|
12
|
-
const { provider, apiKey, model, baseUrl, proxyUrl } = options;
|
|
13
|
-
const actualBaseUrl = baseUrl || provider.baseUrl;
|
|
14
|
-
const startTime = Date.now();
|
|
15
|
-
try {
|
|
16
|
-
// If proxy URL is provided, use it
|
|
17
|
-
if (proxyUrl) {
|
|
18
|
-
const response = await fetch(`${proxyUrl}/test`, {
|
|
19
|
-
method: 'POST',
|
|
20
|
-
headers: { 'Content-Type': 'application/json' },
|
|
21
|
-
body: JSON.stringify({
|
|
22
|
-
provider_id: provider.id,
|
|
23
|
-
api_key: apiKey,
|
|
24
|
-
model: model || '',
|
|
25
|
-
base_url: baseUrl || provider.baseUrl,
|
|
26
|
-
api_format: provider.apiFormat,
|
|
27
|
-
}),
|
|
28
|
-
});
|
|
29
|
-
const data = await response.json();
|
|
30
|
-
return {
|
|
31
|
-
success: data.success,
|
|
32
|
-
latencyMs: data.latency_ms || (Date.now() - startTime),
|
|
33
|
-
message: data.message,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
// Direct API call (for browser-compatible providers)
|
|
37
|
-
const strategy = getStrategy(provider.apiFormat);
|
|
38
|
-
const targetModel = model || '';
|
|
39
|
-
// If no model provided, we cannot test (user must select model first)
|
|
40
|
-
if (!targetModel) {
|
|
41
|
-
return {
|
|
42
|
-
success: false,
|
|
43
|
-
latencyMs: 0,
|
|
44
|
-
message: '请先选择模型 (Please select a model)'
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
const headers = strategy.buildHeaders(apiKey);
|
|
48
|
-
// 使用聊天接口进行测试,发送最简单的请求
|
|
49
|
-
const testPayload = strategy.buildChatPayload(targetModel, [{ role: 'user', content: 'Hi' }], 5);
|
|
50
|
-
const endpoint = strategy.getChatEndpoint(actualBaseUrl, apiKey, targetModel);
|
|
51
|
-
const response = await fetch(endpoint, {
|
|
52
|
-
method: 'POST',
|
|
53
|
-
headers,
|
|
54
|
-
body: JSON.stringify(testPayload),
|
|
55
|
-
});
|
|
56
|
-
const latencyMs = Date.now() - startTime;
|
|
57
|
-
if (response.ok) {
|
|
58
|
-
return { success: true, latencyMs, message: '连接成功' };
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
const errorText = await response.text();
|
|
62
|
-
return {
|
|
63
|
-
success: false,
|
|
64
|
-
latencyMs,
|
|
65
|
-
message: `HTTP ${response.status}: ${errorText.slice(0, 200)}`
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
return {
|
|
71
|
-
success: false,
|
|
72
|
-
latencyMs: Date.now() - startTime,
|
|
73
|
-
message: error instanceof Error ? error.message : String(error),
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Fetch available models from a provider
|
|
79
|
-
*/
|
|
80
|
-
export async function fetchModels(options) {
|
|
81
|
-
const { provider, apiKey, baseUrl, proxyUrl, fallbackToStatic = true } = options;
|
|
82
|
-
// If proxy URL is provided, use it
|
|
83
|
-
if (proxyUrl) {
|
|
84
|
-
try {
|
|
85
|
-
const response = await fetch(`${proxyUrl}/models`, {
|
|
86
|
-
method: 'POST',
|
|
87
|
-
headers: { 'Content-Type': 'application/json' },
|
|
88
|
-
body: JSON.stringify({
|
|
89
|
-
provider_id: provider.id,
|
|
90
|
-
api_key: apiKey || undefined,
|
|
91
|
-
base_url: baseUrl || provider.baseUrl,
|
|
92
|
-
}),
|
|
93
|
-
});
|
|
94
|
-
const data = await response.json();
|
|
95
|
-
if (data.success && data.models?.length > 0) {
|
|
96
|
-
return data.models;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
console.warn('Failed to fetch models via proxy:', error);
|
|
101
|
-
if (!fallbackToStatic)
|
|
102
|
-
throw error;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
// Direct API call
|
|
106
|
-
if (!proxyUrl && provider.supportsModelsApi) {
|
|
107
|
-
try {
|
|
108
|
-
const strategy = getStrategy(provider.apiFormat);
|
|
109
|
-
if (strategy.getModelsEndpoint) {
|
|
110
|
-
const endpoint = strategy.getModelsEndpoint(baseUrl || provider.baseUrl, apiKey || '');
|
|
111
|
-
const headers = strategy.buildHeaders(apiKey || '');
|
|
112
|
-
const response = await fetch(endpoint, {
|
|
113
|
-
method: 'GET',
|
|
114
|
-
headers
|
|
115
|
-
});
|
|
116
|
-
if (response.ok) {
|
|
117
|
-
const data = await response.json();
|
|
118
|
-
const parser = strategy.parseModelsResponse || defaultParseModelsResponse;
|
|
119
|
-
return parser(data);
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
if (!fallbackToStatic)
|
|
123
|
-
throw new Error(`HTTP ${response.status}`);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
catch (e) {
|
|
128
|
-
console.warn('Failed to fetch models directly:', e);
|
|
129
|
-
if (!fallbackToStatic)
|
|
130
|
-
throw e;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
if (!fallbackToStatic && provider.supportsModelsApi) {
|
|
134
|
-
throw new Error('Failed to fetch models');
|
|
135
|
-
}
|
|
136
|
-
// Fallback to static models
|
|
137
|
-
return getStaticModels(provider.id);
|
|
138
|
-
}
|
|
139
|
-
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AI Provider Selector - Config Resolution
|
|
3
|
-
* Resolves ProviderConfig into a list of providers and models
|
|
4
|
-
*/
|
|
5
|
-
import type { Provider, Model, ProviderConfig } from './types';
|
|
6
|
-
export interface ResolvedConfig {
|
|
7
|
-
providers: Provider[];
|
|
8
|
-
getModels: (providerId: string) => Model[];
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Resolve a ProviderConfig into usable providers and models
|
|
12
|
-
*/
|
|
13
|
-
export declare function resolveProviderConfig(config?: ProviderConfig): ResolvedConfig;
|
|
14
|
-
/**
|
|
15
|
-
* Get a single provider by ID from config
|
|
16
|
-
*/
|
|
17
|
-
export declare function getProviderFromConfig(providerId: string, config?: ProviderConfig): Provider | null;
|
|
18
|
-
//# sourceMappingURL=config.d.ts.map
|