@mars-sea/dsh-commandcode-provider 0.8.4 → 0.10.0-alpha.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/CHANGELOG.md +39 -0
- package/README.md +24 -4
- package/README.zh-CN.md +24 -4
- package/lib/client.js +699 -111
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +43 -4
- package/lib/index.js +146 -40
- package/lib/index.js.map +1 -1
- package/package.json +38 -39
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 (command-code@1.
|
|
27
|
+
* Models the official CLI's model table (command-code@1.37.0) 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,11 +32,13 @@ 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.
|
|
35
|
+
* Source: the command-code@1.37.0 bundled model table (dist/cli.mjs),
|
|
36
36
|
* cross-checked with https://commandcode.ai/docs/reference/cli/models.
|
|
37
37
|
* (`stealth/ox-alpha` left this set in command-code@1.32.1, which gave it
|
|
38
38
|
* selectable `['low', 'high', 'max']` efforts; the preview then ended in
|
|
39
|
-
* 1.34.0, removing the model from the catalog entirely.
|
|
39
|
+
* 1.34.0, removing the model from the catalog entirely. `tencent/hy4-preview`
|
|
40
|
+
* joined this set in command-code@1.37.0 — reasoning:!0, no efforts, 1M
|
|
41
|
+
* context, routed through OpenRouter.)
|
|
40
42
|
* Keep in sync via the dsh-commandcode-upstream skill.
|
|
41
43
|
*/
|
|
42
44
|
declare const KNOWN_THINKING_MODELS: ReadonlySet<string>;
|
|
@@ -187,7 +189,7 @@ declare function peakPricingState(modelId: string, now?: number): 'peak' | 'off-
|
|
|
187
189
|
* for models without time-of-day pricing.
|
|
188
190
|
*/
|
|
189
191
|
declare function peakPricingLabel(modelId: string, now?: number): string | undefined;
|
|
190
|
-
declare const COMMAND_CODE_CLI_VERSION = "1.
|
|
192
|
+
declare const COMMAND_CODE_CLI_VERSION = "1.37.0";
|
|
191
193
|
declare const DEFAULT_API_BASE = "https://api.commandcode.ai";
|
|
192
194
|
declare const DEFAULT_GENERATE_MAX_TOKENS = 64000;
|
|
193
195
|
declare const DEFAULT_MAX_OUTPUT_TOKENS = 65536;
|
|
@@ -600,6 +602,23 @@ declare const USAGE_REPORT_ENDPOINT = "commandcode/report";
|
|
|
600
602
|
*/
|
|
601
603
|
declare const usageReportSchema: TypertSchema<CommandCodeAccountsReport>;
|
|
602
604
|
//#endregion
|
|
605
|
+
//#region src/command-locales.d.ts
|
|
606
|
+
/**
|
|
607
|
+
* Locale copy for the `/commandcode` usage command and the friendly
|
|
608
|
+
* image-gate error rewrite. Distinct from `./client/locales.ts` (the
|
|
609
|
+
* settings-page namespace `settings.commandcode`): the command runs on the
|
|
610
|
+
* Host and has no access to the client's `ctx.locale`, so the dictionaries
|
|
611
|
+
* are exposed as plain constants for direct lookup; the resolver lives in
|
|
612
|
+
* `pickCommandLocale()`. The image-gate wrapper also lives on the client
|
|
613
|
+
* but is reached from a non-React path that has no `t` in scope, so the
|
|
614
|
+
* same dictionaries serve both surfaces.
|
|
615
|
+
*
|
|
616
|
+
* zh is the source of truth for the key set; en must carry the exact same
|
|
617
|
+
* keys — a mismatch is a compile error at the lookup site.
|
|
618
|
+
*/
|
|
619
|
+
/** Active locale id recognized by the command and the image-gate wrapper. */
|
|
620
|
+
type LocaleId = 'zh' | 'en';
|
|
621
|
+
//#endregion
|
|
603
622
|
//#region src/commands.d.ts
|
|
604
623
|
/** Everything the command needs beyond the adapter itself. */
|
|
605
624
|
interface CommandCodeCommandDeps<C extends CommandCodeConnectionOptions = CommandCodeConnectionOptions> {
|
|
@@ -611,6 +630,14 @@ interface CommandCodeCommandDeps<C extends CommandCodeConnectionOptions = Comman
|
|
|
611
630
|
* `adapter.getUsage()` report.
|
|
612
631
|
*/
|
|
613
632
|
reports?: () => Promise<CommandCodeAccountsReport>;
|
|
633
|
+
/**
|
|
634
|
+
* Resolve the active locale for one command run. The plugin entry wires
|
|
635
|
+
* this from `Config.lang` and the shell's `LC_ALL`/`LANG`. Absent in
|
|
636
|
+
* programmatic setups (notably the existing test), the command renders
|
|
637
|
+
* with the default locale (`'zh'`) — historically the only language the
|
|
638
|
+
* command ever shipped in.
|
|
639
|
+
*/
|
|
640
|
+
getLocale?: () => LocaleId;
|
|
614
641
|
}
|
|
615
642
|
/** The one registered `/commandcode` command. */
|
|
616
643
|
declare function commandDefinition<C extends CommandCodeConnectionOptions>(deps: CommandCodeCommandDeps<C>): CommandDefinition;
|
|
@@ -906,6 +933,18 @@ interface Config {
|
|
|
906
933
|
* rotation still applies). Unset means "first usable account".
|
|
907
934
|
*/
|
|
908
935
|
activeAccount?: string;
|
|
936
|
+
/**
|
|
937
|
+
* Language override for the `/commandcode` Host-side command's user-facing
|
|
938
|
+
* copy. Host commands cannot read the client's `ctx.locale`, so this is
|
|
939
|
+
* the explicit knob: `'zh'` or `'en'`. Unset means the command reads
|
|
940
|
+
* `LC_ALL`/`LANG` from the launching shell, falling back to `'zh'`. The
|
|
941
|
+
* web settings page is unaffected — it follows the browser's language
|
|
942
|
+
* preference on its own. Two surfaces, two independent locales. The
|
|
943
|
+
* declared type is `string` (the schemastery `pattern` cannot narrow
|
|
944
|
+
* literal types); an unknown value is treated as "unset" by
|
|
945
|
+
* `pickCommandLocale`.
|
|
946
|
+
*/
|
|
947
|
+
lang?: string;
|
|
909
948
|
}
|
|
910
949
|
declare const Config: z<Config>;
|
|
911
950
|
/** One resolution's complete request facts: connection plus credential reference. */
|
package/lib/index.js
CHANGED
|
@@ -2,10 +2,9 @@ import { homedir } from "node:os";
|
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import z from "@deepseek-ai/schemastery";
|
|
4
4
|
import { MAX_TIMER_DELAY_MS } from "@deepseek-ai/dsh-timeout";
|
|
5
|
-
import {
|
|
5
|
+
import { LlmAdapter, LlmError, ReasoningEffortId, ToolCallId, assertUsableApiKey, attributionHeaders, errorChain, resolveRetryPolicy } from "@deepseek-ai/dsh-llm";
|
|
6
6
|
import { credentialRef } from "@deepseek-ai/dsh-credentials";
|
|
7
7
|
import { launchEnvironmentOf } from "@deepseek-ai/dsh-launch-environment";
|
|
8
|
-
import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
|
|
9
8
|
import { existsSync, readFileSync } from "node:fs";
|
|
10
9
|
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
11
10
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
@@ -216,7 +215,7 @@ var CommandCodeAccountPool = class {
|
|
|
216
215
|
* and API key or subscription, and Command Code's terms apply.
|
|
217
216
|
*
|
|
218
217
|
* Wire protocol (reverse-engineered by the pi plugin, command-code@1.28.4;
|
|
219
|
-
* re-verified against command-code@1.
|
|
218
|
+
* re-verified against command-code@1.37.0 — endpoints, request shape, and
|
|
220
219
|
* stream events unchanged):
|
|
221
220
|
* POST {apiBase}/alpha/generate
|
|
222
221
|
* body: { config, memory, taste, skills, params: { model, messages, tools,
|
|
@@ -444,7 +443,7 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
|
|
|
444
443
|
"z-ai/glm-5.3-flash"
|
|
445
444
|
]);
|
|
446
445
|
/**
|
|
447
|
-
* Models the official CLI's model table (command-code@1.
|
|
446
|
+
* Models the official CLI's model table (command-code@1.37.0) marks
|
|
448
447
|
* `reasoning:!0` but defines no selectable `reasoning_effort` levels — they
|
|
449
448
|
* think automatically, with Command Code driving the depth. This is the
|
|
450
449
|
* authoritative "thinks, effort not adjustable" set: `KNOWN_EFFORTS` (which
|
|
@@ -452,11 +451,13 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
|
|
|
452
451
|
* effort levels, and this snapshot is not surfaced in the picker's compact
|
|
453
452
|
* description — it exists for programmatic consumers.
|
|
454
453
|
*
|
|
455
|
-
* Source: the command-code@1.
|
|
454
|
+
* Source: the command-code@1.37.0 bundled model table (dist/cli.mjs),
|
|
456
455
|
* cross-checked with https://commandcode.ai/docs/reference/cli/models.
|
|
457
456
|
* (`stealth/ox-alpha` left this set in command-code@1.32.1, which gave it
|
|
458
457
|
* selectable `['low', 'high', 'max']` efforts; the preview then ended in
|
|
459
|
-
* 1.34.0, removing the model from the catalog entirely.
|
|
458
|
+
* 1.34.0, removing the model from the catalog entirely. `tencent/hy4-preview`
|
|
459
|
+
* joined this set in command-code@1.37.0 — reasoning:!0, no efforts, 1M
|
|
460
|
+
* context, routed through OpenRouter.)
|
|
460
461
|
* Keep in sync via the dsh-commandcode-upstream skill.
|
|
461
462
|
*/
|
|
462
463
|
const KNOWN_THINKING_MODELS = /* @__PURE__ */ new Set([
|
|
@@ -473,6 +474,7 @@ const KNOWN_THINKING_MODELS = /* @__PURE__ */ new Set([
|
|
|
473
474
|
"stepfun/Step-3.5-Flash",
|
|
474
475
|
"stepfun/Step-3.7-Flash",
|
|
475
476
|
"tencent/hy3-paid",
|
|
477
|
+
"tencent/hy4-preview",
|
|
476
478
|
"nvidia/nemotron-3-ultra-550b-a55b",
|
|
477
479
|
"thinkingmachines/inkling",
|
|
478
480
|
"thinkingmachines/inkling-small",
|
|
@@ -525,6 +527,7 @@ const KNOWN_PLANS = {
|
|
|
525
527
|
"stepfun/Step-3.5-Flash": "go",
|
|
526
528
|
"stepfun/Step-3.7-Flash": "go",
|
|
527
529
|
"tencent/hy3-paid": "go",
|
|
530
|
+
"tencent/hy4-preview": "go",
|
|
528
531
|
"thinkingmachines/inkling": "go",
|
|
529
532
|
"thinkingmachines/inkling-small": "go",
|
|
530
533
|
"xai/grok-4.5": "go",
|
|
@@ -759,7 +762,7 @@ function peakPricingLabel(modelId, now = Date.now()) {
|
|
|
759
762
|
if (state === void 0) return void 0;
|
|
760
763
|
return state === "peak" ? "Peak" : "Half";
|
|
761
764
|
}
|
|
762
|
-
const COMMAND_CODE_CLI_VERSION = "1.
|
|
765
|
+
const COMMAND_CODE_CLI_VERSION = "1.37.0";
|
|
763
766
|
const DEFAULT_API_BASE = "https://api.commandcode.ai";
|
|
764
767
|
const DEFAULT_GENERATE_MAX_TOKENS = 64e3;
|
|
765
768
|
const DEFAULT_MAX_OUTPUT_TOKENS = 65536;
|
|
@@ -1638,7 +1641,7 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
1638
1641
|
}, {
|
|
1639
1642
|
type: "tool-call-delta",
|
|
1640
1643
|
index,
|
|
1641
|
-
id:
|
|
1644
|
+
id: ToolCallId(id),
|
|
1642
1645
|
name,
|
|
1643
1646
|
argumentsDelta: args
|
|
1644
1647
|
}, {
|
|
@@ -1646,7 +1649,7 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
1646
1649
|
index,
|
|
1647
1650
|
block: {
|
|
1648
1651
|
type: "tool-call",
|
|
1649
|
-
id:
|
|
1652
|
+
id: ToolCallId(id),
|
|
1650
1653
|
name,
|
|
1651
1654
|
arguments: args
|
|
1652
1655
|
}
|
|
@@ -1790,6 +1793,97 @@ function mapFinishReason(reason) {
|
|
|
1790
1793
|
return { kind: "stop" };
|
|
1791
1794
|
}
|
|
1792
1795
|
//#endregion
|
|
1796
|
+
//#region src/command-locales.ts
|
|
1797
|
+
const commandcodeCommand = {
|
|
1798
|
+
zh: {
|
|
1799
|
+
title: "📊 Command Code 用量{account}",
|
|
1800
|
+
accountTitle: "📊 {label}{badges}",
|
|
1801
|
+
accountSeparator: "────────────────────",
|
|
1802
|
+
activeBadge: " ✅ 当前使用",
|
|
1803
|
+
invalidCredentialBadge: " ⛔ 密钥无效",
|
|
1804
|
+
cooldownBadge: " ⏳ 限额冷却中,重置 {when}",
|
|
1805
|
+
rateLimitBadge: " ⏳ 已达限额(等待窗口探测)",
|
|
1806
|
+
unconfigured: " (未配置 API 密钥)",
|
|
1807
|
+
blockedInvalidKey: "⛔ API 密钥无效或已过期 — 服务端拒绝了全部请求(401),请检查该账户的密钥配置",
|
|
1808
|
+
blockedServiceUnavailable: "⚠️ Command Code 服务暂时不可用(5xx),稍后重试",
|
|
1809
|
+
blockedNetwork: "⚠️ 无法连接 Command Code 服务 — 请检查网络或 API 地址",
|
|
1810
|
+
planLine: " 📦 套餐 {name}{status}{period}",
|
|
1811
|
+
planPeriodSuffix: " · 账期截止 {date}",
|
|
1812
|
+
usageHeader: "── 请求 ──────────────────────────────",
|
|
1813
|
+
requestsLine: " 💬 请求 {n} 次 / 失败 {f} 成功率 {r}%",
|
|
1814
|
+
costLine: " 💰 花费 {money} ({credits} credits)",
|
|
1815
|
+
tokensLine: " 🔤 Token {in} 入 / {out} 出",
|
|
1816
|
+
creditsHeader: "── 信用 ──────────────────────────────",
|
|
1817
|
+
monthlyLine: " 💳 月额度 {monthly} (已购 {purchased} / 赠送 {free})",
|
|
1818
|
+
barLine: " └ {bar} {pct}%",
|
|
1819
|
+
windowsHeader: "── 窗口用量 ──────────────────────────",
|
|
1820
|
+
fiveHourLine: " ⏱ 5 小时 {used} / {cap}{warn}",
|
|
1821
|
+
weeklyLine: " 📅 每周 {used} / {cap}{warn}",
|
|
1822
|
+
windowBarLine: " └ {bar} 重置 {when}",
|
|
1823
|
+
exceededWarning: " ⚠️ 超限!",
|
|
1824
|
+
resetSuffix: "重置 {when}",
|
|
1825
|
+
partialFailures: "⚠️ 部分端点失败: {list}",
|
|
1826
|
+
noData: "(no data — check your API key)",
|
|
1827
|
+
errorText: "Could not fetch Command Code usage: {message}",
|
|
1828
|
+
imageGate: "当前会话已包含图片,而模型 {model} 不支持图片输入;请选择支持图片的模型,或先移除会话中的图片。"
|
|
1829
|
+
},
|
|
1830
|
+
en: {
|
|
1831
|
+
title: "📊 Command Code usage{account}",
|
|
1832
|
+
accountTitle: "📊 {label}{badges}",
|
|
1833
|
+
accountSeparator: "────────────────────",
|
|
1834
|
+
activeBadge: " ✅ active",
|
|
1835
|
+
invalidCredentialBadge: " ⛔ invalid key",
|
|
1836
|
+
cooldownBadge: " ⏳ cooling down, resets {when}",
|
|
1837
|
+
rateLimitBadge: " ⏳ rate-limited (waiting for window probe)",
|
|
1838
|
+
unconfigured: " (no API key configured)",
|
|
1839
|
+
blockedInvalidKey: "⛔ API key invalid or expired — the server rejected every request (401); check the key configured for this account",
|
|
1840
|
+
blockedServiceUnavailable: "⚠️ Command Code service temporarily unavailable (5xx); try again later",
|
|
1841
|
+
blockedNetwork: "⚠️ could not reach the Command Code service — check your network or the API base setting",
|
|
1842
|
+
planLine: " 📦 Plan {name}{status}{period}",
|
|
1843
|
+
planPeriodSuffix: " · period ends {date}",
|
|
1844
|
+
usageHeader: "── Requests ──────────────────────────",
|
|
1845
|
+
requestsLine: " 💬 Requests {n} / failed {f} success rate {r}%",
|
|
1846
|
+
costLine: " 💰 Spend {money} ({credits} credits)",
|
|
1847
|
+
tokensLine: " 🔤 Tokens {in} in / {out} out",
|
|
1848
|
+
creditsHeader: "── Credits ───────────────────────────",
|
|
1849
|
+
monthlyLine: " 💳 Monthly {monthly} (purchased {purchased} / free {free})",
|
|
1850
|
+
barLine: " └ {bar} {pct}%",
|
|
1851
|
+
windowsHeader: "── Window usage ──────────────────────",
|
|
1852
|
+
fiveHourLine: " ⏱ 5-hour {used} / {cap}{warn}",
|
|
1853
|
+
weeklyLine: " 📅 Weekly {used} / {cap}{warn}",
|
|
1854
|
+
windowBarLine: " └ {bar} resets {when}",
|
|
1855
|
+
exceededWarning: " ⚠️ exceeded!",
|
|
1856
|
+
resetSuffix: "resets {when}",
|
|
1857
|
+
partialFailures: "⚠️ some endpoints failed: {list}",
|
|
1858
|
+
noData: "(no data — check your API key)",
|
|
1859
|
+
errorText: "Could not fetch Command Code usage: {message}",
|
|
1860
|
+
imageGate: "This session already contains images, and model {model} does not accept image input; please select an image-capable model, or remove the images from the session first."
|
|
1861
|
+
}
|
|
1862
|
+
};
|
|
1863
|
+
/**
|
|
1864
|
+
* Resolve the active locale for a Host-side command run.
|
|
1865
|
+
*
|
|
1866
|
+
* Priority: explicit `override` (from `Config.lang`) → `LC_ALL` → `LANG` →
|
|
1867
|
+
* the conventional fallback (`'zh'`, matching the existing single-language
|
|
1868
|
+
* behavior so unconfigured deployments keep their current output).
|
|
1869
|
+
*
|
|
1870
|
+
* The values are matched on the leading tag only — `zh_CN.UTF-8`,
|
|
1871
|
+
* `zh-Hans`, `zh` all map to `'zh'`; everything starting with `en` maps to
|
|
1872
|
+
* `'en'`; anything else falls back to `'zh'` (a non-`en` shell that
|
|
1873
|
+
* already has Chinese in the terminal is the closest sensible default;
|
|
1874
|
+
* a Western shell that happens to be neither keeps the existing Chinese
|
|
1875
|
+
* output rather than swapping to half-translated English).
|
|
1876
|
+
*/
|
|
1877
|
+
function pickCommandLocale(override, env = process.env) {
|
|
1878
|
+
if (override === "zh" || override === "en") return override;
|
|
1879
|
+
if (((env.LC_ALL ?? env.LANG ?? "").toLowerCase().split(/[._-]/)[0] ?? "") === "en") return "en";
|
|
1880
|
+
return "zh";
|
|
1881
|
+
}
|
|
1882
|
+
/** Look up a key in the active locale, with an internal en fallback. */
|
|
1883
|
+
function commandCopy(locale, key) {
|
|
1884
|
+
return commandcodeCommand[locale][key] ?? commandcodeCommand.en[key] ?? key;
|
|
1885
|
+
}
|
|
1886
|
+
//#endregion
|
|
1793
1887
|
//#region src/commands.ts
|
|
1794
1888
|
/** Format a dollar amount. */
|
|
1795
1889
|
function money(value) {
|
|
@@ -1806,7 +1900,7 @@ function tokensCompact(value) {
|
|
|
1806
1900
|
if (value >= 1e3) return `${(value / 1e3).toFixed(1)}K`;
|
|
1807
1901
|
return String(value);
|
|
1808
1902
|
}
|
|
1809
|
-
/** Format a millis timestamp as a local date. */
|
|
1903
|
+
/** Format a millis timestamp as a local date; `n/a` when unset. */
|
|
1810
1904
|
function resetLabel(ms) {
|
|
1811
1905
|
if (ms <= 0) return "n/a";
|
|
1812
1906
|
return new Date(ms).toLocaleString();
|
|
@@ -1822,37 +1916,37 @@ function bar(used, cap) {
|
|
|
1822
1916
|
return "█".repeat(filled) + "░".repeat(10 - filled);
|
|
1823
1917
|
}
|
|
1824
1918
|
/** Render one account's rotation mark / cooldown as a short badge. */
|
|
1825
|
-
function markLabel(entry) {
|
|
1826
|
-
if (entry.mark === "invalid-credential") return
|
|
1827
|
-
if (entry.cooldownUntil > 0) return
|
|
1828
|
-
if (entry.mark === "rate-limit") return
|
|
1919
|
+
function markLabel(entry, locale) {
|
|
1920
|
+
if (entry.mark === "invalid-credential") return commandCopy(locale, "invalidCredentialBadge");
|
|
1921
|
+
if (entry.cooldownUntil > 0) return commandCopy(locale, "cooldownBadge").replace("{when}", resetLabel(entry.cooldownUntil));
|
|
1922
|
+
if (entry.mark === "rate-limit") return commandCopy(locale, "rateLimitBadge");
|
|
1829
1923
|
return "";
|
|
1830
1924
|
}
|
|
1831
1925
|
/** Render the usage report as a structured, aligned, bar-chart text view. */
|
|
1832
|
-
function renderReport(report, title) {
|
|
1926
|
+
function renderReport(report, locale, title) {
|
|
1833
1927
|
const lines = [];
|
|
1834
1928
|
const account = report.account ? ` (${report.account.userName || report.account.name})` : "";
|
|
1835
|
-
lines.push(title ??
|
|
1836
|
-
if (report.blocked === "invalid-key") lines.push(
|
|
1837
|
-
else if (report.blocked === "service-unavailable") lines.push(
|
|
1838
|
-
else if (report.blocked === "network") lines.push(
|
|
1929
|
+
lines.push(title ?? commandCopy(locale, "title").replace("{account}", account), "");
|
|
1930
|
+
if (report.blocked === "invalid-key") lines.push(commandCopy(locale, "blockedInvalidKey"), "");
|
|
1931
|
+
else if (report.blocked === "service-unavailable") lines.push(commandCopy(locale, "blockedServiceUnavailable"), "");
|
|
1932
|
+
else if (report.blocked === "network") lines.push(commandCopy(locale, "blockedNetwork"), "");
|
|
1839
1933
|
if (report.plan && report.plan.name !== "") {
|
|
1840
1934
|
const p = report.plan;
|
|
1841
1935
|
const status = p.status !== "" && p.status !== "active" ? ` (${p.status})` : "";
|
|
1842
|
-
const period = p.currentPeriodEnd > 0 ?
|
|
1843
|
-
lines.push(
|
|
1936
|
+
const period = p.currentPeriodEnd > 0 ? commandCopy(locale, "planPeriodSuffix").replace("{date}", new Date(p.currentPeriodEnd).toLocaleDateString()) : "";
|
|
1937
|
+
lines.push(commandCopy(locale, "planLine").replace("{name}", p.name).replace("{status}", status).replace("{period}", period), "");
|
|
1844
1938
|
}
|
|
1845
1939
|
if (report.usage) {
|
|
1846
1940
|
const u = report.usage;
|
|
1847
|
-
lines.push("
|
|
1941
|
+
lines.push(commandCopy(locale, "usageHeader"), commandCopy(locale, "requestsLine").replace("{n}", String(u.completedCount)).replace("{f}", String(u.failedCount)).replace("{r}", String(u.successRate)), commandCopy(locale, "costLine").replace("{money}", money(u.totalCost)).replace("{credits}", moneyShort(u.totalCredits)), commandCopy(locale, "tokensLine").replace("{in}", tokensCompact(u.totalTokensIn)).replace("{out}", tokensCompact(u.totalTokensOut)), "");
|
|
1848
1942
|
}
|
|
1849
1943
|
if (report.credits) {
|
|
1850
1944
|
const c = report.credits;
|
|
1851
1945
|
const monthlyPct = c.monthlyCredits > 0 ? `${(c.monthlyCredits / (c.monthlyCredits + c.purchasedCredits) * 100).toFixed(0)}%` : "—";
|
|
1852
|
-
lines.push("
|
|
1946
|
+
lines.push(commandCopy(locale, "creditsHeader"), commandCopy(locale, "monthlyLine").replace("{monthly}", moneyShort(c.monthlyCredits)).replace("{purchased}", moneyShort(c.purchasedCredits)).replace("{free}", moneyShort(c.freeCredits)), commandCopy(locale, "barLine").replace("{bar}", bar(c.monthlyCredits, c.monthlyCredits + c.purchasedCredits)).replace("{pct}", monthlyPct), "", commandCopy(locale, "windowsHeader"), commandCopy(locale, "fiveHourLine").replace("{used}", moneyShort(c.fiveHour.used)).replace("{cap}", moneyShort(c.fiveHour.cap)).replace("{warn}", c.fiveHour.exceeded ? commandCopy(locale, "exceededWarning") : ""), commandCopy(locale, "windowBarLine").replace("{bar}", bar(c.fiveHour.used, c.fiveHour.cap)).replace("{when}", resetLabel(c.fiveHour.resetAt)), commandCopy(locale, "weeklyLine").replace("{used}", moneyShort(c.weekly.used)).replace("{cap}", moneyShort(c.weekly.cap)).replace("{warn}", c.weekly.exceeded ? commandCopy(locale, "exceededWarning") : ""), commandCopy(locale, "windowBarLine").replace("{bar}", bar(c.weekly.used, c.weekly.cap)).replace("{when}", resetLabel(c.weekly.resetAt)), "");
|
|
1853
1947
|
}
|
|
1854
|
-
if (report.failures.length > 0) lines.push(
|
|
1855
|
-
if (!report.account && !report.usage && !report.credits) lines.push(
|
|
1948
|
+
if (report.failures.length > 0) lines.push(commandCopy(locale, "partialFailures").replace("{list}", report.failures.join("; ")), "");
|
|
1949
|
+
if (!report.account && !report.usage && !report.credits) lines.push(commandCopy(locale, "noData"), "");
|
|
1856
1950
|
return lines.join("\n").trimEnd();
|
|
1857
1951
|
}
|
|
1858
1952
|
/** The one registered `/commandcode` command. */
|
|
@@ -1863,27 +1957,29 @@ function commandDefinition(deps) {
|
|
|
1863
1957
|
description: "Command Code account usage dashboard",
|
|
1864
1958
|
input: { hint: "[status]" },
|
|
1865
1959
|
handler: async () => {
|
|
1960
|
+
const locale = deps.getLocale?.() ?? "zh";
|
|
1866
1961
|
try {
|
|
1867
1962
|
if (deps.reports !== void 0) {
|
|
1868
1963
|
const { accounts } = await deps.reports();
|
|
1869
1964
|
return {
|
|
1870
1965
|
kind: "success",
|
|
1871
1966
|
text: accounts.map((entry) => {
|
|
1872
|
-
const badges = `${entry.active ?
|
|
1873
|
-
const title =
|
|
1874
|
-
if (!entry.configured) return `${title}\n\n
|
|
1875
|
-
return renderReport(entry.report, title);
|
|
1876
|
-
}).join(
|
|
1967
|
+
const badges = `${entry.active ? commandCopy(locale, "activeBadge") : ""}${markLabel(entry, locale)}`;
|
|
1968
|
+
const title = commandCopy(locale, "accountTitle").replace("{label}", entry.label).replace("{badges}", badges);
|
|
1969
|
+
if (!entry.configured) return `${title}\n\n${commandCopy(locale, "unconfigured")}`;
|
|
1970
|
+
return renderReport(entry.report, locale, title);
|
|
1971
|
+
}).join(`\n\n${commandCopy(locale, "accountSeparator")}\n\n`)
|
|
1877
1972
|
};
|
|
1878
1973
|
}
|
|
1879
1974
|
return {
|
|
1880
1975
|
kind: "success",
|
|
1881
|
-
text: renderReport(await adapter.getUsage())
|
|
1976
|
+
text: renderReport(await adapter.getUsage(), locale)
|
|
1882
1977
|
};
|
|
1883
1978
|
} catch (error) {
|
|
1979
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1884
1980
|
return {
|
|
1885
1981
|
kind: "error",
|
|
1886
|
-
text:
|
|
1982
|
+
text: commandCopy(locale, "errorText").replace("{message}", message)
|
|
1887
1983
|
};
|
|
1888
1984
|
}
|
|
1889
1985
|
}
|
|
@@ -2027,6 +2123,11 @@ const USAGE_HOST_CONTRIBUTION = {
|
|
|
2027
2123
|
package: USAGE_REMOTE_PACKAGE,
|
|
2028
2124
|
face: "host",
|
|
2029
2125
|
schemas: [],
|
|
2126
|
+
model: {
|
|
2127
|
+
services: [],
|
|
2128
|
+
events: [],
|
|
2129
|
+
objects: []
|
|
2130
|
+
},
|
|
2030
2131
|
invocations: [{
|
|
2031
2132
|
id: `${USAGE_REMOTE_PACKAGE}#${USAGE_REPORT_ENDPOINT}`,
|
|
2032
2133
|
service: "commandcodeUsage",
|
|
@@ -2603,7 +2704,7 @@ function corsOrigin(origin) {
|
|
|
2603
2704
|
*/
|
|
2604
2705
|
const name = "llm-commandcode";
|
|
2605
2706
|
const inject = ["llm"];
|
|
2606
|
-
const NS =
|
|
2707
|
+
const NS = "llm-commandcode";
|
|
2607
2708
|
const DEFAULT_API_KEY_ENV = "COMMANDCODE_API_KEY";
|
|
2608
2709
|
/** The single provider route this plugin owns. */
|
|
2609
2710
|
const PROVIDER = "commandcode";
|
|
@@ -2623,7 +2724,8 @@ const Config = z.object({
|
|
|
2623
2724
|
apiKeyEnv: z.string().role("credential-ref"),
|
|
2624
2725
|
apiKey: z.string()
|
|
2625
2726
|
})),
|
|
2626
|
-
activeAccount: z.string()
|
|
2727
|
+
activeAccount: z.string(),
|
|
2728
|
+
lang: z.string().pattern(/^(zh|en)$/).default("zh")
|
|
2627
2729
|
});
|
|
2628
2730
|
/**
|
|
2629
2731
|
* The one explicit resolve step from raw config to validated connection
|
|
@@ -2747,10 +2849,12 @@ function apply(ctx, config) {
|
|
|
2747
2849
|
};
|
|
2748
2850
|
})) };
|
|
2749
2851
|
};
|
|
2852
|
+
const commandLocale = () => pickCommandLocale(current().lang);
|
|
2750
2853
|
ctx.inject(["commands"], (commandCtx) => {
|
|
2751
2854
|
applyCommands(commandCtx, {
|
|
2752
2855
|
adapter,
|
|
2753
|
-
reports: usageReports
|
|
2856
|
+
reports: usageReports,
|
|
2857
|
+
getLocale: commandLocale
|
|
2754
2858
|
});
|
|
2755
2859
|
});
|
|
2756
2860
|
const loginFlow = new CommandCodeLoginFlow({
|
|
@@ -2768,11 +2872,13 @@ function apply(ctx, config) {
|
|
|
2768
2872
|
reports: usageReports,
|
|
2769
2873
|
login: loginFlow
|
|
2770
2874
|
});
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2875
|
+
ctx.inject(["settings"], (settingsCtx) => {
|
|
2876
|
+
settingsCtx.settings.installSection(ctx, NS, Config, config, {
|
|
2877
|
+
setSource: (source) => {
|
|
2878
|
+
current = source;
|
|
2879
|
+
},
|
|
2880
|
+
onChange: () => {}
|
|
2881
|
+
});
|
|
2776
2882
|
});
|
|
2777
2883
|
}
|
|
2778
2884
|
//#endregion
|