@mars-sea/dsh-commandcode-provider 0.6.1 → 0.7.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/CHANGELOG.md +27 -0
- package/README.md +59 -135
- package/README.zh-CN.md +58 -136
- package/lib/client.js +154 -23
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +30 -11
- package/lib/index.js +71 -25
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ declare const KNOWN_EFFORTS: Readonly<Record<string, readonly string[]>>;
|
|
|
24
24
|
*/
|
|
25
25
|
declare const KNOWN_IMAGE_MODELS: ReadonlySet<string>;
|
|
26
26
|
/**
|
|
27
|
-
* Models the official CLI's model table (
|
|
27
|
+
* Models the official CLI's model table (command-code@1.32.1) marks
|
|
28
28
|
* `reasoning:!0` but defines no selectable `reasoning_effort` levels — they
|
|
29
29
|
* think automatically, with Command Code driving the depth. This is the
|
|
30
30
|
* authoritative "thinks, effort not adjustable" set: `KNOWN_EFFORTS` (which
|
|
@@ -32,8 +32,10 @@ declare const KNOWN_IMAGE_MODELS: ReadonlySet<string>;
|
|
|
32
32
|
* effort levels, and this snapshot is not surfaced in the picker's compact
|
|
33
33
|
* description — it exists for programmatic consumers.
|
|
34
34
|
*
|
|
35
|
-
* Source: the command-code@1.
|
|
36
|
-
*
|
|
35
|
+
* Source: the command-code@1.32.1 bundled model table (dist/cli.mjs),
|
|
36
|
+
* cross-checked with https://commandcode.ai/docs/reference/cli/models.
|
|
37
|
+
* (`stealth/ox-alpha` left this set in command-code@1.32.1, which gave it
|
|
38
|
+
* selectable `['low', 'high', 'max']` efforts.)
|
|
37
39
|
* Keep in sync via the dsh-commandcode-upstream skill.
|
|
38
40
|
*/
|
|
39
41
|
declare const KNOWN_THINKING_MODELS: ReadonlySet<string>;
|
|
@@ -61,8 +63,9 @@ declare const PLAN_LABELS: Readonly<Record<string, string>>;
|
|
|
61
63
|
*/
|
|
62
64
|
declare const PLAN_ORDER: Readonly<Record<string, number>>;
|
|
63
65
|
/**
|
|
64
|
-
* Comparator for the model picker:
|
|
65
|
-
*
|
|
66
|
+
* Comparator for the model picker: free models first (zero credit cost, usable
|
|
67
|
+
* by every account), then by plan tier (lowest first), then by model name,
|
|
68
|
+
* then by id as a tiebreak. Models with no known plan sort last.
|
|
66
69
|
*/
|
|
67
70
|
declare function compareByPlan(a: {
|
|
68
71
|
id: string;
|
|
@@ -73,7 +76,8 @@ declare function compareByPlan(a: {
|
|
|
73
76
|
}): number;
|
|
74
77
|
/**
|
|
75
78
|
* Subscription plan table, synced from the official CLI bundle's plan maps
|
|
76
|
-
* (`Nn`/`$n` in command-code@1.31.0 `dist/cli.mjs
|
|
79
|
+
* (`Nn`/`$n` in command-code@1.31.0 `dist/cli.mjs`, re-verified unchanged
|
|
80
|
+
* against 1.32.1 where they appear as `Zn`/`er`): subscription `planId`
|
|
77
81
|
* prefix → display name and the plan's monthly credit total. This is the
|
|
78
82
|
* account's own subscription (from `/alpha/billing/subscriptions`) — distinct
|
|
79
83
|
* from {@link KNOWN_PLANS}, which maps catalog models to their minimum tier.
|
|
@@ -150,10 +154,12 @@ declare const KNOWN_DEALS: Readonly<Record<string, KnownDeal>>;
|
|
|
150
154
|
* Models with time-of-day (peak/off-peak) pricing, per the official pricing
|
|
151
155
|
* page (`/docs/resources/pricing-limits`). Since 2026-08-16 16:00 UTC, DeepSeek
|
|
152
156
|
* charges by the hour: peak hours are 01:00–04:00 and 06:00–10:00 UTC (7h/day,
|
|
153
|
-
* full price); the other 17 hours are off-peak at half price. The
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
+
* full price); the other 17 hours are off-peak at half price. The V4 Flash
|
|
158
|
+
* Vision (exp) variant (command-code@1.32.0) shares the V4 Flash windows and
|
|
159
|
+
* peak prices ($0.44/$1.32). The picker shows the *current* state as a compact
|
|
160
|
+
* label (`Peak`/`Half`) matching the English noun style of the other markers
|
|
161
|
+
* (`Image`, `FREE`), so a developer can tell at a glance whether calling the
|
|
162
|
+
* model right now is cheap or expensive.
|
|
157
163
|
*
|
|
158
164
|
* Keep in sync with the official pricing page when the model set or the peak
|
|
159
165
|
* windows change (see the dsh-commandcode-upstream skill).
|
|
@@ -172,7 +178,7 @@ declare function peakPricingState(modelId: string, now?: number): 'peak' | 'off-
|
|
|
172
178
|
* for models without time-of-day pricing.
|
|
173
179
|
*/
|
|
174
180
|
declare function peakPricingLabel(modelId: string, now?: number): string | undefined;
|
|
175
|
-
declare const COMMAND_CODE_CLI_VERSION = "1.
|
|
181
|
+
declare const COMMAND_CODE_CLI_VERSION = "1.32.1";
|
|
176
182
|
declare const DEFAULT_API_BASE = "https://api.commandcode.ai";
|
|
177
183
|
declare const DEFAULT_GENERATE_MAX_TOKENS = 64000;
|
|
178
184
|
declare const DEFAULT_MAX_OUTPUT_TOKENS = 65536;
|
|
@@ -313,6 +319,12 @@ interface CommandCodePlan {
|
|
|
313
319
|
/** Billing period end in millis; 0 when the endpoint did not report one. */
|
|
314
320
|
currentPeriodEnd: number;
|
|
315
321
|
}
|
|
322
|
+
/**
|
|
323
|
+
* Why every account endpoint failed at once (the report then carries no data
|
|
324
|
+
* at all, so the degraded per-endpoint view would hide the root cause behind
|
|
325
|
+
* a generic "partial data" note). Undefined for partial failures.
|
|
326
|
+
*/
|
|
327
|
+
type UsageBlockReason = 'invalid-key' | 'service-unavailable' | 'network';
|
|
316
328
|
/** Everything the usage endpoints report, fetched together. */
|
|
317
329
|
interface CommandCodeUsageReport {
|
|
318
330
|
account?: CommandCodeAccount;
|
|
@@ -321,6 +333,13 @@ interface CommandCodeUsageReport {
|
|
|
321
333
|
plan?: CommandCodePlan;
|
|
322
334
|
/** Endpoint failures degrade the report instead of failing it. */
|
|
323
335
|
failures: string[];
|
|
336
|
+
/**
|
|
337
|
+
* The single reason every endpoint failed, when they all did: `invalid-key`
|
|
338
|
+
* (every call rejected with 401 — the stored key is wrong or expired),
|
|
339
|
+
* `service-unavailable` (every call answered 5xx), or `network` (no HTTP
|
|
340
|
+
* response at all). Undefined when any endpoint succeeded.
|
|
341
|
+
*/
|
|
342
|
+
blocked?: UsageBlockReason;
|
|
324
343
|
}
|
|
325
344
|
declare class CommandCodeAdapter<C extends CommandCodeConnectionOptions = CommandCodeConnectionOptions> extends LlmAdapter {
|
|
326
345
|
private readonly deps;
|
package/lib/index.js
CHANGED
|
@@ -160,11 +160,11 @@ var CommandCodeAccountPool = class {
|
|
|
160
160
|
const revived = selectActiveAccount(await this.resolvedAccounts(), this.deps.preferredId?.());
|
|
161
161
|
if (revived !== void 0) return this.pick(revived);
|
|
162
162
|
const latest = await this.resolvedAccounts();
|
|
163
|
-
if (latest.filter((account) => account.state?.kind === "disabled").length === latest.length) throw new LlmError(`llm-commandcode: every configured Command Code account (${latest.length}) was rejected with 401 — check the stored API keys (Models page / settings) or the auth file`, "INVALID_CREDENTIAL");
|
|
163
|
+
if (latest.filter((account) => account.state?.kind === "disabled").length === latest.length) throw new LlmError(`llm-commandcode: every configured Command Code account (${latest.length}) was rejected with 401 — check the stored API keys (Models page / settings) or the auth file;已配置的 ${latest.length} 个 Command Code 账户密钥均被拒绝(401)——请在设置页检查存储的 API 密钥,或重新运行 command-code login`, "INVALID_CREDENTIAL");
|
|
164
164
|
const resets = latest.map((account) => account.state).filter((state) => state !== void 0 && state.kind === "cooldown" && state.until > 0).map((state) => state.until);
|
|
165
165
|
const earliest = resets.length > 0 ? Math.min(...resets) : 0;
|
|
166
166
|
const wait = earliest > 0 ? Math.max(1e3, earliest - Date.now()) : 0;
|
|
167
|
-
throw new LlmError(`llm-commandcode: all ${latest.length} Command Code account(s) have exhausted their usage window` + (earliest > 0 ? `; the earliest window resets at ${clockLabel(earliest)}` : "") +
|
|
167
|
+
throw new LlmError(`llm-commandcode: all ${latest.length} Command Code account(s) have exhausted their usage window` + (earliest > 0 ? `; the earliest window resets at ${clockLabel(earliest)}` : "") + ` — requests will succeed again after the reset (or add another account);已用尽全部 ${latest.length} 个 Command Code 账户的用量窗口` + (earliest > 0 ? `,最早的重置时间为 ${clockLabel(earliest)}` : "") + "——窗口重置后请求会自动恢复(也可以添加更多账户)", "RATE_LIMIT", wait > 0 && wait <= 9e5 ? { providerRetryAfterMs: wait } : void 0);
|
|
168
168
|
}
|
|
169
169
|
/**
|
|
170
170
|
* Record a rejection against one key. `rate-limit` (429) marks the key
|
|
@@ -214,7 +214,7 @@ var CommandCodeAccountPool = class {
|
|
|
214
214
|
* and API key or subscription, and Command Code's terms apply.
|
|
215
215
|
*
|
|
216
216
|
* Wire protocol (reverse-engineered by the pi plugin, command-code@1.28.4;
|
|
217
|
-
* re-verified against command-code@1.
|
|
217
|
+
* re-verified against command-code@1.32.1 — endpoints, request shape, and
|
|
218
218
|
* stream events unchanged):
|
|
219
219
|
* POST {apiBase}/alpha/generate
|
|
220
220
|
* body: { config, memory, taste, skills, params: { model, messages, tools,
|
|
@@ -281,6 +281,7 @@ const KNOWN_EFFORTS = {
|
|
|
281
281
|
"max"
|
|
282
282
|
],
|
|
283
283
|
"deepseek/deepseek-v4-flash": ["high", "max"],
|
|
284
|
+
"deepseek/deepseek-v4-flash-vision-exp": ["high", "max"],
|
|
284
285
|
"deepseek/deepseek-v4-pro": ["high", "max"],
|
|
285
286
|
"google/gemini-3.1-flash-lite": [
|
|
286
287
|
"low",
|
|
@@ -352,6 +353,11 @@ const KNOWN_EFFORTS = {
|
|
|
352
353
|
"max"
|
|
353
354
|
],
|
|
354
355
|
"sakana/fugu-ultra": ["high", "xhigh"],
|
|
356
|
+
"stealth/ox-alpha": [
|
|
357
|
+
"low",
|
|
358
|
+
"high",
|
|
359
|
+
"max"
|
|
360
|
+
],
|
|
355
361
|
"xai/grok-4.5": [
|
|
356
362
|
"low",
|
|
357
363
|
"medium",
|
|
@@ -399,6 +405,7 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
|
|
|
399
405
|
"claude-opus-5",
|
|
400
406
|
"claude-sonnet-4-6",
|
|
401
407
|
"claude-sonnet-5",
|
|
408
|
+
"deepseek/deepseek-v4-flash-vision-exp",
|
|
402
409
|
"google/gemini-3.1-flash-lite",
|
|
403
410
|
"google/gemini-3.5-flash",
|
|
404
411
|
"google/gemini-3.5-flash-lite",
|
|
@@ -428,7 +435,7 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
|
|
|
428
435
|
"xiaomi/mimo-v2.5"
|
|
429
436
|
]);
|
|
430
437
|
/**
|
|
431
|
-
* Models the official CLI's model table (
|
|
438
|
+
* Models the official CLI's model table (command-code@1.32.1) marks
|
|
432
439
|
* `reasoning:!0` but defines no selectable `reasoning_effort` levels — they
|
|
433
440
|
* think automatically, with Command Code driving the depth. This is the
|
|
434
441
|
* authoritative "thinks, effort not adjustable" set: `KNOWN_EFFORTS` (which
|
|
@@ -436,8 +443,10 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
|
|
|
436
443
|
* effort levels, and this snapshot is not surfaced in the picker's compact
|
|
437
444
|
* description — it exists for programmatic consumers.
|
|
438
445
|
*
|
|
439
|
-
* Source: the command-code@1.
|
|
440
|
-
*
|
|
446
|
+
* Source: the command-code@1.32.1 bundled model table (dist/cli.mjs),
|
|
447
|
+
* cross-checked with https://commandcode.ai/docs/reference/cli/models.
|
|
448
|
+
* (`stealth/ox-alpha` left this set in command-code@1.32.1, which gave it
|
|
449
|
+
* selectable `['low', 'high', 'max']` efforts.)
|
|
441
450
|
* Keep in sync via the dsh-commandcode-upstream skill.
|
|
442
451
|
*/
|
|
443
452
|
const KNOWN_THINKING_MODELS = /* @__PURE__ */ new Set([
|
|
@@ -459,8 +468,7 @@ const KNOWN_THINKING_MODELS = /* @__PURE__ */ new Set([
|
|
|
459
468
|
"poolside/laguna-s-2.1-free",
|
|
460
469
|
"meta/muse-spark-1.1",
|
|
461
470
|
"meta/muse-spark-1.2",
|
|
462
|
-
"meta/muse-spark-1.2-contributor"
|
|
463
|
-
"stealth/ox-alpha"
|
|
471
|
+
"meta/muse-spark-1.2-contributor"
|
|
464
472
|
]);
|
|
465
473
|
/**
|
|
466
474
|
* The minimum subscription plan a model is included in, per the official plan
|
|
@@ -489,6 +497,7 @@ const KNOWN_PLANS = {
|
|
|
489
497
|
"Qwen/Qwen3.8-27B": "go",
|
|
490
498
|
"Qwen/Qwen3.8-Max": "go",
|
|
491
499
|
"deepseek/deepseek-v4-flash": "go",
|
|
500
|
+
"deepseek/deepseek-v4-flash-vision-exp": "go",
|
|
492
501
|
"deepseek/deepseek-v4-pro": "go",
|
|
493
502
|
"gpt-5.6-luna": "go",
|
|
494
503
|
"meta/muse-spark-1.2-contributor": "go",
|
|
@@ -556,10 +565,22 @@ const PLAN_ORDER = {
|
|
|
556
565
|
max: 4
|
|
557
566
|
};
|
|
558
567
|
/**
|
|
559
|
-
*
|
|
560
|
-
*
|
|
568
|
+
* Whether a model is free (requests cost no credits), per the pricing page's
|
|
569
|
+
* deals (`KNOWN_DEALS` `free: true`). Free models lead the picker regardless
|
|
570
|
+
* of tier — they are usable by every account, so they are the best default
|
|
571
|
+
* candidates.
|
|
572
|
+
*/
|
|
573
|
+
function isFreeModel(modelId) {
|
|
574
|
+
return KNOWN_DEALS[modelId]?.free === true;
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Comparator for the model picker: free models first (zero credit cost, usable
|
|
578
|
+
* by every account), then by plan tier (lowest first), then by model name,
|
|
579
|
+
* then by id as a tiebreak. Models with no known plan sort last.
|
|
561
580
|
*/
|
|
562
581
|
function compareByPlan(a, b) {
|
|
582
|
+
const freeDelta = Number(isFreeModel(b.id)) - Number(isFreeModel(a.id));
|
|
583
|
+
if (freeDelta !== 0) return freeDelta;
|
|
563
584
|
const pa = PLAN_ORDER[KNOWN_PLANS[a.id] ?? ""] ?? Number.MAX_SAFE_INTEGER;
|
|
564
585
|
const pb = PLAN_ORDER[KNOWN_PLANS[b.id] ?? ""] ?? Number.MAX_SAFE_INTEGER;
|
|
565
586
|
if (pa !== pb) return pa - pb;
|
|
@@ -569,7 +590,8 @@ function compareByPlan(a, b) {
|
|
|
569
590
|
}
|
|
570
591
|
/**
|
|
571
592
|
* Subscription plan table, synced from the official CLI bundle's plan maps
|
|
572
|
-
* (`Nn`/`$n` in command-code@1.31.0 `dist/cli.mjs
|
|
593
|
+
* (`Nn`/`$n` in command-code@1.31.0 `dist/cli.mjs`, re-verified unchanged
|
|
594
|
+
* against 1.32.1 where they appear as `Zn`/`er`): subscription `planId`
|
|
573
595
|
* prefix → display name and the plan's monthly credit total. This is the
|
|
574
596
|
* account's own subscription (from `/alpha/billing/subscriptions`) — distinct
|
|
575
597
|
* from {@link KNOWN_PLANS}, which maps catalog models to their minimum tier.
|
|
@@ -671,15 +693,21 @@ const KNOWN_DEALS = {
|
|
|
671
693
|
* Models with time-of-day (peak/off-peak) pricing, per the official pricing
|
|
672
694
|
* page (`/docs/resources/pricing-limits`). Since 2026-08-16 16:00 UTC, DeepSeek
|
|
673
695
|
* charges by the hour: peak hours are 01:00–04:00 and 06:00–10:00 UTC (7h/day,
|
|
674
|
-
* full price); the other 17 hours are off-peak at half price. The
|
|
675
|
-
*
|
|
676
|
-
*
|
|
677
|
-
*
|
|
696
|
+
* full price); the other 17 hours are off-peak at half price. The V4 Flash
|
|
697
|
+
* Vision (exp) variant (command-code@1.32.0) shares the V4 Flash windows and
|
|
698
|
+
* peak prices ($0.44/$1.32). The picker shows the *current* state as a compact
|
|
699
|
+
* label (`Peak`/`Half`) matching the English noun style of the other markers
|
|
700
|
+
* (`Image`, `FREE`), so a developer can tell at a glance whether calling the
|
|
701
|
+
* model right now is cheap or expensive.
|
|
678
702
|
*
|
|
679
703
|
* Keep in sync with the official pricing page when the model set or the peak
|
|
680
704
|
* windows change (see the dsh-commandcode-upstream skill).
|
|
681
705
|
*/
|
|
682
|
-
const KNOWN_PEAK_PRICING = /* @__PURE__ */ new Set([
|
|
706
|
+
const KNOWN_PEAK_PRICING = /* @__PURE__ */ new Set([
|
|
707
|
+
"deepseek/deepseek-v4-pro",
|
|
708
|
+
"deepseek/deepseek-v4-flash",
|
|
709
|
+
"deepseek/deepseek-v4-flash-vision-exp"
|
|
710
|
+
]);
|
|
683
711
|
/** Peak hours (UTC, hour-of-day range end-exclusive): 01–03 and 06–09. */
|
|
684
712
|
const PEAK_HOUR_RANGES = [[1, 4], [6, 10]];
|
|
685
713
|
/**
|
|
@@ -703,7 +731,7 @@ function peakPricingLabel(modelId, now = Date.now()) {
|
|
|
703
731
|
if (state === void 0) return void 0;
|
|
704
732
|
return state === "peak" ? "Peak" : "Half";
|
|
705
733
|
}
|
|
706
|
-
const COMMAND_CODE_CLI_VERSION = "1.
|
|
734
|
+
const COMMAND_CODE_CLI_VERSION = "1.32.1";
|
|
707
735
|
const DEFAULT_API_BASE = "https://api.commandcode.ai";
|
|
708
736
|
const DEFAULT_GENERATE_MAX_TOKENS = 64e3;
|
|
709
737
|
const DEFAULT_MAX_OUTPUT_TOKENS = 65536;
|
|
@@ -1009,6 +1037,8 @@ async function messagesToCC(messages, readImage) {
|
|
|
1009
1037
|
}
|
|
1010
1038
|
return out;
|
|
1011
1039
|
}
|
|
1040
|
+
/** Account endpoints fetched by one `getUsage()` run (see the classification there). */
|
|
1041
|
+
const USAGE_ENDPOINT_COUNT = 4;
|
|
1012
1042
|
var CommandCodeAdapter = class extends LlmAdapter {
|
|
1013
1043
|
deps;
|
|
1014
1044
|
catalog = [];
|
|
@@ -1206,6 +1236,7 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
1206
1236
|
const base = this.deps.options().apiBase;
|
|
1207
1237
|
const headers = await this.accountHeaders(apiKey);
|
|
1208
1238
|
const failures = [];
|
|
1239
|
+
const failedStatuses = [];
|
|
1209
1240
|
const getJson = async (path) => {
|
|
1210
1241
|
try {
|
|
1211
1242
|
const response = await this.fetchImpl(`${base}${path}`, {
|
|
@@ -1214,12 +1245,14 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
1214
1245
|
});
|
|
1215
1246
|
if (!response.ok) {
|
|
1216
1247
|
failures.push(`${path}: HTTP ${response.status}`);
|
|
1248
|
+
failedStatuses.push(response.status);
|
|
1217
1249
|
return;
|
|
1218
1250
|
}
|
|
1219
1251
|
const parsed = await response.json();
|
|
1220
1252
|
return isRecord(parsed) ? parsed : void 0;
|
|
1221
1253
|
} catch (error) {
|
|
1222
1254
|
failures.push(`${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1255
|
+
failedStatuses.push(void 0);
|
|
1223
1256
|
return;
|
|
1224
1257
|
}
|
|
1225
1258
|
};
|
|
@@ -1280,6 +1313,12 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
1280
1313
|
currentPeriodEnd: periodEndValue(subData?.currentPeriodEnd)
|
|
1281
1314
|
};
|
|
1282
1315
|
}
|
|
1316
|
+
if (failures.length === USAGE_ENDPOINT_COUNT) {
|
|
1317
|
+
const codes = failedStatuses.filter((status) => status !== void 0);
|
|
1318
|
+
if (codes.length === USAGE_ENDPOINT_COUNT && codes.every((code) => code === 401)) report.blocked = "invalid-key";
|
|
1319
|
+
else if (codes.length === USAGE_ENDPOINT_COUNT && codes.every((code) => code >= 500)) report.blocked = "service-unavailable";
|
|
1320
|
+
else if (codes.length === 0) report.blocked = "network";
|
|
1321
|
+
}
|
|
1283
1322
|
return report;
|
|
1284
1323
|
}
|
|
1285
1324
|
/**
|
|
@@ -1400,8 +1439,8 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
1400
1439
|
} catch (error) {
|
|
1401
1440
|
cleanup();
|
|
1402
1441
|
if (options.signal?.aborted) throw error;
|
|
1403
|
-
if (connectTimedOut || error instanceof DOMException && error.name === "TimeoutError") throw new LlmError(`Command Code API request to ${connection.apiBase}/alpha/generate did not respond within ${connection.requestTimeoutMs}ms: ${errorChain(error)}
|
|
1404
|
-
throw new LlmError(`Command Code API request to ${connection.apiBase}/alpha/generate failed: ${errorChain(error)}
|
|
1442
|
+
if (connectTimedOut || error instanceof DOMException && error.name === "TimeoutError") throw new LlmError(`Command Code API request to ${connection.apiBase}/alpha/generate did not respond within ${connection.requestTimeoutMs}ms: ${errorChain(error)};Command Code API 请求在 ${connection.requestTimeoutMs} 毫秒内未收到响应——通常是网络或代理问题,请检查后重试`, "TIMEOUT", { cause: error });
|
|
1443
|
+
throw new LlmError(`Command Code API request to ${connection.apiBase}/alpha/generate failed: ${errorChain(error)};Command Code API 请求连接失败——通常是网络或代理问题,请检查网络或代理设置后重试`, "TRANSPORT", { cause: error });
|
|
1405
1444
|
}
|
|
1406
1445
|
if (!response.ok) {
|
|
1407
1446
|
const errText = await response.text().catch(() => "");
|
|
@@ -1620,13 +1659,13 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
1620
1659
|
read = await reader.read();
|
|
1621
1660
|
} catch (error) {
|
|
1622
1661
|
if (options.signal?.aborted) throw error;
|
|
1623
|
-
throw new LlmError(`Command Code API stream from ${connection.apiBase} failed while reading: ${errorChain(error)}
|
|
1662
|
+
throw new LlmError(`Command Code API stream from ${connection.apiBase} failed while reading: ${errorChain(error)};Command Code API 流式响应中途断开——网络波动所致,重试通常可恢复`, "TRANSPORT", { cause: error });
|
|
1624
1663
|
} finally {
|
|
1625
1664
|
clearIdle();
|
|
1626
1665
|
}
|
|
1627
1666
|
const { done, value } = read;
|
|
1628
1667
|
if (done) {
|
|
1629
|
-
if (idleFired) throw new LlmError(`Command Code API stream from ${connection.apiBase} was idle for ${connection.streamIdleTimeoutMs}ms (no events) and was treated as a dead connection
|
|
1668
|
+
if (idleFired) throw new LlmError(`Command Code API stream from ${connection.apiBase} was idle for ${connection.streamIdleTimeoutMs}ms (no events) and was treated as a dead connection;Command Code API 流式响应已 ${connection.streamIdleTimeoutMs} 毫秒无任何事件,被判定为死连接——长思考模型可在设置中调大流空闲超时`, "TIMEOUT");
|
|
1630
1669
|
if (buffer.trim()) for (const chunk of handleEvent(parseStreamEventLine(buffer))) yield chunk;
|
|
1631
1670
|
break;
|
|
1632
1671
|
}
|
|
@@ -1645,7 +1684,7 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
1645
1684
|
if (!finished) {
|
|
1646
1685
|
yield* closeText();
|
|
1647
1686
|
yield* closeReasoning();
|
|
1648
|
-
if (!sawContent) throw new LlmError("Command Code returned an empty response", "EMPTY_RESPONSE");
|
|
1687
|
+
if (!sawContent) throw new LlmError("Command Code returned an empty response;Command Code 返回了空响应,重试通常可恢复", "EMPTY_RESPONSE");
|
|
1649
1688
|
yield {
|
|
1650
1689
|
type: "finish",
|
|
1651
1690
|
reason: { kind: "stop" }
|
|
@@ -1678,7 +1717,7 @@ function generateHttpError(status, errText, retryAfterMs) {
|
|
|
1678
1717
|
if (isRecord(parsed) && isRecord(parsed.error)) providerCode = stringValue(parsed.error.code);
|
|
1679
1718
|
} catch {}
|
|
1680
1719
|
const detail = providerCode ?? `HTTP ${status}`;
|
|
1681
|
-
if (status === 401) return new LlmError(`Command Code API error 401 (${detail}): the API key is missing or invalid — check the key stored for COMMANDCODE_API_KEY (Models page) or the auth file
|
|
1720
|
+
if (status === 401) return new LlmError(`Command Code API error 401 (${detail}): the API key is missing or invalid — check the key stored for COMMANDCODE_API_KEY (Models page) or the auth file;Command Code API 返回 401:API 密钥缺失或无效——请在设置页检查 COMMANDCODE_API_KEY 存储的密钥,或检查 auth 文件`, "INVALID_CREDENTIAL", { status: 401 });
|
|
1682
1721
|
return new LlmError(`Command Code API error ${status}${detail === `HTTP ${status}` ? "" : ` (${detail})`}: ${errText.slice(0, 500)}`, status === 429 ? "RATE_LIMIT" : "PROVIDER_HTTP_ERROR", {
|
|
1683
1722
|
status,
|
|
1684
1723
|
...retryAfterMs !== void 0 && retryAfterMs > 0 && retryAfterMs <= 9e5 ? { providerRetryAfterMs: retryAfterMs } : {}
|
|
@@ -1719,8 +1758,7 @@ function money(value) {
|
|
|
1719
1758
|
function moneyShort(value) {
|
|
1720
1759
|
return `$${value.toFixed(2)}`;
|
|
1721
1760
|
}
|
|
1722
|
-
/** Format a token count
|
|
1723
|
-
/** Format a large token count compactly (1.9亿 style). */
|
|
1761
|
+
/** Format a large token count compactly (1.9M style). */
|
|
1724
1762
|
function tokensCompact(value) {
|
|
1725
1763
|
if (value >= 1e9) return `${(value / 1e9).toFixed(1)}B`;
|
|
1726
1764
|
if (value >= 1e6) return `${(value / 1e6).toFixed(1)}M`;
|
|
@@ -1754,6 +1792,9 @@ function renderReport(report, title) {
|
|
|
1754
1792
|
const lines = [];
|
|
1755
1793
|
const account = report.account ? ` (${report.account.userName || report.account.name})` : "";
|
|
1756
1794
|
lines.push(title ?? `📊 Command Code 用量${account}`, "");
|
|
1795
|
+
if (report.blocked === "invalid-key") lines.push("⛔ API 密钥无效或已过期 — 服务端拒绝了全部请求(401),请检查该账户的密钥配置", "");
|
|
1796
|
+
else if (report.blocked === "service-unavailable") lines.push("⚠️ Command Code 服务暂时不可用(5xx),稍后重试", "");
|
|
1797
|
+
else if (report.blocked === "network") lines.push("⚠️ 无法连接 Command Code 服务 — 请检查网络或 API 地址", "");
|
|
1757
1798
|
if (report.plan && report.plan.name !== "") {
|
|
1758
1799
|
const p = report.plan;
|
|
1759
1800
|
const status = p.status !== "" && p.status !== "active" ? ` (${p.status})` : "";
|
|
@@ -1864,6 +1905,11 @@ function parseUsageReport(value) {
|
|
|
1864
1905
|
const failures = source.failures;
|
|
1865
1906
|
if (!Array.isArray(failures) || failures.some((entry) => typeof entry !== "string")) reject("failures");
|
|
1866
1907
|
const report = { failures };
|
|
1908
|
+
if (source.blocked !== void 0) {
|
|
1909
|
+
const blocked = source.blocked;
|
|
1910
|
+
if (blocked !== "invalid-key" && blocked !== "service-unavailable" && blocked !== "network") reject("blocked");
|
|
1911
|
+
report.blocked = blocked;
|
|
1912
|
+
}
|
|
1867
1913
|
if (source.account !== void 0) {
|
|
1868
1914
|
const account = record(source.account, "account");
|
|
1869
1915
|
report.account = {
|