@mars-sea/dsh-commandcode-provider 0.10.0-alpha.1 → 0.10.0-alpha.2
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 +15 -1
- package/README.md +9 -0
- package/README.zh-CN.md +9 -0
- package/lib/client.js +578 -89
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +91 -12
- package/lib/index.js +120 -27
- 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 (command-code@1.
|
|
27
|
+
* Models the official CLI's model table (command-code@1.38.2) 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,13 +32,15 @@ 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.38.2 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
39
|
* 1.34.0, removing the model from the catalog entirely. `tencent/hy4-preview`
|
|
40
40
|
* joined this set in command-code@1.37.0 — reasoning:!0, no efforts, 1M
|
|
41
|
-
* context, routed through OpenRouter
|
|
41
|
+
* context, routed through OpenRouter — then gained selectable
|
|
42
|
+
* `['low', 'medium', 'high']` efforts in command-code@1.38.0 and moved to
|
|
43
|
+
* `KNOWN_EFFORTS`.)
|
|
42
44
|
* Keep in sync via the dsh-commandcode-upstream skill.
|
|
43
45
|
*/
|
|
44
46
|
declare const KNOWN_THINKING_MODELS: ReadonlySet<string>;
|
|
@@ -189,7 +191,7 @@ declare function peakPricingState(modelId: string, now?: number): 'peak' | 'off-
|
|
|
189
191
|
* for models without time-of-day pricing.
|
|
190
192
|
*/
|
|
191
193
|
declare function peakPricingLabel(modelId: string, now?: number): string | undefined;
|
|
192
|
-
declare const COMMAND_CODE_CLI_VERSION = "1.
|
|
194
|
+
declare const COMMAND_CODE_CLI_VERSION = "1.38.2";
|
|
193
195
|
declare const DEFAULT_API_BASE = "https://api.commandcode.ai";
|
|
194
196
|
declare const DEFAULT_GENERATE_MAX_TOKENS = 64000;
|
|
195
197
|
declare const DEFAULT_MAX_OUTPUT_TOKENS = 65536;
|
|
@@ -263,8 +265,12 @@ type ResolveAttachments = () => AttachmentStore | undefined;
|
|
|
263
265
|
interface CommandCodeAdapterDeps<C extends CommandCodeConnectionOptions = CommandCodeConnectionOptions> {
|
|
264
266
|
/** Resolve the current connection facts (fresh per request, settings-aware). */
|
|
265
267
|
options: () => C;
|
|
266
|
-
/**
|
|
267
|
-
|
|
268
|
+
/**
|
|
269
|
+
* Resolve a usable API key for the given connection facts and the request's
|
|
270
|
+
* model id, or throw `MISSING_CREDENTIAL`. The model is optional: hosts
|
|
271
|
+
* without model-aware routing ignore it.
|
|
272
|
+
*/
|
|
273
|
+
resolveApiKey: (connection: C, model?: string) => Promise<string>;
|
|
268
274
|
/**
|
|
269
275
|
* Multi-account rotation hook: the request sent with `rejectedKey` was
|
|
270
276
|
* refused with 429 (`rate-limit`) or 401 (`invalid-credential`) before
|
|
@@ -273,7 +279,7 @@ interface CommandCodeAdapterDeps<C extends CommandCodeConnectionOptions = Comman
|
|
|
273
279
|
* Only pre-stream rejections rotate — a mid-stream failure never replays a
|
|
274
280
|
* partially consumed generation against another account.
|
|
275
281
|
*/
|
|
276
|
-
rotateApiKey?: (rejectedKey: string, rejection: 'rate-limit' | 'invalid-credential', connection: C) => Promise<string | undefined>;
|
|
282
|
+
rotateApiKey?: (rejectedKey: string, rejection: 'rate-limit' | 'invalid-credential', connection: C, model?: string) => Promise<string | undefined>;
|
|
277
283
|
/** HTTP transport override (tests); defaults to the global `fetch`. */
|
|
278
284
|
fetchImpl?: typeof fetch;
|
|
279
285
|
/** Resolve the optional durable attachment service for image input (tests); defaults to none. */
|
|
@@ -502,6 +508,27 @@ interface CommandCodeAccountPoolDeps {
|
|
|
502
508
|
* account falls back to the first usable slot.
|
|
503
509
|
*/
|
|
504
510
|
preferredId?(): string | undefined;
|
|
511
|
+
/**
|
|
512
|
+
* Model → account routing rules, re-read per resolution so settings changes
|
|
513
|
+
* apply live. Each rule lists catalog model ids (see
|
|
514
|
+
* {@link CommandCodeModelAccountRule}) to an account slot id. When the
|
|
515
|
+
* request's model matches a rule and that account is usable, it serves
|
|
516
|
+
* before the preferred/rotation selection; an unusable routed account falls
|
|
517
|
+
* back to the normal selection (the router is a hint, never a hard gate).
|
|
518
|
+
*/
|
|
519
|
+
modelAccountRules?(): readonly CommandCodeModelAccountRule[];
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* One "route these models to that account" rule. `models` lists catalog ids
|
|
523
|
+
* (`deepseek/deepseek-v4-pro`, …); `account` is a slot id (`default` or an
|
|
524
|
+
* extra account's credential reference). A request whose model id is in the
|
|
525
|
+
* list routes to that account. The first matching rule in list order wins.
|
|
526
|
+
*/
|
|
527
|
+
interface CommandCodeModelAccountRule {
|
|
528
|
+
/** Catalog model ids to match against the request's model. */
|
|
529
|
+
models: string[];
|
|
530
|
+
/** Account slot id to prefer for matching models. */
|
|
531
|
+
account: string;
|
|
505
532
|
}
|
|
506
533
|
/**
|
|
507
534
|
* Whether an account with this rotation state can serve a request right now.
|
|
@@ -517,6 +544,18 @@ declare function accountUsable(state: CommandCodeAccountState | undefined): bool
|
|
|
517
544
|
* entry (the usage view's active badge) so both always agree.
|
|
518
545
|
*/
|
|
519
546
|
declare function selectActiveAccount(accounts: readonly ResolvedAccount[], preferredId: string | undefined): ResolvedAccount | undefined;
|
|
547
|
+
/**
|
|
548
|
+
* The first routing rule whose model list contains the request's model id.
|
|
549
|
+
* Undefined when no rule matches.
|
|
550
|
+
*/
|
|
551
|
+
declare function matchModelRule(model: string, rules: readonly CommandCodeModelAccountRule[] | undefined): CommandCodeModelAccountRule | undefined;
|
|
552
|
+
/**
|
|
553
|
+
* The routed account for a request's model: the first usable account whose
|
|
554
|
+
* slot id matches the first matching rule's target. Undefined when no rule
|
|
555
|
+
* matches or the routed account is not usable (the caller then falls back to
|
|
556
|
+
* the normal preferred/rotation selection).
|
|
557
|
+
*/
|
|
558
|
+
declare function selectAccountForModel(accounts: readonly ResolvedAccount[], model: string, rules: readonly CommandCodeModelAccountRule[] | undefined): ResolvedAccount | undefined;
|
|
520
559
|
/**
|
|
521
560
|
* The account pool. Rotation state is keyed by API key (never logged), so two
|
|
522
561
|
* slots resolving to the same credential share one mark, and a key changed in
|
|
@@ -541,12 +580,17 @@ declare class CommandCodeAccountPool {
|
|
|
541
580
|
*/
|
|
542
581
|
describeAccounts(): Promise<ResolvedAccount[]>;
|
|
543
582
|
/**
|
|
544
|
-
* Hand out the
|
|
545
|
-
*
|
|
546
|
-
*
|
|
547
|
-
*
|
|
583
|
+
* Hand out the key for a request: the model-routed account when the
|
|
584
|
+
* request's model matches a rule (and that account is usable), else the
|
|
585
|
+
* manually preferred account when usable, else the first usable account in
|
|
586
|
+
* rotation order. Returns `undefined` when no account resolves any key at
|
|
587
|
+
* all (the caller then reports the missing credential). Throws
|
|
588
|
+
* `RATE_LIMIT` — naming the earliest window reset — or
|
|
548
589
|
* `INVALID_CREDENTIAL` when accounts exist but none can serve.
|
|
549
590
|
*
|
|
591
|
+
* `options.model` is the request's model id; routing rules re-read per
|
|
592
|
+
* resolution, so a settings change applies live.
|
|
593
|
+
*
|
|
550
594
|
* `options.exclude` skips one key during the probe-revival pass: the
|
|
551
595
|
* rotation hook excludes the just-rejected key so a probe that clears its
|
|
552
596
|
* window cannot re-offer the same key within the same request (the adapter
|
|
@@ -554,6 +598,7 @@ declare class CommandCodeAccountPool {
|
|
|
554
598
|
*/
|
|
555
599
|
resolveKey(options?: {
|
|
556
600
|
exclude?: string;
|
|
601
|
+
model?: string;
|
|
557
602
|
}): Promise<{
|
|
558
603
|
key: string;
|
|
559
604
|
slot: CommandCodeAccountSlot;
|
|
@@ -601,6 +646,17 @@ declare const USAGE_REPORT_ENDPOINT = "commandcode/report";
|
|
|
601
646
|
* deliberately minimal so one `parse` function satisfies it.
|
|
602
647
|
*/
|
|
603
648
|
declare const usageReportSchema: TypertSchema<CommandCodeAccountsReport>;
|
|
649
|
+
/** One catalog entry the settings page's routing-rule editor offers. */
|
|
650
|
+
interface CommandCodeCatalogModel {
|
|
651
|
+
/** Catalog model id (e.g. `deepseek/deepseek-v4-pro`). */
|
|
652
|
+
id: string;
|
|
653
|
+
/** Display name from the catalog. */
|
|
654
|
+
name: string;
|
|
655
|
+
}
|
|
656
|
+
/** The model-catalog Remote result: the full catalog, sorted for picking. */
|
|
657
|
+
interface CommandCodeCatalog {
|
|
658
|
+
models: CommandCodeCatalogModel[];
|
|
659
|
+
}
|
|
604
660
|
//#endregion
|
|
605
661
|
//#region src/command-locales.d.ts
|
|
606
662
|
/**
|
|
@@ -718,6 +774,12 @@ interface CommandCodeUsageDeps<C extends CommandCodeConnectionOptions = CommandC
|
|
|
718
774
|
* entry around `adapter.getUsage()`.
|
|
719
775
|
*/
|
|
720
776
|
reports?: () => Promise<CommandCodeAccountsReport>;
|
|
777
|
+
/**
|
|
778
|
+
* Model-catalog source for the routing-rule editor (wired by the plugin
|
|
779
|
+
* entry). Absent, the `models` endpoint answers an empty list — the page's
|
|
780
|
+
* rule editor degrades to the empty state.
|
|
781
|
+
*/
|
|
782
|
+
listModels?: () => Promise<CommandCodeCatalog>;
|
|
721
783
|
/**
|
|
722
784
|
* The browser-login flow (wired by the plugin entry). Absent means the
|
|
723
785
|
* login endpoints answer `idle` / reject with a plain message — the page's
|
|
@@ -744,6 +806,13 @@ declare class CommandCodeUsageService<C extends CommandCodeConnectionOptions = C
|
|
|
744
806
|
* the failure branch the page renders as a hint.
|
|
745
807
|
*/
|
|
746
808
|
report(): Promise<CommandCodeAccountsReport>;
|
|
809
|
+
/**
|
|
810
|
+
* The model catalog for the settings page's routing-rule editor. The
|
|
811
|
+
* browser never calls the Command Code API directly — the Host serves the
|
|
812
|
+
* catalog (already fetched/cached by the adapter) so rules can be picked
|
|
813
|
+
* from the live model list instead of typed by hand.
|
|
814
|
+
*/
|
|
815
|
+
models(): Promise<CommandCodeCatalog>;
|
|
747
816
|
/**
|
|
748
817
|
* Start (or rejoin) a browser-login attempt and return its fresh status —
|
|
749
818
|
* `waiting` carrying the Studio URL. Rejects when the flow cannot start
|
|
@@ -933,6 +1002,16 @@ interface Config {
|
|
|
933
1002
|
* rotation still applies). Unset means "first usable account".
|
|
934
1003
|
*/
|
|
935
1004
|
activeAccount?: string;
|
|
1005
|
+
/**
|
|
1006
|
+
* Model → account routing rules. Each rule lists catalog model ids to an
|
|
1007
|
+
* account slot id (`default`, or an extra account's credential reference).
|
|
1008
|
+
* When a request's model is in a rule's list and the routed account is
|
|
1009
|
+
* usable, that account serves — before the manual {@link activeAccount} and
|
|
1010
|
+
* the passive rotation order. A routed account that is exhausted or invalid
|
|
1011
|
+
* falls back to the normal selection, so the router is a hint, never a hard
|
|
1012
|
+
* gate. The first matching rule wins.
|
|
1013
|
+
*/
|
|
1014
|
+
modelAccountRules?: CommandCodeModelAccountRule[];
|
|
936
1015
|
/**
|
|
937
1016
|
* Language override for the `/commandcode` Host-side command's user-facing
|
|
938
1017
|
* copy. Host commands cannot read the client's `ctx.locale`, so this is
|
|
@@ -960,5 +1039,5 @@ interface ResolvedCommandCodeOptions extends CommandCodeConnectionOptions {
|
|
|
960
1039
|
declare function resolveAdapterOptions(config: Config): ResolvedCommandCodeOptions;
|
|
961
1040
|
declare function apply(ctx: Context, config: Config): void;
|
|
962
1041
|
//#endregion
|
|
963
|
-
export { type ApiKeyValidation, BILLING_ACCESS_TTL_MS, COMMAND_CODE_CLI_VERSION, type CommandCodeAccountConfig, CommandCodeAccountPool, type CommandCodeAccountSlot, type CommandCodeAccountState, type CommandCodeAccountUsage, type CommandCodeAccountsReport, CommandCodeAdapter, type CommandCodeAdapterDeps, type CommandCodeBillingAccess, type CommandCodeCommandDeps, type CommandCodeConnectionOptions, type CommandCodeLoginCredentials, type CommandCodeLoginFailureReason, CommandCodeLoginFlow, type CommandCodeLoginFlowDeps, type CommandCodeLoginStatus, type CommandCodeUsageDeps, type CommandCodeUsageReport, CommandCodeUsageService, Config, DEFAULT_API_BASE, DEFAULT_GENERATE_MAX_TOKENS, DEFAULT_MAX_OUTPUT_TOKENS, DEFAULT_MODELS_CACHE_PATH, DEFAULT_REQUEST_TIMEOUT_MS, DEFAULT_STREAM_IDLE_TIMEOUT_MS, KNOWN_DEALS, KNOWN_EFFORTS, KNOWN_IMAGE_MODELS, KNOWN_PEAK_PRICING, KNOWN_PLANS, KNOWN_SUBSCRIPTION_PLANS, KNOWN_THINKING_MODELS, LOGIN_ALLOWED_ORIGINS, LOGIN_BEGIN_ENDPOINT, LOGIN_BODY_LIMIT_BYTES, LOGIN_CANCEL_ENDPOINT, LOGIN_MAX_PORT_ATTEMPTS, LOGIN_START_PORT, LOGIN_STATUS_ENDPOINT, LOGIN_TIMEOUT_MS, type LoginFlowFacade, PLAN_LABELS, PLAN_ORDER, PROVIDER, type ResolveAttachments, ResolvedCommandCodeOptions, USAGE_REPORT_ENDPOINT, accountUsable, apply, applyCommands, applyUsageRemote, buildCommandAuthUrl, capabilityDescription, commandDefinition, compareByPlan, dealLabel, formatContext, inject, loginStatusSchema, modelVisibleInPlan, name, parseLoginStatus, peakPricingLabel, peakPricingState, planLabel, projectSlugFromPath, resolveAdapterOptions, resolveAuthFileApiKey, selectActiveAccount, studioBaseForApiBase, subscriptionPlanInfo, usageReportSchema, validateCommandApiKey };
|
|
1042
|
+
export { type ApiKeyValidation, BILLING_ACCESS_TTL_MS, COMMAND_CODE_CLI_VERSION, type CommandCodeAccountConfig, CommandCodeAccountPool, type CommandCodeAccountSlot, type CommandCodeAccountState, type CommandCodeAccountUsage, type CommandCodeAccountsReport, CommandCodeAdapter, type CommandCodeAdapterDeps, type CommandCodeBillingAccess, type CommandCodeCommandDeps, type CommandCodeConnectionOptions, type CommandCodeLoginCredentials, type CommandCodeLoginFailureReason, CommandCodeLoginFlow, type CommandCodeLoginFlowDeps, type CommandCodeLoginStatus, type CommandCodeModelAccountRule, type CommandCodeUsageDeps, type CommandCodeUsageReport, CommandCodeUsageService, Config, DEFAULT_API_BASE, DEFAULT_GENERATE_MAX_TOKENS, DEFAULT_MAX_OUTPUT_TOKENS, DEFAULT_MODELS_CACHE_PATH, DEFAULT_REQUEST_TIMEOUT_MS, DEFAULT_STREAM_IDLE_TIMEOUT_MS, KNOWN_DEALS, KNOWN_EFFORTS, KNOWN_IMAGE_MODELS, KNOWN_PEAK_PRICING, KNOWN_PLANS, KNOWN_SUBSCRIPTION_PLANS, KNOWN_THINKING_MODELS, LOGIN_ALLOWED_ORIGINS, LOGIN_BEGIN_ENDPOINT, LOGIN_BODY_LIMIT_BYTES, LOGIN_CANCEL_ENDPOINT, LOGIN_MAX_PORT_ATTEMPTS, LOGIN_START_PORT, LOGIN_STATUS_ENDPOINT, LOGIN_TIMEOUT_MS, type LoginFlowFacade, PLAN_LABELS, PLAN_ORDER, PROVIDER, type ResolveAttachments, ResolvedCommandCodeOptions, USAGE_REPORT_ENDPOINT, accountUsable, apply, applyCommands, applyUsageRemote, buildCommandAuthUrl, capabilityDescription, commandDefinition, compareByPlan, dealLabel, formatContext, inject, loginStatusSchema, matchModelRule, modelVisibleInPlan, name, parseLoginStatus, peakPricingLabel, peakPricingState, planLabel, projectSlugFromPath, resolveAdapterOptions, resolveAuthFileApiKey, selectAccountForModel, selectActiveAccount, studioBaseForApiBase, subscriptionPlanInfo, usageReportSchema, validateCommandApiKey };
|
|
964
1043
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.js
CHANGED
|
@@ -21,9 +21,11 @@ import { createServer as createServer$1 } from "node:net";
|
|
|
21
21
|
* This module owns that rotation:
|
|
22
22
|
*
|
|
23
23
|
* - {@link CommandCodeAccountPool.resolveKey} hands out the first account
|
|
24
|
-
* whose key is not currently marked exhausted,
|
|
25
|
-
*
|
|
26
|
-
*
|
|
24
|
+
* whose key is not currently marked exhausted — or, when the request's
|
|
25
|
+
* model matches a {@link CommandCodeModelAccountRule} and that account is
|
|
26
|
+
* usable, the routed account — resolving each slot's key lazily (literal
|
|
27
|
+
* config key → credential seam → launch environment → the official CLI
|
|
28
|
+
* auth file for the default slot only).
|
|
27
29
|
* - {@link CommandCodeAccountPool.markRejected} records a 429 (rate limit,
|
|
28
30
|
* window unknown) or 401 (invalid key, disabled until the config changes)
|
|
29
31
|
* against the exact API key, so several slots sharing one key share one
|
|
@@ -79,6 +81,25 @@ function selectActiveAccount(accounts, preferredId) {
|
|
|
79
81
|
return usable[0];
|
|
80
82
|
}
|
|
81
83
|
/**
|
|
84
|
+
* The first routing rule whose model list contains the request's model id.
|
|
85
|
+
* Undefined when no rule matches.
|
|
86
|
+
*/
|
|
87
|
+
function matchModelRule(model, rules) {
|
|
88
|
+
if (model === "" || rules === void 0 || rules.length === 0) return void 0;
|
|
89
|
+
for (const rule of rules) if (rule.models.includes(model)) return rule;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The routed account for a request's model: the first usable account whose
|
|
93
|
+
* slot id matches the first matching rule's target. Undefined when no rule
|
|
94
|
+
* matches or the routed account is not usable (the caller then falls back to
|
|
95
|
+
* the normal preferred/rotation selection).
|
|
96
|
+
*/
|
|
97
|
+
function selectAccountForModel(accounts, model, rules) {
|
|
98
|
+
const rule = matchModelRule(model, rules);
|
|
99
|
+
if (rule === void 0) return void 0;
|
|
100
|
+
return accounts.find((account) => account.slot.id === rule.account && accountUsable(account.state));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
82
103
|
* The account pool. Rotation state is keyed by API key (never logged), so two
|
|
83
104
|
* slots resolving to the same credential share one mark, and a key changed in
|
|
84
105
|
* the credentials service starts with a clean slate.
|
|
@@ -130,12 +151,17 @@ var CommandCodeAccountPool = class {
|
|
|
130
151
|
return out;
|
|
131
152
|
}
|
|
132
153
|
/**
|
|
133
|
-
* Hand out the
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
154
|
+
* Hand out the key for a request: the model-routed account when the
|
|
155
|
+
* request's model matches a rule (and that account is usable), else the
|
|
156
|
+
* manually preferred account when usable, else the first usable account in
|
|
157
|
+
* rotation order. Returns `undefined` when no account resolves any key at
|
|
158
|
+
* all (the caller then reports the missing credential). Throws
|
|
159
|
+
* `RATE_LIMIT` — naming the earliest window reset — or
|
|
137
160
|
* `INVALID_CREDENTIAL` when accounts exist but none can serve.
|
|
138
161
|
*
|
|
162
|
+
* `options.model` is the request's model id; routing rules re-read per
|
|
163
|
+
* resolution, so a settings change applies live.
|
|
164
|
+
*
|
|
139
165
|
* `options.exclude` skips one key during the probe-revival pass: the
|
|
140
166
|
* rotation hook excludes the just-rejected key so a probe that clears its
|
|
141
167
|
* window cannot re-offer the same key within the same request (the adapter
|
|
@@ -144,6 +170,8 @@ var CommandCodeAccountPool = class {
|
|
|
144
170
|
async resolveKey(options) {
|
|
145
171
|
const accounts = await this.resolvedAccounts();
|
|
146
172
|
if (accounts.length === 0) return;
|
|
173
|
+
const routed = selectAccountForModel(accounts, options?.model ?? "", this.deps.modelAccountRules?.());
|
|
174
|
+
if (routed !== void 0) return this.pick(routed);
|
|
147
175
|
const chosen = selectActiveAccount(accounts, this.deps.preferredId?.());
|
|
148
176
|
if (chosen !== void 0) return this.pick(chosen);
|
|
149
177
|
await Promise.all(accounts.map(async (account) => {
|
|
@@ -215,7 +243,7 @@ var CommandCodeAccountPool = class {
|
|
|
215
243
|
* and API key or subscription, and Command Code's terms apply.
|
|
216
244
|
*
|
|
217
245
|
* Wire protocol (reverse-engineered by the pi plugin, command-code@1.28.4;
|
|
218
|
-
* re-verified against command-code@1.
|
|
246
|
+
* re-verified against command-code@1.38.2 — endpoints, request shape, and
|
|
219
247
|
* stream events unchanged):
|
|
220
248
|
* POST {apiBase}/alpha/generate
|
|
221
249
|
* body: { config, memory, taste, skills, params: { model, messages, tools,
|
|
@@ -359,6 +387,11 @@ const KNOWN_EFFORTS = {
|
|
|
359
387
|
"max"
|
|
360
388
|
],
|
|
361
389
|
"sakana/fugu-ultra": ["high", "xhigh"],
|
|
390
|
+
"tencent/hy4-preview": [
|
|
391
|
+
"low",
|
|
392
|
+
"medium",
|
|
393
|
+
"high"
|
|
394
|
+
],
|
|
362
395
|
"xai/grok-4.5": [
|
|
363
396
|
"low",
|
|
364
397
|
"medium",
|
|
@@ -443,7 +476,7 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
|
|
|
443
476
|
"z-ai/glm-5.3-flash"
|
|
444
477
|
]);
|
|
445
478
|
/**
|
|
446
|
-
* Models the official CLI's model table (command-code@1.
|
|
479
|
+
* Models the official CLI's model table (command-code@1.38.2) marks
|
|
447
480
|
* `reasoning:!0` but defines no selectable `reasoning_effort` levels — they
|
|
448
481
|
* think automatically, with Command Code driving the depth. This is the
|
|
449
482
|
* authoritative "thinks, effort not adjustable" set: `KNOWN_EFFORTS` (which
|
|
@@ -451,13 +484,15 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
|
|
|
451
484
|
* effort levels, and this snapshot is not surfaced in the picker's compact
|
|
452
485
|
* description — it exists for programmatic consumers.
|
|
453
486
|
*
|
|
454
|
-
* Source: the command-code@1.
|
|
487
|
+
* Source: the command-code@1.38.2 bundled model table (dist/cli.mjs),
|
|
455
488
|
* cross-checked with https://commandcode.ai/docs/reference/cli/models.
|
|
456
489
|
* (`stealth/ox-alpha` left this set in command-code@1.32.1, which gave it
|
|
457
490
|
* selectable `['low', 'high', 'max']` efforts; the preview then ended in
|
|
458
491
|
* 1.34.0, removing the model from the catalog entirely. `tencent/hy4-preview`
|
|
459
492
|
* joined this set in command-code@1.37.0 — reasoning:!0, no efforts, 1M
|
|
460
|
-
* context, routed through OpenRouter
|
|
493
|
+
* context, routed through OpenRouter — then gained selectable
|
|
494
|
+
* `['low', 'medium', 'high']` efforts in command-code@1.38.0 and moved to
|
|
495
|
+
* `KNOWN_EFFORTS`.)
|
|
461
496
|
* Keep in sync via the dsh-commandcode-upstream skill.
|
|
462
497
|
*/
|
|
463
498
|
const KNOWN_THINKING_MODELS = /* @__PURE__ */ new Set([
|
|
@@ -474,7 +509,6 @@ const KNOWN_THINKING_MODELS = /* @__PURE__ */ new Set([
|
|
|
474
509
|
"stepfun/Step-3.5-Flash",
|
|
475
510
|
"stepfun/Step-3.7-Flash",
|
|
476
511
|
"tencent/hy3-paid",
|
|
477
|
-
"tencent/hy4-preview",
|
|
478
512
|
"nvidia/nemotron-3-ultra-550b-a55b",
|
|
479
513
|
"thinkingmachines/inkling",
|
|
480
514
|
"thinkingmachines/inkling-small",
|
|
@@ -514,6 +548,7 @@ const KNOWN_PLANS = {
|
|
|
514
548
|
"deepseek/deepseek-v4-flash-vision-exp": "go",
|
|
515
549
|
"deepseek/deepseek-v4-pro": "go",
|
|
516
550
|
"gpt-5.6-luna": "go",
|
|
551
|
+
"inclusionai/ling-3.0-flash-free": "go",
|
|
517
552
|
"meta/muse-spark-1.2-contributor": "go",
|
|
518
553
|
"minimax/minimax-m2.7-free": "go",
|
|
519
554
|
"minimax/minimax-m3-free": "go",
|
|
@@ -526,6 +561,7 @@ const KNOWN_PLANS = {
|
|
|
526
561
|
"poolside/laguna-s-2.1-free": "go",
|
|
527
562
|
"stepfun/Step-3.5-Flash": "go",
|
|
528
563
|
"stepfun/Step-3.7-Flash": "go",
|
|
564
|
+
"tencent/Hy3": "go",
|
|
529
565
|
"tencent/hy3-paid": "go",
|
|
530
566
|
"tencent/hy4-preview": "go",
|
|
531
567
|
"thinkingmachines/inkling": "go",
|
|
@@ -690,10 +726,6 @@ function modelVisibleInPlan(modelId, access) {
|
|
|
690
726
|
return weight <= access.tierWeight;
|
|
691
727
|
}
|
|
692
728
|
const KNOWN_DEALS = {
|
|
693
|
-
"google/gemini-3.7-flash": {
|
|
694
|
-
label: "50% off",
|
|
695
|
-
expiresAt: "2026-12-31T23:59:59Z"
|
|
696
|
-
},
|
|
697
729
|
"MiniMaxAI/MiniMax-M3": { label: "50% off" },
|
|
698
730
|
"xiaomi/mimo-v2.5-pro": { label: "99% off" },
|
|
699
731
|
"xiaomi/mimo-v2.5": { label: "98% off" },
|
|
@@ -762,7 +794,7 @@ function peakPricingLabel(modelId, now = Date.now()) {
|
|
|
762
794
|
if (state === void 0) return void 0;
|
|
763
795
|
return state === "peak" ? "Peak" : "Half";
|
|
764
796
|
}
|
|
765
|
-
const COMMAND_CODE_CLI_VERSION = "1.
|
|
797
|
+
const COMMAND_CODE_CLI_VERSION = "1.38.2";
|
|
766
798
|
const DEFAULT_API_BASE = "https://api.commandcode.ai";
|
|
767
799
|
const DEFAULT_GENERATE_MAX_TOKENS = 64e3;
|
|
768
800
|
const DEFAULT_MAX_OUTPUT_TOKENS = 65536;
|
|
@@ -1405,7 +1437,7 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
1405
1437
|
readImage = (ref) => attachments.readImage(ref).then((stored) => stored.data);
|
|
1406
1438
|
}
|
|
1407
1439
|
const connection = this.deps.options();
|
|
1408
|
-
let apiKey = await this.deps.resolveApiKey(connection);
|
|
1440
|
+
let apiKey = await this.deps.resolveApiKey(connection, options.model);
|
|
1409
1441
|
const modelMax = this.catalog.find((m) => m.id === options.model)?.maxTokens ?? 65536;
|
|
1410
1442
|
const maxTokens = Math.min(options.maxTokens ?? modelMax, modelMax, DEFAULT_GENERATE_MAX_TOKENS);
|
|
1411
1443
|
const effort = options.reasoningEffort;
|
|
@@ -1515,7 +1547,7 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
1515
1547
|
}
|
|
1516
1548
|
const rotate = this.deps.rotateApiKey;
|
|
1517
1549
|
if ((attempt.status === 429 || attempt.status === 401) && rotate !== void 0 && options.signal?.aborted !== true && tried.size < MAX_ACCOUNT_ROTATIONS) {
|
|
1518
|
-
const next = await rotate(apiKey, attempt.status === 429 ? "rate-limit" : "invalid-credential", connection);
|
|
1550
|
+
const next = await rotate(apiKey, attempt.status === 429 ? "rate-limit" : "invalid-credential", connection, options.model);
|
|
1519
1551
|
if (next !== void 0 && !tried.has(next)) {
|
|
1520
1552
|
apiKey = next;
|
|
1521
1553
|
continue;
|
|
@@ -2142,6 +2174,39 @@ const USAGE_HOST_CONTRIBUTION = {
|
|
|
2142
2174
|
}
|
|
2143
2175
|
}]
|
|
2144
2176
|
};
|
|
2177
|
+
/** Canonical `<namespace>/<method>` endpoint of the model-catalog Remote. */
|
|
2178
|
+
const MODELS_ENDPOINT = "commandcode/models";
|
|
2179
|
+
/** Parse one untrusted boundary value into a {@link CommandCodeCatalogModel}. */
|
|
2180
|
+
function parseCatalogModel(value) {
|
|
2181
|
+
const source = record(value, "model");
|
|
2182
|
+
return {
|
|
2183
|
+
id: stringField(source, "id", "model.id"),
|
|
2184
|
+
name: stringField(source, "name", "model.name")
|
|
2185
|
+
};
|
|
2186
|
+
}
|
|
2187
|
+
/** Parse the wire result into a {@link CommandCodeCatalog}. */
|
|
2188
|
+
function parseCatalog(value) {
|
|
2189
|
+
const models = record(value, "result").models;
|
|
2190
|
+
if (!Array.isArray(models)) reject$1("models");
|
|
2191
|
+
return { models: models.map(parseCatalogModel) };
|
|
2192
|
+
}
|
|
2193
|
+
/**
|
|
2194
|
+
* The model-catalog invocation descriptor, sharing the same `commandcodeUsage`
|
|
2195
|
+
* service and `commandcode` namespace as the usage report.
|
|
2196
|
+
*/
|
|
2197
|
+
const MODELS_DESCRIPTOR = {
|
|
2198
|
+
id: `${USAGE_REMOTE_PACKAGE}#${MODELS_ENDPOINT}`,
|
|
2199
|
+
service: "commandcodeUsage",
|
|
2200
|
+
namespace: "commandcode",
|
|
2201
|
+
method: "models",
|
|
2202
|
+
invocation: { kind: "direct" },
|
|
2203
|
+
parameters: [],
|
|
2204
|
+
result: {
|
|
2205
|
+
mode: "strict",
|
|
2206
|
+
typeSymbol: `${USAGE_REMOTE_PACKAGE}#CommandCodeCatalog`,
|
|
2207
|
+
schema: { parse: parseCatalog }
|
|
2208
|
+
}
|
|
2209
|
+
};
|
|
2145
2210
|
//#endregion
|
|
2146
2211
|
//#region src/login-wire.ts
|
|
2147
2212
|
/** The canonical endpoint paths of the three login Remotes. */
|
|
@@ -2254,6 +2319,15 @@ var CommandCodeUsageService = class extends TypertRemoteService {
|
|
|
2254
2319
|
}] };
|
|
2255
2320
|
}
|
|
2256
2321
|
/**
|
|
2322
|
+
* The model catalog for the settings page's routing-rule editor. The
|
|
2323
|
+
* browser never calls the Command Code API directly — the Host serves the
|
|
2324
|
+
* catalog (already fetched/cached by the adapter) so rules can be picked
|
|
2325
|
+
* from the live model list instead of typed by hand.
|
|
2326
|
+
*/
|
|
2327
|
+
async models() {
|
|
2328
|
+
return this.deps.listModels?.() ?? { models: [] };
|
|
2329
|
+
}
|
|
2330
|
+
/**
|
|
2257
2331
|
* Start (or rejoin) a browser-login attempt and return its fresh status —
|
|
2258
2332
|
* `waiting` carrying the Studio URL. Rejects when the flow cannot start
|
|
2259
2333
|
* (no free loopback port, disposed plugin); the Gateway folds the throw
|
|
@@ -2287,7 +2361,11 @@ function applyUsageRemote(ctx, deps) {
|
|
|
2287
2361
|
new CommandCodeUsageService(remoteCtx, deps);
|
|
2288
2362
|
const unregister = remoteCtx.typert.register({
|
|
2289
2363
|
...USAGE_HOST_CONTRIBUTION,
|
|
2290
|
-
invocations: [
|
|
2364
|
+
invocations: [
|
|
2365
|
+
...USAGE_HOST_CONTRIBUTION.invocations,
|
|
2366
|
+
MODELS_DESCRIPTOR,
|
|
2367
|
+
...LOGIN_DESCRIPTORS
|
|
2368
|
+
]
|
|
2291
2369
|
});
|
|
2292
2370
|
remoteCtx.effect(() => () => void unregister(), "dsh-commandcode-provider: usage remote");
|
|
2293
2371
|
});
|
|
@@ -2725,6 +2803,10 @@ const Config = z.object({
|
|
|
2725
2803
|
apiKey: z.string()
|
|
2726
2804
|
})),
|
|
2727
2805
|
activeAccount: z.string(),
|
|
2806
|
+
modelAccountRules: z.array(z.object({
|
|
2807
|
+
models: z.array(z.string()),
|
|
2808
|
+
account: z.string()
|
|
2809
|
+
})),
|
|
2728
2810
|
lang: z.string().pattern(/^(zh|en)$/).default("zh")
|
|
2729
2811
|
});
|
|
2730
2812
|
/**
|
|
@@ -2795,10 +2877,11 @@ function apply(ctx, config) {
|
|
|
2795
2877
|
resolveRef,
|
|
2796
2878
|
authFileKey: resolveAuthFileApiKey,
|
|
2797
2879
|
probeWindow: (apiKey) => adapter.probeFiveHourWindow(apiKey),
|
|
2798
|
-
preferredId
|
|
2880
|
+
preferredId,
|
|
2881
|
+
modelAccountRules: () => current().modelAccountRules ?? []
|
|
2799
2882
|
});
|
|
2800
|
-
const resolveApiKey = async (connection) => {
|
|
2801
|
-
const resolved = await pool.resolveKey();
|
|
2883
|
+
const resolveApiKey = async (connection, model) => {
|
|
2884
|
+
const resolved = await pool.resolveKey(model === void 0 ? {} : { model });
|
|
2802
2885
|
if (resolved !== void 0) return assertUsableApiKey(resolved.key, "llm-commandcode", resolved.slot.ref ?? `${resolved.slot.label} (config.apiKey)`);
|
|
2803
2886
|
const ref = connection.apiKeyEnv;
|
|
2804
2887
|
throw new LlmError(`llm-commandcode: no API key for provider route "${PROVIDER}"; store ${ref} through the credentials service (the web Models page writes it), export it in the launching environment, set config.apiKey, or run \`command-code login\` to write ~/.commandcode/auth.json`, "MISSING_CREDENTIAL");
|
|
@@ -2806,9 +2889,12 @@ function apply(ctx, config) {
|
|
|
2806
2889
|
const adapter = new CommandCodeAdapter({
|
|
2807
2890
|
options,
|
|
2808
2891
|
resolveApiKey,
|
|
2809
|
-
rotateApiKey: async (rejectedKey, rejection) => {
|
|
2892
|
+
rotateApiKey: async (rejectedKey, rejection, _connection, model) => {
|
|
2810
2893
|
pool.markRejected(rejectedKey, rejection);
|
|
2811
|
-
const resolved = await pool.resolveKey({ exclude: rejectedKey }
|
|
2894
|
+
const resolved = await pool.resolveKey(model === void 0 ? { exclude: rejectedKey } : {
|
|
2895
|
+
exclude: rejectedKey,
|
|
2896
|
+
model
|
|
2897
|
+
});
|
|
2812
2898
|
return resolved === void 0 ? void 0 : assertUsableApiKey(resolved.key, "llm-commandcode", resolved.slot.ref ?? `${resolved.slot.label} (config.apiKey)`);
|
|
2813
2899
|
},
|
|
2814
2900
|
resolveAttachments: () => {
|
|
@@ -2867,10 +2953,17 @@ function apply(ctx, config) {
|
|
|
2867
2953
|
}
|
|
2868
2954
|
});
|
|
2869
2955
|
ctx.effect(() => () => loginFlow.dispose(), "dsh-commandcode-provider: login flow");
|
|
2956
|
+
const catalogForRules = async () => {
|
|
2957
|
+
return { models: (await adapter.listModels(PROVIDER)).map((model) => ({
|
|
2958
|
+
id: model.id,
|
|
2959
|
+
name: model.name.replace(/\s*\(CC\)$/, "")
|
|
2960
|
+
})) };
|
|
2961
|
+
};
|
|
2870
2962
|
applyUsageRemote(ctx, {
|
|
2871
2963
|
adapter,
|
|
2872
2964
|
reports: usageReports,
|
|
2873
|
-
login: loginFlow
|
|
2965
|
+
login: loginFlow,
|
|
2966
|
+
listModels: catalogForRules
|
|
2874
2967
|
});
|
|
2875
2968
|
ctx.inject(["settings"], (settingsCtx) => {
|
|
2876
2969
|
settingsCtx.settings.installSection(ctx, NS, Config, config, {
|
|
@@ -2882,6 +2975,6 @@ function apply(ctx, config) {
|
|
|
2882
2975
|
});
|
|
2883
2976
|
}
|
|
2884
2977
|
//#endregion
|
|
2885
|
-
export { BILLING_ACCESS_TTL_MS, COMMAND_CODE_CLI_VERSION, CommandCodeAccountPool, CommandCodeAdapter, CommandCodeLoginFlow, CommandCodeUsageService, Config, DEFAULT_API_BASE, DEFAULT_GENERATE_MAX_TOKENS, DEFAULT_MAX_OUTPUT_TOKENS, DEFAULT_MODELS_CACHE_PATH, DEFAULT_REQUEST_TIMEOUT_MS, DEFAULT_STREAM_IDLE_TIMEOUT_MS, KNOWN_DEALS, KNOWN_EFFORTS, KNOWN_IMAGE_MODELS, KNOWN_PEAK_PRICING, KNOWN_PLANS, KNOWN_SUBSCRIPTION_PLANS, KNOWN_THINKING_MODELS, LOGIN_ALLOWED_ORIGINS, LOGIN_BEGIN_ENDPOINT, LOGIN_BODY_LIMIT_BYTES, LOGIN_CANCEL_ENDPOINT, LOGIN_MAX_PORT_ATTEMPTS, LOGIN_START_PORT, LOGIN_STATUS_ENDPOINT, LOGIN_TIMEOUT_MS, PLAN_LABELS, PLAN_ORDER, PROVIDER, USAGE_REPORT_ENDPOINT, accountUsable, apply, applyCommands, applyUsageRemote, buildCommandAuthUrl, capabilityDescription, commandDefinition, compareByPlan, dealLabel, formatContext, inject, loginStatusSchema, modelVisibleInPlan, name, parseLoginStatus, peakPricingLabel, peakPricingState, planLabel, projectSlugFromPath, resolveAdapterOptions, resolveAuthFileApiKey, selectActiveAccount, studioBaseForApiBase, subscriptionPlanInfo, usageReportSchema, validateCommandApiKey };
|
|
2978
|
+
export { BILLING_ACCESS_TTL_MS, COMMAND_CODE_CLI_VERSION, CommandCodeAccountPool, CommandCodeAdapter, CommandCodeLoginFlow, CommandCodeUsageService, Config, DEFAULT_API_BASE, DEFAULT_GENERATE_MAX_TOKENS, DEFAULT_MAX_OUTPUT_TOKENS, DEFAULT_MODELS_CACHE_PATH, DEFAULT_REQUEST_TIMEOUT_MS, DEFAULT_STREAM_IDLE_TIMEOUT_MS, KNOWN_DEALS, KNOWN_EFFORTS, KNOWN_IMAGE_MODELS, KNOWN_PEAK_PRICING, KNOWN_PLANS, KNOWN_SUBSCRIPTION_PLANS, KNOWN_THINKING_MODELS, LOGIN_ALLOWED_ORIGINS, LOGIN_BEGIN_ENDPOINT, LOGIN_BODY_LIMIT_BYTES, LOGIN_CANCEL_ENDPOINT, LOGIN_MAX_PORT_ATTEMPTS, LOGIN_START_PORT, LOGIN_STATUS_ENDPOINT, LOGIN_TIMEOUT_MS, PLAN_LABELS, PLAN_ORDER, PROVIDER, USAGE_REPORT_ENDPOINT, accountUsable, apply, applyCommands, applyUsageRemote, buildCommandAuthUrl, capabilityDescription, commandDefinition, compareByPlan, dealLabel, formatContext, inject, loginStatusSchema, matchModelRule, modelVisibleInPlan, name, parseLoginStatus, peakPricingLabel, peakPricingState, planLabel, projectSlugFromPath, resolveAdapterOptions, resolveAuthFileApiKey, selectAccountForModel, selectActiveAccount, studioBaseForApiBase, subscriptionPlanInfo, usageReportSchema, validateCommandApiKey };
|
|
2886
2979
|
|
|
2887
2980
|
//# sourceMappingURL=index.js.map
|