@eddyskywalker/dsh-chatgpt-subscription 0.33.0 → 0.34.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.
Files changed (74) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +51 -110
  3. package/lib/client.js +1483 -335
  4. package/lib/client.js.map +1 -1
  5. package/lib/index.js +5934 -1974
  6. package/lib/types/client/common/format.d.ts +10 -0
  7. package/lib/types/client/common/format.d.ts.map +1 -1
  8. package/lib/types/client/hub/brand-icons.d.ts +2 -2
  9. package/lib/types/client/hub/brand-icons.d.ts.map +1 -1
  10. package/lib/types/client/hub/providers.d.ts.map +1 -1
  11. package/lib/types/client/index.d.ts +2 -0
  12. package/lib/types/client/index.d.ts.map +1 -1
  13. package/lib/types/client/opendesign/OpenDesignComposerQuota.d.ts +20 -0
  14. package/lib/types/client/opendesign/OpenDesignComposerQuota.d.ts.map +1 -0
  15. package/lib/types/client/opendesign/OpenDesignSection.d.ts +18 -0
  16. package/lib/types/client/opendesign/OpenDesignSection.d.ts.map +1 -0
  17. package/lib/types/client/opendesign/api.d.ts +45 -0
  18. package/lib/types/client/opendesign/api.d.ts.map +1 -0
  19. package/lib/types/client/opendesign/locales.d.ts +689 -0
  20. package/lib/types/client/opendesign/locales.d.ts.map +1 -0
  21. package/lib/types/client/opendesign/styles.d.ts +11 -0
  22. package/lib/types/client/opendesign/styles.d.ts.map +1 -0
  23. package/lib/types/client/qoder/QoderSection.d.ts +12 -2
  24. package/lib/types/client/qoder/QoderSection.d.ts.map +1 -1
  25. package/lib/types/client/qoder/locales.d.ts +7 -1
  26. package/lib/types/client/qoder/locales.d.ts.map +1 -1
  27. package/lib/types/client/qoder/useQoderSection.d.ts.map +1 -1
  28. package/lib/types/host/common/model-request-control.d.ts +1 -1
  29. package/lib/types/host/common/model-request-control.d.ts.map +1 -1
  30. package/lib/types/host/common/request-diagnostics.d.ts +1 -1
  31. package/lib/types/host/common/request-diagnostics.d.ts.map +1 -1
  32. package/lib/types/host/kimi-code/adapter.d.ts +31 -0
  33. package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
  34. package/lib/types/host/kimi-code/mapper.d.ts +8 -0
  35. package/lib/types/host/kimi-code/mapper.d.ts.map +1 -1
  36. package/lib/types/host/kimi-code/types.d.ts +92 -0
  37. package/lib/types/host/kimi-code/types.d.ts.map +1 -1
  38. package/lib/types/host/opendesign/account-pool.d.ts +54 -0
  39. package/lib/types/host/opendesign/account-pool.d.ts.map +1 -0
  40. package/lib/types/host/opendesign/adapter.d.ts +69 -0
  41. package/lib/types/host/opendesign/adapter.d.ts.map +1 -0
  42. package/lib/types/host/opendesign/catalog.d.ts +44 -0
  43. package/lib/types/host/opendesign/catalog.d.ts.map +1 -0
  44. package/lib/types/host/opendesign/client.d.ts +148 -0
  45. package/lib/types/host/opendesign/client.d.ts.map +1 -0
  46. package/lib/types/host/opendesign/line.d.ts +49 -0
  47. package/lib/types/host/opendesign/line.d.ts.map +1 -0
  48. package/lib/types/host/opendesign/mapper.d.ts +128 -0
  49. package/lib/types/host/opendesign/mapper.d.ts.map +1 -0
  50. package/lib/types/host/opendesign/oauth.d.ts +105 -0
  51. package/lib/types/host/opendesign/oauth.d.ts.map +1 -0
  52. package/lib/types/host/opendesign/routes.d.ts +74 -0
  53. package/lib/types/host/opendesign/routes.d.ts.map +1 -0
  54. package/lib/types/host/opendesign/token-store.d.ts +154 -0
  55. package/lib/types/host/opendesign/token-store.d.ts.map +1 -0
  56. package/lib/types/host/opendesign/types.d.ts +180 -0
  57. package/lib/types/host/opendesign/types.d.ts.map +1 -0
  58. package/lib/types/host/qoder/adapter.d.ts +26 -2
  59. package/lib/types/host/qoder/adapter.d.ts.map +1 -1
  60. package/lib/types/host/qoder/client.d.ts +112 -0
  61. package/lib/types/host/qoder/client.d.ts.map +1 -1
  62. package/lib/types/host/qoder/model-catalog.d.ts +52 -6
  63. package/lib/types/host/qoder/model-catalog.d.ts.map +1 -1
  64. package/lib/types/host/qoder/routes.d.ts +23 -0
  65. package/lib/types/host/qoder/routes.d.ts.map +1 -1
  66. package/lib/types/host/qoder/token-store.d.ts +56 -7
  67. package/lib/types/host/qoder/token-store.d.ts.map +1 -1
  68. package/lib/types/index.d.ts +11 -1
  69. package/lib/types/index.d.ts.map +1 -1
  70. package/lib/types/shared/opendesign-contracts.d.ts +159 -0
  71. package/lib/types/shared/opendesign-contracts.d.ts.map +1 -0
  72. package/lib/types/shared/qoder-contracts.d.ts +40 -1
  73. package/lib/types/shared/qoder-contracts.d.ts.map +1 -1
  74. package/package.json +1 -1
@@ -0,0 +1,154 @@
1
+ import type { CredentialStore } from '../token-store.ts';
2
+ /**
3
+ * Shared non-secret display facts of one credential.
4
+ */
5
+ interface OpenDesignCredentialBase {
6
+ /** User-chosen label so several accounts are distinguishable. */
7
+ alias?: string;
8
+ /** Unix milliseconds the credential was added to the pool. */
9
+ addedAt?: number;
10
+ /** Per-account gateway override; empty means the line's own base URL. */
11
+ baseURL?: string;
12
+ }
13
+ /**
14
+ * One stored OpenDesign API key.
15
+ *
16
+ * The gateway authenticates with a static key, so there is no refresh token and
17
+ * nothing expires. The key is host-only and never crosses to a browser; the
18
+ * settings card renders the alias and the account row, never this value.
19
+ */
20
+ export interface OpenDesignApiKeyCredentials extends OpenDesignCredentialBase {
21
+ /** Present on every record this line writes; absent records predate the marker. */
22
+ kind?: 'api-key';
23
+ /** Host-only bearer key, created in the OpenDesign Cloud console. */
24
+ apiKey: string;
25
+ }
26
+ /**
27
+ * One account signed in through browser device authorization.
28
+ *
29
+ * The approval issues a pair (upstream issue nexu-io/open-design#8870): a
30
+ * `vela_ctrl_…` control key that reads the control plane (wallet balance and
31
+ * friends) and an `sk-amr-…` runtime key that serves the link gateway. Neither
32
+ * carries a published expiry, so there is no refresh lifecycle here — a revoked
33
+ * key is replaced by signing in again, not refreshed.
34
+ */
35
+ export interface OpenDesignOAuthCredentials extends OpenDesignCredentialBase {
36
+ kind: 'oauth';
37
+ /** Control-plane bearer (`vela_ctrl_…`): wallet reads, never chat. */
38
+ controlKey: string;
39
+ /** Link-gateway bearer (`sk-amr-…`): chat and the live catalog. */
40
+ runtimeKey: string;
41
+ /** The account's identity as the approval returned it. */
42
+ user?: {
43
+ id?: string;
44
+ email?: string;
45
+ name?: string;
46
+ plan?: string;
47
+ };
48
+ }
49
+ export type OpenDesignCredentials = OpenDesignApiKeyCredentials | OpenDesignOAuthCredentials;
50
+ /** Whether one credential is a device-flow session rather than a pasted key. */
51
+ export declare function isOpenDesignOAuthCredentials(credentials: OpenDesignCredentials): credentials is OpenDesignOAuthCredentials;
52
+ /** The chat bearer (`Authorization` value) for one credential. */
53
+ export declare function bearerFor(credentials: OpenDesignCredentials): string;
54
+ /** The control-plane bearer for one credential, when it has one. */
55
+ export declare function controlKeyFor(credentials: OpenDesignCredentials): string | undefined;
56
+ /**
57
+ * Stable identity of one key.
58
+ *
59
+ * The console hands the user a bare key and the gateway answers no profile for
60
+ * it, so the key's own digest is the only identity available. It is never
61
+ * written anywhere: it exists to tell two pasted keys apart inside the pool
62
+ * document, and it is not a credential and cannot be used as one.
63
+ */
64
+ export declare function credentialsIdentity(credentials: OpenDesignCredentials): string;
65
+ /** The user-facing label for one credential, when it states one. */
66
+ export declare function credentialsLabel(credentials: OpenDesignCredentials): string | undefined;
67
+ /** One catalog entry, as the last successful gateway listing published it. */
68
+ export interface OpenDesignCatalogModel {
69
+ id: string;
70
+ name?: string;
71
+ contextWindow?: number;
72
+ maxTokens?: number;
73
+ reasoning?: boolean;
74
+ efforts?: string[];
75
+ input?: string[];
76
+ }
77
+ /**
78
+ * Everything this line stores besides credentials.
79
+ *
80
+ * `enabledModelIds === null` is "no filter": every known model, including ones
81
+ * a later sync adds. An array is an explicit selection, and an empty one
82
+ * switches every model off. Modelling "all" as null rather than as an explicit
83
+ * all-ids list means a model the service adds later is not silently hidden by a
84
+ * selection made before it existed.
85
+ *
86
+ * The synced catalog lives in this same document (`catalogModels`), so a
87
+ * restart rehydrates it from a local read with no network in the path — the
88
+ * picker never has to wait on the gateway to show what was already discovered.
89
+ */
90
+ export interface OpenDesignModelSettings {
91
+ enabled: boolean;
92
+ baseURL: string;
93
+ enabledModelIds: string[] | null;
94
+ catalogModels: OpenDesignCatalogModel[];
95
+ /** Models the route must not advertise even though it still knows them. */
96
+ hiddenModels: string[];
97
+ /** Per-model context-window override; absent uses the resolved window. */
98
+ contextWindowOverrides: Record<string, number>;
99
+ defaultContextWindow: number;
100
+ defaultMaxTokens: number;
101
+ maxConcurrentRequests: number;
102
+ streamIdleTimeoutMs: number;
103
+ }
104
+ export interface OpenDesignPreferenceStore {
105
+ status(): OpenDesignModelSettings;
106
+ read(): Promise<OpenDesignModelSettings>;
107
+ update(patch: Partial<OpenDesignModelSettings>): Promise<OpenDesignModelSettings>;
108
+ }
109
+ export declare function credentialPath(): string;
110
+ export declare function modelSettingsPath(): string;
111
+ /** Validate one stored credential: a device-flow session or a static API key. */
112
+ export declare function parseOpenDesignCredentials(value: unknown): OpenDesignCredentials;
113
+ /** Encrypted credential store for the single-key (pre-pool) configuration. */
114
+ export declare class FileCredentialStore {
115
+ private readonly filePath;
116
+ private readonly backend;
117
+ constructor(filePath?: string, backend?: CredentialStore<OpenDesignCredentials>);
118
+ path(): string;
119
+ read(): Promise<OpenDesignCredentials | null>;
120
+ write(credentials: OpenDesignCredentials): Promise<void>;
121
+ clear(): Promise<void>;
122
+ }
123
+ /** Parse one whole settings document. */
124
+ export declare function parseOpenDesignModelSettings(value: unknown): OpenDesignModelSettings;
125
+ /** The document a fresh install starts from. */
126
+ export declare function defaultOpenDesignModelSettings(): OpenDesignModelSettings;
127
+ /**
128
+ * Model and connection settings, bound to a JSON file beside the encrypted
129
+ * credential store.
130
+ *
131
+ * The file is written atomically (temp + rename) so a crash mid-write leaves the
132
+ * previous document intact rather than a truncated one that reads as "reset all
133
+ * settings".
134
+ */
135
+ export declare class OpenDesignModelSettingsStore implements OpenDesignPreferenceStore {
136
+ private readonly filePath;
137
+ private cached;
138
+ private loadPromise;
139
+ constructor(filePath?: string);
140
+ path(): string;
141
+ status(): OpenDesignModelSettings;
142
+ /** Read the document at activation time, synchronously. */
143
+ readSync(): OpenDesignModelSettings;
144
+ read(): Promise<OpenDesignModelSettings>;
145
+ private load;
146
+ write(settings: OpenDesignModelSettings): Promise<OpenDesignModelSettings>;
147
+ update(patch: Partial<OpenDesignModelSettings>): Promise<OpenDesignModelSettings>;
148
+ /** Record a catalog sync without touching the user's selection. */
149
+ storeCatalog(models: OpenDesignCatalogModel[]): Promise<OpenDesignModelSettings>;
150
+ /** Store or clear (null) one model's context-window override. */
151
+ setContextWindowOverride(model: string, contextWindow: number | null): Promise<OpenDesignModelSettings>;
152
+ }
153
+ export {};
154
+ //# sourceMappingURL=token-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../../../src/host/opendesign/token-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Static facts about the OpenDesign subscription API.
3
+ *
4
+ * The upstream is the OpenDesign link gateway, an OpenAI-compatible endpoint
5
+ * fronting the models a plan's credits can spend. Authentication is a static
6
+ * API key in `Authorization: Bearer`, created in the OpenDesign Cloud console
7
+ * (workspace → API keys): there is no OAuth flow here and nothing expires.
8
+ *
9
+ * Evidence for every constant is in docs/opendesign-line-plan.md; the short
10
+ * version: the gateway host and its `/v1` OpenAI spelling come from the Cloud
11
+ * console's quick-setup bundle (it composes `{link}/v1` for OpenAI clients and
12
+ * recommends Chat Completions for DeepSeek Harness), and each protocol endpoint
13
+ * was probed unauthenticated and answered the expected 401 envelope.
14
+ *
15
+ * The model table below is transcribed from the public, unauthenticated price
16
+ * list — id spellings, display names where the pricing page publishes them, and
17
+ * USD-per-1M-token prices. It carries NO context windows: the gateway does not
18
+ * publish them to an API key, so a model's window is the line default until the
19
+ * user overrides it or a live catalog entry states one. The table is a fallback,
20
+ * not a ceiling: a model the live catalog discovers is adopted with what that
21
+ * listing published rather than hidden.
22
+ */
23
+ export declare const PROVIDER_ID = "opendesign";
24
+ export declare const PROVIDER_NAME = "OpenDesign";
25
+ /**
26
+ * Default gateway base URL, OpenAI protocol spelling (the `/v1` suffix is part
27
+ * of it; the Anthropic spelling is the bare host and is not what this line
28
+ * speaks). Overridable per deployment and per account.
29
+ */
30
+ export declare const DEFAULT_BASE_URL = "https://amr-link.open-design.ai/v1";
31
+ /** Public, unauthenticated price list; the shipped table's source. */
32
+ export declare const MODEL_PRICES_URL = "https://amr-api.open-design.ai/api/v1/public/model-prices";
33
+ /**
34
+ * The AMR control-plane base: device authorization and the wallet balance live
35
+ * under it. The device flow's contract is probed live (2026-10-21) and pinned
36
+ * by test/opendesign-oauth.test.ts; the wallet read's shape comes from the
37
+ * open-source daemon's reader (apps/daemon/src/integrations/vela-wallet.ts,
38
+ * nexu-io/open-design) plus issue #8870's field report.
39
+ */
40
+ export declare const AMR_API_BASE = "https://amr-api.open-design.ai/api/v1";
41
+ /** Device-authorization endpoints under {@link AMR_API_BASE}. */
42
+ export declare const DEVICE_AUTHORIZATIONS_PATH = "/cli/device-authorizations";
43
+ export declare const WALLET_BALANCE_PATH = "/wallet/balance";
44
+ /**
45
+ * What the create call says about this client. The service stores host /
46
+ * profile / cliVersion per authorization (its console lists devices by them);
47
+ * the profile vocabulary is 'prod' | 'test' | 'feature-test' | 'local' per the
48
+ * open-source daemon, and this line only ever speaks to prod.
49
+ */
50
+ export declare const DEVICE_CLIENT_PROFILE = "prod";
51
+ export declare const DEVICE_CLIENT_NAME = "dsh-chatgpt-subscription";
52
+ /** Conservative context capacity for a model no catalog describes. */
53
+ export declare const DEFAULT_CONTEXT_WINDOW = 128000;
54
+ /**
55
+ * Per-request output budget when the caller states none.
56
+ *
57
+ * A budget, not a ceiling: the harness reserves it as completion room before it
58
+ * compacts, so this decides how much of the window stays available. 64k keeps
59
+ * the reserve far below the compaction ratio while leaving room for a
60
+ * tool-calling agent's longest turn.
61
+ */
62
+ export declare const DEFAULT_MAX_TOKENS = 64000;
63
+ /**
64
+ * Streams one account may keep open at once; `0` lifts the cap.
65
+ *
66
+ * The cheapest published plan states "10 concurrent tasks"
67
+ * (https://open-design.ai/pricing/, 2026-10-21), so 10 is the one entitlement
68
+ * every paid key definitely has; a deployment that knows its plan may raise it.
69
+ */
70
+ export declare const DEFAULT_MAX_CONCURRENT_REQUESTS = 10;
71
+ /** Idle budget for one OpenDesign stream. */
72
+ export declare const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 300000;
73
+ /** How long a quota refusal keeps one account out of rotation. */
74
+ export declare const POOL_COOLDOWN_MS: number;
75
+ /**
76
+ * One published model entry.
77
+ *
78
+ * `contextWindow` and `maxTokens` are the VENDOR's published figures, not a
79
+ * promise about this gateway's clamp: no OpenDesign endpoint publishes a window
80
+ * to an API key (the control-plane catalog does, and the live sync prefers it).
81
+ * They are transcribed from this repository's already-sourced tables of the same
82
+ * vendor models — the command-code registry transcription
83
+ * (src/host/command-code/model-catalog.ts), the cline-pass table
84
+ * (src/host/cline-pass/types.ts), the Claude catalog
85
+ * (src/host/claude/model-catalog.ts) and the antigravity catalog
86
+ * (src/host/antigravity/types.ts) — because this line's fallback must not be a
87
+ * flat 128k for every model while those facts sit in the same repository.
88
+ * Per-model conflict resolution prefers the cline-pass table where the two
89
+ * disagree, since it is the OpenAI-chat gateway closest to this one. A live
90
+ * catalog entry and a user override both beat this table, so a clamp this
91
+ * transcription gets wrong costs one correction in the editor, not a permanent
92
+ * ceiling.
93
+ *
94
+ * `efforts` is the selectable reasoning ladder in DSH spelling (`none` is DSH's
95
+ * "do not think"; the command-code registry spells the same level `off` and it
96
+ * is translated here). An empty ladder with `reasoning: false` means no source
97
+ * publishes one for that model; a model with no row data at all keeps the
98
+ * line's default trio rather than being declared a non-reasoner.
99
+ */
100
+ export interface OpenDesignModelMeta {
101
+ name: string;
102
+ /**
103
+ * USD per 1M tokens from the public price list. Shown, never fabricated: a
104
+ * model the price list does not carry simply has no figure.
105
+ */
106
+ pricing?: {
107
+ input: number;
108
+ output: number;
109
+ };
110
+ /** The vendor's published context window; absent when no source documents one. */
111
+ contextWindow?: number;
112
+ /** The vendor's published output ceiling; absent when no source documents one. */
113
+ maxTokens?: number;
114
+ /**
115
+ * Selectable reasoning levels, least to greatest, in DSH spelling. Absent
116
+ * means "use the line default"; an empty array means the model exposes none.
117
+ */
118
+ efforts?: readonly string[];
119
+ /**
120
+ * Whether the model takes an effort knob at all. Absent means yes; `false`
121
+ * marks the rows whose source publishes no ladder.
122
+ */
123
+ reasoning?: boolean;
124
+ /** Accepted input modalities, as the source table declares them. */
125
+ input: readonly string[];
126
+ }
127
+ /**
128
+ * The subscription's models at release time, keyed by wire id.
129
+ *
130
+ * Id spellings and prices are transcribed from MODEL_PRICES_URL (fetched
131
+ * 2026-10-21, 37 entries, all chat models — the plan's image models are priced
132
+ * per call and are not in it). Display names use the pricing page's spelling
133
+ * where that page lists the model (https://open-design.ai/pricing/) and are
134
+ * derived from the id otherwise; the live catalog's own name wins once one is
135
+ * read. Windows, output caps, modalities and ladders come from the sibling
136
+ * tables named on {@link OpenDesignModelMeta}; the live control-plane catalog
137
+ * (which does publish `metadata.contextWindowTokens`) overrides them when read.
138
+ */
139
+ export declare const MODEL_CATALOG: Readonly<Record<string, OpenDesignModelMeta>>;
140
+ /** Subscription models current at release time; the live catalog extends this. */
141
+ export declare const DEFAULT_MODELS: readonly string[];
142
+ /**
143
+ * The effort ladder a model with no published ladder is advertised with.
144
+ *
145
+ * The OpenAI trio every compatible gateway accepts; an input outside it is a
146
+ * 400 on some gateways, so the default stays deliberately small. A model whose
147
+ * own row publishes a ladder uses that instead.
148
+ */
149
+ export declare const DEFAULT_EFFORTS: readonly string[];
150
+ /** Published entry for one model id, if the shipped table knows it. */
151
+ export declare function catalogEntry(model: string): OpenDesignModelMeta | undefined;
152
+ /**
153
+ * One model as the live catalog describes it, after merging the shipped table,
154
+ * the last gateway listing and any per-model override.
155
+ */
156
+ export interface OpenDesignModelInfo {
157
+ id: string;
158
+ displayName: string;
159
+ contextWindow: number;
160
+ maxTokens: number;
161
+ reasoning: boolean;
162
+ /** Selectable effort ladder; empty when the model exposes none. */
163
+ efforts: readonly string[];
164
+ input: readonly string[];
165
+ pricing?: {
166
+ input: number;
167
+ output: number;
168
+ };
169
+ }
170
+ /** One model's metadata as the last gateway listing published it. */
171
+ export interface OpenDesignDiscoveredModel {
172
+ name?: string;
173
+ contextWindow?: number;
174
+ maxTokens?: number;
175
+ input?: string[];
176
+ reasoning?: boolean;
177
+ /** Selectable effort levels, when the listing publishes them. */
178
+ efforts?: string[];
179
+ }
180
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/host/opendesign/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,eAAO,MAAM,WAAW,eAAe,CAAA;AACvC,eAAO,MAAM,aAAa,eAAe,CAAA;AAEzC;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,uCAAuC,CAAA;AAEpE,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,8DAA8D,CAAA;AAE3F;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,0CAA0C,CAAA;AAEnE,iEAAiE;AACjE,eAAO,MAAM,0BAA0B,+BAA+B,CAAA;AACtE,eAAO,MAAM,mBAAmB,oBAAoB,CAAA;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,SAAS,CAAA;AAC3C,eAAO,MAAM,kBAAkB,6BAA6B,CAAA;AAE5D,sEAAsE;AACtE,eAAO,MAAM,sBAAsB,SAAU,CAAA;AAE7C;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,QAAS,CAAA;AAExC;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,KAAK,CAAA;AAEjD,6CAA6C;AAC7C,eAAO,MAAM,8BAA8B,SAAU,CAAA;AAErD,kEAAkE;AAClE,eAAO,MAAM,gBAAgB,QAAc,CAAA;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IAC3C,kFAAkF;IAClF,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,oEAAoE;IACpE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CACzB;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CA0CtE,CAAA;AAEF,kFAAkF;AAClF,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAA8C,CAAA;AAE1F;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAA6C,CAAA;AAE1F,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAE3E;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,OAAO,CAAA;IAClB,mEAAmE;IACnE,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5C;AAED,qEAAqE;AACrE,MAAM,WAAW,yBAAyB;IACxC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB"}
@@ -52,11 +52,35 @@ export declare const QODER_POOL_COOLDOWN_MS: number;
52
52
  /**
53
53
  * 这个部署能调的模型:**进程内缓存优先、随包目录兜底,请求路径上绝不联网**。
54
54
  *
55
- * 实时目录只由 \`/catalog/refresh\` 与登录/adopt 产生(见 routes.ts);
55
+ * 实时目录由 \`/catalog/refresh\`、登录/adopt,以及 \`GET /status\` **应答背后**
56
+ * 的那次自动刷新产生(见 routes.ts);本函数自己一次请求都不发——
56
57
  * 让每一次模型解析都去打上游只会把设置页变成一条压测。
57
58
  */
58
59
  export declare function cachedQoderModelCatalog(region: QoderRegion): readonly QoderModelEntry[];
59
- /** 设置卡片渲染的模型总数(hub 概览与状态共用同一份读数;取两区随包表的较大者)。 */
60
+ /**
61
+ * 一行的白名单该按哪一套规则收敛;**口径只有这一处**。
62
+ *
63
+ * 适配器的过滤(listModels)与状态面的勾选标记(getQoderStatus)都从这里读,
64
+ * 免得两边各写一份「兜底阶段要不要按白名单筛」而慢慢漂开。
65
+ *
66
+ * - 实时目录:按白名单收敛 + 过滤(上游下线一个模型后,那份残留 id 不该再占名额,
67
+ * 也不该让「已选 N / M」的分子大于目录条目数);
68
+ * - 兜底表:**不按白名单筛**,全部返回(它是能力占位,且与白名单不是同一套 id
69
+ * 词汇表——见 client.ts 的 qoderCatalogIsLive);
70
+ * - `[]`(用户明确全关)与 `null`(不过滤)在两种阶段下的含义都不变:全关就是全关。
71
+ *
72
+ * @param stored 用户存下来的选择(三态)。
73
+ * @param live 当前拿到的是实时目录(true)还是随包兜底表(false)。
74
+ * @param catalog 当前这一份目录(兜底阶段它只用来决定「有没有条目可给」)。
75
+ * @returns 收敛后的白名单;`null` = 不过滤。
76
+ */
77
+ export declare function convergeQoderSelection(stored: readonly string[] | null, live: boolean, catalog: readonly QoderModelEntry[]): string[] | null;
78
+ /**
79
+ * 设置卡片渲染的模型总数(hub 概览用;取两区随包表的较大者)。
80
+ *
81
+ * ⚠ 它**不带区域**,所以只适合当「这条线路大概有几个模型」的量级读数。
82
+ * 需要与勾选收敛对齐时用 {@link cachedQoderModelCatalog}(按区取,分子分母同源)。
83
+ */
60
84
  export declare function qoderCatalogSize(): number;
61
85
  /** 记下一次请求的用量(流读到终止帧之后调用)。 */
62
86
  export declare function rememberQoderCacheUsage(usage: {
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../src/host/qoder/adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../src/host/qoder/adapter.ts"],"names":[],"mappings":"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"}
@@ -98,8 +98,120 @@ export type QoderCatalogEntry = QoderModelEntry;
98
98
  export declare function fetchQoderModelCatalog(credentials: QoderUpstreamCredential, options?: QoderRequestOptions): Promise<QoderCatalogEntry[]>;
99
99
  /** 本进程当前记住的目录(纯内存读,不触发任何网络请求)。 */
100
100
  export declare function getCachedQoderModelCatalog(region?: QoderRegion): readonly QoderCatalogEntry[];
101
+ /**
102
+ * 本进程此刻拿到的目录是**实时目录**(上游真的答过)还是**随包兜底表**。
103
+ *
104
+ * 这条判定必须单独导出、口径只有一处,因为下游对它有两个消费者而两处的后果都很具体:
105
+ *
106
+ * - `adapter.listModels` 与状态面的勾选标记要知道「这一份目录是不是这个账号真实可用的
107
+ * 集合」,才知道用不用用户的白名单去筛它(见下面的「两套 id 词汇表」);
108
+ * - 任何自己拼「缓存有没有 / 是不是空」的地方都会与它漂:一处按 `undefined` 判空、
109
+ * 另一处按「条目数为 0」判空,兜底表就会被当成本账号的真实目录。
110
+ *
111
+ * -------------------------------------------------------------------------
112
+ * 两套 id 词汇表(这是缺陷 1 的证据,别再合并它们)
113
+ * -------------------------------------------------------------------------
114
+ * 用户的白名单是在设置卡片上对着**实时目录**勾出来的 id,而实时目录的 id 就是上游
115
+ * `display_name` 去空白(model-catalog.ts `toQoderModelId`);随包兜底表照录
116
+ * pi-provider 的静态表,同一批模型在两边**叫法不同**:
117
+ *
118
+ * | 实时目录(用户勾的) | 随包兜底表 |
119
+ * | --- | --- |
120
+ * | `DeepSeek-Flash` | `DeepSeek-V4-Flash` |
121
+ * | `Qwen3.8-Flash` | `Qwen3.8-Max` / `Qwen3.7-Plus` |
122
+ * | `Ultimate` | `Ultimate`(少数恰好同名) |
123
+ *
124
+ * 所以「用白名单去筛兜底表」这件事在冷启动时必然收敛成空集,而 `listModels` 返回空
125
+ * 会让 DSH 把整个 provider 分组过滤掉——选择器里连 Qoder 都不剩。
126
+ *
127
+ * @param region 要判定的区域(目录是区域的属性,别的区域的缓存不算数)。
128
+ */
129
+ export declare function qoderCatalogIsLive(region: QoderRegion): boolean;
101
130
  /** 清掉内存目录、快照 scope 与在飞的去重。 */
102
131
  export declare function clearCachedQoderModelCatalog(): void;
132
+ /**
133
+ * 当前进程的目录缓存是否「需要(或应该)拉一次」:空缓存、别的区域的缓存、
134
+ * 或者已经旧到过了 {@link CATALOG_CACHE_TTL_MS}。
135
+ *
136
+ * 之所以把这条判定单独导出,是因为它有两个消费者而只能有一份口径:设置卡片的
137
+ * `GET /status` 要在应答背后决定「这次要不要顺手拉一次」,而不是每条路径
138
+ * 各写一遍「有没有缓存 / 过没过期」。判定口径分叉的那种后果很具体——一处按
139
+ * `undefined` 判空、另一处按「条目数为 0」判空,于是空数组缓存永远被判成
140
+ * 「有缓存,不用拉」,选择器就永远停在兜底表上。
141
+ *
142
+ * 读的是与 {@link loadQoderModelCatalog} **同一个** `cachedCatalog` 与其
143
+ * `fetchedAt`,所以「这里说不用拉」与「那边会直接命中缓存」是同一件事。
144
+ * 纯读:不联网、不写缓存、不改任何状态,因此可以在应答路径上随手调用。
145
+ *
146
+ * @param region 要判定的区域(目录是区域的属性,别的区域的缓存不算数)。
147
+ * @param now 当前时刻;显式传入是为了让「过期」这件事在测试里可确定。
148
+ */
149
+ /**
150
+ * 缓存目录的写入时刻(Unix 毫秒),没有缓存时为 undefined。
151
+ *
152
+ * 给「过期判定」的测试一个**确定**的基准:测试原先在 await 返回后用
153
+ * `Date.now()` 去推边界,而缓存里的 `fetchedAt` 是稍早一次 `Date.now()`,
154
+ * 两次读时钟之间的毫秒差会让「差一毫秒到期仍算新鲜」这条断言偶发翻车。
155
+ * 读的是与 {@link qoderCatalogNeedsRefresh} 同一个字段,纯读、无副作用。
156
+ */
157
+ export declare function qoderCatalogFetchedAt(region: QoderRegion): number | undefined;
158
+ export declare function qoderCatalogNeedsRefresh(region: QoderRegion, now?: number): boolean;
159
+ /**
160
+ * 进程内实时目录的指纹:还没有实时目录(只有随包兜底表)时是空数组的序列化。
161
+ *
162
+ * 「这次刷新有没有真的换掉目录」的判定**只有这一处**。它有两个调用方,而两处
163
+ * 判错的后果都很具体:
164
+ *
165
+ * - `routes.ts` 的刷新路径在这一条上决定发不发 `llm/adapters-updated`:这张卡片
166
+ * 每 60 秒轮询一次,无条件发就等于让模型选择器每拍重建一遍;
167
+ * - `index.ts` 的**启动预热**同样要发一次,而且启动那一刻根本没有任何订阅方在等,
168
+ * 发早发晚都不影响正确性——但它与刷新路径必须是同一句判词,否则「目录变了没有」
169
+ * 在两条路径上会给出两个答案。
170
+ *
171
+ * 用 id 序列而不是数组引用:{@link loadQoderModelCatalog} 命中缓存时会把**同一个
172
+ * 数组**交回来,按引用比较永远相等,那样「目录真的变了」就永远判不出来。
173
+ *
174
+ * @param region 要取指纹的区域(目录是区域的属性,别的区域的缓存不算数)。
175
+ */
176
+ export declare function qoderCatalogFingerprint(region: QoderRegion): string;
177
+ /**
178
+ * 启动预热:把上一次落盘的真实目录**立刻**放回进程内缓存,再让上游刷新跑在背后。
179
+ *
180
+ * ---------------------------------------------------------------------------
181
+ * 为什么要在启动时预热
182
+ * ---------------------------------------------------------------------------
183
+ * `cachedCatalog` 是进程内的,宿主一重启它就是空的;而此时磁盘快照
184
+ * (`<DSH_HOME>/storages/qoder-global-catalog.json`)里明明躺着上一次的真实目录。
185
+ * 没有预热时,唯一把它读回来的入口是 `loadQoderModelCatalog`,而它只被设置页的
186
+ * `GET /status` / 登录 / adopt / `POST /catalog/refresh` 调用——于是**启动之后、
187
+ * 用户第一次打开设置页之前**,`adapter.listModels` 读到的是随包兜底表(全球区
188
+ * 15 条),模型选择器就把这一大片缺省模型摊在用户面前;等设置页被打开、那次
189
+ * 应答背后的刷新落地,它才换成真实的两条。用户看到的是「重启后先冒出一堆假模型,
190
+ * 点一下设置页才正常」。
191
+ *
192
+ * 预热把这段空窗压到进程启动的第一拍:快照是本地读,几十毫秒内就位。
193
+ *
194
+ * ---------------------------------------------------------------------------
195
+ * 为什么不能 await(调用方必须 `void ... .catch()`)
196
+ * ---------------------------------------------------------------------------
197
+ * 第二段(`loadQoderModelCatalog`)在**没有快照**的机器上就是一次真实的上游请求:
198
+ * 它会跟随 COSY 版本、签一次名、打一次目录端点,超时上限是 `DISCOVERY_TIMEOUT_MS`。
199
+ * 把它 await 在插件装配里,等于让整个宿主插件的装载挂在一条可降级的网络请求上——
200
+ * 离线、上游抽风、代理没起来,都会变成「插件装不上」,而这条线路在没有目录时本来
201
+ * 就有一张随包兜底表可用。所以:预热是**尽力而为**,失败一律吞掉,调用方不等待。
202
+ *
203
+ * 有快照时它不会等网络:快照回填之后 `loadQoderModelCatalog` 走的是「陈旧缓存
204
+ * 立刻返回 + 后台刷新」那条路(见该函数),所以正常机器的预热是毫秒级的。
205
+ *
206
+ * @param credentials 预热用的凭据切片。没有账号时调用方不该调用本函数。
207
+ * @param options 与其它上游函数同一套注入缝(fetchFn / env)。
208
+ * @returns **快照回填之后、网络刷新之前**那份目录的指纹,也就是这次预热里「上游那一版
209
+ * 将要顶替掉的是什么」。调用方拿它当比较基线:与它不同才算「目录真的变了」。
210
+ * 只为发一次事件而返回它,而不是让调用方自己再取一次——那样它取到的是回填**之前**
211
+ * 的空目录,冷启动时永远「变了」,等于每次启动都无条件发事件。
212
+ * 预热失败时返回回填后(可能仍为空)的指纹。
213
+ */
214
+ export declare function warmQoderModelCatalog(credentials: QoderUpstreamCredential, options?: QoderRequestOptions): Promise<string>;
103
215
  /**
104
216
  * TTL 缓存 + in-flight 去重 + 磁盘快照的目录读取(三层各解决一件事,
105
217
  * 照抄 step-code/client.ts 的同名结构):
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/host/qoder/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/host/qoder/client.ts"],"names":[],"mappings":"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"}
@@ -97,6 +97,31 @@ export declare function readQoderThinkingConfig(record: QoderUpstreamModelRecord
97
97
  thinkingDisableable: boolean;
98
98
  isReasoning: boolean;
99
99
  };
100
+ /**
101
+ * 一行能力 → 落盘快照的条目:**快照读取侧的反格式**。
102
+ *
103
+ * 写成一处而不是各写一遍,是因为写入侧(client.ts 的 refreshQoderModelCatalog)与
104
+ * 读取侧(rehydrateQoderCatalogFromSnapshot)必须**互为反函数**。这两侧曾经对不上,
105
+ * 后果是静默的:写入侧存的是上游原始形状(`display_name` / `context_config`),
106
+ * 读取侧却拿 {@link parseQoderModelListing} 去解析它——那个解析器只认 `payload.chat`,
107
+ * 于是**任何**快照都解析成空数组,被当作「没有可用的快照」丢掉。冷启动于是永远
108
+ * 从兜底表起步,而磁盘上那份真实目录一次都没被读回来过。
109
+ *
110
+ * 形状与 {@link entryFromQoderRecord} 的输入完全对齐(`key` + `display_name` +
111
+ * `context_config.token_count`),所以真实载荷与快照走的是同一个解析器,字段缺了
112
+ * 也走同一套兜底。
113
+ */
114
+ export declare function persistedQoderModelRecord(entry: QoderModelEntry): QoderUpstreamModelRecord;
115
+ /**
116
+ * 解析**落盘快照**的 `models` 字段(`persistedQoderModelRecord` 写出去的那一组)。
117
+ *
118
+ * 单独一个函数而不是把 {@link parseQoderModelListing} 放宽成「也认得裸数组」:
119
+ * 那个函数读的是上游应答(`{ chat: [...] }`)的契约,让它同时接受另一种形状,
120
+ * 下一次有人改上游解析规则时就会顺手改坏快照的回读。两个形状,两个入口,一处口径。
121
+ *
122
+ * @returns 解析出的能力行;一个都解析不出时是空数组(调用方据此判「没有可用快照」)。
123
+ */
124
+ export declare function parsePersistedQoderModelEntries(value: unknown, region: QoderRegion): QoderModelEntry[];
100
125
  /**
101
126
  * 上游一个条目 → 一行能力。
102
127
  *
@@ -125,7 +150,12 @@ export declare const QODER_MODEL_CATALOG_GLOBAL: readonly QoderModelEntry[];
125
150
  export declare const QODER_MODEL_CATALOG_CN: readonly QoderModelEntry[];
126
151
  /** 一个区域的随包兜底表。 */
127
152
  export declare function bundledQoderCatalog(region: QoderRegion): readonly QoderModelEntry[];
128
- /** 首次安装默认勾选的模型:空数组 = 不过滤(与 step-code 同一语义,见 token-store 的注释)。 */
153
+ /**
154
+ * 首次安装默认勾选的模型。
155
+ *
156
+ * 本线路的三态里「没挑过」是 `null`(不过滤),不是一张 id 表,所以这里刻意是
157
+ * 空数组、且**不再**参与设置装配——它只是历史常量,保留是为了不打断已有的导入面。
158
+ */
129
159
  export declare const DEFAULT_VISIBLE_MODEL_IDS: readonly string[];
130
160
  /**
131
161
  * 未知模型的**未声明**行。
@@ -151,6 +181,22 @@ export declare function maxOutputTokensFor(id: string, catalog: readonly QoderMo
151
181
  export declare function defaultContextWindowFor(id: string, catalog: readonly QoderModelEntry[], region?: QoderRegion): number;
152
182
  /** 目录里的全部公开 id。 */
153
183
  export declare function listModelIds(catalog: readonly QoderModelEntry[]): string[];
184
+ /**
185
+ * 把用户存下来的白名单收敛到「这个部署此刻真的有的模型」上。
186
+ *
187
+ * 为什么必须收敛:白名单是用户昨天在**昨天的目录**上勾的,而本线路的目录是登录后
188
+ * 从上游实时发现的(随包表只是兜底)。上游下线一个模型、或用户换了一个区登录,
189
+ * 残留的 id 就会一直留在设置里——它既让「已选 N / M」的分子大于目录条目数,
190
+ * 也让卡片上出现一个勾着却根本不存在的行。
191
+ *
192
+ * 口径只有这一处:适配器的过滤(listModels)与状态面的勾选标记(getQoderStatus)
193
+ * 都从这里读,避免两边各写一份「什么算可用」而慢慢漂移。
194
+ *
195
+ * @param stored - 存下来的选择:`null` = 不过滤(原样返回 null),否则是白名单。
196
+ * @param available - 当前目录里真实存在的 id。
197
+ * @returns `null`(不过滤)或收敛后的白名单;保持 `stored` 的顺序并去重。
198
+ */
199
+ export declare function convergeQoderEnabledModelIds(stored: readonly string[] | null, available: readonly string[]): string[] | null;
154
200
  /** 目录条目数,供 hub 概览显示「M 个模型可用」。 */
155
201
  export declare function catalogSize(catalog: readonly QoderModelEntry[]): number;
156
202
  /** {@link catalogSize} 的别名(与兄弟线路的调用形状一致)。 */
@@ -165,13 +211,13 @@ export declare function describeQoderModel(entry: QoderModelEntry, prefix?: stri
165
211
  /** 用户设置对目录装配的两处覆盖。 */
166
212
  export interface QoderCatalogOptionOverrides {
167
213
  /**
168
- * 用户勾选的模型 id。
214
+ * 用户勾选的模型 id,**三态**(与 token-store 的 `QoderModelSettings` 同源):
169
215
  *
170
- * **缺省或空数组 = 不过滤(全选)**;非空 = 显式选择(含只有一项)。
171
- * 语义逐字照抄 step-code:schemastery 会把缺省的 `z.array(z.string())` 归一化成 `[]`,
172
- * 所以没有「null = 不过滤」的第三态。真要把模型全关,关线路总开关是明确且语义正确的动作。
216
+ * - `null` / 缺省 = 不过滤,目录里的每一行都勾上;
217
+ * - `[]` = 用户明确全关,一个都不勾;
218
+ * - 非空 = 白名单,只有列出的那些勾上。
173
219
  */
174
- enabledModelIds?: readonly string[];
220
+ enabledModelIds?: readonly string[] | null;
175
221
  /** 逐模型上下文窗口覆盖;null / 非正数表示用目录默认值。 */
176
222
  contextWindowOverrides?: Readonly<Record<string, number | null | undefined>>;
177
223
  }