@spacex110/core 0.1.11

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/src/config.ts ADDED
@@ -0,0 +1,104 @@
1
+ /**
2
+ * AI Provider Selector - Config Resolution
3
+ * Resolves ProviderConfig into a list of providers and models
4
+ */
5
+
6
+ import type { Provider, Model, ProviderConfig, CustomProviderDefinition } from './types';
7
+ import { PROVIDERS } from './providers';
8
+ import { getStaticModels } from './models';
9
+
10
+ export interface ResolvedConfig {
11
+ providers: Provider[];
12
+ getModels: (providerId: string) => Model[];
13
+ }
14
+
15
+ /**
16
+ * Resolve a ProviderConfig into usable providers and models
17
+ */
18
+ export function resolveProviderConfig(config?: ProviderConfig): ResolvedConfig {
19
+ // Default config: use all built-in providers
20
+ if (!config) {
21
+ return {
22
+ providers: Object.values(PROVIDERS),
23
+ getModels: (providerId: string) => getStaticModels(providerId),
24
+ };
25
+ }
26
+
27
+ const { mode, include, exclude, custom } = config;
28
+ let providers: Provider[] = [];
29
+
30
+ // Handle built-in providers based on mode
31
+ if (mode === 'default') {
32
+ let builtInProviders = Object.values(PROVIDERS);
33
+
34
+ // Apply include filter
35
+ if (include && include.length > 0) {
36
+ builtInProviders = builtInProviders.filter(p => include.includes(p.id));
37
+ }
38
+
39
+ // Apply exclude filter
40
+ if (exclude && exclude.length > 0) {
41
+ builtInProviders = builtInProviders.filter(p => !exclude.includes(p.id));
42
+ }
43
+
44
+ providers = [...builtInProviders];
45
+ }
46
+
47
+ // Handle custom providers
48
+ const customModelsMap: Record<string, Model[]> = {};
49
+
50
+ if (custom) {
51
+ for (const [id, def] of Object.entries(custom)) {
52
+ const customProvider: Provider = {
53
+ id,
54
+ name: def.name,
55
+ baseUrl: def.baseUrl,
56
+ needsApiKey: def.needsApiKey,
57
+ apiFormat: def.apiFormat,
58
+ supportsModelsApi: def.supportsModelsApi ?? false,
59
+ icon: def.icon,
60
+ };
61
+
62
+ // Check if provider already exists (for override)
63
+ const existingIndex = providers.findIndex(p => p.id === id);
64
+
65
+ if (existingIndex >= 0) {
66
+ // Merge/Override existing provider
67
+ // We keep the original icon if custom doesn't provide one
68
+ providers[existingIndex] = {
69
+ ...providers[existingIndex],
70
+ ...customProvider,
71
+ icon: customProvider.icon || providers[existingIndex].icon
72
+ };
73
+ } else {
74
+ // Add new provider
75
+ providers.push(customProvider);
76
+ }
77
+
78
+ // Store custom models if provided
79
+ if (def.models && def.models.length > 0) {
80
+ customModelsMap[id] = def.models;
81
+ }
82
+ }
83
+ }
84
+
85
+ // Create getModels function that checks custom models first
86
+ const getModels = (providerId: string): Model[] => {
87
+ // Check custom models first
88
+ if (customModelsMap[providerId]) {
89
+ return customModelsMap[providerId];
90
+ }
91
+ // Fall back to static models
92
+ return getStaticModels(providerId);
93
+ };
94
+
95
+ return { providers, getModels };
96
+ }
97
+
98
+ /**
99
+ * Get a single provider by ID from config
100
+ */
101
+ export function getProviderFromConfig(providerId: string, config?: ProviderConfig): Provider | null {
102
+ const { providers } = resolveProviderConfig(config);
103
+ return providers.find(p => p.id === providerId) || null;
104
+ }
package/src/i18n.ts ADDED
@@ -0,0 +1,66 @@
1
+ export const I18N = {
2
+ zh: {
3
+ save: '保存配置',
4
+ saved: '保存成功',
5
+ providerLabel: 'Provider',
6
+ modelLabel: 'Model',
7
+ selectProvider: '选择 Provider...',
8
+ customBaseUrl: '自定义 Base URL',
9
+ apiKeyLabel: 'API Key',
10
+ apiKeyPlaceholder: '输入 API Key...',
11
+ testConnection: '测试模型连接',
12
+ testing: '测试中...',
13
+ testSuccess: '连接成功',
14
+ testFailed: '测试连通性失败',
15
+ selectModel: '选择 Model...',
16
+ searchModel: '搜索或自定义模型...',
17
+ useCustom: '使用自定义',
18
+ noModels: '暂无模型数据',
19
+ apiKeyTip: '输入 API Key 后可获取完整模型列表',
20
+ fetchModelsFailed: '拉取模型列表失败,已使用离线模型列表',
21
+ refreshingModels: '列表刷新中...',
22
+ modelListUpdated: '模型列表已刷新',
23
+ preview: '配置预览',
24
+ unselected: '(未选择)',
25
+ customProvider: '自定义 (Custom)',
26
+ baseUrlRequired: '请输入 Base URL',
27
+ baseUrlPlaceholder: '输入 API 地址,如 http://localhost:11434/v1',
28
+ apiKeyOptional: 'API Key(可选)',
29
+ modelAllTypes: '全部',
30
+ modelCount: '个',
31
+ },
32
+ en: {
33
+ save: 'Save Config',
34
+ saved: 'Saved',
35
+ providerLabel: 'Provider',
36
+ modelLabel: 'Model',
37
+ selectProvider: 'Select Provider...',
38
+ customBaseUrl: 'Custom Base URL',
39
+ apiKeyLabel: 'API Key',
40
+ apiKeyPlaceholder: 'Enter API Key...',
41
+ testConnection: 'Test Model Connection',
42
+ testing: 'Testing...',
43
+ testSuccess: 'Connection Successful',
44
+ testFailed: 'Connection Failed',
45
+ selectModel: 'Select Model...',
46
+ searchModel: 'Search or custom models...',
47
+ useCustom: 'Use custom',
48
+ noModels: 'No models found',
49
+ apiKeyTip: 'Enter API Key to fetch full model list',
50
+ fetchModelsFailed: 'Failed to fetch model list, using offline models',
51
+ refreshingModels: 'Refreshing models...',
52
+ modelListUpdated: 'Model list updated',
53
+ preview: 'Config Preview',
54
+ unselected: '(Unselected)',
55
+ customProvider: '自定义 (Custom)',
56
+ baseUrlRequired: 'Base URL is required',
57
+ baseUrlPlaceholder: 'Enter API URL, e.g. http://localhost:11434/v1',
58
+ apiKeyOptional: 'API Key (optional)',
59
+ modelAllTypes: 'All',
60
+ modelCount: '',
61
+ }
62
+ } as const;
63
+
64
+ export type Language = keyof typeof I18N;
65
+ export type I18NKeys = keyof typeof I18N['zh'];
66
+
package/src/index.ts ADDED
@@ -0,0 +1,97 @@
1
+ /**
2
+ * AI Provider Selector - Core Package
3
+ * Framework-agnostic logic for AI provider configuration
4
+ */
5
+
6
+ // I18N
7
+ export * from './i18n';
8
+
9
+ // Types
10
+ export type {
11
+ Provider,
12
+ Model,
13
+ AIConfig,
14
+
15
+ ApiFormat,
16
+ TestConnectionOptions,
17
+ TestConnectionResult,
18
+ FetchModelsOptions,
19
+ StorageAdapter,
20
+ // New config types
21
+ ProviderConfig,
22
+ CustomProviderDefinition,
23
+ AIConfigFormProps,
24
+ // Fetcher types
25
+ ModelFetcher,
26
+ FetcherParams,
27
+ FetcherActionType,
28
+ // Model capability
29
+ ModelCapability,
30
+ } from './types';
31
+
32
+ export {
33
+ MODEL_CAPABILITIES,
34
+ } from './types';
35
+
36
+ // Providers
37
+ export {
38
+ PROVIDERS,
39
+ PROVIDER_ID,
40
+ type ProviderId,
41
+ getProvider,
42
+ getAllProviders,
43
+ getProvidersByFormat
44
+ } from './providers';
45
+
46
+ // Models
47
+ export {
48
+ STATIC_MODELS,
49
+ getStaticModels
50
+ } from './models';
51
+
52
+ // API
53
+ export {
54
+ testConnection,
55
+ fetchModels
56
+ } from './api';
57
+
58
+ // Storage
59
+ export {
60
+ encryptedStorageAdapter,
61
+ plainStorageAdapter,
62
+ defaultStorageAdapter,
63
+ localStorageAdapter, // deprecated
64
+ createConfigStorage
65
+ } from './storage';
66
+
67
+
68
+
69
+ // Config Resolution
70
+ export {
71
+ resolveProviderConfig,
72
+ getProviderFromConfig,
73
+ type ResolvedConfig
74
+ } from './config';
75
+
76
+ // Strategies
77
+ export {
78
+ type ProviderStrategy,
79
+ strategyRegistry,
80
+ getStrategy,
81
+ sendDirectChat,
82
+ sendDirectChatStream,
83
+ testDirectConnection,
84
+ type DirectChatOptions,
85
+ type DirectChatStreamOptions,
86
+ type DirectChatResult,
87
+ } from './strategies';
88
+
89
+ // Channel Manager (Headless)
90
+ export {
91
+ AIChannelManager,
92
+ type ChannelConfig,
93
+ type ChannelManagerOptions,
94
+ type ChannelFilter,
95
+ type ChatResult,
96
+ type ChannelEventType,
97
+ } from './channel-manager';
package/src/models.ts ADDED
@@ -0,0 +1,202 @@
1
+ /**
2
+ * AI Provider Selector - Static Model Definitions
3
+ * Models data when API doesn't support /models endpoint
4
+ */
5
+
6
+ import type { Model } from './types';
7
+ import { PROVIDER_ID } from './providers';
8
+
9
+ export const STATIC_MODELS: Record<string, Model[]> = {
10
+ [PROVIDER_ID.OPENAI]: [
11
+ { id: 'gpt-5.2-pro', name: 'GPT-5.2 Pro' },
12
+ { id: 'gpt-5.2', name: 'GPT-5.2' },
13
+ { id: 'gpt-5', name: 'GPT-5' },
14
+ { id: 'gpt-5-mini', name: 'GPT-5 Mini' },
15
+ { id: 'gpt-5-nano', name: 'GPT-5 Nano' },
16
+ { id: 'gpt-4.1', name: 'GPT-4.1' },
17
+ ],
18
+ [PROVIDER_ID.ANTHROPIC]: [
19
+ { id: 'claude-opus-4.5-20251101', name: 'Claude Opus 4.5' },
20
+ { id: 'claude-opus-4.5-20251101-thinking', name: 'Claude Opus 4.5 Thinking' },
21
+ { id: 'claude-sonnet-4.5-20250929', name: 'Claude Sonnet 4.5' },
22
+ { id: 'claude-sonnet-4.5-20250929-thinking', name: 'Claude Sonnet 4.5 Thinking' },
23
+ { id: 'claude-haiku-4.5-20251001', name: 'Claude Haiku 4.5' },
24
+ { id: 'claude-haiku-4.5-20251001-thinking', name: 'Claude Haiku 4.5 Thinking' },
25
+ { id: 'claude-opus-4.1-20250805', name: 'Claude Opus 4.1' },
26
+ { id: 'claude-opus-4.1-20250805-thinking', name: 'Claude Opus 4.1 Thinking' },
27
+ ],
28
+ [PROVIDER_ID.GEMINI]: [
29
+ { id: 'gemini-3-flash-preview', name: 'Gemini 3 Flash Preview' },
30
+ { id: 'gemini-3-pro-preview', name: 'Gemini 3 Pro Preview' },
31
+ { id: 'gemini-2.5-pro', name: 'Gemini 2.5 Pro' },
32
+ { id: 'gemini-2.5-flash', name: 'Gemini 2.5 Flash' },
33
+ { id: 'gemini-2.5-flash-lite', name: 'Gemini 2.5 Flash-Lite' },
34
+ ],
35
+ [PROVIDER_ID.DEEPSEEK]: [
36
+ { id: 'deepseek-chat', name: 'Deepseek Chat' },
37
+ { id: 'deepseek-reasoner', name: 'Deepseek Reasoner' },
38
+ ],
39
+ [PROVIDER_ID.MISTRAL]: [
40
+ { id: 'mistral-large-latest', name: 'Mistral Large' },
41
+ { id: 'mistral-medium-latest', name: 'Mistral Medium' },
42
+ { id: 'mistral-small-latest', name: 'Mistral Small' },
43
+ { id: 'codestral-latest', name: 'Codestral' },
44
+ { id: 'devstral-latest', name: 'Devstral' },
45
+ { id: 'magistral-medium-latest', name: 'Magistral Medium' },
46
+ { id: 'pixtral-large-latest', name: 'Pixtral Large' },
47
+ { id: 'pixtral-12b-latest', name: 'Pixtral 12B' },
48
+ { id: 'ministral-8b-latest', name: 'Ministral 8B' },
49
+ { id: 'ministral-3b-latest', name: 'Ministral 3B' },
50
+ ],
51
+ [PROVIDER_ID.GROQ]: [
52
+ { id: 'canopylabs/orpheus-v1-english', name: 'Orpheus V1 English' },
53
+ { id: 'canopylabs/orpheus-arabic-saudi', name: 'Orpheus Arabic Saudi' },
54
+ { id: 'moonshotai/kimi-k2-instruct', name: 'Kimi K2 Instruct' },
55
+ { id: 'groq/compound-mini', name: 'Compound Mini' },
56
+ { id: 'llama-3.3-70b-versatile', name: 'Llama 3.3 70B Versatile' },
57
+ { id: 'openai/gpt-oss-120b', name: 'Gpt Oss 120B' },
58
+ { id: 'qwen/qwen3-32b', name: 'Qwen3 32B' },
59
+ { id: 'groq/compound', name: 'Compound' },
60
+ { id: 'meta-llama/llama-4-maverick-17b-128e-instruct', name: 'Llama 4 Maverick 17B 128E Instruct' },
61
+ ],
62
+ [PROVIDER_ID.XAI]: [
63
+ { id: 'grok-4', name: 'Grok 4' },
64
+ { id: 'grok-4-fast', name: 'Grok 4 Fast' },
65
+ { id: 'grok-3-latest', name: 'Grok 3' },
66
+ { id: 'grok-3-fast', name: 'Grok 3 Fast' },
67
+ { id: 'grok-3-mini-latest', name: 'Grok 3 Mini' },
68
+ { id: 'grok-3-mini-fast', name: 'Grok 3 Mini Fast' },
69
+ { id: 'grok-vision-beta', name: 'Grok Vision (Beta)' },
70
+ ],
71
+ [PROVIDER_ID.TOGETHER]: [
72
+ { id: 'Qwen/Qwen2.5-72B-Instruct-Turbo', name: 'Qwen2.5 72B Instruct Turbo' },
73
+ { id: 'Qwen/Qwen3-235B-A22B-Thinking-2507', name: 'Qwen3 235B A22B Thinking 2507' },
74
+ { id: 'deepseek-ai/DeepSeek-R1', name: 'Deepseek R1' },
75
+ { id: 'deepseek-ai/DeepSeek-V3.1', name: 'Deepseek V3.1' },
76
+ { id: 'meta-llama/Llama-3.2-3B-Instruct-Turbo', name: 'Llama 3.2 3B Instruct Turbo' },
77
+ { id: 'meta-llama/Llama-3.3-70B-Instruct-Turbo', name: 'Llama 3.3 70B Instruct Turbo' },
78
+ { id: 'meta-llama/Llama-3.3-70B-Instruct-Turbo-Free', name: 'Llama 3.3 70B Instruct Turbo Free' },
79
+ ],
80
+ [PROVIDER_ID.FIREWORKS]: [
81
+ { id: 'accounts/fireworks/models/llama4-scout-instruct-basic', name: 'Llama4 Scout Instruct Basic' },
82
+ { id: 'accounts/fireworks/models/qwen3-vl-235b-a22b-thinking', name: 'Qwen3 Vl 235B A22B Thinking' },
83
+ { id: 'accounts/fireworks/models/deepseek-v3p2', name: 'Deepseek V3P2' },
84
+ { id: 'accounts/fireworks/models/qwen3-vl-30b-a3b-thinking', name: 'Qwen3 Vl 30B A3B Thinking' },
85
+ { id: 'accounts/fireworks/models/qwen3-8b', name: 'Qwen3 8B' },
86
+ { id: 'accounts/fireworks/models/qwen3-vl-30b-a3b-instruct', name: 'Qwen3 Vl 30B A3B Instruct' },
87
+ { id: 'accounts/fireworks/models/qwen2p5-vl-32b-instruct', name: 'Qwen2P5 Vl 32B Instruct' },
88
+ { id: 'accounts/fireworks/models/llama4-maverick-instruct-basic', name: 'Llama4 Maverick Instruct Basic' },
89
+ { id: 'accounts/fireworks/models/qwen3-235b-a22b-thinking-2507', name: 'Qwen3 235B A22B Thinking 2507' },
90
+ { id: 'accounts/fireworks/models/qwen3-coder-480b-a35b-instruct', name: 'Qwen3 Coder 480B A35B Instruct' },
91
+ ],
92
+ [PROVIDER_ID.DEEPINFRA]: [
93
+ { id: 'meta-llama/Llama-3.2-11B-Vision-Instruct', name: 'Llama 3.2 11B Vision Instruct' },
94
+ { id: 'Qwen/Qwen3-32B', name: 'Qwen3 32B' },
95
+ { id: 'NousResearch/Hermes-3-Llama-3.1-70B', name: 'Hermes 3 Llama 3.1 70B' },
96
+ { id: 'Qwen/Qwen2.5-72B-Instruct', name: 'Qwen2.5 72B Instruct' },
97
+ { id: 'deepseek-ai/DeepSeek-V3-0324', name: 'Deepseek V3 0324' },
98
+ { id: 'Qwen/Qwen3-VL-235B-A22B-Instruct', name: 'Qwen3 Vl 235B A22B Instruct' },
99
+ { id: 'meta-llama/Llama-3.2-3B-Instruct', name: 'Llama 3.2 3B Instruct' },
100
+ { id: 'Qwen/Qwen2.5-VL-32B-Instruct', name: 'Qwen2.5 Vl 32B Instruct' },
101
+ { id: 'meta-llama/Meta-Llama-3.1-8B-Instruct', name: 'Meta Llama 3.1 8B Instruct' },
102
+ { id: 'Qwen/Qwen3-Coder-480B-A35B-Instruct-Turbo', name: 'Qwen3 Coder 480B A35B Instruct Turbo' },
103
+ ],
104
+ [PROVIDER_ID.OPENROUTER]: [
105
+ { id: 'google/gemini-3-flash-preview', name: 'Gemini 3 Flash Preview' },
106
+ { id: 'mistralai/mistral-small-creative', name: 'Mistral Small Creative' },
107
+ { id: 'openai/gpt-5.2-chat', name: 'Gpt 5.2 Chat' },
108
+ { id: 'openai/gpt-5.2-pro', name: 'Gpt 5.2 Pro' },
109
+ { id: 'openai/gpt-5.2', name: 'Gpt 5.2' },
110
+ { id: 'mistralai/devstral-2512', name: 'Devstral 2512' },
111
+ { id: 'openai/gpt-5.1-codex-max', name: 'Gpt 5.1 Codex Max' },
112
+ { id: 'mistralai/ministral-14b-2512', name: 'Ministral 14B 2512' },
113
+ { id: 'mistralai/ministral-8b-2512', name: 'Ministral 8B 2512' },
114
+ { id: 'mistralai/ministral-3b-2512', name: 'Ministral 3B 2512' },
115
+ { id: 'mistralai/mistral-large-2512', name: 'Mistral Large 2512' },
116
+ { id: 'deepseek/deepseek-v3.2-speciale', name: 'Deepseek V3.2 Speciale' },
117
+ ],
118
+ [PROVIDER_ID.PERPLEXITY]: [
119
+ { id: 'codellama-34b-instruct', name: 'Codellama 34B Instruct' },
120
+ { id: 'codellama-70b-instruct', name: 'Codellama 70B Instruct' },
121
+ { id: 'llama-2-70b-chat', name: 'Llama 2 70B Chat' },
122
+ { id: 'llama-3.1-70b-instruct', name: 'Llama 3.1 70B Instruct' },
123
+ { id: 'llama-3.1-8b-instruct', name: 'Llama 3.1 8B Instruct' },
124
+ { id: 'llama-3.1-sonar-huge-128k-online', name: 'Llama 3.1 Sonar Huge 128K Online' },
125
+ { id: 'llama-3.1-sonar-large-128k-chat', name: 'Llama 3.1 Sonar Large 128K Chat' },
126
+ { id: 'llama-3.1-sonar-large-128k-online', name: 'Llama 3.1 Sonar Large 128K Online' },
127
+ { id: 'llama-3.1-sonar-small-128k-chat', name: 'Llama 3.1 Sonar Small 128K Chat' },
128
+ ],
129
+ [PROVIDER_ID.COHERE]: [
130
+ { id: 'command-a-vision-07-2025', name: 'Command A Vision 07 2025' },
131
+ { id: 'command-a-reasoning-08-2025', name: 'Command A Reasoning 08 2025' },
132
+ { id: 'command-r-08-2024', name: 'Command R 08 2024' },
133
+ { id: 'command-r7b-arabic-02-2025', name: 'Command R7B Arabic 02 2025' },
134
+ { id: 'command-r7b-12-2024', name: 'Command R7B 12 2024' },
135
+ ],
136
+ [PROVIDER_ID.MOONSHOT]: [
137
+ { id: 'moonshot-v1-128k', name: 'Moonshot 128K' },
138
+ { id: 'moonshot-v1-32k', name: 'Moonshot 32K' },
139
+ { id: 'moonshot-v1-8k', name: 'Moonshot 8K' },
140
+ { id: 'kimi-k2-0711-chat', name: 'Kimi K2 Chat' },
141
+ { id: 'moonshot-v1-auto', name: 'Moonshot Auto' },
142
+ ],
143
+ [PROVIDER_ID.QWEN]: [
144
+ { id: 'qwen-flash', name: 'Qwen Flash' },
145
+ { id: 'qwen3-vl-plus-2025-12-19', name: 'Qwen3 Vl Plus 2025 12 19' },
146
+ { id: 'qwen3-tts-vd-realtime-2025-12-16', name: 'Qwen3 Tts Vd Realtime 2025 12 16' },
147
+ { id: 'qwen-image-edit-plus-2025-12-15', name: 'Qwen Image Edit Plus 2025 12 15' },
148
+ { id: 'qwen3-omni-flash-2025-12-01', name: 'Qwen3 Omni Flash 2025 12 01' },
149
+ { id: 'qwen3-omni-flash-realtime-2025-12-01', name: 'Qwen3 Omni Flash Realtime 2025 12 01' },
150
+ { id: 'qwen3-livetranslate-flash-2025-12-01', name: 'Qwen3 Livetranslate Flash 2025 12 01' },
151
+ { id: 'qwen3-livetranslate-flash', name: 'Qwen3 Livetranslate Flash' },
152
+ { id: 'qwen-plus-2025-12-01', name: 'Qwen Plus 2025 12 01' },
153
+ { id: 'qwen3-tts-vc-realtime-2025-11-27', name: 'Qwen3 Tts Vc Realtime 2025 11 27' },
154
+ ],
155
+ [PROVIDER_ID.ZHIPU]: [
156
+ { id: 'glm-4.5', name: 'Glm 4.5' },
157
+ { id: 'glm-4.5-air', name: 'Glm 4.5 Air' },
158
+ { id: 'glm-4.6', name: 'Glm 4.6' },
159
+ { id: 'glm-4.7', name: 'Glm 4.7' },
160
+ ],
161
+ [PROVIDER_ID.SILICONFLOW]: [
162
+ { id: 'deepseek-ai/DeepSeek-V3.2', name: 'Deepseek V3.2' },
163
+ { id: 'deepseek-ai/DeepSeek-V3.1-Terminus', name: 'Deepseek V3.1 Terminus' },
164
+ { id: 'deepseek-ai/DeepSeek-R1', name: 'Deepseek R1' },
165
+ { id: 'deepseek-ai/DeepSeek-V3', name: 'Deepseek V3' },
166
+ { id: 'zai-org/GLM-4.6V', name: 'Glm 4.6V' },
167
+ { id: 'zai-org/GLM-4.6', name: 'Glm 4.6' },
168
+ { id: 'Pro/zai-org/GLM-4.7', name: 'Glm 4.7' },
169
+ { id: 'Qwen/Qwen3-VL-32B-Instruct', name: 'Qwen3 Vl 32B Instruct' },
170
+ ],
171
+ [PROVIDER_ID.OLLAMA]: [
172
+ { id: 'llama3.3', name: 'Llama 3.3' },
173
+ { id: 'llama3.2', name: 'Llama 3.2' },
174
+ { id: 'qwq', name: 'QwQ (推理)' },
175
+ { id: 'qwen3:32b', name: 'Qwen3 32B' },
176
+ { id: 'deepseek-r1:32b', name: 'DeepSeek R1 32B' },
177
+ { id: 'deepseek-coder-v2', name: 'DeepSeek Coder V2' },
178
+ { id: 'gemma3:27b', name: 'Gemma 3 27B' },
179
+ { id: 'mistral:7b', name: 'Mistral 7B' },
180
+ { id: 'phi4', name: 'Phi 4' },
181
+ { id: 'codellama', name: 'Code Llama' },
182
+ ],
183
+ [PROVIDER_ID.DOUBAO]: [
184
+ { id: 'doubao-seed-1-8-251215', name: 'Doubao 1.8' },
185
+ { id: "doubao-seed-1-6-251015",name: "Doubao 1.6"},
186
+ { id: 'doubao-seed-1-6-lite-251015', name: 'Doubao 1.6 Lite' },
187
+ { id: 'doubao-seed-1-6-flash-250828', name: 'Doubao 1.6 Flash' },
188
+ { id: 'doubao-seed-1-6-thinking-250615', name: 'Doubao 1.6 Thinking' },
189
+ ],
190
+ [PROVIDER_ID.MINIMAX]: [
191
+ { id: 'MiniMax-M2.1', name: 'MiniMax M2.1' },
192
+ { id: 'MiniMax-M2.1-lightning', name: 'MiniMax M2.1 Lightning' },
193
+ { id: 'MiniMax-M2', name: 'MiniMax M2' },
194
+ ],
195
+ };
196
+
197
+ /**
198
+ * Get static models for a provider
199
+ */
200
+ export function getStaticModels(providerId: string): Model[] {
201
+ return STATIC_MODELS[providerId] || [];
202
+ }