thatgfsj-code 0.3.0 → 0.4.0
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/cmd/index.js +1 -1
- package/dist/config/index.d.ts +5 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +22 -4
- package/dist/config/index.js.map +1 -1
- package/dist/config/providers.d.ts +5 -10
- package/dist/config/providers.d.ts.map +1 -1
- package/dist/config/providers.js +152 -78
- package/dist/config/providers.js.map +1 -1
- package/dist/config/types.d.ts +1 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/llm/anthropic.d.ts +34 -3
- package/dist/llm/anthropic.d.ts.map +1 -1
- package/dist/llm/anthropic.js +83 -35
- package/dist/llm/anthropic.js.map +1 -1
- package/dist/llm/gemini.d.ts +14 -1
- package/dist/llm/gemini.d.ts.map +1 -1
- package/dist/llm/gemini.js +56 -23
- package/dist/llm/gemini.js.map +1 -1
- package/dist/llm/index.d.ts +9 -8
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/llm/index.js +75 -80
- package/dist/llm/index.js.map +1 -1
- package/dist/llm/openai.d.ts +30 -3
- package/dist/llm/openai.d.ts.map +1 -1
- package/dist/llm/openai.js +45 -28
- package/dist/llm/openai.js.map +1 -1
- package/dist/tui/output.js +1 -1
- package/dist/tui/welcome.d.ts +5 -1
- package/dist/tui/welcome.d.ts.map +1 -1
- package/dist/tui/welcome.js +75 -29
- package/dist/tui/welcome.js.map +1 -1
- package/package.json +1 -1
- package/src/cmd/index.ts +1 -1
- package/src/config/index.ts +21 -4
- package/src/config/providers.ts +153 -79
- package/src/config/types.ts +11 -5
- package/src/llm/anthropic.ts +90 -39
- package/src/llm/gemini.ts +65 -30
- package/src/llm/index.ts +77 -87
- package/src/llm/openai.ts +46 -34
- package/src/tui/output.ts +1 -1
- package/src/tui/welcome.ts +86 -32
package/dist/tui/welcome.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"welcome.js","sourceRoot":"","sources":["../../src/tui/welcome.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,
|
|
1
|
+
{"version":3,"file":"welcome.js","sourceRoot":"","sources":["../../src/tui/welcome.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/cmd/index.ts
CHANGED
|
@@ -41,7 +41,7 @@ process.on('unhandledRejection', (reason) => {
|
|
|
41
41
|
program
|
|
42
42
|
.name('gfcode')
|
|
43
43
|
.description('🤖 Thatgfsj Code - AI Coding Assistant')
|
|
44
|
-
.version('0.
|
|
44
|
+
.version('0.4.0')
|
|
45
45
|
.argument('[prompt]', 'Task to execute (omit to start interactive mode)')
|
|
46
46
|
.option('-m, --model <model>', 'Specify model')
|
|
47
47
|
.option('-i, --interactive', 'Force interactive mode')
|
package/src/config/index.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Config Manager - Handles configuration loading and saving
|
|
3
|
-
*
|
|
3
|
+
* Supports custom providers (relay stations / 中转站)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
7
7
|
import { join, dirname } from 'path';
|
|
8
8
|
import { homedir } from 'os';
|
|
9
9
|
import type { Config, AIConfig, ProviderName } from './types.js';
|
|
10
|
-
import { PROVIDERS, getApiKeyFromEnv } from './providers.js';
|
|
10
|
+
import { PROVIDERS, getApiKeyFromEnv, isCustomProvider } from './providers.js';
|
|
11
11
|
|
|
12
12
|
const DEFAULT_CONFIG: Config = {
|
|
13
13
|
model: 'Qwen/Qwen2.5-7B-Instruct',
|
|
@@ -73,8 +73,18 @@ export class ConfigManager {
|
|
|
73
73
|
apiKey = getApiKeyFromEnv(provider);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
// Base URL: config > provider default
|
|
77
|
-
|
|
76
|
+
// Base URL: config > env > provider default
|
|
77
|
+
let baseUrl = config.baseUrl;
|
|
78
|
+
if (!baseUrl) {
|
|
79
|
+
// Check env for custom base URL
|
|
80
|
+
if (provider === 'custom_openai') {
|
|
81
|
+
baseUrl = process.env.CUSTOM_BASE_URL || '';
|
|
82
|
+
} else if (provider === 'custom_anthropic') {
|
|
83
|
+
baseUrl = process.env.CUSTOM_BASE_URL || '';
|
|
84
|
+
} else {
|
|
85
|
+
baseUrl = providerConfig.baseUrl;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
78
88
|
|
|
79
89
|
return { ...config, provider, baseUrl, model, apiKey: apiKey || '' };
|
|
80
90
|
}
|
|
@@ -127,4 +137,11 @@ export class ConfigManager {
|
|
|
127
137
|
hasApiKey(): boolean {
|
|
128
138
|
return !!this.config.apiKey;
|
|
129
139
|
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Check if using a custom provider
|
|
143
|
+
*/
|
|
144
|
+
isCustomProvider(): boolean {
|
|
145
|
+
return isCustomProvider(this.config.provider);
|
|
146
|
+
}
|
|
130
147
|
}
|
package/src/config/providers.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Provider definitions and model catalogs
|
|
3
|
-
*
|
|
3
|
+
* Updated with correct API formats and more providers
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { ProviderConfig, ProviderName, ModelInfo } from './types.js';
|
|
@@ -12,16 +12,9 @@ export const PROVIDERS: Record<ProviderName, ProviderConfig> = {
|
|
|
12
12
|
name: 'SiliconFlow (硅基流动)',
|
|
13
13
|
baseUrl: 'https://api.siliconflow.cn/v1',
|
|
14
14
|
defaultModel: 'Qwen/Qwen2.5-7B-Instruct',
|
|
15
|
-
envKeys: ['SILICONFLOW_API_KEY'
|
|
15
|
+
envKeys: ['SILICONFLOW_API_KEY'],
|
|
16
16
|
format: 'openai',
|
|
17
17
|
},
|
|
18
|
-
minimax: {
|
|
19
|
-
name: 'MiniMax',
|
|
20
|
-
baseUrl: 'https://api.minimax.io/anthropic/v1',
|
|
21
|
-
defaultModel: 'MiniMax-M2.5',
|
|
22
|
-
envKeys: ['MINIMAX_API_KEY', 'OPENAI_API_KEY'],
|
|
23
|
-
format: 'anthropic',
|
|
24
|
-
},
|
|
25
18
|
openai: {
|
|
26
19
|
name: 'OpenAI',
|
|
27
20
|
baseUrl: 'https://api.openai.com/v1',
|
|
@@ -29,132 +22,213 @@ export const PROVIDERS: Record<ProviderName, ProviderConfig> = {
|
|
|
29
22
|
envKeys: ['OPENAI_API_KEY'],
|
|
30
23
|
format: 'openai',
|
|
31
24
|
},
|
|
25
|
+
deepseek: {
|
|
26
|
+
name: 'DeepSeek (深度求索)',
|
|
27
|
+
baseUrl: 'https://api.deepseek.com',
|
|
28
|
+
defaultModel: 'deepseek-chat',
|
|
29
|
+
envKeys: ['DEEPSEEK_API_KEY'],
|
|
30
|
+
format: 'openai',
|
|
31
|
+
},
|
|
32
|
+
kimi: {
|
|
33
|
+
name: 'Kimi (月之暗面)',
|
|
34
|
+
baseUrl: 'https://api.moonshot.cn/v1',
|
|
35
|
+
defaultModel: 'kimi-k2.6',
|
|
36
|
+
envKeys: ['KIMI_API_KEY', 'MOONSHOT_API_KEY'],
|
|
37
|
+
format: 'openai',
|
|
38
|
+
},
|
|
39
|
+
zhipu: {
|
|
40
|
+
name: 'Zhipu GLM (智谱)',
|
|
41
|
+
baseUrl: 'https://open.bigmodel.cn/api/paas/v4',
|
|
42
|
+
defaultModel: 'glm-4-flash',
|
|
43
|
+
envKeys: ['ZHIPU_API_KEY', 'GLM_API_KEY'],
|
|
44
|
+
format: 'openai',
|
|
45
|
+
},
|
|
46
|
+
minimax: {
|
|
47
|
+
name: 'MiniMax',
|
|
48
|
+
baseUrl: 'https://api.minimax.chat/v1',
|
|
49
|
+
defaultModel: 'MiniMax-Text-01',
|
|
50
|
+
envKeys: ['MINIMAX_API_KEY'],
|
|
51
|
+
format: 'openai',
|
|
52
|
+
},
|
|
53
|
+
baichuan: {
|
|
54
|
+
name: 'Baichuan (百川)',
|
|
55
|
+
baseUrl: 'https://api.baichuan-ai.com/v1',
|
|
56
|
+
defaultModel: 'Baichuan4',
|
|
57
|
+
envKeys: ['BAICHUAN_API_KEY'],
|
|
58
|
+
format: 'openai',
|
|
59
|
+
},
|
|
60
|
+
stepfun: {
|
|
61
|
+
name: 'Stepfun (阶跃星辰)',
|
|
62
|
+
baseUrl: 'https://api.stepfun.com/v1',
|
|
63
|
+
defaultModel: 'step-1-flash',
|
|
64
|
+
envKeys: ['STEPFUN_API_KEY'],
|
|
65
|
+
format: 'openai',
|
|
66
|
+
},
|
|
67
|
+
doubao: {
|
|
68
|
+
name: 'Doubao (火山引擎豆包)',
|
|
69
|
+
baseUrl: 'https://ark.cn-beijing.volces.com/api/v3',
|
|
70
|
+
defaultModel: 'doubao-1.5-pro-32k',
|
|
71
|
+
envKeys: ['DOUBAO_API_KEY', 'ARK_API_KEY'],
|
|
72
|
+
format: 'openai',
|
|
73
|
+
},
|
|
32
74
|
anthropic: {
|
|
33
|
-
name: 'Anthropic',
|
|
75
|
+
name: 'Anthropic (Claude)',
|
|
34
76
|
baseUrl: 'https://api.anthropic.com/v1',
|
|
35
|
-
defaultModel: 'claude-
|
|
77
|
+
defaultModel: 'claude-sonnet-4-20250514',
|
|
36
78
|
envKeys: ['ANTHROPIC_API_KEY'],
|
|
37
79
|
format: 'anthropic',
|
|
38
80
|
},
|
|
39
|
-
ollama: {
|
|
40
|
-
name: 'Ollama (Local)',
|
|
41
|
-
baseUrl: process.env.OLLAMA_BASE_URL || 'http://localhost:11434',
|
|
42
|
-
defaultModel: 'llama2',
|
|
43
|
-
envKeys: [],
|
|
44
|
-
format: 'openai',
|
|
45
|
-
},
|
|
46
81
|
gemini: {
|
|
47
82
|
name: 'Google Gemini',
|
|
48
83
|
baseUrl: 'https://generativelanguage.googleapis.com/v1beta',
|
|
49
|
-
defaultModel: 'gemini-
|
|
84
|
+
defaultModel: 'gemini-2.0-flash',
|
|
50
85
|
envKeys: ['GEMINI_API_KEY'],
|
|
51
86
|
format: 'gemini',
|
|
52
87
|
},
|
|
53
|
-
|
|
54
|
-
name: '
|
|
55
|
-
baseUrl: '
|
|
56
|
-
defaultModel: '
|
|
57
|
-
envKeys: [
|
|
88
|
+
ollama: {
|
|
89
|
+
name: 'Ollama (本地)',
|
|
90
|
+
baseUrl: 'http://localhost:11434/v1',
|
|
91
|
+
defaultModel: 'llama3.1',
|
|
92
|
+
envKeys: [],
|
|
58
93
|
format: 'openai',
|
|
59
94
|
},
|
|
60
|
-
|
|
61
|
-
name: '
|
|
62
|
-
baseUrl: 'https://
|
|
63
|
-
defaultModel: '
|
|
64
|
-
envKeys: ['
|
|
95
|
+
ernie: {
|
|
96
|
+
name: 'ERNIE (百度文心)',
|
|
97
|
+
baseUrl: 'https://qianfan.baidubce.com/v2',
|
|
98
|
+
defaultModel: 'ernie-4.5-8k',
|
|
99
|
+
envKeys: ['ERNIE_API_KEY', 'QIANFAN_API_KEY'],
|
|
65
100
|
format: 'openai',
|
|
66
101
|
},
|
|
67
|
-
|
|
68
|
-
name: '
|
|
69
|
-
baseUrl: '
|
|
70
|
-
defaultModel: '
|
|
71
|
-
envKeys: ['
|
|
102
|
+
custom_openai: {
|
|
103
|
+
name: '自定义 OpenAI 兼容 (中转站)',
|
|
104
|
+
baseUrl: '',
|
|
105
|
+
defaultModel: 'gpt-4o-mini',
|
|
106
|
+
envKeys: ['CUSTOM_API_KEY'],
|
|
72
107
|
format: 'openai',
|
|
73
108
|
},
|
|
109
|
+
custom_anthropic: {
|
|
110
|
+
name: '自定义 Anthropic 兼容 (中转站)',
|
|
111
|
+
baseUrl: '',
|
|
112
|
+
defaultModel: 'claude-sonnet-4-20250514',
|
|
113
|
+
envKeys: ['CUSTOM_API_KEY'],
|
|
114
|
+
format: 'anthropic',
|
|
115
|
+
},
|
|
74
116
|
};
|
|
75
117
|
|
|
76
118
|
// ==================== Model Catalogs ====================
|
|
77
119
|
|
|
78
120
|
export const MODEL_CATALOGS: Record<ProviderName, ModelInfo[]> = {
|
|
79
121
|
siliconflow: [
|
|
80
|
-
{ id: 'Qwen/Qwen2.5-7B-Instruct', name: 'Qwen2.5-7B
|
|
81
|
-
{ id: 'Qwen/Qwen2.5-32B-Instruct', name: 'Qwen2.5-32B', desc: '
|
|
122
|
+
{ id: 'Qwen/Qwen2.5-7B-Instruct', name: 'Qwen2.5-7B', desc: '免费,日常编程' },
|
|
123
|
+
{ id: 'Qwen/Qwen2.5-32B-Instruct', name: 'Qwen2.5-32B', desc: '更强性能' },
|
|
82
124
|
{ id: 'Qwen/Qwen2.5-72B-Instruct', name: 'Qwen2.5-72B', desc: '旗舰模型' },
|
|
83
|
-
{ id: '
|
|
84
|
-
{ id: 'Pro/deepseek-ai/DeepSeek-V3', name: 'DeepSeek-V3', desc: '
|
|
85
|
-
{ id: 'Pro/deepseek-ai/DeepSeek-R1', name: 'DeepSeek-R1', desc: '
|
|
125
|
+
{ id: 'Qwen/Qwen3-8B', name: 'Qwen3-8B', desc: '最新 Qwen3' },
|
|
126
|
+
{ id: 'Pro/deepseek-ai/DeepSeek-V3', name: 'DeepSeek-V3', desc: '深度求索' },
|
|
127
|
+
{ id: 'Pro/deepseek-ai/DeepSeek-R1', name: 'DeepSeek-R1', desc: '推理模型' },
|
|
128
|
+
{ id: 'deepseek-ai/DeepSeek-V3', name: 'DeepSeek-V3 (免费)', desc: '免费版' },
|
|
86
129
|
{ id: 'THUDM/glm-4-9b-chat', name: 'GLM-4-9B', desc: '智谱模型' },
|
|
87
|
-
{ id: '
|
|
88
|
-
{ id: '01-ai/Yi-1.5-34B-Chat', name: 'Yi-1.5-34B', desc: '零一万物' },
|
|
89
|
-
{ id: 'microsoft/WizardLM-2-8x22B', name: 'WizardLM-2', desc: '微软开源' },
|
|
90
|
-
],
|
|
91
|
-
minimax: [
|
|
92
|
-
{ id: 'MiniMax-M2.5', name: 'MiniMax-M2.5 (推荐)', desc: 'Agent 能力最强' },
|
|
93
|
-
{ id: 'MiniMax-M2.1', name: 'MiniMax-M2.1', desc: '稳定版本' },
|
|
130
|
+
{ id: 'internlm/internlm2_5-7b-chat', name: 'InternLM2.5-7B', desc: '书生模型' },
|
|
94
131
|
],
|
|
95
132
|
openai: [
|
|
96
|
-
{ id: 'gpt-4o-mini', name: 'GPT-4o-mini
|
|
97
|
-
{ id: 'gpt-4o', name: 'GPT-4o', desc: '
|
|
133
|
+
{ id: 'gpt-4o-mini', name: 'GPT-4o-mini', desc: '性价比高' },
|
|
134
|
+
{ id: 'gpt-4o', name: 'GPT-4o', desc: '旗舰多模态' },
|
|
98
135
|
{ id: 'gpt-4-turbo', name: 'GPT-4-Turbo', desc: '强性能' },
|
|
136
|
+
{ id: 'o3-mini', name: 'o3-mini', desc: '推理模型' },
|
|
99
137
|
],
|
|
100
|
-
|
|
101
|
-
{ id: '
|
|
102
|
-
{ id: '
|
|
103
|
-
{ id: 'claude-3-opus-20240229', name: 'Claude-3-Opus', desc: '最强性能' },
|
|
138
|
+
deepseek: [
|
|
139
|
+
{ id: 'deepseek-chat', name: 'DeepSeek-Chat', desc: '通用对话' },
|
|
140
|
+
{ id: 'deepseek-reasoner', name: 'DeepSeek-Reasoner', desc: '推理增强' },
|
|
104
141
|
],
|
|
105
|
-
|
|
106
|
-
{ id: '
|
|
107
|
-
{ id: '
|
|
108
|
-
{ id: '
|
|
142
|
+
kimi: [
|
|
143
|
+
{ id: 'kimi-k2.6', name: 'Kimi K2.6', desc: '最新旗舰,支持思考' },
|
|
144
|
+
{ id: 'kimi-k2.5', name: 'Kimi K2.5', desc: '稳定版' },
|
|
145
|
+
{ id: 'moonshot-v1-128k', name: 'Moonshot-128K', desc: '超长上下文' },
|
|
146
|
+
{ id: 'moonshot-v1-32k', name: 'Moonshot-32K', desc: '长上下文' },
|
|
147
|
+
{ id: 'moonshot-v1-8k', name: 'Moonshot-8K', desc: '基础版' },
|
|
109
148
|
],
|
|
110
|
-
|
|
111
|
-
{ id: '
|
|
112
|
-
{ id: '
|
|
113
|
-
{ id: '
|
|
149
|
+
zhipu: [
|
|
150
|
+
{ id: 'glm-4-plus', name: 'GLM-4-Plus', desc: '旗舰模型' },
|
|
151
|
+
{ id: 'glm-4-flash', name: 'GLM-4-Flash', desc: '快速免费' },
|
|
152
|
+
{ id: 'glm-4-long', name: 'GLM-4-Long', desc: '超长上下文 1M' },
|
|
153
|
+
{ id: 'glm-4-flashx', name: 'GLM-4-FlashX', desc: '加速版' },
|
|
154
|
+
{ id: 'glm-4-air', name: 'GLM-4-Air', desc: '轻量版' },
|
|
114
155
|
],
|
|
115
|
-
|
|
116
|
-
{ id: '
|
|
117
|
-
{ id: '
|
|
118
|
-
{ id: 'moonshot-v1-128k', name: 'Moonshot-V1-128K', desc: '超长上下文' },
|
|
156
|
+
minimax: [
|
|
157
|
+
{ id: 'MiniMax-Text-01', name: 'MiniMax-Text-01', desc: '旗舰模型' },
|
|
158
|
+
{ id: 'abab6.5s-chat', name: 'abab6.5s', desc: '轻量版' },
|
|
119
159
|
],
|
|
120
|
-
|
|
121
|
-
{ id: '
|
|
122
|
-
{ id: '
|
|
160
|
+
baichuan: [
|
|
161
|
+
{ id: 'Baichuan4', name: 'Baichuan4', desc: '最新旗舰' },
|
|
162
|
+
{ id: 'Baichuan3-Turbo', name: 'Baichuan3-Turbo', desc: '快速版' },
|
|
163
|
+
],
|
|
164
|
+
stepfun: [
|
|
165
|
+
{ id: 'step-1-flash', name: 'Step-1-Flash', desc: '快速免费' },
|
|
166
|
+
{ id: 'step-1-8k', name: 'Step-1-8K', desc: '基础版' },
|
|
167
|
+
{ id: 'step-2-16k', name: 'Step-2-16K', desc: '增强版' },
|
|
168
|
+
],
|
|
169
|
+
doubao: [
|
|
170
|
+
{ id: 'doubao-1.5-pro-32k', name: 'Doubao-1.5-Pro-32K', desc: '旗舰版' },
|
|
171
|
+
{ id: 'doubao-1.5-lite-32k', name: 'Doubao-1.5-Lite-32K', desc: '轻量版' },
|
|
172
|
+
{ id: 'doubao-pro-256k', name: 'Doubao-Pro-256K', desc: '超长上下文' },
|
|
173
|
+
],
|
|
174
|
+
anthropic: [
|
|
175
|
+
{ id: 'claude-sonnet-4-20250514', name: 'Claude Sonnet 4', desc: '最新旗舰' },
|
|
176
|
+
{ id: 'claude-3-5-haiku-20241022', name: 'Claude 3.5 Haiku', desc: '快速便宜' },
|
|
177
|
+
{ id: 'claude-3-opus-20240229', name: 'Claude 3 Opus', desc: '最强性能' },
|
|
178
|
+
],
|
|
179
|
+
gemini: [
|
|
180
|
+
{ id: 'gemini-2.0-flash', name: 'Gemini 2.0 Flash', desc: '最新快速' },
|
|
181
|
+
{ id: 'gemini-2.5-pro-preview-05-06', name: 'Gemini 2.5 Pro', desc: '最强推理' },
|
|
182
|
+
{ id: 'gemini-1.5-flash', name: 'Gemini 1.5 Flash', desc: '经典版' },
|
|
183
|
+
],
|
|
184
|
+
ollama: [
|
|
185
|
+
{ id: 'llama3.1', name: 'Llama 3.1', desc: 'Meta 开源' },
|
|
186
|
+
{ id: 'qwen2.5', name: 'Qwen 2.5', desc: '通义千问' },
|
|
187
|
+
{ id: 'deepseek-coder-v2', name: 'DeepSeek Coder V2', desc: '编程专用' },
|
|
188
|
+
{ id: 'codellama', name: 'Code Llama', desc: 'Meta 编程' },
|
|
189
|
+
{ id: 'mistral', name: 'Mistral', desc: '高性能' },
|
|
123
190
|
],
|
|
124
191
|
ernie: [
|
|
125
|
-
{ id: 'ernie-4.
|
|
192
|
+
{ id: 'ernie-4.5-8k', name: 'ERNIE-4.5-8K', desc: '最新旗舰' },
|
|
193
|
+
{ id: 'ernie-4.0-8k', name: 'ERNIE-4.0-8K', desc: '强性能' },
|
|
126
194
|
{ id: 'ernie-3.5-8k', name: 'ERNIE-3.5-8K', desc: '性价比高' },
|
|
127
195
|
],
|
|
196
|
+
custom_openai: [
|
|
197
|
+
{ id: 'gpt-4o-mini', name: 'GPT-4o-mini', desc: '默认模型,可自定义' },
|
|
198
|
+
{ id: 'gpt-4o', name: 'GPT-4o', desc: '可自定义' },
|
|
199
|
+
{ id: 'claude-sonnet-4-20250514', name: 'Claude Sonnet 4', desc: '可自定义' },
|
|
200
|
+
],
|
|
201
|
+
custom_anthropic: [
|
|
202
|
+
{ id: 'claude-sonnet-4-20250514', name: 'Claude Sonnet 4', desc: '默认模型,可自定义' },
|
|
203
|
+
{ id: 'claude-3-5-haiku-20241022', name: 'Claude 3.5 Haiku', desc: '可自定义' },
|
|
204
|
+
],
|
|
128
205
|
};
|
|
129
206
|
|
|
130
207
|
// ==================== Helpers ====================
|
|
131
208
|
|
|
132
|
-
/**
|
|
133
|
-
* Get models for a specific provider
|
|
134
|
-
*/
|
|
135
209
|
export function getModelsForProvider(provider: ProviderName): ModelInfo[] {
|
|
136
|
-
return MODEL_CATALOGS[provider] ||
|
|
210
|
+
return MODEL_CATALOGS[provider] || [];
|
|
137
211
|
}
|
|
138
212
|
|
|
139
|
-
/**
|
|
140
|
-
* Get API key for a provider from environment variables
|
|
141
|
-
*/
|
|
142
213
|
export function getApiKeyFromEnv(provider: ProviderName): string {
|
|
143
214
|
const providerConfig = PROVIDERS[provider];
|
|
144
215
|
if (!providerConfig) return '';
|
|
145
|
-
|
|
146
216
|
for (const envKey of providerConfig.envKeys) {
|
|
147
217
|
if (process.env[envKey]) return process.env[envKey];
|
|
148
218
|
}
|
|
149
219
|
return '';
|
|
150
220
|
}
|
|
151
221
|
|
|
152
|
-
/**
|
|
153
|
-
* List all provider names
|
|
154
|
-
*/
|
|
155
222
|
export function listProviders(): Array<{ key: ProviderName; name: string }> {
|
|
156
223
|
return Object.entries(PROVIDERS).map(([key, val]) => ({
|
|
157
224
|
key: key as ProviderName,
|
|
158
225
|
name: val.name,
|
|
159
226
|
}));
|
|
160
227
|
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Check if a provider name is a custom/relay provider
|
|
231
|
+
*/
|
|
232
|
+
export function isCustomProvider(provider: ProviderName): boolean {
|
|
233
|
+
return provider === 'custom_openai' || provider === 'custom_anthropic';
|
|
234
|
+
}
|
package/src/config/types.ts
CHANGED
|
@@ -4,14 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
export type ProviderName =
|
|
6
6
|
| 'siliconflow'
|
|
7
|
-
| 'minimax'
|
|
8
7
|
| 'openai'
|
|
8
|
+
| 'deepseek'
|
|
9
|
+
| 'kimi'
|
|
10
|
+
| 'zhipu'
|
|
11
|
+
| 'minimax'
|
|
12
|
+
| 'baichuan'
|
|
13
|
+
| 'stepfun'
|
|
14
|
+
| 'doubao'
|
|
9
15
|
| 'anthropic'
|
|
10
|
-
| 'ollama'
|
|
11
16
|
| 'gemini'
|
|
12
|
-
| '
|
|
13
|
-
| '
|
|
14
|
-
| '
|
|
17
|
+
| 'ollama'
|
|
18
|
+
| 'ernie'
|
|
19
|
+
| 'custom_openai'
|
|
20
|
+
| 'custom_anthropic';
|
|
15
21
|
|
|
16
22
|
export interface ProviderConfig {
|
|
17
23
|
name: string;
|
package/src/llm/anthropic.ts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Anthropic Provider
|
|
3
|
-
* Works with: Anthropic Claude
|
|
3
|
+
* Works with: Anthropic Claude API
|
|
4
|
+
* Also works with any Anthropic-compatible relay station (中转站)
|
|
5
|
+
*
|
|
6
|
+
* API: POST {baseUrl}/messages
|
|
7
|
+
* Auth: x-api-key: {apiKey}, anthropic-version: 2023-06-01
|
|
8
|
+
* Streaming: SSE with "event: ..." and "data: {...}" lines
|
|
9
|
+
*
|
|
10
|
+
* Key differences from OpenAI:
|
|
11
|
+
* - System message is separate (top-level "system" field)
|
|
12
|
+
* - No "system" role in messages array
|
|
13
|
+
* - Tool use blocks have type "tool_use" with "input" (not "arguments")
|
|
14
|
+
* - Tool results use role "tool_result" (not "tool")
|
|
4
15
|
*/
|
|
5
16
|
|
|
6
17
|
import type { ChatMessage, ChatResponse, ChatOptions } from '../types.js';
|
|
@@ -9,7 +20,7 @@ import type { LLMProvider, ProviderConfig } from './provider.js';
|
|
|
9
20
|
|
|
10
21
|
export class AnthropicProvider implements LLMProvider {
|
|
11
22
|
readonly name = 'anthropic';
|
|
12
|
-
|
|
23
|
+
protected config: ProviderConfig;
|
|
13
24
|
|
|
14
25
|
constructor(config: ProviderConfig) {
|
|
15
26
|
this.config = config;
|
|
@@ -31,16 +42,7 @@ export class AnthropicProvider implements LLMProvider {
|
|
|
31
42
|
|
|
32
43
|
async chat(messages: ChatMessage[], options?: ChatOptions): Promise<ChatResponse> {
|
|
33
44
|
const body = this.buildRequest(messages, false, options);
|
|
34
|
-
|
|
35
|
-
const response = await fetch(`${this.config.baseUrl}/messages`, {
|
|
36
|
-
method: 'POST',
|
|
37
|
-
headers: {
|
|
38
|
-
'Content-Type': 'application/json',
|
|
39
|
-
'x-api-key': this.config.apiKey,
|
|
40
|
-
'anthropic-version': '2023-06-01',
|
|
41
|
-
},
|
|
42
|
-
body: JSON.stringify(body),
|
|
43
|
-
});
|
|
45
|
+
const response = await this.doRequest(body);
|
|
44
46
|
|
|
45
47
|
if (!response.ok) {
|
|
46
48
|
const text = await response.text().catch(() => '');
|
|
@@ -48,41 +50,37 @@ export class AnthropicProvider implements LLMProvider {
|
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
const data = await response.json();
|
|
51
|
-
|
|
53
|
+
|
|
54
|
+
// Extract text content
|
|
55
|
+
const textBlocks = data.content?.filter((b: any) => b.type === 'text') || [];
|
|
56
|
+
const content = textBlocks.map((b: any) => b.text).join('');
|
|
57
|
+
|
|
58
|
+
// Extract tool calls
|
|
52
59
|
const toolUseBlocks = data.content?.filter((b: any) => b.type === 'tool_use') || [];
|
|
60
|
+
const toolCalls = toolUseBlocks.length > 0 ? toolUseBlocks.map((b: any) => ({
|
|
61
|
+
id: b.id,
|
|
62
|
+
type: 'function' as const,
|
|
63
|
+
function: {
|
|
64
|
+
name: b.name,
|
|
65
|
+
arguments: JSON.stringify(b.input),
|
|
66
|
+
},
|
|
67
|
+
})) : undefined;
|
|
53
68
|
|
|
54
69
|
return {
|
|
55
|
-
content
|
|
70
|
+
content,
|
|
56
71
|
role: 'assistant',
|
|
57
72
|
usage: data.usage ? {
|
|
58
73
|
prompt_tokens: data.usage.input_tokens || 0,
|
|
59
74
|
completion_tokens: data.usage.output_tokens || 0,
|
|
60
75
|
total_tokens: (data.usage.input_tokens || 0) + (data.usage.output_tokens || 0),
|
|
61
76
|
} : undefined,
|
|
62
|
-
tool_calls:
|
|
63
|
-
id: b.id,
|
|
64
|
-
type: 'function' as const,
|
|
65
|
-
function: {
|
|
66
|
-
name: b.name,
|
|
67
|
-
arguments: JSON.stringify(b.input),
|
|
68
|
-
},
|
|
69
|
-
})) : undefined,
|
|
77
|
+
tool_calls: toolCalls,
|
|
70
78
|
};
|
|
71
79
|
}
|
|
72
80
|
|
|
73
81
|
async *chatStream(messages: ChatMessage[], options?: ChatOptions): AsyncGenerator<string, ChatResponse> {
|
|
74
82
|
const body = this.buildRequest(messages, true, options);
|
|
75
|
-
|
|
76
|
-
const response = await fetch(`${this.config.baseUrl}/messages`, {
|
|
77
|
-
method: 'POST',
|
|
78
|
-
headers: {
|
|
79
|
-
'Content-Type': 'application/json',
|
|
80
|
-
'x-api-key': this.config.apiKey,
|
|
81
|
-
'anthropic-version': '2023-06-01',
|
|
82
|
-
'anthropic-dangerous-direct-browser-access': 'true',
|
|
83
|
-
},
|
|
84
|
-
body: JSON.stringify(body),
|
|
85
|
-
});
|
|
83
|
+
const response = await this.doRequest(body);
|
|
86
84
|
|
|
87
85
|
if (!response.ok || !response.body) {
|
|
88
86
|
const text = await response.text().catch(() => '');
|
|
@@ -109,6 +107,8 @@ export class AnthropicProvider implements LLMProvider {
|
|
|
109
107
|
|
|
110
108
|
try {
|
|
111
109
|
const data = JSON.parse(trimmed.slice(6));
|
|
110
|
+
|
|
111
|
+
// content_block_delta: incremental text
|
|
112
112
|
if (data.type === 'content_block_delta' && data.delta?.type === 'text_delta') {
|
|
113
113
|
const text = data.delta.text;
|
|
114
114
|
fullContent += text;
|
|
@@ -126,21 +126,72 @@ export class AnthropicProvider implements LLMProvider {
|
|
|
126
126
|
return { content: fullContent, role: 'assistant' };
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
/**
|
|
130
|
+
* Build request body for Anthropic API
|
|
131
|
+
*/
|
|
132
|
+
protected buildRequest(messages: ChatMessage[], stream: boolean, options?: ChatOptions) {
|
|
130
133
|
// Anthropic uses separate system message
|
|
131
134
|
const systemMsg = messages.find(m => m.role === 'system');
|
|
132
135
|
const nonSystemMsgs = messages.filter(m => m.role !== 'system');
|
|
133
136
|
|
|
137
|
+
// Convert messages to Anthropic format
|
|
138
|
+
const anthropicMessages = nonSystemMsgs.map(m => {
|
|
139
|
+
if (m.role === 'tool') {
|
|
140
|
+
// Tool result message
|
|
141
|
+
return {
|
|
142
|
+
role: 'user',
|
|
143
|
+
content: [{
|
|
144
|
+
type: 'tool_result',
|
|
145
|
+
tool_use_id: m.tool_call_id,
|
|
146
|
+
content: m.content,
|
|
147
|
+
}],
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
if (m.tool_calls && m.tool_calls.length > 0) {
|
|
151
|
+
// Assistant message with tool calls
|
|
152
|
+
const blocks: any[] = [];
|
|
153
|
+
if (m.content) {
|
|
154
|
+
blocks.push({ type: 'text', text: m.content });
|
|
155
|
+
}
|
|
156
|
+
for (const tc of m.tool_calls) {
|
|
157
|
+
blocks.push({
|
|
158
|
+
type: 'tool_use',
|
|
159
|
+
id: tc.id,
|
|
160
|
+
name: tc.function.name,
|
|
161
|
+
input: JSON.parse(tc.function.arguments || '{}'),
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return { role: 'assistant', content: blocks };
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
role: m.role === 'assistant' ? 'assistant' : 'user',
|
|
168
|
+
content: m.content,
|
|
169
|
+
};
|
|
170
|
+
});
|
|
171
|
+
|
|
134
172
|
return {
|
|
135
173
|
model: this.config.model,
|
|
136
|
-
max_tokens: options?.maxTokens ?? this.config.maxTokens,
|
|
174
|
+
max_tokens: options?.maxTokens ?? this.config.maxTokens ?? 4096,
|
|
137
175
|
temperature: options?.temperature ?? this.config.temperature,
|
|
138
176
|
...(systemMsg && { system: systemMsg.content }),
|
|
139
|
-
messages:
|
|
140
|
-
role: m.role === 'assistant' ? 'assistant' : 'user',
|
|
141
|
-
content: m.content,
|
|
142
|
-
})),
|
|
177
|
+
messages: anthropicMessages,
|
|
143
178
|
stream,
|
|
144
179
|
};
|
|
145
180
|
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Execute the HTTP request
|
|
184
|
+
*/
|
|
185
|
+
protected async doRequest(body: any): Promise<Response> {
|
|
186
|
+
const url = `${this.config.baseUrl}/messages`;
|
|
187
|
+
return fetch(url, {
|
|
188
|
+
method: 'POST',
|
|
189
|
+
headers: {
|
|
190
|
+
'Content-Type': 'application/json',
|
|
191
|
+
'x-api-key': this.config.apiKey,
|
|
192
|
+
'anthropic-version': '2023-06-01',
|
|
193
|
+
},
|
|
194
|
+
body: JSON.stringify(body),
|
|
195
|
+
});
|
|
196
|
+
}
|
|
146
197
|
}
|