dsh-plugin-subscription-oauth 0.16.3 → 0.17.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.
Files changed (43) hide show
  1. package/README.dev.md +1 -1
  2. package/README.md +7 -6
  3. package/README.zh.dev.md +1 -1
  4. package/README.zh.md +7 -6
  5. package/lib/client/FastModeButton.d.ts +0 -1
  6. package/lib/client/FastModeButton.js +48 -11
  7. package/lib/client.js +32 -9
  8. package/lib/client.js.map +1 -1
  9. package/lib/index.js +21 -0
  10. package/lib/protocol.d.ts +9 -0
  11. package/lib/providers/antigravity.d.ts +34 -4
  12. package/lib/providers/antigravity.js +100 -28
  13. package/lib/providers/ark-provider.d.ts +10 -0
  14. package/lib/providers/ark-provider.js +16 -2
  15. package/lib/providers/ark.d.ts +104 -10
  16. package/lib/providers/ark.js +186 -48
  17. package/lib/providers/catalog.d.ts +92 -0
  18. package/lib/providers/catalog.js +191 -0
  19. package/lib/providers/common.d.ts +14 -0
  20. package/lib/providers/common.js +23 -0
  21. package/lib/providers/glm-provider.d.ts +10 -0
  22. package/lib/providers/glm-provider.js +16 -2
  23. package/lib/providers/glm.d.ts +100 -16
  24. package/lib/providers/glm.js +182 -85
  25. package/lib/providers/grok.d.ts +114 -27
  26. package/lib/providers/grok.js +330 -129
  27. package/lib/providers/kimi-provider.d.ts +10 -0
  28. package/lib/providers/kimi-provider.js +16 -4
  29. package/lib/providers/kimi.d.ts +122 -32
  30. package/lib/providers/kimi.js +243 -122
  31. package/lib/providers/mimo-provider.d.ts +14 -1
  32. package/lib/providers/mimo-provider.js +17 -6
  33. package/lib/providers/mimo.d.ts +164 -19
  34. package/lib/providers/mimo.js +318 -19
  35. package/lib/providers/model-cache.d.ts +57 -0
  36. package/lib/providers/model-cache.js +105 -0
  37. package/lib/providers/responses-stream.d.ts +8 -0
  38. package/lib/providers/responses-stream.js +21 -5
  39. package/lib/providers/workbuddy-provider.d.ts +17 -0
  40. package/lib/providers/workbuddy-provider.js +14 -6
  41. package/lib/providers/workbuddy.d.ts +140 -13
  42. package/lib/providers/workbuddy.js +501 -59
  43. package/package.json +1 -1
@@ -99,16 +99,21 @@ export function createKimiProvider(options) {
99
99
  hiddenModels: () => options.preferences.hiddenIds(KIMI_PROVIDER_ID),
100
100
  userModels: () => options.preferences.extraIds(KIMI_PROVIDER_ID),
101
101
  modelOrder: () => options.preferences.orderOf(KIMI_PROVIDER_ID),
102
+ defaultModel: options.defaultModel ?? KIMI_DEFAULT_MODEL,
103
+ ...options.cachedListing === undefined ? {} : { cachedListing: options.cachedListing },
104
+ ...options.saveListing === undefined ? {} : { saveListing: options.saveListing },
102
105
  ...options.extraModels === undefined ? {} : { extraModels: options.extraModels },
103
106
  fetchFn,
104
107
  });
105
- const spec = {
106
- id: KIMI_PROVIDER_ID,
108
+ // Read the cached table now rather than at the first picker query: the Settings page
109
+ // reads the catalog synchronously, so a request-free start must already have it.
110
+ void adapter.hydrate().catch(() => undefined);
111
+ const spec = { id: KIMI_PROVIDER_ID,
107
112
  displayName: KIMI_PROVIDER_NAME,
108
113
  codeUrl: KIMI_CODE_URL,
109
114
  credentialFile: options.credentialFile,
110
115
  discovery: options.discovery,
111
- defaultModel: KIMI_DEFAULT_MODEL,
116
+ defaultModel: options.defaultModel ?? KIMI_DEFAULT_MODEL,
112
117
  catalog: () => adapter.catalogEntries(),
113
118
  catalogOwn: () => adapter.ownCatalogEntries(),
114
119
  fallbackContextWindow: KIMI_CONTEXT_WINDOW,
@@ -151,12 +156,19 @@ export function createKimiProvider(options) {
151
156
  removeModel: (id) => controller.removeModel(id),
152
157
  usage: (force) => controller.usage(force),
153
158
  reload: () => controller.reload(),
154
- modelVariants: (id) => {
159
+ modelVariants: async (id) => {
160
+ // A variant is known only once the route has read its listing, whose row names it.
161
+ // The composer asks exactly once, so the read is awaited here: "no fast variant"
162
+ // must mean the route really has none, not that its table was still loading.
163
+ await adapter.hydrate();
155
164
  const pair = adapter.fastPairOf(id);
156
165
  const image = adapter.imageModelId();
157
166
  return {
158
167
  ...pair === undefined ? {} : { fast: pair.wireId, fastBase: pair.baseId, fastRung: fastWordOf(pair.wireId) },
159
168
  ...image === undefined ? {} : { image },
169
+ // Nothing read yet: the answer above is provisional, and the caller is told so
170
+ // rather than being left to read silence as "this model has no variant".
171
+ ...adapter.hasListing() ? {} : { pending: true },
160
172
  };
161
173
  },
162
174
  };
@@ -32,14 +32,6 @@ export interface KimiSession extends SessionBase {
32
32
  * @returns the session, or undefined when required fields are missing.
33
33
  */
34
34
  export declare function parseKimiSession(value: unknown): KimiSession | undefined;
35
- /**
36
- * Kimi Code's live coding catalog.
37
- *
38
- * `kimi-for-coding` is the stable subscription alias Moonshot re-points at each
39
- * coding release; `k3` is the current flagship, with the `[1m]` suffix selecting
40
- * its 1M-token window.
41
- */
42
- export declare const KIMI_MODELS: readonly KimiModelEntry[];
43
35
  /** Constructor dependencies for {@link KimiAdapter}. */
44
36
  export interface KimiAdapterOptions {
45
37
  /** Resolved Kimi Code API base (`<base>/responses`). */
@@ -73,6 +65,14 @@ export interface KimiAdapterOptions {
73
65
  readUsage?: (account: string) => Promise<readonly UsageWindow[]>;
74
66
  /** Extra model ids from the plugin configuration, appended to the catalog. */
75
67
  extraModels?: readonly string[];
68
+ /**
69
+ * Model this route preselects, and therefore always offers.
70
+ *
71
+ * Configuration rather than a shipped fact: a subscription that re-points its
72
+ * alias at a new release follows the config instead of this build's release
73
+ * cadence. Defaults to {@link KIMI_DEFAULT_MODEL}.
74
+ */
75
+ defaultModel?: string;
76
76
  /**
77
77
  * The user's model rank for this route, most preferred first.
78
78
  *
@@ -96,41 +96,101 @@ export interface KimiAdapterOptions {
96
96
  * endpoint is the authority on what it serves, not this build.
97
97
  */
98
98
  userModels?: () => Promise<readonly string[]>;
99
+ /**
100
+ * The payload of the endpoint's last live listing, as the cache kept it.
101
+ *
102
+ * Read once per session, before the first catalog query, so the picker offers real
103
+ * models without asking the endpoint anything. A route that fetched once and cached
104
+ * the answer has no reason to fetch again on every refresh; the Settings "refresh
105
+ * models" action is what re-reads it.
106
+ */
107
+ cachedListing?: () => Promise<unknown>;
108
+ /** Record what a live listing just produced, replacing the cached table. */
109
+ saveListing?: (payload: unknown) => Promise<void>;
99
110
  }
100
111
  /** Kimi Code adapter serving the `kimi` provider route. */
101
112
  export declare class KimiAdapter extends LlmAdapter {
102
113
  private readonly options;
103
- /** Live catalog ids seen this session, used to accept renamed models. */
104
- private discovered;
105
- /** Image-generation model id, when discovery reported one. */
114
+ /**
115
+ * The catalog this route serves: entries derived from the endpoint's own listing,
116
+ * either the one just read or the one the cache kept from the last read.
117
+ *
118
+ * Undefined means neither source has produced a listing yet, so only the configured
119
+ * default model is offered until one does.
120
+ */
121
+ private live;
122
+ /** Whether the cached listing has been read; it is read at most once per session. */
123
+ private hydrated;
124
+ /** Image-generation model id, when the listing reported one. */
106
125
  private imageModel;
107
126
  /**
108
127
  * Fast-variant wire id per picker row, for the composer's quick-mode button.
109
128
  *
110
- * Seeded from the curated aliases — `kimi-for-coding-highspeed` is one — so the button
111
- * exists before any discovery run, and then updated from the live catalog, which is
112
- * the authority on what this account actually serves.
129
+ * Derived from the listing: `kimi-for-coding-highspeed` is a row of its own there,
130
+ * and pairs with `kimi-for-coding` because its name is that of a listed model plus
131
+ * the provider's own fast word.
113
132
  */
114
133
  private readonly fastVariants;
115
134
  /** Ids the user added by hand, cached so the sync catalog can name them. */
116
135
  private userAddedIds;
136
+ /**
137
+ * Model ids the endpoint renamed during this session, and what each became.
138
+ *
139
+ * Learned from the endpoint's own refusal (`Please set model id as \`k3\``), so a
140
+ * spelling retired after this build shipped is repaired without a plugin update. The
141
+ * first turn pays one refused request; every later turn goes straight to the current id.
142
+ */
143
+ private readonly renamed;
117
144
  /** Tools already reported as flattened, so each is stated once. */
118
145
  private readonly flattenedTools;
119
146
  constructor(options: KimiAdapterOptions);
120
147
  /**
121
- * Record the fast variants the curated catalog already names as aliases.
148
+ * Adopt the rows of one live listing as this route's catalog.
122
149
  *
123
- * The alias is the recognition: `kimi-for-coding-highspeed` is stated as an accepted
124
- * id of `kimi-for-coding`, so the route can offer the quick-mode button without
125
- * waiting for a live list that may never name it. A row a live catalog already paired
126
- * keeps that pairing, so this only fills the gaps.
150
+ * Everything the picker shows is derived here from the endpoint's own answer: the
151
+ * rows that become picker entries, the fast variant that pairs with each row, and
152
+ * the image model that is called by an agent rather than chosen. Nothing about
153
+ * which models exist, or what each one is, is decided by this build.
154
+ *
155
+ * Fast variants ride with their base row instead of becoming rows of their own: they
156
+ * share the row's visibility switch and are reached by the composer's quick-mode
157
+ * button. A variant is recognized by its own name — the provider's fast word appended
158
+ * to a listed model's id — so no curated alias map is needed to pair them.
159
+ *
160
+ * @param rows - decoded rows of the endpoint's listing, in the endpoint's order.
161
+ * @returns the entries to publish, in picker order.
127
162
  */
128
- private seedCuratedFastVariants;
163
+ private adoptListing;
164
+ /**
165
+ * Put this route's stable label on one entry, when the id has one.
166
+ *
167
+ * The listing states what the model *is*; the label states what the *id* is, which only
168
+ * this route knows (see {@link STABLE_MODEL_LABELS}).
169
+ *
170
+ * @param entry - the entry built from the listing.
171
+ * @returns the entry, relabelled when its id has a stable label.
172
+ */
173
+ private labelled;
174
+ /**
175
+ * Read the cached listing, once, so the picker works without asking the endpoint.
176
+ *
177
+ * Called before the first catalog query. A read failure is a cache miss, never a
178
+ * failure: the route simply has no listing until one is fetched.
179
+ */
180
+ hydrate(): Promise<void>;
129
181
  /** The fast pair one picker id belongs to, from either side. */
130
182
  fastPairOf(id: string): {
131
183
  baseId: string;
132
184
  wireId: string;
133
185
  } | undefined;
186
+ /**
187
+ * Whether this route has read a model listing yet.
188
+ *
189
+ * A variant is derived from the listing, so until one has been read "this model has no
190
+ * variant" and "the listing has not arrived" look identical from outside; a caller that
191
+ * asks once (the composer's quick-mode button) needs to tell them apart.
192
+ */
193
+ hasListing(): boolean;
134
194
  /**
135
195
  * Tool schemas in the shape Moonshot accepts: no `$ref`, and under its size
136
196
  * ceiling. A declaration too large to send keeps its arguments, and that is
@@ -157,19 +217,27 @@ export declare class KimiAdapter extends LlmAdapter {
157
217
  */
158
218
  private catalog;
159
219
  /**
160
- * The catalog to present: the shipped entries in their curated order and with
161
- * their curated metadata, then any configured extra id, then any live id this
162
- * build does not know.
220
+ * The catalog to present: the models the endpoint's listing named, in its own order,
221
+ * each with the metadata that listing stated, then the configured extras.
163
222
  *
164
- * The live list never removes a shipped entry: the endpoint serves variants
165
- * such as `k3[1m]` that its own `/models` listing omits, so absence there is
166
- * not evidence of retirement.
223
+ * There is no shipped roster to fall back to. A listing is read once and cached (see
224
+ * {@link hydrate} and {@link fetchCatalog}), and that cached table is what the picker
225
+ * shows until the next read, so a model released, renamed or retired server-side is
226
+ * reflected without a plugin update or a request per refresh.
167
227
  */
168
228
  private shippedCatalog;
169
- /** Whether one shipped entry covers a live model id. */
170
- private entryMatches;
171
- /** Resolve a requested model id onto its catalog entry. */
229
+ /** Resolve a requested model id onto the entry the endpoint's listing described. */
172
230
  private entryFor;
231
+ /**
232
+ * The model one wire id names, when the endpoint has retired the spelling.
233
+ *
234
+ * Consulted only for an id the current listing does not serve, so an id the endpoint
235
+ * itself reports is always dispatched exactly as reported.
236
+ *
237
+ * @param model - the requested model id.
238
+ * @returns the current spelling, or undefined when the id is not a known retirement.
239
+ */
240
+ private repairModelId;
173
241
  /** Re-read the ids the user added by hand. */
174
242
  private syncUserModels;
175
243
  /**
@@ -179,9 +247,18 @@ export declare class KimiAdapter extends LlmAdapter {
179
247
  * the endpoint's own defaults are the honest description.
180
248
  */
181
249
  private addedEntries;
182
- /** Record the live catalog for the picker; failures keep the shipped list. */
250
+ /**
251
+ * Adopt the ids a caller reports as the served set, without a listing.
252
+ *
253
+ * {@link fetchCatalog} already derived the entries from the rows it read, and the
254
+ * controller reports those same ids back here; the entries it recorded are kept. A
255
+ * caller that only has ids (a test, another discovery path) gets conservative entries
256
+ * for them.
257
+ *
258
+ * @param ids - model ids the caller reports.
259
+ */
183
260
  discover(ids: readonly string[]): void;
184
- /** The curated catalog, for the Settings page's model list. */
261
+ /** The catalog, for the Settings page's model list. */
185
262
  catalogEntries(): readonly KimiModelEntry[];
186
263
  /** What this route itself serves, without the ids added by hand. */
187
264
  ownCatalogEntries(): readonly KimiModelEntry[];
@@ -191,6 +268,19 @@ export declare class KimiAdapter extends LlmAdapter {
191
268
  private identity;
192
269
  /** Resolve image blocks through the attachment service, when it is present. */
193
270
  private imageResolver;
194
- /** Read the live `/models` catalog, or undefined when unavailable. */
271
+ /**
272
+ * Read the endpoint's model listing and adopt it as this route's catalog.
273
+ *
274
+ * This is the one place a model table is produced, and it is the endpoint's own
275
+ * answer: what the listing names is what the picker offers, with the display name,
276
+ * context window, modalities and reasoning ladder the listing states. The rows are
277
+ * also handed to {@link KimiAdapterOptions.saveListing}, so the next session starts
278
+ * from this table instead of asking again — the Settings "refresh models" action is
279
+ * what re-reads it.
280
+ *
281
+ * @param accessToken - bearer for the account.
282
+ * @param signal - optional cancellation.
283
+ * @returns the model ids now served, or undefined when the listing is unavailable.
284
+ */
195
285
  fetchCatalog(accessToken: string, signal?: AbortSignal): Promise<readonly string[] | undefined>;
196
286
  }