kc-beta 0.1.2 → 0.2.1
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/bin/kc-beta.js +14 -2
- package/package.json +1 -1
- package/src/agent/context-window.js +151 -0
- package/src/agent/engine.js +202 -5
- package/src/agent/event-log.js +111 -0
- package/src/agent/llm-client.js +352 -59
- package/src/agent/pipelines/base.js +6 -0
- package/src/agent/pipelines/distillation.js +18 -0
- package/src/agent/pipelines/extraction.js +21 -0
- package/src/agent/pipelines/initializer.js +22 -6
- package/src/agent/pipelines/production-qc.js +19 -0
- package/src/agent/pipelines/skill-authoring.js +14 -0
- package/src/agent/pipelines/skill-testing.js +20 -0
- package/src/agent/retry.js +83 -0
- package/src/agent/session-state.js +78 -0
- package/src/agent/token-counter.js +62 -0
- package/src/agent/tools/document-parse.js +3 -3
- package/src/agent/tools/web-search.js +107 -0
- package/src/agent/tools/worker-llm-call.js +14 -5
- package/src/cli/components.js +16 -4
- package/src/cli/config.js +246 -0
- package/src/cli/index.js +99 -10
- package/src/cli/onboard.js +151 -57
- package/src/config.js +20 -7
- package/src/providers.js +370 -0
package/src/providers.js
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider registry for Multi-LLM support.
|
|
3
|
+
* Centralizes provider metadata, default models, and model classification.
|
|
4
|
+
*
|
|
5
|
+
* Aligned with kc_reborn/platform/backend/app/providers.py
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const PROVIDERS = [
|
|
9
|
+
{
|
|
10
|
+
id: "siliconflow",
|
|
11
|
+
name: "SiliconFlow",
|
|
12
|
+
baseUrl: "https://api.siliconflow.cn/v1",
|
|
13
|
+
authType: "bearer",
|
|
14
|
+
apiFormat: "openai",
|
|
15
|
+
modelsEndpoint: "/models",
|
|
16
|
+
defaultModel: "glm-5",
|
|
17
|
+
defaultTiers: {
|
|
18
|
+
tier1: "Pro/zai-org/GLM-5, Pro/moonshotai/Kimi-K2.5",
|
|
19
|
+
tier2: "Pro/deepseek-ai/DeepSeek-V3.2, Pro/MiniMaxAI/MiniMax-M2.5",
|
|
20
|
+
tier3: "Qwen/Qwen3.5-122B-A10B",
|
|
21
|
+
tier4: "Qwen/Qwen3.5-35B-A3B",
|
|
22
|
+
},
|
|
23
|
+
labels: {
|
|
24
|
+
en: "SiliconFlow (recommended for China)",
|
|
25
|
+
zh: "SiliconFlow(国内推荐)",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "aliyun",
|
|
30
|
+
name: "Aliyun",
|
|
31
|
+
// Coding plan URL — regular API uses dashscope.aliyuncs.com/compatible-mode/v1
|
|
32
|
+
baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
33
|
+
codingPlanUrl: "https://coding.dashscope.aliyuncs.com/v1",
|
|
34
|
+
authType: "bearer",
|
|
35
|
+
apiFormat: "openai",
|
|
36
|
+
modelsEndpoint: null, // Aliyun coding plan doesn't support /models
|
|
37
|
+
supportsCodingPlanKey: true,
|
|
38
|
+
defaultModel: "glm-5",
|
|
39
|
+
defaultTiers: {
|
|
40
|
+
tier1: "qwen3.6-plus",
|
|
41
|
+
tier2: "",
|
|
42
|
+
tier3: "",
|
|
43
|
+
tier4: "",
|
|
44
|
+
},
|
|
45
|
+
// Curated model list (coding plan doesn't have /models endpoint)
|
|
46
|
+
curatedModels: [
|
|
47
|
+
{ id: "qwen3.6-plus", ownedBy: "qwen" },
|
|
48
|
+
{ id: "qwen3.5-plus", ownedBy: "qwen" },
|
|
49
|
+
{ id: "qwen3-max-2026-01-23", ownedBy: "qwen" },
|
|
50
|
+
{ id: "qwen3-coder-next", ownedBy: "qwen" },
|
|
51
|
+
{ id: "qwen3-coder-plus", ownedBy: "qwen" },
|
|
52
|
+
{ id: "glm-5", ownedBy: "zhipu" },
|
|
53
|
+
{ id: "glm-4.7", ownedBy: "zhipu" },
|
|
54
|
+
{ id: "kimi-k2.5", ownedBy: "kimi" },
|
|
55
|
+
{ id: "MiniMax-M2.5", ownedBy: "minimax" },
|
|
56
|
+
],
|
|
57
|
+
labels: {
|
|
58
|
+
en: "Aliyun Bailian",
|
|
59
|
+
zh: "阿里云百炼",
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: "volcanocloud",
|
|
64
|
+
name: "VolcanoCloud",
|
|
65
|
+
baseUrl: "https://ark.cn-beijing.volces.com/api/v3",
|
|
66
|
+
authType: "bearer",
|
|
67
|
+
apiFormat: "openai",
|
|
68
|
+
modelsEndpoint: null, // VolcanoCloud coding plan — use curated list
|
|
69
|
+
defaultModel: "glm-5",
|
|
70
|
+
defaultTiers: {
|
|
71
|
+
tier1: "doubao-seed-2-0-pro-260215, deepseek-v3-2-251201",
|
|
72
|
+
tier2: "glm-4-7-251222, doubao-1-5-pro-32k-250115",
|
|
73
|
+
tier3: "doubao-seed-2-0-mini-260215",
|
|
74
|
+
tier4: "doubao-seed-2-0-lite-260215, doubao-1-5-lite-32k-250115",
|
|
75
|
+
},
|
|
76
|
+
curatedModels: [
|
|
77
|
+
{ id: "doubao-seed-2-0-pro-260215", ownedBy: "bytedance" },
|
|
78
|
+
{ id: "deepseek-v3-2-251201", ownedBy: "deepseek" },
|
|
79
|
+
{ id: "glm-4-7-251222", ownedBy: "zhipu" },
|
|
80
|
+
{ id: "doubao-1-5-pro-32k-250115", ownedBy: "bytedance" },
|
|
81
|
+
{ id: "doubao-seed-2-0-mini-260215", ownedBy: "bytedance" },
|
|
82
|
+
{ id: "doubao-seed-2-0-lite-260215", ownedBy: "bytedance" },
|
|
83
|
+
{ id: "doubao-1-5-lite-32k-250115", ownedBy: "bytedance" },
|
|
84
|
+
],
|
|
85
|
+
labels: {
|
|
86
|
+
en: "VolcanoCloud (ByteDance)",
|
|
87
|
+
zh: "火山云(字节跳动)",
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
id: "anthropic",
|
|
92
|
+
name: "Anthropic",
|
|
93
|
+
baseUrl: "https://api.anthropic.com",
|
|
94
|
+
authType: "x-api-key",
|
|
95
|
+
apiFormat: "anthropic",
|
|
96
|
+
modelsEndpoint: null, // Use curated list
|
|
97
|
+
defaultModel: "claude-sonnet-4-20250514",
|
|
98
|
+
defaultTiers: {
|
|
99
|
+
tier1: "claude-sonnet-4-20250514",
|
|
100
|
+
tier2: "claude-sonnet-4-20250514",
|
|
101
|
+
tier3: "claude-haiku-4-5-20251001",
|
|
102
|
+
tier4: "claude-haiku-4-5-20251001",
|
|
103
|
+
},
|
|
104
|
+
curatedModels: [
|
|
105
|
+
{ id: "claude-opus-4-20250514", ownedBy: "anthropic" },
|
|
106
|
+
{ id: "claude-sonnet-4-20250514", ownedBy: "anthropic" },
|
|
107
|
+
{ id: "claude-haiku-4-5-20251001", ownedBy: "anthropic" },
|
|
108
|
+
],
|
|
109
|
+
labels: {
|
|
110
|
+
en: "Anthropic",
|
|
111
|
+
zh: "Anthropic",
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
id: "openai",
|
|
116
|
+
name: "OpenAI",
|
|
117
|
+
baseUrl: "https://api.openai.com/v1",
|
|
118
|
+
authType: "bearer",
|
|
119
|
+
apiFormat: "openai",
|
|
120
|
+
modelsEndpoint: "/models",
|
|
121
|
+
defaultModel: "gpt-4o",
|
|
122
|
+
defaultTiers: {
|
|
123
|
+
tier1: "gpt-4o",
|
|
124
|
+
tier2: "gpt-4o-mini",
|
|
125
|
+
tier3: "gpt-4o-mini",
|
|
126
|
+
tier4: "gpt-4o-mini",
|
|
127
|
+
},
|
|
128
|
+
labels: {
|
|
129
|
+
en: "OpenAI",
|
|
130
|
+
zh: "OpenAI",
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: "zhipu",
|
|
135
|
+
name: "Zhipu/GLM",
|
|
136
|
+
baseUrl: "https://open.bigmodel.cn/api/paas/v4",
|
|
137
|
+
authType: "bearer",
|
|
138
|
+
apiFormat: "openai",
|
|
139
|
+
modelsEndpoint: "/models",
|
|
140
|
+
defaultModel: "glm-4-plus",
|
|
141
|
+
defaultTiers: {
|
|
142
|
+
tier1: "glm-4-plus",
|
|
143
|
+
tier2: "glm-4-air",
|
|
144
|
+
tier3: "glm-4-flash",
|
|
145
|
+
tier4: "glm-4-flash",
|
|
146
|
+
},
|
|
147
|
+
labels: {
|
|
148
|
+
en: "Zhipu GLM",
|
|
149
|
+
zh: "智谱 GLM",
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
id: "minimax",
|
|
154
|
+
name: "MiniMax",
|
|
155
|
+
baseUrl: "https://api.minimax.chat/v1",
|
|
156
|
+
authType: "bearer",
|
|
157
|
+
apiFormat: "openai",
|
|
158
|
+
modelsEndpoint: "/models",
|
|
159
|
+
defaultModel: "MiniMax-M2.5",
|
|
160
|
+
defaultTiers: {
|
|
161
|
+
tier1: "MiniMax-M2.5",
|
|
162
|
+
tier2: "MiniMax-M2.5",
|
|
163
|
+
tier3: "MiniMax-M1",
|
|
164
|
+
tier4: "MiniMax-M1",
|
|
165
|
+
},
|
|
166
|
+
labels: {
|
|
167
|
+
en: "MiniMax",
|
|
168
|
+
zh: "MiniMax",
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
id: "openrouter",
|
|
173
|
+
name: "OpenRouter",
|
|
174
|
+
baseUrl: "https://openrouter.ai/api/v1",
|
|
175
|
+
authType: "bearer",
|
|
176
|
+
apiFormat: "openai",
|
|
177
|
+
modelsEndpoint: "/models",
|
|
178
|
+
defaultModel: "anthropic/claude-sonnet-4-20250514",
|
|
179
|
+
defaultTiers: {
|
|
180
|
+
tier1: "anthropic/claude-sonnet-4-20250514",
|
|
181
|
+
tier2: "google/gemini-2.5-flash",
|
|
182
|
+
tier3: "google/gemini-2.5-flash",
|
|
183
|
+
tier4: "google/gemini-2.5-flash",
|
|
184
|
+
},
|
|
185
|
+
labels: {
|
|
186
|
+
en: "OpenRouter",
|
|
187
|
+
zh: "OpenRouter",
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
id: "bedrock",
|
|
192
|
+
name: "Bedrock",
|
|
193
|
+
baseUrl: "",
|
|
194
|
+
authType: "aws-sigv4",
|
|
195
|
+
apiFormat: "anthropic",
|
|
196
|
+
modelsEndpoint: null,
|
|
197
|
+
defaultModel: "anthropic.claude-sonnet-4-20250514-v1:0",
|
|
198
|
+
defaultTiers: {
|
|
199
|
+
tier1: "anthropic.claude-sonnet-4-20250514-v1:0",
|
|
200
|
+
tier2: "anthropic.claude-sonnet-4-20250514-v1:0",
|
|
201
|
+
tier3: "anthropic.claude-haiku-4-5-20251001-v1:0",
|
|
202
|
+
tier4: "anthropic.claude-haiku-4-5-20251001-v1:0",
|
|
203
|
+
},
|
|
204
|
+
labels: {
|
|
205
|
+
en: "AWS Bedrock (not yet supported)",
|
|
206
|
+
zh: "AWS Bedrock(暂未支持)",
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
id: "custom",
|
|
211
|
+
name: "Custom",
|
|
212
|
+
baseUrl: "",
|
|
213
|
+
authType: "bearer",
|
|
214
|
+
apiFormat: "openai",
|
|
215
|
+
modelsEndpoint: "/models",
|
|
216
|
+
defaultModel: "",
|
|
217
|
+
defaultTiers: { tier1: "", tier2: "", tier3: "", tier4: "" },
|
|
218
|
+
labels: {
|
|
219
|
+
en: "Custom (enter base URL)",
|
|
220
|
+
zh: "自定义(输入接口地址)",
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
];
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Known model capability rankings (partial — used to sort discovered models).
|
|
227
|
+
* Pattern-matched against lowercase model ID. Higher = more capable.
|
|
228
|
+
* Aligned with kc_reborn providers.py _MODEL_RANKING.
|
|
229
|
+
*/
|
|
230
|
+
const MODEL_RANKING = {
|
|
231
|
+
// Anthropic
|
|
232
|
+
"claude-opus-4": 100,
|
|
233
|
+
"claude-sonnet-4": 90,
|
|
234
|
+
"claude-haiku-4": 70,
|
|
235
|
+
// OpenAI
|
|
236
|
+
"gpt-4o": 90,
|
|
237
|
+
"gpt-4o-mini": 70,
|
|
238
|
+
"gpt-4-turbo": 85,
|
|
239
|
+
"o1": 95,
|
|
240
|
+
"o3": 95,
|
|
241
|
+
// Qwen (Aliyun Bailian)
|
|
242
|
+
"qwen3.6-plus": 90,
|
|
243
|
+
"qwen3.5-plus": 85,
|
|
244
|
+
"qwen3-max": 88,
|
|
245
|
+
"qwen3-coder-next": 85,
|
|
246
|
+
"qwen3-coder-plus": 80,
|
|
247
|
+
"qwen-plus": 75,
|
|
248
|
+
"qwen-turbo": 60,
|
|
249
|
+
"qwen3.5-397b": 85,
|
|
250
|
+
"qwen3.5-122b": 75,
|
|
251
|
+
"qwen3.5-35b": 65,
|
|
252
|
+
// Zhipu
|
|
253
|
+
"glm-5": 90,
|
|
254
|
+
"glm-4.7": 80,
|
|
255
|
+
"glm-4": 75,
|
|
256
|
+
// Others
|
|
257
|
+
"kimi-k2.5": 85,
|
|
258
|
+
"kimi-k2": 80,
|
|
259
|
+
"minimax-m2": 80,
|
|
260
|
+
"deepseek-v3": 85,
|
|
261
|
+
"deepseek-r1": 90,
|
|
262
|
+
// VolcanoCloud (ByteDance Doubao)
|
|
263
|
+
"doubao-seed-2-0-pro": 90,
|
|
264
|
+
"doubao-seed-2-0-code": 88,
|
|
265
|
+
"doubao-seed-2-0-mini": 75,
|
|
266
|
+
"doubao-seed-2-0-lite": 65,
|
|
267
|
+
"doubao-seed-1-8": 85,
|
|
268
|
+
"doubao-seed-1-6": 80,
|
|
269
|
+
"doubao-1-5-pro": 80,
|
|
270
|
+
"doubao-1-5-lite": 60,
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Estimate model capability rank (0-100) based on known patterns.
|
|
275
|
+
* @param {string} modelId
|
|
276
|
+
* @returns {number}
|
|
277
|
+
*/
|
|
278
|
+
function rankModel(modelId) {
|
|
279
|
+
const lower = modelId.toLowerCase();
|
|
280
|
+
for (const [pattern, rank] of Object.entries(MODEL_RANKING)) {
|
|
281
|
+
if (lower.includes(pattern)) return rank;
|
|
282
|
+
}
|
|
283
|
+
return 50; // Unknown model: assume mid-tier
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Patterns to filter out non-chat models from discovery results.
|
|
288
|
+
*/
|
|
289
|
+
const EXCLUDE_PATTERNS = [
|
|
290
|
+
/embed/i, /tts/i, /whisper/i, /dall-e/i, /audio/i, /image/i,
|
|
291
|
+
/moderation/i, /rerank/i,
|
|
292
|
+
];
|
|
293
|
+
|
|
294
|
+
/** @returns {Array} All provider definitions */
|
|
295
|
+
export function getProviders() {
|
|
296
|
+
return PROVIDERS;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* @param {string} id - Provider ID
|
|
301
|
+
* @returns {object|undefined}
|
|
302
|
+
*/
|
|
303
|
+
export function getProviderById(id) {
|
|
304
|
+
return PROVIDERS.find((p) => p.id === id);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Get display labels for the onboard menu.
|
|
309
|
+
* @param {string} lang - "en" or "zh"
|
|
310
|
+
* @returns {Array<{id: string, label: string}>}
|
|
311
|
+
*/
|
|
312
|
+
export function getProviderLabels(lang) {
|
|
313
|
+
return PROVIDERS.map((p) => ({
|
|
314
|
+
id: p.id,
|
|
315
|
+
label: p.labels[lang] || p.labels.en || p.name,
|
|
316
|
+
}));
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Classify a list of discovered models into tier assignments.
|
|
321
|
+
* Uses the same ranking-based approach as kc_reborn's propose_tiers().
|
|
322
|
+
*
|
|
323
|
+
* @param {Array<{id: string, name?: string}>} models - Models from /models endpoint or curated list
|
|
324
|
+
* @returns {{ conductor: string, tiers: {tier1: string, tier2: string, tier3: string, tier4: string}, unclassified: string[] }}
|
|
325
|
+
*/
|
|
326
|
+
export function classifyModels(models) {
|
|
327
|
+
// Filter out non-chat models
|
|
328
|
+
const chatModels = models.filter((m) => {
|
|
329
|
+
const name = m.id || m.name || "";
|
|
330
|
+
return !EXCLUDE_PATTERNS.some((re) => re.test(name));
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// Rank and sort by capability
|
|
334
|
+
const ranked = [...chatModels].sort((a, b) => rankModel(b.id) - rankModel(a.id));
|
|
335
|
+
|
|
336
|
+
// Select conductor (highest ranked)
|
|
337
|
+
const conductor = ranked[0]?.id || "";
|
|
338
|
+
|
|
339
|
+
// Distribute across tiers by rank
|
|
340
|
+
const tierBuckets = { tier1: [], tier2: [], tier3: [], tier4: [] };
|
|
341
|
+
|
|
342
|
+
for (const m of ranked) {
|
|
343
|
+
const rank = rankModel(m.id);
|
|
344
|
+
if (rank >= 85) tierBuckets.tier1.push(m.id);
|
|
345
|
+
else if (rank >= 70) tierBuckets.tier2.push(m.id);
|
|
346
|
+
else if (rank >= 55) tierBuckets.tier3.push(m.id);
|
|
347
|
+
else tierBuckets.tier4.push(m.id);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const tiers = {
|
|
351
|
+
tier1: tierBuckets.tier1.slice(0, 3).join(", "),
|
|
352
|
+
tier2: tierBuckets.tier2.slice(0, 3).join(", "),
|
|
353
|
+
tier3: tierBuckets.tier3.slice(0, 2).join(", "),
|
|
354
|
+
tier4: tierBuckets.tier4.slice(0, 2).join(", "),
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
const unclassified = ranked.filter((m) => rankModel(m.id) === 50).map((m) => m.id);
|
|
358
|
+
|
|
359
|
+
return { conductor, tiers, unclassified };
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Get curated models for providers that don't support /models endpoint.
|
|
364
|
+
* @param {string} providerId
|
|
365
|
+
* @returns {Array<{id: string, ownedBy: string}>|null}
|
|
366
|
+
*/
|
|
367
|
+
export function getCuratedModels(providerId) {
|
|
368
|
+
const provider = getProviderById(providerId);
|
|
369
|
+
return provider?.curatedModels || null;
|
|
370
|
+
}
|