@mars-sea/dsh-commandcode-provider 0.11.17 → 0.12.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/lib/index.d.ts CHANGED
@@ -7,16 +7,63 @@ import { Context } from "@deepseek-ai/cordis";
7
7
  import { AttachmentStore } 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.66.0";
10
+ declare const COMMAND_CODE_CLI_VERSION = "1.68.0";
11
11
  declare const DEFAULT_API_BASE = "https://api.commandcode.ai";
12
- declare const DEFAULT_GENERATE_MAX_TOKENS = 64000;
13
- declare const DEFAULT_MAX_OUTPUT_TOKENS = 65536;
12
+ /**
13
+ * The output budget this bundle asks for, and the ceiling it will never exceed.
14
+ *
15
+ * 131 072, chosen against a measured provider limit rather than a round guess.
16
+ * Probing `/alpha/generate` directly on 2026-09-28: 64 000 → 200, 131 072 → 200,
17
+ * 196 608 → 200, **200 000 → 200, 200 704 → 400**, 1 000 000 → 400. The server
18
+ * therefore caps `max_tokens` at 200 000, and it does so identically for a
19
+ * 262 144-window model (`stealth/pixel-canary`) and a 1 000 000-window one
20
+ * (`stealth/space-bunny-alpha`) — the cap is global, not per model. 131 072
21
+ * keeps a 35 % margin under it while covering the real output ceiling of the
22
+ * models that have one (Claude 64 K, Gemini 64 K, several at 128 K).
23
+ *
24
+ * The old 64 000 was never a provider requirement: it cost nothing in latency
25
+ * (a 64 000 request answered headers in 1.28 s against 1.57 s for 131 072) but
26
+ * it did cap what a model could ever say in one turn.
27
+ *
28
+ * This is only an UPPER bound. `requestContextBudget` lowers it per request
29
+ * from the prompt actually being sent, so raising the ceiling cannot push a
30
+ * large session over its window.
31
+ */
32
+ declare const DEFAULT_GENERATE_MAX_TOKENS = 131072;
33
+ /**
34
+ * The fallback when the catalog carries no output ceiling for a model.
35
+ *
36
+ * `/provider/v1/models` publishes only `context_length` — no output limit — so
37
+ * the catalog cannot learn one per model and derives a stand-in from the
38
+ * window instead. Kept equal to {@link DEFAULT_GENERATE_MAX_TOKENS} on purpose:
39
+ * a lower value here would silently re-cap every request through
40
+ * `Math.min(contextLength, this)` before the ceiling above is ever consulted.
41
+ */
42
+ declare const DEFAULT_MAX_OUTPUT_TOKENS = 131072;
14
43
  /** How long the picker's plan-filter billing facts stay cached before refetching. */
15
44
  declare const BILLING_ACCESS_TTL_MS: number;
16
45
  /** Endpoint protocol selected for one generate call. */
17
46
  type CommandCodeProtocol = 'cli' | 'openai';
18
- /** Head-of-request timeout: how long to wait for the first response byte. */
19
- declare const DEFAULT_REQUEST_TIMEOUT_MS = 60000;
47
+ /**
48
+ * Head-of-request timeout: how long to wait for the first response byte.
49
+ *
50
+ * 300 s, and that number is the official CLI's, not a round choice. Decompiled
51
+ * from `command-code@1.66.0`: its `createNodeTransport` fetch passes only the
52
+ * caller's `signal` and sets no timeout at all, so the model request inherits
53
+ * Node/undici's own default — measured at 301.0 s against a local server that
54
+ * accepts the connection and never sends headers. The previous 60 s default was
55
+ * five times stricter than the CLI it emulates, and being stricter only ever
56
+ * costs legitimate requests: a slow upstream first token on the Provider API
57
+ * route can outlast 60 s, and the official CLI simply waits it out. Measured
58
+ * headers (2026-09-28, 26 250-token prompt, `max_tokens: 16` to separate the
59
+ * header from the generation): `/alpha/generate` 2.12 / 2.56 / 2.75 s,
60
+ * `/provider/v1/chat/completions` 5.52 / 2.98 / 3.70 s — a ~1.1 s median gap
61
+ * with the Provider API route varying over a 2.5 s span against the CLI route's
62
+ * 0.6 s. A gateway that is genuinely dead now takes longer to name itself,
63
+ * which is what the consecutive-timeout streak exists to bound (three
64
+ * attempts, then a diagnosis instead of another re-send).
65
+ */
66
+ declare const DEFAULT_REQUEST_TIMEOUT_MS = 300000;
20
67
  /** Stream idle timeout: a generation that stalls this long is a dead connection. */
21
68
  declare const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 300000;
22
69
  declare function projectSlugFromPath(pathName: string): string;
@@ -46,13 +93,23 @@ interface CommandCodeConnectionOptions {
46
93
  /** Model catalog cache path. */
47
94
  modelsCachePath: string;
48
95
  /**
49
- * Milliseconds to wait for generate response headers / first byte (default 60s).
96
+ * Milliseconds to wait for generate response headers / first byte (default
97
+ * 300s, the official CLI's own budget — see
98
+ * {@link DEFAULT_REQUEST_TIMEOUT_MS}).
50
99
  * Must not bound the subsequent body stream — long generations are gated by
51
100
  * {@link streamIdleTimeoutMs} and the caller AbortSignal instead.
52
101
  */
53
102
  requestTimeoutMs: number;
54
103
  /** Milliseconds a stream may stall before it is treated as a dead connection (default 300s). */
55
104
  streamIdleTimeoutMs: number;
105
+ /**
106
+ * Opt-in CLI cache mitigation: after this same model has answered with an
107
+ * image in its history, ask dsh's durable image-offload surface to replace
108
+ * that image before the next replay. This protects the growing text prefix
109
+ * when Command Code's multimodal cache retreats to the first image, but the
110
+ * model cannot inspect the old pixels again without a fresh tool/user image.
111
+ */
112
+ offloadSeenImagesForCache?: boolean;
56
113
  /**
57
114
  * Whether the picker hides models above the account's subscription tier
58
115
  * (default true). The filter fails open: unknown plan, billing-endpoint
@@ -279,7 +336,29 @@ declare class CommandCodeAdapter<C extends CommandCodeConnectionOptions = Comman
279
336
  private readonly billingAccess;
280
337
  private readonly billingAccessInflight;
281
338
  private readonly protocolCache;
339
+ /**
340
+ * Consecutive header timeouts for the last request shape, counted ACROSS
341
+ * `stream()` calls: dsh-llm-retry re-invokes this same instance, so this is
342
+ * the only place a streak can live. One slot rather than a map is the point —
343
+ * the claim is "consecutive", and a single record cannot grow.
344
+ */
345
+ private headerTimeoutStreak;
282
346
  constructor(deps: CommandCodeAdapterDeps<C>);
347
+ /**
348
+ * Grade one failed attempt: a headers timeout that repeats on an unchanged
349
+ * payload eventually leaves the retryable whitelist.
350
+ *
351
+ * `providerRetryPolicy()` cannot express this itself — dsh-llm's
352
+ * `NormalRetryPolicyConfig` carries a single scalar `maxRetries` next to the
353
+ * code list, so there is no per-code limit to lower. Escalating from here is
354
+ * the only way to keep `RATE_LIMIT` / `SERVER` / `TRANSPORT` retryable (each
355
+ * carries a real "try again later" signal) while stopping the one code that,
356
+ * repeated unchanged, only burns the user's session.
357
+ *
358
+ * @returns the error to surface: unchanged for any other failure, the
359
+ * original timeout below the threshold, and a terminal one at it.
360
+ */
361
+ private gradeHeaderTimeout;
283
362
  /**
284
363
  * Display metadata for the picker's provider group header. The base class
285
364
  * returns the raw route id (`commandcode`, all lowercase) as the name, which
@@ -323,22 +402,35 @@ declare class CommandCodeAdapter<C extends CommandCodeConnectionOptions = Comman
323
402
  listModels(provider: string, opts?: {
324
403
  unfiltered?: boolean;
325
404
  }): Promise<readonly LlmModelInfo[]>;
405
+ /**
406
+ * The per-model allowance bracket this account POOL falls into, or undefined
407
+ * when there is nothing honest to show.
408
+ *
409
+ * The pricing page publishes a per-model monthly allowance for GOAT and Pro
410
+ * only — its own words are "the boost is a per-model allowance, so it lives on
411
+ * the plans that have them" — so a pool whose highest plan is Go, Provider,
412
+ * Max or Ultra gets undefined rather than a neighbouring tier's figure. Taking
413
+ * the HIGHEST tier matches the question the picker already answers for a pool
414
+ * (see `modelVisibleForAnyAccount`): what the user can reach, not what the one
415
+ * account serving this request happens to be. The fail-open shape is the same
416
+ * too — an unreachable billing endpoint yields undefined, which hides the
417
+ * allowance instead of inventing one.
418
+ */
419
+ allowanceTier(): Promise<'goat' | 'pro' | undefined>;
326
420
  resolveModel(provider: string, model: string, signal?: AbortSignal): Promise<LlmResolvedModelInfo>;
327
421
  /** The headers every authenticated account endpoint shares. */
328
422
  private accountHeaders;
329
423
  /**
330
- * Fetch one account endpoint and parse its JSON body. Returns the HTTP
331
- * status alongside the parsed record so each caller applies its own failure
332
- * accounting: the billing probe fails open silently, the usage report books
333
- * failures per endpoint. Non-2xx and invalid JSON bodies come back without a
334
- * record; only a fetch failure propagates to the caller.
424
+ * Fetch one JSON GET and return its HTTP status with a parsed record. The
425
+ * catalog, billing probe, and usage report each apply their own failure
426
+ * policy. Non-2xx and invalid JSON bodies come back without a record; only
427
+ * a fetch failure propagates to the caller.
335
428
  *
336
- * `timeoutMs` is the caller's budget for this one request. The default is the
337
- * CATALOG probe's short cap, which fits the picker's fail-open reads; the
338
- * usage report deliberately passes the connection's own request budget so an
339
- * account query is not held to a stricter (and invisible) limit than chat.
429
+ * `timeoutMs` is the caller's budget, unless it provides its own signal.
430
+ * The usage report passes the connection's request budget rather than the
431
+ * catalog/picker's shorter default.
340
432
  */
341
- private fetchEndpointJson;
433
+ private fetchJson;
342
434
  /**
343
435
  * Every account's billing facts behind the picker's plan filter, in the
344
436
  * pool's rotation order and cached per key for {@link BILLING_ACCESS_TTL_MS}
@@ -616,26 +708,18 @@ declare class CommandCodeAccountPool {
616
708
  */
617
709
  describeAccounts(): Promise<ResolvedAccount[]>;
618
710
  /**
619
- * Hand out the key for a request: the model-routed account when the request's
620
- * model matches a rule (and that account is usable), else the manually
621
- * preferred account when usable, else the first usable account in rotation
622
- * order. Returns `undefined` when no account resolves any key at all, or when
623
- * an account this request already used is still UNMARKED — that rejection is
624
- * the honest answer, so the caller's own rejection surfaces as itself. Throws
625
- * `RATE_LIMIT` (naming the earliest window reset) or `INVALID_CREDENTIAL`
626
- * when accounts exist but every one of them is marked.
627
- *
628
- * `options.model` is the request's model id; routing rules re-read per
629
- * resolution, so a settings change applies live. `options.tried` lists the
630
- * keys this request has already used — the just-rejected one included — and
631
- * they are removed from the resolution entirely, which is what lets one
632
- * request walk a four-account pool: a rejection that does not mark the key
633
- * (no credits, a model outside the account's plan) would otherwise be offered
634
- * again on every attempt and the accounts behind it never reached.
711
+ * Hand out the key for a request: the model-routed account when usable, else
712
+ * the manually preferred account when usable, else the first usable account
713
+ * in rotation order. Returns `undefined` when no account resolves any key,
714
+ * or when an account this request already used is still UNMARKED — the
715
+ * caller's own rejection is the honest answer then. Throws `RATE_LIMIT` /
716
+ * `INVALID_CREDENTIAL` when every account is marked.
635
717
  *
636
- * An explicit selection (the pin or a model rule) that a rate-limit mark would
637
- * demote is probed before the fallback serves, so "falls back while exhausted"
638
- * never becomes "stays demoted until the process restarts" (issue #51).
718
+ * `options.tried` lists the keys this request already used; they are removed
719
+ * from the resolution entirely, which is what lets one request walk a
720
+ * four-account pool. An explicit selection (pin or model rule) that a
721
+ * rate-limit mark would demote is probed first, so a fallback never becomes
722
+ * permanent (issue #51). Rules re-read per resolution, so settings apply live.
639
723
  */
640
724
  resolveKey(options?: {
641
725
  tried?: readonly string[];
@@ -699,26 +783,25 @@ declare class CommandCodeAccountPool {
699
783
  * attempt waits out the interval.
700
784
  */
701
785
  private probeExplicit;
786
+ /**
787
+ * Stamp a probe-read window onto one key. A known reset becomes a cooldown
788
+ * that expires by itself; without one the mark stays `unknown`, so a later
789
+ * probe can still learn it — and a mark that already carries a cooldown
790
+ * keeps it, never trading a known reset for an unknown one. The cause is
791
+ * `window` either way: a probe that read a window as exceeded IS window
792
+ * evidence, whatever the key was marked for. An `until: 0` cooldown would
793
+ * read as "never usable again" to {@link accountUsable}, so `unknown` it is.
794
+ */
795
+ private stampWindowMark;
702
796
  /** Hand out the chosen account's key. */
703
797
  private pick;
704
798
  }
705
799
  //#endregion
800
+ //#region src/plan-tiers.d.ts
801
+ declare const PLAN_LABELS: Readonly<Record<string, string>>;
802
+ declare const PLAN_ORDER: Readonly<Record<string, number>>;
803
+ //#endregion
706
804
  //#region src/capabilities.d.ts
707
- /**
708
- * Static capability snapshot for the Command Code provider: model →
709
- * reasoning-effort levels, vision/thinking flags, model → minimum plan tier,
710
- * subscription-plan labels, deals, and hourly (peak/off-peak) pricing.
711
- *
712
- * Everything here is synced from official sources — the command-code CLI
713
- * bundle's model table (`dist/cli.mjs`, re-verified at command-code@1.66.0) and
714
- * the official plan/pricing/model docs; see the dsh-commandcode-upstream skill
715
- * for the extraction procedures. Keeping the snapshot in its own module
716
- * confines those frequent sync diffs here: src/adapter.ts holds only the stable
717
- * wire/runtime logic. The read helpers live here too, for the same reason.
718
- *
719
- * Ported from pi-commandcode-provider (MIT); originally part of src/adapter.ts
720
- * and split out so upstream syncs stay reviewable.
721
- */
722
805
  declare const KNOWN_EFFORTS: Readonly<Record<string, readonly string[]>>;
723
806
  /**
724
807
  * Models whose Capabilities include Vision, per the official Command Code
@@ -738,12 +821,13 @@ declare const KNOWN_EFFORTS: Readonly<Record<string, readonly string[]>>;
738
821
  declare const KNOWN_IMAGE_MODELS: ReadonlySet<string>;
739
822
  /**
740
823
  * Models WITHOUT a zero-data-retention upstream, per the official CLI's own
741
- * registry (`command-code@1.66.0` `dist/cli.mjs`): `modelSupportsZdr(id)` is
824
+ * registry (`command-code@1.68.0` `dist/cli.mjs`): `modelSupportsZdr(id)` is
742
825
  * exactly `!nonZdrSet.has(canonicalize(id))`, and `knownModelSupportsZdr`
743
826
  * carries the same membership in the sibling route table — the UNION of both
744
827
  * is this set. Reading only the sibling route table would drop `meituan/
745
- * LongCat-2.0` and `stealth/pixel-canary`, which each appear in
746
- * `modelSupportsZdr` alone. The official docs (commandcode.ai/docs/resources/
828
+ * LongCat-2.0`, which appears in `modelSupportsZdr` alone (re-read from the
829
+ * 1.66.0 / 1.67.0 / 1.68.0 artifacts on 2026-09-29: the two stealth-preview
830
+ * rows sit in BOTH sets, so LongCat is the only divergence). The official docs (commandcode.ai/docs/resources/
747
831
  * zdr) put it in prose — "99% of our models have ZDR-capable upstreams … only
748
832
  * a small handful of models are affected" — so the CLI's exclusion list is
749
833
  * the only per-model evidence there is; a ZDR request naming one of these
@@ -765,8 +849,10 @@ declare const KNOWN_IMAGE_MODELS: ReadonlySet<string>;
765
849
  * (its `zdr:{only:[…]}` provider routes and the per-provider `zdr`/`noTraining`
766
850
  * flags) is upstream-internal routing, not a per-model contract, so this table
767
851
  * is the snapshot of the exclusion set and nothing more. It is a rare change:
768
- * 20 members held across 1.62.0 → 1.64.0, and 1.65.0 and 1.66.0 each added
769
- * exactly one (the two stealth-preview models below).
852
+ * 20 members held across 1.62.0 → 1.64.0, 1.65.0 and 1.66.0 each added exactly
853
+ * one (the two stealth-preview models below), 1.67.0 added one
854
+ * (`deepseek/deepseek-v4.1-flash-fast`), and 1.68.0 changed nothing — 23
855
+ * members as of 2026-09-29.
770
856
  */
771
857
  declare const KNOWN_NON_ZDR_MODELS: ReadonlySet<string>;
772
858
  /**
@@ -796,8 +882,8 @@ declare const KNOWN_THINKING_MODELS: ReadonlySet<string>;
796
882
  * `/docs/plans/max` and `/docs/resources/pricing-limits`). Each plan's model
797
883
  * list is a superset of the one below it: Go ⊂ GOAT ⊂ Pro ⊂ Provider/Max.
798
884
  * Models absent from every plan list (Claude Opus/Fable, Fugu Ultra) are
799
- * Provider-tier. Re-verified at command-code@1.66.0 (2026-09-27): 82 catalog
800
- * ids at 52/60/74/82 cumulative, a strict superset chain — every release since
885
+ * Provider-tier. Re-verified at command-code@1.68.0 (2026-09-29): 84 catalog
886
+ * ids at 53/62/76/84 cumulative, a strict superset chain — every release since
801
887
  * 1.49.0 has been additive with no tier move, and per-entry tags below name the
802
888
  * release that added each row.
803
889
  *
@@ -810,13 +896,6 @@ declare const KNOWN_THINKING_MODELS: ReadonlySet<string>;
810
896
  * dsh-commandcode-upstream skill).
811
897
  */
812
898
  declare const KNOWN_PLANS: Readonly<Record<string, string>>;
813
- /** Official display labels for each plan tier. */
814
- declare const PLAN_LABELS: Readonly<Record<string, string>>;
815
- /**
816
- * Plan-tier sort weights, low to high. Models outside the snapshot (unknown
817
- * plans) sort after every known tier, keeping known models predictable.
818
- */
819
- declare const PLAN_ORDER: Readonly<Record<string, number>>;
820
899
  /**
821
900
  * Comparator for the model picker: free models first (zero credit cost, usable
822
901
  * by every account), then by plan tier (lowest first), then by model name,
@@ -832,7 +911,7 @@ declare function compareByPlan(a: {
832
911
  /**
833
912
  * Subscription plan table, synced from the official CLI bundle's plan maps
834
913
  * (located by the `"individual-go"` key in `dist/cli.mjs`, re-verified unchanged
835
- * through command-code@1.66.0): subscription `planId` prefix → display name and
914
+ * through command-code@1.68.0): subscription `planId` prefix → display name and
836
915
  * the plan's monthly credit total. This is the account's own subscription
837
916
  * (from `/alpha/billing/subscriptions`) — distinct from {@link KNOWN_PLANS},
838
917
  * which maps catalog models to their minimum tier.
@@ -917,7 +996,7 @@ declare const KNOWN_DEALS: Readonly<Record<string, KnownDeal>>;
917
996
  * charges by the hour: peak hours are 01:00–04:00 and 06:00–10:00 UTC (7h per
918
997
  * weekday, full price) **Monday to Friday only**; the other 17 hours of a
919
998
  * weekday and every hour of Saturday/Sunday (UTC) are off-peak at half price.
920
- * Exactly four models carry the page's `timeOfDay` block (the four rows below).
999
+ * Exactly five models carry the page's `timeOfDay` block (the five rows below).
921
1000
  * The picker shows the *current* state as a compact label (`Peak`/`Half`)
922
1001
  * matching the English noun style of the other markers (`Image`, `FREE`), so a
923
1002
  * developer can tell at a glance whether calling the model right now is cheap
@@ -1024,6 +1103,20 @@ interface CommandCodeCatalogModel {
1024
1103
  * capability snapshot, so the Host stamps it per entry.
1025
1104
  */
1026
1105
  tier?: string;
1106
+ /**
1107
+ * Per-model MONTHLY allowance in USD: how much of the plan's monthly credit
1108
+ * pool this one model may draw, already resolved by the Host against the
1109
+ * account pool's highest plan (the pricing page publishes an allowance for
1110
+ * GOAT and Pro only). Undefined when that plan has no published allowance
1111
+ * (Go, Provider, Max, Ultra) or when billing could not be read — the browser
1112
+ * shows nothing rather than guessing a neighbouring tier's figure.
1113
+ *
1114
+ * Deliberately a plain number and not the `{ goat, pro }` pair: the bracket is
1115
+ * a Host decision that already depends on facts the browser does not hold, and
1116
+ * shipping both figures would invite a second, divergent rule here. Note this
1117
+ * is dollars per MONTH, unlike every rate in `CommandCodePriceTable`.
1118
+ */
1119
+ allowance?: number;
1027
1120
  }
1028
1121
  /** The model-catalog Remote result: the full catalog, sorted for picking. */
1029
1122
  interface CommandCodeCatalog {
@@ -1696,6 +1789,13 @@ interface Config {
1696
1789
  requestTimeoutMs?: number;
1697
1790
  /** Milliseconds a stream may stall before being treated as a dead connection; defaults to 300s. */
1698
1791
  streamIdleTimeoutMs?: number;
1792
+ /**
1793
+ * Opt-in cache mitigation for the CLI route: after this model has answered,
1794
+ * durably offload its earlier images before later turns. Old pixels then
1795
+ * require a fresh read/attachment if the model needs to inspect them again.
1796
+ * Defaults to false to preserve full image history.
1797
+ */
1798
+ offloadSeenImagesForCache?: boolean;
1699
1799
  /**
1700
1800
  * Transport failures one request absorbs before the failure is surfaced;
1701
1801
  * defaults to 5. The route's retry policy is near-unbounded on purpose