@mars-sea/dsh-commandcode-provider 0.11.17 → 0.12.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/lib/index.d.ts CHANGED
@@ -6,17 +6,96 @@ import { WebRuntime, WebSearchProvider, WebSearchRequest, WebSearchResult } from
6
6
  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
+ //#region src/request-timing.d.ts
10
+ type Phase = 'credentials' | 'images' | 'body' | 'serialization' | 'headers';
11
+ type Outcome = 'finished' | 'error' | 'aborted' | 'cancelled';
12
+ interface RequestTimingSummary {
13
+ version: 1;
14
+ startedAt: number;
15
+ model: string;
16
+ outcome: Outcome;
17
+ errorCode?: string;
18
+ totalMs: number;
19
+ phasesMs: Record<Phase, number>;
20
+ firstByteMs?: number;
21
+ firstContentMs?: number;
22
+ attempts: Array<{
23
+ protocol: string;
24
+ bodyBytes: number;
25
+ headersMs: number;
26
+ status?: number;
27
+ }>;
28
+ }
29
+ type RequestTimingSink = (summary: RequestTimingSummary) => void | Promise<void>;
30
+ //#endregion
9
31
  //#region src/adapter.d.ts
10
- declare const COMMAND_CODE_CLI_VERSION = "1.66.0";
32
+ declare const COMMAND_CODE_CLI_VERSION = "1.72.1";
11
33
  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;
34
+ /**
35
+ * The output budget this bundle asks for, and the ceiling it will never exceed.
36
+ *
37
+ * 131 072, chosen against a measured provider limit rather than a round guess.
38
+ * Probing `/alpha/generate` directly on 2026-09-28: 64 000 → 200, 131 072 → 200,
39
+ * 196 608 → 200, **200 000 → 200, 200 704 → 400**, 1 000 000 → 400. The server
40
+ * therefore caps `max_tokens` at 200 000, and it does so identically for a
41
+ * 262 144-window model (`stealth/pixel-canary`) and a 1 000 000-window one
42
+ * (`stealth/space-bunny-alpha`) — the cap is global, not per model. 131 072
43
+ * keeps a 35 % margin under it while covering the real output ceiling of the
44
+ * models that have one (Claude 64 K, Gemini 64 K, several at 128 K).
45
+ *
46
+ * The old 64 000 was never a provider requirement: it cost nothing in latency
47
+ * (a 64 000 request answered headers in 1.28 s against 1.57 s for 131 072) but
48
+ * it did cap what a model could ever say in one turn.
49
+ *
50
+ * This is only an UPPER bound. `requestContextBudget` lowers it per request
51
+ * from the prompt actually being sent, so raising the ceiling cannot push a
52
+ * large session over its window.
53
+ */
54
+ declare const DEFAULT_GENERATE_MAX_TOKENS = 131072;
55
+ /**
56
+ * The fallback when the catalog carries no output ceiling for a model.
57
+ *
58
+ * `/provider/v1/models` publishes only `context_length` — no output limit — so
59
+ * the catalog cannot learn one per model and derives a stand-in from the
60
+ * window instead. Kept equal to {@link DEFAULT_GENERATE_MAX_TOKENS} on purpose:
61
+ * a lower value here would silently re-cap every request through
62
+ * `Math.min(contextLength, this)` before the ceiling above is ever consulted.
63
+ */
64
+ declare const DEFAULT_MAX_OUTPUT_TOKENS = 131072;
14
65
  /** How long the picker's plan-filter billing facts stay cached before refetching. */
15
66
  declare const BILLING_ACCESS_TTL_MS: number;
16
- /** Endpoint protocol selected for one generate call. */
17
- 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;
67
+ /**
68
+ * Endpoint protocol selected for one generate call.
69
+ *
70
+ * `messages` is the Anthropic Messages surface at
71
+ * `{apiBase}/provider/v1/messages`, the only Provider API route the Claude
72
+ * family answers (posted to `/chat/completions` they refuse with `400 Model
73
+ * "<id>" must be called via /provider/v1/messages`). `openai` is the
74
+ * documented Chat Completions surface; `cli` is Command Code's private
75
+ * `/alpha/generate` transport, kept for Go-plan keys (the one plan without
76
+ * Provider API access) and as the `upgrade_required` fallback.
77
+ */
78
+ type CommandCodeProtocol = 'cli' | 'openai' | 'messages';
79
+ /**
80
+ * Head-of-request timeout: how long to wait for the first response byte.
81
+ *
82
+ * 300 s, and that number is the official CLI's, not a round choice. Decompiled
83
+ * from `command-code@1.66.0`: its `createNodeTransport` fetch passes only the
84
+ * caller's `signal` and sets no timeout at all, so the model request inherits
85
+ * Node/undici's own default — measured at 301.0 s against a local server that
86
+ * accepts the connection and never sends headers. The previous 60 s default was
87
+ * five times stricter than the CLI it emulates, and being stricter only ever
88
+ * costs legitimate requests: a slow upstream first token on the Provider API
89
+ * route can outlast 60 s, and the official CLI simply waits it out. Measured
90
+ * headers (2026-09-28, 26 250-token prompt, `max_tokens: 16` to separate the
91
+ * header from the generation): `/alpha/generate` 2.12 / 2.56 / 2.75 s,
92
+ * `/provider/v1/chat/completions` 5.52 / 2.98 / 3.70 s — a ~1.1 s median gap
93
+ * with the Provider API route varying over a 2.5 s span against the CLI route's
94
+ * 0.6 s. A gateway that is genuinely dead now takes longer to name itself,
95
+ * which is what the consecutive-timeout streak exists to bound (three
96
+ * attempts, then a diagnosis instead of another re-send).
97
+ */
98
+ declare const DEFAULT_REQUEST_TIMEOUT_MS = 300000;
20
99
  /** Stream idle timeout: a generation that stalls this long is a dead connection. */
21
100
  declare const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 300000;
22
101
  declare function projectSlugFromPath(pathName: string): string;
@@ -46,13 +125,23 @@ interface CommandCodeConnectionOptions {
46
125
  /** Model catalog cache path. */
47
126
  modelsCachePath: string;
48
127
  /**
49
- * Milliseconds to wait for generate response headers / first byte (default 60s).
128
+ * Milliseconds to wait for generate response headers / first byte (default
129
+ * 300s, the official CLI's own budget — see
130
+ * {@link DEFAULT_REQUEST_TIMEOUT_MS}).
50
131
  * Must not bound the subsequent body stream — long generations are gated by
51
132
  * {@link streamIdleTimeoutMs} and the caller AbortSignal instead.
52
133
  */
53
134
  requestTimeoutMs: number;
54
135
  /** Milliseconds a stream may stall before it is treated as a dead connection (default 300s). */
55
136
  streamIdleTimeoutMs: number;
137
+ /**
138
+ * Opt-in CLI cache mitigation: after this same model has answered with an
139
+ * image in its history, ask dsh's durable image-offload surface to replace
140
+ * that image before the next replay. This protects the growing text prefix
141
+ * when Command Code's multimodal cache retreats to the first image, but the
142
+ * model cannot inspect the old pixels again without a fresh tool/user image.
143
+ */
144
+ offloadSeenImagesForCache?: boolean;
56
145
  /**
57
146
  * Whether the picker hides models above the account's subscription tier
58
147
  * (default true). The filter fails open: unknown plan, billing-endpoint
@@ -124,6 +213,8 @@ interface AccountRotationContext {
124
213
  }
125
214
  /** Everything the adapter needs beyond the request itself. */
126
215
  interface CommandCodeAdapterDeps<C extends CommandCodeConnectionOptions = CommandCodeConnectionOptions> {
216
+ /** 可选的数值耗时接收器;不接收提示词、凭据或错误正文。 */
217
+ onRequestTiming?: RequestTimingSink;
127
218
  /** Resolve the current connection facts (fresh per request, settings-aware). */
128
219
  options: () => C;
129
220
  /**
@@ -269,6 +360,7 @@ interface CommandCodeUsageReport {
269
360
  declare class CommandCodeAdapter<C extends CommandCodeConnectionOptions = CommandCodeConnectionOptions> extends LlmAdapter {
270
361
  private readonly deps;
271
362
  private catalog;
363
+ private catalogState;
272
364
  private readonly fetchImpl;
273
365
  private readonly resolveAttachments;
274
366
  /**
@@ -279,7 +371,37 @@ declare class CommandCodeAdapter<C extends CommandCodeConnectionOptions = Comman
279
371
  private readonly billingAccess;
280
372
  private readonly billingAccessInflight;
281
373
  private readonly protocolCache;
374
+ /** Namespace account-derived facts by gateway without exposing the key. */
375
+ private accountCacheKey;
376
+ /**
377
+ * Consecutive header timeouts for the last request shape, counted ACROSS
378
+ * `stream()` calls: dsh-llm-retry re-invokes this same instance, so this is
379
+ * the only place a streak can live. Keyed by `sessionId` (not by `agent`:
380
+ * `GenerateOptions` carries no agent reference, only `sessionId`) so
381
+ * concurrent sessions on this one shared adapter instance cannot clear or
382
+ * inflate each other's count. A call with no `sessionId` (a one-shot,
383
+ * session-less caller) falls back to {@link GLOBAL_HEADER_TIMEOUT_KEY},
384
+ * matching the old single-slot behavior for exactly that case. Bounded by
385
+ * {@link MAX_HEADER_TIMEOUT_STREAK_ENTRIES} with FIFO eviction (`Map`
386
+ * preserves insertion order) since the key space is per-session rather than
387
+ * per-account/model, so it is not naturally small like `protocolCache`.
388
+ */
389
+ private readonly headerTimeoutStreaks;
390
+ private static readonly MAX_HEADER_TIMEOUT_STREAK_ENTRIES;
282
391
  constructor(deps: CommandCodeAdapterDeps<C>);
392
+ /**
393
+ * Grade one failed attempt: a headers timeout that repeats on an unchanged
394
+ * payload eventually leaves the retryable whitelist.
395
+ *
396
+ * `providerRetryPolicy()` cannot express this itself — dsh-llm's
397
+ * `NormalRetryPolicyConfig` carries one `maxRetries` for every listed code.
398
+ * Escalating here stops repeated identical header timeouts with a specific
399
+ * diagnosis; the agent listener separately caps ordinary transient errors.
400
+ *
401
+ * @returns the error to surface: unchanged for any other failure, the
402
+ * original timeout below the threshold, and a terminal one at it.
403
+ */
404
+ private gradeHeaderTimeout;
283
405
  /**
284
406
  * Display metadata for the picker's provider group header. The base class
285
407
  * returns the raw route id (`commandcode`, all lowercase) as the name, which
@@ -289,12 +411,11 @@ declare class CommandCodeAdapter<C extends CommandCodeConnectionOptions = Comman
289
411
  */
290
412
  providerInfo(provider: string): LlmProviderInfo;
291
413
  /**
292
- * Near-unbounded retry for transient failures only (`mode: 'normal'` with
293
- * an explicit 1000-attempt cap — opencode-style persistence without the
294
- * unbounded loop): `RATE_LIMIT`/`SERVER`/`TIMEOUT`/`TRANSPORT`/
295
- * `EMPTY_RESPONSE` retry up to 1000 times with waits doubling from 500 ms
296
- * and capping at 15 minutes (±10% jitter), so an exhausted 5-hour window
297
- * recovers in-session instead of failing after two tries. Permanent failures
414
+ * The official executor owns backoff and provider reset waits. Its high
415
+ * route-wide cap lets a confirmed `RATE_LIMIT` window recover in-session;
416
+ * our request-error listener limits `SERVER`/`TIMEOUT`/`EMPTY_RESPONSE`/
417
+ * `THROTTLED` to three retries and `TRANSPORT` to its separate budget.
418
+ * Waits double from 500 ms and cap at 15 minutes (±10% jitter). Permanent failures
298
419
  * (an invalid key's `INVALID_CREDENTIAL`, `UNSUPPORTED_CONTENT`, plan
299
420
  * rejections) are absent from the whitelist and surface immediately instead
300
421
  * of looping. Waits the pool/adapter attach as `providerRetryAfterMs` are
@@ -318,27 +439,42 @@ declare class CommandCodeAdapter<C extends CommandCodeConnectionOptions = Comman
318
439
  * requirement — the meter throws when the counts differ.
319
440
  */
320
441
  imageRequestPricing(_provider: string, model: string): LlmImageRequestPricing | undefined;
321
- /** Refresh the catalog (live fetch, cache fallback) and return it. */
442
+ /** 地址或缓存文件变化时丢弃旧目录,防止旧网关的路由声明影响新请求。 */
443
+ private currentCatalogState;
444
+ /** 共享一次刷新;调用者取消只结束自己的等待,不取消其他调用者的请求。 */
322
445
  private loadCatalog;
323
446
  listModels(provider: string, opts?: {
324
447
  unfiltered?: boolean;
325
448
  }): Promise<readonly LlmModelInfo[]>;
449
+ /**
450
+ * The per-model allowance bracket this account POOL falls into, or undefined
451
+ * when there is nothing honest to show.
452
+ *
453
+ * The pricing page publishes a per-model monthly allowance for GOAT and Pro
454
+ * only — its own words are "the boost is a per-model allowance, so it lives on
455
+ * the plans that have them" — so a pool whose highest plan is Go, Provider,
456
+ * Max or Ultra gets undefined rather than a neighbouring tier's figure. Taking
457
+ * the HIGHEST tier matches the question the picker already answers for a pool
458
+ * (see `modelVisibleForAnyAccount`): what the user can reach, not what the one
459
+ * account serving this request happens to be. The fail-open shape is the same
460
+ * too — an unreachable billing endpoint yields undefined, which hides the
461
+ * allowance instead of inventing one.
462
+ */
463
+ allowanceTier(): Promise<'goat' | 'pro' | undefined>;
326
464
  resolveModel(provider: string, model: string, signal?: AbortSignal): Promise<LlmResolvedModelInfo>;
327
465
  /** The headers every authenticated account endpoint shares. */
328
466
  private accountHeaders;
329
467
  /**
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.
468
+ * Fetch one JSON GET and return its HTTP status with a parsed record. The
469
+ * catalog, billing probe, and usage report each apply their own failure
470
+ * policy. Non-2xx and invalid JSON bodies come back without a record; only
471
+ * a fetch failure propagates to the caller.
335
472
  *
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.
473
+ * `timeoutMs` is the caller's budget, unless it provides its own signal.
474
+ * The usage report passes the connection's request budget rather than the
475
+ * catalog/picker's shorter default.
340
476
  */
341
- private fetchEndpointJson;
477
+ private fetchJson;
342
478
  /**
343
479
  * Every account's billing facts behind the picker's plan filter, in the
344
480
  * pool's rotation order and cached per key for {@link BILLING_ACCESS_TTL_MS}
@@ -374,25 +510,36 @@ declare class CommandCodeAdapter<C extends CommandCodeConnectionOptions = Comman
374
510
  /** Fresh cached billing tier weight for a key, or undefined when not known. */
375
511
  private cachedBillingTierWeight;
376
512
  /** Cached protocol decision for a key, or undefined when expired/unknown. */
377
- private cachedProtocolUseCli;
513
+ private cachedProtocol;
378
514
  private rememberProtocol;
379
515
  /**
380
- * Choose the initial protocol for one request. A fresh protocol cache entry
381
- * wins; otherwise a cached (not network-fetched) billing tier of Go is
382
- * treated as CLI-only. Unknown accounts default to Provider API and fall
383
- * back only after an `upgrade_required` rejection.
516
+ * True when the catalog routes `model` to `/provider/v1/messages`.
384
517
  *
385
- * Models the Provider API serves ONLY through `/provider/v1/messages` (the
386
- * Claude family — `requiresMessagesEndpoint()`) always take the CLI
387
- * transport, on any tier and even under a forced `'openai'` preference:
388
- * that option is documented as "prefer the Provider API, still fall back",
389
- * and the 400 these models answer with is not a preference to be honoured
390
- * but a hard refusal. `/alpha/generate` routes every one of them, so this
391
- * costs nothing.
518
+ * The catalog's own `supported_endpoints` is authoritative (it is what
519
+ * upstream publishes per model); `requiresMessagesEndpoint()` — the
520
+ * `claude-*` prefix rule — is the fallback for a catalog entry that carries
521
+ * no route list, which is the shape every pre-1.55 cache file has.
522
+ */
523
+ private routesToMessages;
524
+ /**
525
+ * Choose the initial protocol for one request.
526
+ *
527
+ * Models the Provider API serves only through `/provider/v1/messages` (the
528
+ * Claude family) take the Messages transport on any tier and even under a
529
+ * forced `'openai'` preference: that option is documented as "prefer the
530
+ * Provider API, still fall back", and the 400 these models answer with on
531
+ * Chat Completions (`Model "<id>" must be called via /provider/v1/messages`)
532
+ * is a hard refusal, not a preference to honour.
392
533
  *
393
534
  * That decision is deliberately NOT written to `protocolCache`, which is
394
- * keyed by API key alone: remembering it would pin the whole ACCOUNT to the
395
- * CLI transport and drag every other model off it until the entry expired.
535
+ * keyed by gateway and API key: it depends on the model, not just the account, so
536
+ * remembering it would pin the whole ACCOUNT to one transport and drag
537
+ * every other model along (issue #46).
538
+ *
539
+ * Otherwise a fresh protocol cache entry wins, then a cached (not
540
+ * network-fetched) billing tier of Go — the one plan without Provider API
541
+ * access. Unknown accounts default to Chat Completions and fall back to the
542
+ * CLI transport only after an `upgrade_required` rejection.
396
543
  */
397
544
  private resolveProtocol;
398
545
  /**
@@ -443,6 +590,26 @@ declare class CommandCodeAdapter<C extends CommandCodeConnectionOptions = Comman
443
590
  resetAt: number;
444
591
  } | undefined>;
445
592
  stream(options: GenerateOptions): AsyncIterable<StreamChunk>;
593
+ /**
594
+ * One turn, with at most one output-ceiling downshift.
595
+ *
596
+ * The ceiling a model accepts is not published anywhere the request can be
597
+ * built from (see `modelOutputTokenLimit`), and the endpoint states it only
598
+ * by refusing. That refusal is worth one retry rather than a failed turn: the
599
+ * harness's own recovery for it — compact the context — cannot help, because
600
+ * nothing about the context is wrong, and resending the identical request
601
+ * would be refused identically (issue #71). Reading the stated ceiling off
602
+ * the rejection turns one wasted turn into one, for good: it is recorded
603
+ * process-wide, so the next request for this model is built correctly
604
+ * without spending the round trip again.
605
+ *
606
+ * Only BEFORE the first chunk reaches the host. Once a delta has been
607
+ * delivered the answer is already partly on screen, and a second request
608
+ * would duplicate it — so from that point the error stands and says what is
609
+ * actually wrong. One downshift per turn, and a second refusal surfaces.
610
+ */
611
+ private streamRequest;
612
+ private streamAttempt;
446
613
  }
447
614
  //#endregion
448
615
  //#region src/accounts.d.ts
@@ -616,26 +783,18 @@ declare class CommandCodeAccountPool {
616
783
  */
617
784
  describeAccounts(): Promise<ResolvedAccount[]>;
618
785
  /**
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.
786
+ * Hand out the key for a request: the model-routed account when usable, else
787
+ * the manually preferred account when usable, else the first usable account
788
+ * in rotation order. Returns `undefined` when no account resolves any key,
789
+ * or when an account this request already used is still UNMARKED — the
790
+ * caller's own rejection is the honest answer then. Throws `RATE_LIMIT` /
791
+ * `INVALID_CREDENTIAL` when every account is marked.
635
792
  *
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).
793
+ * `options.tried` lists the keys this request already used; they are removed
794
+ * from the resolution entirely, which is what lets one request walk a
795
+ * four-account pool. An explicit selection (pin or model rule) that a
796
+ * rate-limit mark would demote is probed first, so a fallback never becomes
797
+ * permanent (issue #51). Rules re-read per resolution, so settings apply live.
639
798
  */
640
799
  resolveKey(options?: {
641
800
  tried?: readonly string[];
@@ -699,26 +858,25 @@ declare class CommandCodeAccountPool {
699
858
  * attempt waits out the interval.
700
859
  */
701
860
  private probeExplicit;
861
+ /**
862
+ * Stamp a probe-read window onto one key. A known reset becomes a cooldown
863
+ * that expires by itself; without one the mark stays `unknown`, so a later
864
+ * probe can still learn it — and a mark that already carries a cooldown
865
+ * keeps it, never trading a known reset for an unknown one. The cause is
866
+ * `window` either way: a probe that read a window as exceeded IS window
867
+ * evidence, whatever the key was marked for. An `until: 0` cooldown would
868
+ * read as "never usable again" to {@link accountUsable}, so `unknown` it is.
869
+ */
870
+ private stampWindowMark;
702
871
  /** Hand out the chosen account's key. */
703
872
  private pick;
704
873
  }
705
874
  //#endregion
875
+ //#region src/plan-tiers.d.ts
876
+ declare const PLAN_LABELS: Readonly<Record<string, string>>;
877
+ declare const PLAN_ORDER: Readonly<Record<string, number>>;
878
+ //#endregion
706
879
  //#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
880
  declare const KNOWN_EFFORTS: Readonly<Record<string, readonly string[]>>;
723
881
  /**
724
882
  * Models whose Capabilities include Vision, per the official Command Code
@@ -738,12 +896,13 @@ declare const KNOWN_EFFORTS: Readonly<Record<string, readonly string[]>>;
738
896
  declare const KNOWN_IMAGE_MODELS: ReadonlySet<string>;
739
897
  /**
740
898
  * 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
899
+ * registry (`command-code@1.72.1` `dist/cli.mjs`): `modelSupportsZdr(id)` is
742
900
  * exactly `!nonZdrSet.has(canonicalize(id))`, and `knownModelSupportsZdr`
743
901
  * carries the same membership in the sibling route table — the UNION of both
744
902
  * 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/
903
+ * LongCat-2.0`, which appears in `modelSupportsZdr` alone (re-read from the
904
+ * 1.66.0 / 1.67.0 / 1.68.0 artifacts on 2026-09-29: the two stealth-preview
905
+ * rows sit in BOTH sets, so LongCat is the only divergence). The official docs (commandcode.ai/docs/resources/
747
906
  * zdr) put it in prose — "99% of our models have ZDR-capable upstreams … only
748
907
  * a small handful of models are affected" — so the CLI's exclusion list is
749
908
  * the only per-model evidence there is; a ZDR request naming one of these
@@ -765,8 +924,10 @@ declare const KNOWN_IMAGE_MODELS: ReadonlySet<string>;
765
924
  * (its `zdr:{only:[…]}` provider routes and the per-provider `zdr`/`noTraining`
766
925
  * flags) is upstream-internal routing, not a per-model contract, so this table
767
926
  * 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).
927
+ * 20 members held across 1.62.0 → 1.64.0, 1.65.0 and 1.66.0 each added exactly
928
+ * one (the two stealth-preview models below), 1.67.0 added one
929
+ * (`deepseek/deepseek-v4.1-flash-fast`), and 1.68.0 changed nothing — 23
930
+ * members as of 2026-09-29.
770
931
  */
771
932
  declare const KNOWN_NON_ZDR_MODELS: ReadonlySet<string>;
772
933
  /**
@@ -796,8 +957,8 @@ declare const KNOWN_THINKING_MODELS: ReadonlySet<string>;
796
957
  * `/docs/plans/max` and `/docs/resources/pricing-limits`). Each plan's model
797
958
  * list is a superset of the one below it: Go ⊂ GOAT ⊂ Pro ⊂ Provider/Max.
798
959
  * 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
960
+ * Provider-tier. Re-verified at command-code@1.72.1 (2026-09-30): 86 catalog
961
+ * ids at 53/62/76/84 cumulative, a strict superset chain — every release since
801
962
  * 1.49.0 has been additive with no tier move, and per-entry tags below name the
802
963
  * release that added each row.
803
964
  *
@@ -810,13 +971,6 @@ declare const KNOWN_THINKING_MODELS: ReadonlySet<string>;
810
971
  * dsh-commandcode-upstream skill).
811
972
  */
812
973
  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
974
  /**
821
975
  * Comparator for the model picker: free models first (zero credit cost, usable
822
976
  * by every account), then by plan tier (lowest first), then by model name,
@@ -832,7 +986,7 @@ declare function compareByPlan(a: {
832
986
  /**
833
987
  * Subscription plan table, synced from the official CLI bundle's plan maps
834
988
  * (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
989
+ * through command-code@1.72.1): subscription `planId` prefix → display name and
836
990
  * the plan's monthly credit total. This is the account's own subscription
837
991
  * (from `/alpha/billing/subscriptions`) — distinct from {@link KNOWN_PLANS},
838
992
  * which maps catalog models to their minimum tier.
@@ -917,7 +1071,7 @@ declare const KNOWN_DEALS: Readonly<Record<string, KnownDeal>>;
917
1071
  * charges by the hour: peak hours are 01:00–04:00 and 06:00–10:00 UTC (7h per
918
1072
  * weekday, full price) **Monday to Friday only**; the other 17 hours of a
919
1073
  * 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).
1074
+ * Exactly five models carry the page's `timeOfDay` block (the five rows below).
921
1075
  * The picker shows the *current* state as a compact label (`Peak`/`Half`)
922
1076
  * matching the English noun style of the other markers (`Image`, `FREE`), so a
923
1077
  * developer can tell at a glance whether calling the model right now is cheap
@@ -1024,6 +1178,20 @@ interface CommandCodeCatalogModel {
1024
1178
  * capability snapshot, so the Host stamps it per entry.
1025
1179
  */
1026
1180
  tier?: string;
1181
+ /**
1182
+ * Per-model MONTHLY allowance in USD: how much of the plan's monthly credit
1183
+ * pool this one model may draw, already resolved by the Host against the
1184
+ * account pool's highest plan (the pricing page publishes an allowance for
1185
+ * GOAT and Pro only). Undefined when that plan has no published allowance
1186
+ * (Go, Provider, Max, Ultra) or when billing could not be read — the browser
1187
+ * shows nothing rather than guessing a neighbouring tier's figure.
1188
+ *
1189
+ * Deliberately a plain number and not the `{ goat, pro }` pair: the bracket is
1190
+ * a Host decision that already depends on facts the browser does not hold, and
1191
+ * shipping both figures would invite a second, divergent rule here. Note this
1192
+ * is dollars per MONTH, unlike every rate in `CommandCodePriceTable`.
1193
+ */
1194
+ allowance?: number;
1027
1195
  }
1028
1196
  /** The model-catalog Remote result: the full catalog, sorted for picking. */
1029
1197
  interface CommandCodeCatalog {
@@ -1696,11 +1864,18 @@ interface Config {
1696
1864
  requestTimeoutMs?: number;
1697
1865
  /** Milliseconds a stream may stall before being treated as a dead connection; defaults to 300s. */
1698
1866
  streamIdleTimeoutMs?: number;
1867
+ /**
1868
+ * Opt-in cache mitigation for the CLI route: after this model has answered,
1869
+ * durably offload its earlier images before later turns. Old pixels then
1870
+ * require a fresh read/attachment if the model needs to inspect them again.
1871
+ * Defaults to false to preserve full image history.
1872
+ */
1873
+ offloadSeenImagesForCache?: boolean;
1699
1874
  /**
1700
1875
  * Transport failures one request absorbs before the failure is surfaced;
1701
- * defaults to 5. The route's retry policy is near-unbounded on purpose
1702
- * (1000 attempts, waits doubling to 15 minutes) because that shape is for
1703
- * the failures a provider asks to have retried; a transport failure is not
1876
+ * defaults to 5. The route's policy allows long waits for confirmed usage
1877
+ * windows, while ordinary transient errors have a separate three-retry
1878
+ * budget. A transport failure is not
1704
1879
  * one of those, and after ~15.5 s of grace the wait is pure stall, so it is
1705
1880
  * capped here (issue #39). 0 surfaces every transport failure immediately.
1706
1881
  */