@mars-sea/dsh-commandcode-provider 0.11.4 → 0.11.6
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 +24 -0
- package/lib/client.js +66 -18
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +171 -36
- package/lib/index.js +429 -73
- package/lib/index.js.map +1 -1
- package/package.json +51 -38
package/lib/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { Context } from "@deepseek-ai/cordis";
|
|
|
7
7
|
import { AttachmentStore, ImageAttachmentRef } from "@deepseek-ai/dsh-attachment";
|
|
8
8
|
import { CommandDefinition } from "@deepseek-ai/dsh-commands";
|
|
9
9
|
//#region src/adapter.d.ts
|
|
10
|
-
declare const COMMAND_CODE_CLI_VERSION = "1.
|
|
10
|
+
declare const COMMAND_CODE_CLI_VERSION = "1.57.0";
|
|
11
11
|
declare const DEFAULT_API_BASE = "https://api.commandcode.ai";
|
|
12
12
|
declare const DEFAULT_GENERATE_MAX_TOKENS = 64000;
|
|
13
13
|
declare const DEFAULT_MAX_OUTPUT_TOKENS = 65536;
|
|
@@ -100,6 +100,22 @@ interface CommandCodeConnectionOptions {
|
|
|
100
100
|
* text-only request never depends on the attachment seam.
|
|
101
101
|
*/
|
|
102
102
|
type ResolveAttachments = () => AttachmentStore | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* Why a pre-stream rejection rotates to another account. `rate-limit` and
|
|
105
|
+
* `invalid-credential` are the two the pool records as marks; `unavailable` is
|
|
106
|
+
* an account-scoped rejection that must NOT become a mark — the account's key
|
|
107
|
+
* is valid and its windows may be open, the ACCOUNT just cannot serve THIS
|
|
108
|
+
* request (no credits, a model outside its plan) — so the pool moves on
|
|
109
|
+
* without remembering anything.
|
|
110
|
+
*/
|
|
111
|
+
type AccountRotationReason = 'rate-limit' | 'invalid-credential' | 'unavailable';
|
|
112
|
+
/** What the rotation hook knows about the request it is rotating within. */
|
|
113
|
+
interface AccountRotationContext {
|
|
114
|
+
/** Every API key this request has already used, just-rejected key included. */
|
|
115
|
+
tried: readonly string[];
|
|
116
|
+
/** The provider's own reset time for a `rate-limit` rejection, in millis. */
|
|
117
|
+
resetAtMs?: number;
|
|
118
|
+
}
|
|
103
119
|
/** Everything the adapter needs beyond the request itself. */
|
|
104
120
|
interface CommandCodeAdapterDeps<C extends CommandCodeConnectionOptions = CommandCodeConnectionOptions> {
|
|
105
121
|
/** Resolve the current connection facts (fresh per request, settings-aware). */
|
|
@@ -112,13 +128,33 @@ interface CommandCodeAdapterDeps<C extends CommandCodeConnectionOptions = Comman
|
|
|
112
128
|
resolveApiKey: (connection: C, model?: string) => Promise<string>;
|
|
113
129
|
/**
|
|
114
130
|
* Multi-account rotation hook: the request sent with `rejectedKey` was
|
|
115
|
-
* refused
|
|
116
|
-
*
|
|
117
|
-
* account's key to retry with, or
|
|
118
|
-
* Only pre-stream rejections rotate — a
|
|
119
|
-
* partially consumed generation against
|
|
131
|
+
* refused before any response body streamed, for an account-scoped reason
|
|
132
|
+
* (see {@link AccountRotationReason}). The host marks that key when the
|
|
133
|
+
* reason warrants it and returns the next account's key to retry with, or
|
|
134
|
+
* `undefined` to surface the failure. Only pre-stream rejections rotate — a
|
|
135
|
+
* mid-stream failure never replays a partially consumed generation against
|
|
136
|
+
* another account.
|
|
137
|
+
*
|
|
138
|
+
* `rotation.tried` lists every key this request has already used (the
|
|
139
|
+
* just-rejected one included). The host must not offer one of them again:
|
|
140
|
+
* with several accounts a rejection that does not mark the key (a plan or
|
|
141
|
+
* balance rejection is model-specific, not account-fatal) would otherwise
|
|
142
|
+
* re-offer the same account on every attempt and the pool could never reach
|
|
143
|
+
* the accounts behind it.
|
|
144
|
+
*
|
|
145
|
+
* `rotation.resetAtMs` carries the provider's own reset time when the
|
|
146
|
+
* rejection body published one, so the host can hold the key out until then
|
|
147
|
+
* instead of waiting for a billing probe to learn the same fact.
|
|
148
|
+
*/
|
|
149
|
+
rotateApiKey?: (rejectedKey: string, rejection: AccountRotationReason, connection: C, model?: string, rotation?: AccountRotationContext) => Promise<string | undefined>;
|
|
150
|
+
/**
|
|
151
|
+
* Every API key the host can serve from, in rotation order and deduplicated
|
|
152
|
+
* — the multi-account pool's own list. The picker's plan filter asks all of
|
|
153
|
+
* them, because the pool (not any single account) is what serves a request;
|
|
154
|
+
* a host without a pool omits this seam and the filter falls back to the key
|
|
155
|
+
* that would serve the current request.
|
|
120
156
|
*/
|
|
121
|
-
|
|
157
|
+
resolveAccountKeys?: () => Promise<readonly string[]>;
|
|
122
158
|
/** HTTP transport override (tests); defaults to the global `fetch`. */
|
|
123
159
|
fetchImpl?: typeof fetch;
|
|
124
160
|
/** Resolve the optional durable attachment service for image input (tests); defaults to none. */
|
|
@@ -302,11 +338,30 @@ declare class CommandCodeAdapter<C extends CommandCodeConnectionOptions = Comman
|
|
|
302
338
|
*/
|
|
303
339
|
private fetchEndpointJson;
|
|
304
340
|
/**
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
*
|
|
341
|
+
* Every account's billing facts behind the picker's plan filter, in the
|
|
342
|
+
* pool's rotation order and cached per key for {@link BILLING_ACCESS_TTL_MS}
|
|
343
|
+
* (so the extra accounts cost their three requests once per TTL, not once
|
|
344
|
+
* per picker load). `undefined` means the filter cannot be evaluated at all
|
|
345
|
+
* — no key resolved — which {@link modelVisibleForAnyAccount} reads as
|
|
346
|
+
* "show everything".
|
|
347
|
+
*
|
|
348
|
+
* The serving account is only the first entry: with several accounts the
|
|
349
|
+
* model list must not depend on which of them rotation happens to be using.
|
|
350
|
+
*/
|
|
351
|
+
private loadPoolBillingAccess;
|
|
352
|
+
/**
|
|
353
|
+
* The API keys the picker's plan filter must consult: every account the host
|
|
354
|
+
* can serve from, in rotation order, when the host exposes one. A host
|
|
355
|
+
* without a pool (or without the seam) reports just the key that would serve
|
|
356
|
+
* this request — exactly the pre-pool behaviour.
|
|
357
|
+
*/
|
|
358
|
+
private poolAccountKeys;
|
|
359
|
+
/**
|
|
360
|
+
* One account's billing facts, cached for {@link BILLING_ACCESS_TTL_MS} and
|
|
361
|
+
* shared across concurrent callers. `undefined` means "unknown — show
|
|
362
|
+
* everything" (fail-open).
|
|
308
363
|
*/
|
|
309
|
-
private
|
|
364
|
+
private loadBillingAccessForKey;
|
|
310
365
|
/**
|
|
311
366
|
* The billing facts behind the picker's plan filter, mirroring the CLI's
|
|
312
367
|
* `createBilling` flow: whoami yields the org id, then the subscriptions
|
|
@@ -354,14 +409,29 @@ declare class CommandCodeAdapter<C extends CommandCodeConnectionOptions = Comman
|
|
|
354
409
|
*/
|
|
355
410
|
getUsage(apiKey?: string): Promise<CommandCodeUsageReport>;
|
|
356
411
|
/**
|
|
357
|
-
* Probe one account's
|
|
412
|
+
* Probe one account's real usage windows from `/alpha/billing/credits`. The
|
|
358
413
|
* multi-account pool calls this when every account is marked exhausted: an
|
|
359
|
-
* account whose
|
|
360
|
-
* `resetAt` values feed the "earliest reset" error message.
|
|
361
|
-
*
|
|
362
|
-
*
|
|
414
|
+
* account whose windows no longer report `exceeded` is revived, and the
|
|
415
|
+
* `resetAt` values feed the "earliest reset" error message.
|
|
416
|
+
*
|
|
417
|
+
* BOTH windows the endpoint publishes are read, not just `fiveHour`. An
|
|
418
|
+
* account can have an open five-hour window and an exhausted WEEKLY quota at
|
|
419
|
+
* the same time (the two are metered separately), and reading only the
|
|
420
|
+
* shorter one revived such an account as "usable" — the pool then handed it
|
|
421
|
+
* out, the provider rejected the request again, and the next all-marked pass
|
|
422
|
+
* revived it once more, so a used-up account kept coming back (issue #51's
|
|
423
|
+
* follow-up: "切到一个不可用账号"). `exceeded` is therefore true when ANY
|
|
424
|
+
* published window is exceeded, and `resetAt` is the LATEST reset among the
|
|
425
|
+
* exceeded ones — the binding constraint, because a clear five-hour window
|
|
426
|
+
* buys nothing while the weekly quota is spent.
|
|
427
|
+
*
|
|
428
|
+
* Returns `undefined` when the probe itself failed (transport, non-200, or a
|
|
429
|
+
* payload with no window limits at all) — a failed probe never changes pool
|
|
430
|
+
* state. The monthly/purchased/free credit balances are deliberately NOT part
|
|
431
|
+
* of this answer: they are balances rather than windows, they carry no reset
|
|
432
|
+
* time, and the server remains the final gate on them.
|
|
363
433
|
*/
|
|
364
|
-
|
|
434
|
+
probeWindowLimits(apiKey: string): Promise<{
|
|
365
435
|
exceeded: boolean;
|
|
366
436
|
resetAt: number;
|
|
367
437
|
} | undefined>;
|
|
@@ -414,8 +484,13 @@ interface ResolvedAccount {
|
|
|
414
484
|
/** The key's current rotation state; undefined means usable. */
|
|
415
485
|
state: CommandCodeAccountState | undefined;
|
|
416
486
|
}
|
|
417
|
-
/**
|
|
418
|
-
|
|
487
|
+
/**
|
|
488
|
+
* One account's real rate-limit state, probed from `/alpha/billing/credits`:
|
|
489
|
+
* `exceeded` is true when ANY of the account's usage windows is spent, and
|
|
490
|
+
* `resetAt` is the latest reset among them (the binding constraint — an open
|
|
491
|
+
* five-hour window buys nothing while the weekly quota is exhausted).
|
|
492
|
+
*/
|
|
493
|
+
interface AccountWindowProbe {
|
|
419
494
|
exceeded: boolean;
|
|
420
495
|
resetAt: number;
|
|
421
496
|
}
|
|
@@ -427,13 +502,19 @@ interface CommandCodeAccountPoolDeps {
|
|
|
427
502
|
resolveRef(ref: CredentialRef): Promise<string | undefined>;
|
|
428
503
|
/** The official CLI auth-file key (`~/.commandcode/auth.json`); default slot only. */
|
|
429
504
|
authFileKey(): string | undefined;
|
|
430
|
-
/**
|
|
431
|
-
|
|
505
|
+
/**
|
|
506
|
+
* Probe one key's usage windows — BOTH windows the endpoint publishes (the
|
|
507
|
+
* five-hour and the weekly one), not just the five-hour one; see
|
|
508
|
+
* {@link AccountWindowProbe}. Undefined when the probe itself failed.
|
|
509
|
+
*/
|
|
510
|
+
probeWindow(apiKey: string): Promise<AccountWindowProbe | undefined>;
|
|
432
511
|
/**
|
|
433
512
|
* The manually selected account (a slot id, e.g. `default` or an extra's
|
|
434
513
|
* credential reference), re-read per resolution. The preferred account
|
|
435
514
|
* serves whenever it is usable; an unknown id or an exhausted preferred
|
|
436
|
-
* account falls back to the first usable slot
|
|
515
|
+
* account falls back to the first usable slot — and an exhausted one is
|
|
516
|
+
* re-probed on the way (see {@link CommandCodeAccountPool.resolveKey}), so
|
|
517
|
+
* the fallback lasts only as long as the window really is exceeded.
|
|
437
518
|
*/
|
|
438
519
|
preferredId?(): string | undefined;
|
|
439
520
|
/**
|
|
@@ -445,6 +526,13 @@ interface CommandCodeAccountPoolDeps {
|
|
|
445
526
|
* back to the normal selection (the router is a hint, never a hard gate).
|
|
446
527
|
*/
|
|
447
528
|
modelAccountRules?(): readonly CommandCodeModelAccountRule[];
|
|
529
|
+
/**
|
|
530
|
+
* Clock seam for the explicit-account probe throttle. Tests drive it so the
|
|
531
|
+
* "the interval elapsed, probe again" half of
|
|
532
|
+
* {@link CommandCodeAccountPool.canProbeExplicit} is reachable without
|
|
533
|
+
* waiting a real minute; production reads `Date.now()`.
|
|
534
|
+
*/
|
|
535
|
+
now?(): number;
|
|
448
536
|
}
|
|
449
537
|
/**
|
|
450
538
|
* One "route these models to that account" rule. `models` lists catalog ids
|
|
@@ -493,6 +581,8 @@ declare class CommandCodeAccountPool {
|
|
|
493
581
|
private readonly deps;
|
|
494
582
|
/** Rotation state by API key. */
|
|
495
583
|
private readonly states;
|
|
584
|
+
/** Last explicit-revival probe attempt by API key (throttles a failing probe). */
|
|
585
|
+
private readonly explicitProbes;
|
|
496
586
|
constructor(deps: CommandCodeAccountPoolDeps);
|
|
497
587
|
/**
|
|
498
588
|
* Resolve every slot's key, deduplicated by key (first slot wins). Slots
|
|
@@ -519,25 +609,37 @@ declare class CommandCodeAccountPool {
|
|
|
519
609
|
* `options.model` is the request's model id; routing rules re-read per
|
|
520
610
|
* resolution, so a settings change applies live.
|
|
521
611
|
*
|
|
522
|
-
* `options.
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
612
|
+
* `options.tried` lists the keys this request has already used — the
|
|
613
|
+
* just-rejected one included. They are removed from the resolution entirely,
|
|
614
|
+
* which is what lets one request walk a four-account pool: an account-scoped
|
|
615
|
+
* rejection that does not mark the key (no credits, a model outside the
|
|
616
|
+
* account's plan) would otherwise be offered again on every attempt, and the
|
|
617
|
+
* accounts behind it would never be reached.
|
|
618
|
+
*
|
|
619
|
+
* An explicit selection (the pin or a model rule) that a rate-limit mark
|
|
620
|
+
* would demote is probed before the fallback serves, so "falls back while
|
|
621
|
+
* exhausted" never becomes "stays demoted until the process restarts".
|
|
526
622
|
*/
|
|
527
623
|
resolveKey(options?: {
|
|
528
|
-
|
|
624
|
+
tried?: readonly string[];
|
|
529
625
|
model?: string;
|
|
530
626
|
}): Promise<{
|
|
531
627
|
key: string;
|
|
532
628
|
slot: CommandCodeAccountSlot;
|
|
533
629
|
} | undefined>;
|
|
534
630
|
/**
|
|
535
|
-
* Record a rejection against one key. `rate-limit`
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
*
|
|
631
|
+
* Record a rejection against one key. `rate-limit` marks the key exhausted
|
|
632
|
+
* (`429`/`RATE_LIMITED`) — as a `cooldown` until `resetAtMs` when the
|
|
633
|
+
* rejection body published the provider's own reset time, otherwise as an
|
|
634
|
+
* `unknown` mark whose reset is probed lazily — and `invalid-credential`
|
|
635
|
+
* (401) disables the key until the stored credential changes.
|
|
636
|
+
*
|
|
637
|
+
* `resetAtMs` is seconds-to-millis converted by the adapter from the
|
|
638
|
+
* provider's `error.rateLimit.reset`: knowing the real reset immediately is
|
|
639
|
+
* what keeps an exhausted account out of rotation for exactly as long as the
|
|
640
|
+
* provider said, instead of until a probe happens to run.
|
|
539
641
|
*/
|
|
540
|
-
markRejected(apiKey: string, rejection: AccountRejection): void;
|
|
642
|
+
markRejected(apiKey: string, rejection: AccountRejection, resetAtMs?: number): void;
|
|
541
643
|
/**
|
|
542
644
|
* One account's key: literal → credential seam → auth file (default slot).
|
|
543
645
|
*
|
|
@@ -553,6 +655,35 @@ declare class CommandCodeAccountPool {
|
|
|
553
655
|
* agree on one string.
|
|
554
656
|
*/
|
|
555
657
|
private resolveSlotKey;
|
|
658
|
+
/**
|
|
659
|
+
* The account the user explicitly asked for: the slot a model rule routes
|
|
660
|
+
* the request to when that id exists among the resolved slots, else the
|
|
661
|
+
* manually pinned slot. Consulted only on the fallback path — a usable
|
|
662
|
+
* routed account already returned above — so unlike
|
|
663
|
+
* {@link selectAccountForModel} it does NOT require the account to be
|
|
664
|
+
* usable, which is exactly what {@link resolveKey} re-probes.
|
|
665
|
+
*/
|
|
666
|
+
private explicitAccount;
|
|
667
|
+
/**
|
|
668
|
+
* Whether an explicitly selected account's mark is due for a window probe.
|
|
669
|
+
* Only an `unknown` mark (a 429 whose reset was never learned) is worth
|
|
670
|
+
* re-probing: a `cooldown` already carries its reset time and expires by
|
|
671
|
+
* itself, and a `disabled` (401) key stays out until the stored credential
|
|
672
|
+
* changes. The interval bounds a probe endpoint that keeps failing.
|
|
673
|
+
*/
|
|
674
|
+
private canProbeExplicit;
|
|
675
|
+
/** The clock the probe throttle reads; injected so a test can travel in time. */
|
|
676
|
+
private now;
|
|
677
|
+
/**
|
|
678
|
+
* Probe one explicitly selected account's window and apply the answer. A
|
|
679
|
+
* window that is no longer exceeded drops the mark, so the user's own
|
|
680
|
+
* selection serves again on this very request. An exceeded one is stamped
|
|
681
|
+
* as a cooldown carrying the provider's reset time, after which
|
|
682
|
+
* {@link accountUsable} lets the account back in with no further probe. A
|
|
683
|
+
* probe that fails changes nothing: the mark stays `unknown` and the next
|
|
684
|
+
* attempt waits out the interval.
|
|
685
|
+
*/
|
|
686
|
+
private probeExplicit;
|
|
556
687
|
/** Hand out the chosen account's key. */
|
|
557
688
|
private pick;
|
|
558
689
|
}
|
|
@@ -615,8 +746,9 @@ declare const KNOWN_IMAGE_MODELS: ReadonlySet<string>;
|
|
|
615
746
|
* `['low', 'medium', 'high']` efforts in command-code@1.38.0 and moved to
|
|
616
747
|
* `KNOWN_EFFORTS`. `moonshotai/Kimi-K3` followed the same path in
|
|
617
748
|
* command-code@1.39.3 — it gained `['low', 'high', 'max']` efforts and moved
|
|
618
|
-
* to `KNOWN_EFFORTS`. command-code@1.42.0 added
|
|
619
|
-
*
|
|
749
|
+
* to `KNOWN_EFFORTS`. command-code@1.42.0 added LongCat 2.0 (then
|
|
750
|
+
* `meituan/LongCat-2.0:free`, now the paid `meituan/LongCat-2.0`; reasoning:!0,
|
|
751
|
+
* no efforts). command-code@1.45.0 gave the Muse Spark family
|
|
620
752
|
* (1.1, 1.2, 1.2-contributor, 1.3, 1.3-contributor) selectable
|
|
621
753
|
* `['low', 'medium', 'high', 'xhigh']` efforts — they moved to `KNOWN_EFFORTS`.
|
|
622
754
|
* command-code@1.51.3 gave `MiniMaxAI/MiniMax-M3` selectable
|
|
@@ -639,11 +771,14 @@ declare const KNOWN_THINKING_MODELS: ReadonlySet<string>;
|
|
|
639
771
|
* the official plan/pricing pages grants individual-provider/max/ultra and
|
|
640
772
|
* teams-pro only, and the CLI's plan-access map blocks it on Go/GOAT/Pro.
|
|
641
773
|
* command-code@1.41.0 added `Qwen/Qwen3.8-Max-0902` (Go) and 1.42.0 added
|
|
642
|
-
*
|
|
774
|
+
* LongCat 2.0 (Go — a free promo until 2026-09-19, when the backend renamed
|
|
775
|
+
* `meituan/LongCat-2.0:free` to the paid `meituan/LongCat-2.0`); 1.43.0 added
|
|
643
776
|
* `google/gemini-3.8-flash` (GOAT) and 1.44.0 added `meta/muse-spark-1.3`
|
|
644
777
|
* (GOAT) plus its Contributor sibling (Go); command-code@1.52.0 added the
|
|
645
778
|
* free `inclusionai/ling-3.0-flash-sante:free` (Go); command-code@1.53.0
|
|
646
|
-
* added `deepseek/deepseek-v4.1-flash` (Go).
|
|
779
|
+
* added `deepseek/deepseek-v4.1-flash` (Go); command-code@1.56.0 added
|
|
780
|
+
* `Qwen/Qwen3.8-Omni-Flash` (Go); command-code@1.57.0 added
|
|
781
|
+
* `z-ai/glm-5.3-flashx` (Go).
|
|
647
782
|
*
|
|
648
783
|
* The Provider API exposes no plan metadata, so this snapshot is the source of
|
|
649
784
|
* truth for the picker's plan annotation — it answers "which plan do I need to
|