bingocode 1.0.13 → 1.0.15
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/LICENSE +29 -38
- package/package.json +3 -3
- package/src/cli/ProviderPanel.tsx +725 -725
- package/src/manager/CliMenuManager.tsx +5 -20
- package/src/server/config/providerPresets.ts +93 -93
- package/src/server/config/providers.yaml +145 -145
|
@@ -8,6 +8,7 @@ import { LogoV2 } from '../components/LogoV2/LogoV2.tsx';
|
|
|
8
8
|
import { CondensedLogo } from '../components/LogoV2/CondensedLogo.tsx';
|
|
9
9
|
import fs from 'fs';
|
|
10
10
|
import path from 'path';
|
|
11
|
+
import os from 'os';
|
|
11
12
|
import { ensureSingletonLocalServer } from '../server/ensureSingletonLocalServer.ts';
|
|
12
13
|
// 新增:通用 UI 元素与顶部工具栏
|
|
13
14
|
import { TopBar, BottomBar, Panel, Hint, Kbd, SecondaryMenu } from '../manager/CliMenuUi.tsx';
|
|
@@ -20,7 +21,8 @@ import { useTheme } from '../components/design-system/ThemeProvider.js';
|
|
|
20
21
|
// 配置相关(仅使用可用接口)
|
|
21
22
|
import { getGlobalConfig, saveGlobalConfig } from '../utils/config.ts';
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
// markedSessions 存到 ~/.claude-cli/ 固定目录,不受 cwd 影响
|
|
25
|
+
const MARKED_FILE = path.join(os.homedir(), '.claude-cli', 'markedSessions.json');
|
|
24
26
|
|
|
25
27
|
// 固定尺寸视口(可用环境变量覆盖)
|
|
26
28
|
const VIEW_W = Number(process.env.CLI_VIEW_W || 96);
|
|
@@ -182,7 +184,7 @@ export const CliMenuManager: React.FC = () => {
|
|
|
182
184
|
(async () => {
|
|
183
185
|
try {
|
|
184
186
|
if (apiUrl) return;
|
|
185
|
-
const entry = path.resolve(
|
|
187
|
+
const entry = path.resolve(import.meta.dir, '../server/index.ts');
|
|
186
188
|
const handle = await ensureSingletonLocalServer({ serverEntry: entry });
|
|
187
189
|
if (!mounted) { await handle.stopIfLast(); return; }
|
|
188
190
|
setApiUrl(handle.baseUrl);
|
|
@@ -678,24 +680,7 @@ export const CliMenuManager: React.FC = () => {
|
|
|
678
680
|
setSelectedHistory(null);
|
|
679
681
|
setMsgsPage(0);
|
|
680
682
|
} else if (item.value === '__continue') {
|
|
681
|
-
|
|
682
|
-
const fsReq = require('fs');
|
|
683
|
-
const pathReq = require('path');
|
|
684
|
-
const { spawn } = require('child_process');
|
|
685
|
-
const pkgPath = pathReq.resolve(process.cwd(), 'package.json');
|
|
686
|
-
const pkgJson = JSON.parse(fsReq.readFileSync(pkgPath, 'utf-8'));
|
|
687
|
-
const bins = pkgJson.bin || {};
|
|
688
|
-
const isWin = process.platform === 'win32';
|
|
689
|
-
let binName = isWin
|
|
690
|
-
? bins['claude-haha'] ? 'claude-haha' : bins['claude'] ? 'claude' : Object.keys(bins)[0]
|
|
691
|
-
: bins['claude-linux'] ? 'claude-linux' : bins['claude'] ? 'claude' : Object.keys(bins)[0];
|
|
692
|
-
const spawnCmd = isWin ? 'cmd' : 'sh';
|
|
693
|
-
const spawnArgs = isWin
|
|
694
|
-
? ['/c', binName, '--resume', selectedHistory.id]
|
|
695
|
-
: ['-c', `./${binName} --resume ${selectedHistory.id}`];
|
|
696
|
-
// 静默启动继续会话
|
|
697
|
-
resumeSession(selectedHistory.id);
|
|
698
|
-
} catch { }
|
|
683
|
+
resumeSession(selectedHistory.id);
|
|
699
684
|
} else if (item.value === '__delete') {
|
|
700
685
|
setHistoryMenuStage('deleteConfirm');
|
|
701
686
|
} else if (item.value === '__toggle_mark') {
|
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
// Provider presets — loaded from providers.yaml at startup
|
|
2
|
-
// Original work inspired by cc-switch (https://github.com/farion1231/cc-switch) by Jason Young, MIT License
|
|
3
|
-
|
|
4
|
-
//@C:ID=M.PP.providerPresets;K=M;V=2.0;P=Import dependencies;D=API;M=Providers;S=ModelConfiguration
|
|
5
|
-
import { readFileSync } from 'fs'
|
|
6
|
-
import { fileURLToPath } from 'url'
|
|
7
|
-
import { parse } from 'yaml'
|
|
8
|
-
import path from 'path'
|
|
9
|
-
import type { ApiFormat } from '../types/provider.js'
|
|
10
|
-
|
|
11
|
-
//@C:ID=T.PP.ModelMapping;K=T;V=1.0;P=Define model type mappings;D=API;M=Providers;S=ModelConfiguration
|
|
12
|
-
export type ModelMapping = {
|
|
13
|
-
main: string
|
|
14
|
-
haiku: string
|
|
15
|
-
sonnet: string
|
|
16
|
-
opus: string
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
//@C:ID=T.PP.ProviderField;K=T;V=1.0;P=Define per-provider field descriptor;D=API;M=Providers;S=ModelConfiguration
|
|
20
|
-
export type ProviderField = {
|
|
21
|
-
/** Field key: 'name' | 'apiKey' | 'baseUrl' map to top-level fields; others go into extra.<key> */
|
|
22
|
-
key: string
|
|
23
|
-
/** Human-readable label shown in the CLI form */
|
|
24
|
-
label: string
|
|
25
|
-
required?: boolean
|
|
26
|
-
/** If true, input is masked in the terminal */
|
|
27
|
-
secret?: boolean
|
|
28
|
-
placeholder?: string
|
|
29
|
-
/** Default value pre-filled in the form */
|
|
30
|
-
default?: string
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
//@C:ID=T.PP.ProviderPreset;K=T;V=2.0;P=Define provider preset structure;D=API;M=Providers;S=ModelConfiguration
|
|
34
|
-
export type ProviderPreset = {
|
|
35
|
-
id: string
|
|
36
|
-
name: string
|
|
37
|
-
baseUrl: string
|
|
38
|
-
apiFormat: ApiFormat
|
|
39
|
-
defaultModels: ModelMapping
|
|
40
|
-
needsApiKey: boolean
|
|
41
|
-
websiteUrl: string
|
|
42
|
-
/** Ordered list of fields to render when adding a new provider from this preset */
|
|
43
|
-
fields: ProviderField[]
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
//@C:ID=D.PP.PROVIDER_PRESETS;K=D;V=2.0;P=Load provider presets from yaml;D=API;M=Providers;S=ModelConfiguration
|
|
47
|
-
function loadPresetsFromYaml(): ProviderPreset[] {
|
|
48
|
-
try {
|
|
49
|
-
const yamlPath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'providers.yaml')
|
|
50
|
-
const raw = parse(readFileSync(yamlPath, 'utf-8')) as { presets?: ProviderPreset[] }
|
|
51
|
-
const presets = raw?.presets
|
|
52
|
-
if (!Array.isArray(presets) || presets.length === 0) {
|
|
53
|
-
throw new Error('providers.yaml missing presets array')
|
|
54
|
-
}
|
|
55
|
-
// Ensure fields is always an array
|
|
56
|
-
return presets.map(p => ({ ...p, fields: Array.isArray(p.fields) ? p.fields : [] }))
|
|
57
|
-
} catch (err) {
|
|
58
|
-
console.error('[providerPresets] Failed to load providers.yaml, falling back to defaults:', err)
|
|
59
|
-
// Minimal fallback so the server can still start
|
|
60
|
-
return [
|
|
61
|
-
{
|
|
62
|
-
id: 'official',
|
|
63
|
-
name: 'Claude Official',
|
|
64
|
-
baseUrl: '',
|
|
65
|
-
apiFormat: 'anthropic',
|
|
66
|
-
defaultModels: { main: '', haiku: '', sonnet: '', opus: '' },
|
|
67
|
-
needsApiKey: false,
|
|
68
|
-
websiteUrl: 'https://www.anthropic.com/claude-code',
|
|
69
|
-
fields: [{ key: 'name', label: 'Provider 昵称', required: true }],
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
id: 'custom',
|
|
73
|
-
name: 'Custom',
|
|
74
|
-
baseUrl: '',
|
|
75
|
-
apiFormat: 'anthropic',
|
|
76
|
-
defaultModels: { main: '', haiku: '', sonnet: '', opus: '' },
|
|
77
|
-
needsApiKey: true,
|
|
78
|
-
websiteUrl: '',
|
|
79
|
-
fields: [
|
|
80
|
-
{ key: 'name', label: 'Provider 昵称', required: true },
|
|
81
|
-
{ key: 'baseUrl', label: 'Base URL', required: true },
|
|
82
|
-
{ key: 'apiKey', label: 'API Key', required: false, secret: true },
|
|
83
|
-
],
|
|
84
|
-
},
|
|
85
|
-
]
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export const PROVIDER_PRESETS: ProviderPreset[] = loadPresetsFromYaml()
|
|
90
|
-
|
|
91
|
-
export async function loadProviderPresets(): Promise<ProviderPreset[]> {
|
|
92
|
-
return PROVIDER_PRESETS
|
|
93
|
-
}
|
|
1
|
+
// Provider presets — loaded from providers.yaml at startup
|
|
2
|
+
// Original work inspired by cc-switch (https://github.com/farion1231/cc-switch) by Jason Young, MIT License
|
|
3
|
+
|
|
4
|
+
//@C:ID=M.PP.providerPresets;K=M;V=2.0;P=Import dependencies;D=API;M=Providers;S=ModelConfiguration
|
|
5
|
+
import { readFileSync } from 'fs'
|
|
6
|
+
import { fileURLToPath } from 'url'
|
|
7
|
+
import { parse } from 'yaml'
|
|
8
|
+
import path from 'path'
|
|
9
|
+
import type { ApiFormat } from '../types/provider.js'
|
|
10
|
+
|
|
11
|
+
//@C:ID=T.PP.ModelMapping;K=T;V=1.0;P=Define model type mappings;D=API;M=Providers;S=ModelConfiguration
|
|
12
|
+
export type ModelMapping = {
|
|
13
|
+
main: string
|
|
14
|
+
haiku: string
|
|
15
|
+
sonnet: string
|
|
16
|
+
opus: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//@C:ID=T.PP.ProviderField;K=T;V=1.0;P=Define per-provider field descriptor;D=API;M=Providers;S=ModelConfiguration
|
|
20
|
+
export type ProviderField = {
|
|
21
|
+
/** Field key: 'name' | 'apiKey' | 'baseUrl' map to top-level fields; others go into extra.<key> */
|
|
22
|
+
key: string
|
|
23
|
+
/** Human-readable label shown in the CLI form */
|
|
24
|
+
label: string
|
|
25
|
+
required?: boolean
|
|
26
|
+
/** If true, input is masked in the terminal */
|
|
27
|
+
secret?: boolean
|
|
28
|
+
placeholder?: string
|
|
29
|
+
/** Default value pre-filled in the form */
|
|
30
|
+
default?: string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
//@C:ID=T.PP.ProviderPreset;K=T;V=2.0;P=Define provider preset structure;D=API;M=Providers;S=ModelConfiguration
|
|
34
|
+
export type ProviderPreset = {
|
|
35
|
+
id: string
|
|
36
|
+
name: string
|
|
37
|
+
baseUrl: string
|
|
38
|
+
apiFormat: ApiFormat
|
|
39
|
+
defaultModels: ModelMapping
|
|
40
|
+
needsApiKey: boolean
|
|
41
|
+
websiteUrl: string
|
|
42
|
+
/** Ordered list of fields to render when adding a new provider from this preset */
|
|
43
|
+
fields: ProviderField[]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//@C:ID=D.PP.PROVIDER_PRESETS;K=D;V=2.0;P=Load provider presets from yaml;D=API;M=Providers;S=ModelConfiguration
|
|
47
|
+
function loadPresetsFromYaml(): ProviderPreset[] {
|
|
48
|
+
try {
|
|
49
|
+
const yamlPath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'providers.yaml')
|
|
50
|
+
const raw = parse(readFileSync(yamlPath, 'utf-8')) as { presets?: ProviderPreset[] }
|
|
51
|
+
const presets = raw?.presets
|
|
52
|
+
if (!Array.isArray(presets) || presets.length === 0) {
|
|
53
|
+
throw new Error('providers.yaml missing presets array')
|
|
54
|
+
}
|
|
55
|
+
// Ensure fields is always an array
|
|
56
|
+
return presets.map(p => ({ ...p, fields: Array.isArray(p.fields) ? p.fields : [] }))
|
|
57
|
+
} catch (err) {
|
|
58
|
+
console.error('[providerPresets] Failed to load providers.yaml, falling back to defaults:', err)
|
|
59
|
+
// Minimal fallback so the server can still start
|
|
60
|
+
return [
|
|
61
|
+
{
|
|
62
|
+
id: 'official',
|
|
63
|
+
name: 'Claude Official',
|
|
64
|
+
baseUrl: '',
|
|
65
|
+
apiFormat: 'anthropic',
|
|
66
|
+
defaultModels: { main: '', haiku: '', sonnet: '', opus: '' },
|
|
67
|
+
needsApiKey: false,
|
|
68
|
+
websiteUrl: 'https://www.anthropic.com/claude-code',
|
|
69
|
+
fields: [{ key: 'name', label: 'Provider 昵称', required: true }],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: 'custom',
|
|
73
|
+
name: 'Custom',
|
|
74
|
+
baseUrl: '',
|
|
75
|
+
apiFormat: 'anthropic',
|
|
76
|
+
defaultModels: { main: '', haiku: '', sonnet: '', opus: '' },
|
|
77
|
+
needsApiKey: true,
|
|
78
|
+
websiteUrl: '',
|
|
79
|
+
fields: [
|
|
80
|
+
{ key: 'name', label: 'Provider 昵称', required: true },
|
|
81
|
+
{ key: 'baseUrl', label: 'Base URL', required: true },
|
|
82
|
+
{ key: 'apiKey', label: 'API Key', required: false, secret: true },
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export const PROVIDER_PRESETS: ProviderPreset[] = loadPresetsFromYaml()
|
|
90
|
+
|
|
91
|
+
export async function loadProviderPresets(): Promise<ProviderPreset[]> {
|
|
92
|
+
return PROVIDER_PRESETS
|
|
93
|
+
}
|
|
@@ -1,145 +1,145 @@
|
|
|
1
|
-
version: 2
|
|
2
|
-
|
|
3
|
-
# Provider 预设配置
|
|
4
|
-
# fields 数组声明新增时需填写的字段
|
|
5
|
-
# key: 'name' | 'apiKey' | 'baseUrl' 直接映射到顶层字段,其余存入 extra.<key>
|
|
6
|
-
# secret: true 时前端使用密码掩码显示
|
|
7
|
-
|
|
8
|
-
presets:
|
|
9
|
-
- id: official
|
|
10
|
-
name: Claude Official
|
|
11
|
-
baseUrl: ''
|
|
12
|
-
apiFormat: anthropic
|
|
13
|
-
needsApiKey: false
|
|
14
|
-
websiteUrl: https://www.anthropic.com/claude-code
|
|
15
|
-
defaultModels:
|
|
16
|
-
main: ''
|
|
17
|
-
haiku: ''
|
|
18
|
-
sonnet: ''
|
|
19
|
-
opus: ''
|
|
20
|
-
fields:
|
|
21
|
-
- key: name
|
|
22
|
-
label: Provider 昵称
|
|
23
|
-
required: true
|
|
24
|
-
secret: false
|
|
25
|
-
placeholder: 'e.g. Claude Official'
|
|
26
|
-
|
|
27
|
-
- id: deepseek
|
|
28
|
-
name: DeepSeek
|
|
29
|
-
baseUrl: https://api.deepseek.com/anthropic
|
|
30
|
-
apiFormat: anthropic
|
|
31
|
-
needsApiKey: true
|
|
32
|
-
websiteUrl: https://platform.deepseek.com
|
|
33
|
-
defaultModels:
|
|
34
|
-
main: DeepSeek-V3.2
|
|
35
|
-
haiku: DeepSeek-V3.2
|
|
36
|
-
sonnet: DeepSeek-V3.2
|
|
37
|
-
opus: DeepSeek-V3.2
|
|
38
|
-
fields:
|
|
39
|
-
- key: name
|
|
40
|
-
label: Provider 昵称
|
|
41
|
-
required: true
|
|
42
|
-
secret: false
|
|
43
|
-
placeholder: 'e.g. My DeepSeek'
|
|
44
|
-
- key: apiKey
|
|
45
|
-
label: API Key
|
|
46
|
-
required: true
|
|
47
|
-
secret: true
|
|
48
|
-
placeholder: 'sk-...'
|
|
49
|
-
|
|
50
|
-
- id: zhipuglm
|
|
51
|
-
name: Zhipu GLM
|
|
52
|
-
baseUrl: https://open.bigmodel.cn/api/anthropic
|
|
53
|
-
apiFormat: anthropic
|
|
54
|
-
needsApiKey: true
|
|
55
|
-
websiteUrl: https://open.bigmodel.cn
|
|
56
|
-
defaultModels:
|
|
57
|
-
main: glm-5
|
|
58
|
-
haiku: glm-5
|
|
59
|
-
sonnet: glm-5
|
|
60
|
-
opus: glm-5
|
|
61
|
-
fields:
|
|
62
|
-
- key: name
|
|
63
|
-
label: Provider 昵称
|
|
64
|
-
required: true
|
|
65
|
-
secret: false
|
|
66
|
-
placeholder: 'e.g. My GLM'
|
|
67
|
-
- key: apiKey
|
|
68
|
-
label: API Key
|
|
69
|
-
required: true
|
|
70
|
-
secret: true
|
|
71
|
-
placeholder: '智谱 API Key'
|
|
72
|
-
|
|
73
|
-
- id: kimi
|
|
74
|
-
name: Kimi
|
|
75
|
-
baseUrl: https://api.moonshot.cn/anthropic
|
|
76
|
-
apiFormat: anthropic
|
|
77
|
-
needsApiKey: true
|
|
78
|
-
websiteUrl: https://platform.moonshot.cn
|
|
79
|
-
defaultModels:
|
|
80
|
-
main: kimi-k2.5
|
|
81
|
-
haiku: kimi-k2.5
|
|
82
|
-
sonnet: kimi-k2.5
|
|
83
|
-
opus: kimi-k2.5
|
|
84
|
-
fields:
|
|
85
|
-
- key: name
|
|
86
|
-
label: Provider 昵称
|
|
87
|
-
required: true
|
|
88
|
-
secret: false
|
|
89
|
-
placeholder: 'e.g. My Kimi'
|
|
90
|
-
- key: apiKey
|
|
91
|
-
label: API Key
|
|
92
|
-
required: true
|
|
93
|
-
secret: true
|
|
94
|
-
placeholder: 'Moonshot API Key'
|
|
95
|
-
|
|
96
|
-
- id: minimax
|
|
97
|
-
name: MiniMax
|
|
98
|
-
baseUrl: https://api.minimaxi.com/anthropic
|
|
99
|
-
apiFormat: anthropic
|
|
100
|
-
needsApiKey: true
|
|
101
|
-
websiteUrl: https://platform.minimaxi.com
|
|
102
|
-
defaultModels:
|
|
103
|
-
main: MiniMax-M2.7
|
|
104
|
-
haiku: MiniMax-M2.7
|
|
105
|
-
sonnet: MiniMax-M2.7
|
|
106
|
-
opus: MiniMax-M2.7
|
|
107
|
-
fields:
|
|
108
|
-
- key: name
|
|
109
|
-
label: Provider 昵称
|
|
110
|
-
required: true
|
|
111
|
-
secret: false
|
|
112
|
-
placeholder: 'e.g. My MiniMax'
|
|
113
|
-
- key: apiKey
|
|
114
|
-
label: API Key
|
|
115
|
-
required: true
|
|
116
|
-
secret: true
|
|
117
|
-
placeholder: 'MiniMax API Key'
|
|
118
|
-
|
|
119
|
-
- id: custom
|
|
120
|
-
name: Custom
|
|
121
|
-
baseUrl: ''
|
|
122
|
-
apiFormat:
|
|
123
|
-
needsApiKey: true
|
|
124
|
-
websiteUrl: ''
|
|
125
|
-
defaultModels:
|
|
126
|
-
main: ''
|
|
127
|
-
haiku: ''
|
|
128
|
-
sonnet: ''
|
|
129
|
-
opus: ''
|
|
130
|
-
fields:
|
|
131
|
-
- key: name
|
|
132
|
-
label: Provider 昵称
|
|
133
|
-
required: true
|
|
134
|
-
secret: false
|
|
135
|
-
placeholder: 'e.g. My Custom Provider'
|
|
136
|
-
- key: baseUrl
|
|
137
|
-
label: Base URL
|
|
138
|
-
required: true
|
|
139
|
-
secret: false
|
|
140
|
-
placeholder: 'https://your-api-endpoint.com/
|
|
141
|
-
- key: apiKey
|
|
142
|
-
label: API Key
|
|
143
|
-
required: false
|
|
144
|
-
secret: true
|
|
145
|
-
placeholder: '(可选)API Key'
|
|
1
|
+
version: 2
|
|
2
|
+
|
|
3
|
+
# Provider 预设配置
|
|
4
|
+
# fields 数组声明新增时需填写的字段
|
|
5
|
+
# key: 'name' | 'apiKey' | 'baseUrl' 直接映射到顶层字段,其余存入 extra.<key>
|
|
6
|
+
# secret: true 时前端使用密码掩码显示
|
|
7
|
+
|
|
8
|
+
presets:
|
|
9
|
+
- id: official
|
|
10
|
+
name: Claude Official
|
|
11
|
+
baseUrl: ''
|
|
12
|
+
apiFormat: anthropic
|
|
13
|
+
needsApiKey: false
|
|
14
|
+
websiteUrl: https://www.anthropic.com/claude-code
|
|
15
|
+
defaultModels:
|
|
16
|
+
main: ''
|
|
17
|
+
haiku: ''
|
|
18
|
+
sonnet: ''
|
|
19
|
+
opus: ''
|
|
20
|
+
fields:
|
|
21
|
+
- key: name
|
|
22
|
+
label: Provider 昵称
|
|
23
|
+
required: true
|
|
24
|
+
secret: false
|
|
25
|
+
placeholder: 'e.g. Claude Official'
|
|
26
|
+
|
|
27
|
+
- id: deepseek
|
|
28
|
+
name: DeepSeek
|
|
29
|
+
baseUrl: https://api.deepseek.com/anthropic
|
|
30
|
+
apiFormat: anthropic
|
|
31
|
+
needsApiKey: true
|
|
32
|
+
websiteUrl: https://platform.deepseek.com
|
|
33
|
+
defaultModels:
|
|
34
|
+
main: DeepSeek-V3.2
|
|
35
|
+
haiku: DeepSeek-V3.2
|
|
36
|
+
sonnet: DeepSeek-V3.2
|
|
37
|
+
opus: DeepSeek-V3.2
|
|
38
|
+
fields:
|
|
39
|
+
- key: name
|
|
40
|
+
label: Provider 昵称
|
|
41
|
+
required: true
|
|
42
|
+
secret: false
|
|
43
|
+
placeholder: 'e.g. My DeepSeek'
|
|
44
|
+
- key: apiKey
|
|
45
|
+
label: API Key
|
|
46
|
+
required: true
|
|
47
|
+
secret: true
|
|
48
|
+
placeholder: 'sk-...'
|
|
49
|
+
|
|
50
|
+
- id: zhipuglm
|
|
51
|
+
name: Zhipu GLM
|
|
52
|
+
baseUrl: https://open.bigmodel.cn/api/anthropic
|
|
53
|
+
apiFormat: anthropic
|
|
54
|
+
needsApiKey: true
|
|
55
|
+
websiteUrl: https://open.bigmodel.cn
|
|
56
|
+
defaultModels:
|
|
57
|
+
main: glm-5
|
|
58
|
+
haiku: glm-5
|
|
59
|
+
sonnet: glm-5
|
|
60
|
+
opus: glm-5
|
|
61
|
+
fields:
|
|
62
|
+
- key: name
|
|
63
|
+
label: Provider 昵称
|
|
64
|
+
required: true
|
|
65
|
+
secret: false
|
|
66
|
+
placeholder: 'e.g. My GLM'
|
|
67
|
+
- key: apiKey
|
|
68
|
+
label: API Key
|
|
69
|
+
required: true
|
|
70
|
+
secret: true
|
|
71
|
+
placeholder: '智谱 API Key'
|
|
72
|
+
|
|
73
|
+
- id: kimi
|
|
74
|
+
name: Kimi
|
|
75
|
+
baseUrl: https://api.moonshot.cn/anthropic
|
|
76
|
+
apiFormat: anthropic
|
|
77
|
+
needsApiKey: true
|
|
78
|
+
websiteUrl: https://platform.moonshot.cn
|
|
79
|
+
defaultModels:
|
|
80
|
+
main: kimi-k2.5
|
|
81
|
+
haiku: kimi-k2.5
|
|
82
|
+
sonnet: kimi-k2.5
|
|
83
|
+
opus: kimi-k2.5
|
|
84
|
+
fields:
|
|
85
|
+
- key: name
|
|
86
|
+
label: Provider 昵称
|
|
87
|
+
required: true
|
|
88
|
+
secret: false
|
|
89
|
+
placeholder: 'e.g. My Kimi'
|
|
90
|
+
- key: apiKey
|
|
91
|
+
label: API Key
|
|
92
|
+
required: true
|
|
93
|
+
secret: true
|
|
94
|
+
placeholder: 'Moonshot API Key'
|
|
95
|
+
|
|
96
|
+
- id: minimax
|
|
97
|
+
name: MiniMax
|
|
98
|
+
baseUrl: https://api.minimaxi.com/anthropic
|
|
99
|
+
apiFormat: anthropic
|
|
100
|
+
needsApiKey: true
|
|
101
|
+
websiteUrl: https://platform.minimaxi.com
|
|
102
|
+
defaultModels:
|
|
103
|
+
main: MiniMax-M2.7
|
|
104
|
+
haiku: MiniMax-M2.7
|
|
105
|
+
sonnet: MiniMax-M2.7
|
|
106
|
+
opus: MiniMax-M2.7
|
|
107
|
+
fields:
|
|
108
|
+
- key: name
|
|
109
|
+
label: Provider 昵称
|
|
110
|
+
required: true
|
|
111
|
+
secret: false
|
|
112
|
+
placeholder: 'e.g. My MiniMax'
|
|
113
|
+
- key: apiKey
|
|
114
|
+
label: API Key
|
|
115
|
+
required: true
|
|
116
|
+
secret: true
|
|
117
|
+
placeholder: 'MiniMax API Key'
|
|
118
|
+
|
|
119
|
+
- id: custom
|
|
120
|
+
name: Custom
|
|
121
|
+
baseUrl: ''
|
|
122
|
+
apiFormat: openai_chat
|
|
123
|
+
needsApiKey: true
|
|
124
|
+
websiteUrl: ''
|
|
125
|
+
defaultModels:
|
|
126
|
+
main: ''
|
|
127
|
+
haiku: ''
|
|
128
|
+
sonnet: ''
|
|
129
|
+
opus: ''
|
|
130
|
+
fields:
|
|
131
|
+
- key: name
|
|
132
|
+
label: Provider 昵称
|
|
133
|
+
required: true
|
|
134
|
+
secret: false
|
|
135
|
+
placeholder: 'e.g. My Custom Provider'
|
|
136
|
+
- key: baseUrl
|
|
137
|
+
label: Base URL
|
|
138
|
+
required: true
|
|
139
|
+
secret: false
|
|
140
|
+
placeholder: 'https://your-api-endpoint.com/v1'
|
|
141
|
+
- key: apiKey
|
|
142
|
+
label: API Key
|
|
143
|
+
required: false
|
|
144
|
+
secret: true
|
|
145
|
+
placeholder: '(可选)API Key'
|