dsh-plugin-subscription-oauth 0.8.13 → 0.8.15
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/auth/provider-controller.js +21 -17
- package/lib/auth/tokens.js +1 -1
- package/lib/client/FastModeButton.d.ts +50 -0
- package/lib/client/FastModeButton.js +94 -0
- package/lib/client/UsageChip.js +2 -1
- package/lib/client/index.d.ts +14 -1
- package/lib/client/index.js +46 -2
- package/lib/client/styles.d.ts +8 -0
- package/lib/client/styles.js +61 -0
- package/lib/client.js +205 -3
- package/lib/client.js.map +1 -1
- package/lib/index.js +2 -0
- package/lib/protocol.d.ts +13 -1
- package/lib/providers/antigravity-catalog.d.ts +29 -9
- package/lib/providers/antigravity-catalog.js +212 -56
- package/lib/providers/antigravity.d.ts +2 -0
- package/lib/providers/antigravity.js +25 -3
- package/lib/providers/ark-provider.js +4 -0
- package/lib/providers/ark.d.ts +4 -0
- package/lib/providers/ark.js +16 -2
- package/lib/providers/glm-provider.js +4 -0
- package/lib/providers/glm.d.ts +4 -0
- package/lib/providers/glm.js +16 -2
- package/lib/providers/grok.d.ts +109 -3
- package/lib/providers/grok.js +258 -34
- package/lib/providers/kimi-provider.js +9 -0
- package/lib/providers/kimi.d.ts +28 -0
- package/lib/providers/kimi.js +89 -9
- package/lib/translate/antigravity.js +3 -3
- package/package.json +1 -1
package/lib/providers/grok.d.ts
CHANGED
|
@@ -116,8 +116,86 @@ interface GrokCliMetadata {
|
|
|
116
116
|
export declare function isImageModel(id: string): boolean;
|
|
117
117
|
/** True when a model id names a fast/lightspeed variant of a base model. */
|
|
118
118
|
export declare function isFastVariant(id: string): boolean;
|
|
119
|
-
/**
|
|
119
|
+
/**
|
|
120
|
+
* Every prefix of one model id, longest first, down to its first token.
|
|
121
|
+
*
|
|
122
|
+
* `grok-4.7-build-fast` → [`grok-4.7-build`, `grok-4.7`, `grok`]. A fast variant pairs
|
|
123
|
+
* with the longest prefix that is itself a listed model id, which is how
|
|
124
|
+
* `grok-4.7-build-fast` lands on `grok-4.7` (its own prefix `grok-4.7-build` is not a
|
|
125
|
+
* model) instead of inventing a base that no catalog row serves.
|
|
126
|
+
*
|
|
127
|
+
* @param id - model id.
|
|
128
|
+
* @returns the candidate bases, longest first.
|
|
129
|
+
*/
|
|
130
|
+
export declare function baseCandidatesOf(id: string): readonly string[];
|
|
131
|
+
/**
|
|
132
|
+
* The base model id a fast variant belongs to, derived only from its own name.
|
|
133
|
+
*
|
|
134
|
+
* The fast token is removed, then any trailing generation qualifier (`build`, `beta`,
|
|
135
|
+
* `rc`, …) left behind by that removal, then any `@Nk` context suffix. What remains is
|
|
136
|
+
* the base (`grok-4.7-build-fast@500k` → `grok-4.7`, `kimi-for-coding-highspeed` →
|
|
137
|
+
* `kimi-for-coding`). Whether the base is a real catalog row is the index's job, not
|
|
138
|
+
* this function's.
|
|
139
|
+
*/
|
|
120
140
|
export declare function baseModelOf(id: string): string;
|
|
141
|
+
/**
|
|
142
|
+
* The fast variant of one picker row, from either side of the pair.
|
|
143
|
+
*
|
|
144
|
+
* Shared by every route that discovers fast ids, so the composer's quick-mode button
|
|
145
|
+
* behaves the same wherever a fast model is identifiable: it finds the pair when asked
|
|
146
|
+
* about the base row, and when asked about the fast id itself — which is what the
|
|
147
|
+
* selection becomes once the mode is on — so it can switch back off again.
|
|
148
|
+
*/
|
|
149
|
+
export declare class FastVariantIndex {
|
|
150
|
+
private readonly byBase;
|
|
151
|
+
private readonly rowOfVariant;
|
|
152
|
+
private readonly knownIds;
|
|
153
|
+
/** Forget every pair and every known id, before re-reading a catalog. */
|
|
154
|
+
clear(): void;
|
|
155
|
+
/**
|
|
156
|
+
* Record one id the catalog listed.
|
|
157
|
+
*
|
|
158
|
+
* Listed ids are what a variant may pair with: the pair is the longest listed prefix
|
|
159
|
+
* of the variant's own name, so nothing is invented that no row actually serves.
|
|
160
|
+
*
|
|
161
|
+
* @param id - a wire id from a catalog.
|
|
162
|
+
*/
|
|
163
|
+
noteListed(id: string): void;
|
|
164
|
+
/**
|
|
165
|
+
* Pair one fast id with its base, purely from its own name.
|
|
166
|
+
*
|
|
167
|
+
* Every listed prefix of the id is a candidate base, longest first; the first one
|
|
168
|
+
* that is itself a listed model wins. No curated alias or hardcoded map is needed:
|
|
169
|
+
* a provider that names its variants after the base model pairs them automatically.
|
|
170
|
+
*
|
|
171
|
+
* @param id - a wire id the catalog named.
|
|
172
|
+
* @returns the base id, or undefined when no listed prefix names one.
|
|
173
|
+
*/
|
|
174
|
+
pair(id: string): string | undefined;
|
|
175
|
+
/**
|
|
176
|
+
* Record one id, if it names a fast variant.
|
|
177
|
+
*
|
|
178
|
+
* The first variant named for a row wins: a catalog that lists two spellings of the
|
|
179
|
+
* same variant (`kimi-for-coding-highspeed` and `kimi-k2.7-code-highspeed`) offers
|
|
180
|
+
* one button, and the earlier entry is the more specific one.
|
|
181
|
+
*
|
|
182
|
+
* @param id - a wire id from a catalog.
|
|
183
|
+
* @param rowOf - maps a base id to the picker row that serves it, when the catalog
|
|
184
|
+
* spells the base differently from the variant's own prefix.
|
|
185
|
+
*/
|
|
186
|
+
note(id: string, rowOf?: (base: string) => string | undefined): void;
|
|
187
|
+
/** The fast variant's wire id for one picker row, when the catalog named one. */
|
|
188
|
+
variantOf(baseId: string): string | undefined;
|
|
189
|
+
/** The pair one picker id belongs to, from either side. */
|
|
190
|
+
pairOf(id: string): {
|
|
191
|
+
baseId: string;
|
|
192
|
+
wireId: string;
|
|
193
|
+
} | undefined;
|
|
194
|
+
}
|
|
195
|
+
/** Extract the context size from a model id's `@Nk` suffix, or undefined. */
|
|
196
|
+
export declare function contextOf(id: string): number | undefined;
|
|
197
|
+
/** Strip the `@Nk` context suffix from a model id. */
|
|
198
|
+
export declare function stripContext(id: string): string;
|
|
121
199
|
/** Constructor dependencies for {@link GrokAdapter}. */
|
|
122
200
|
export interface GrokAdapterOptions {
|
|
123
201
|
/** API base; `<base>/responses` and `<base>/models`. */
|
|
@@ -190,6 +268,11 @@ export declare class GrokAdapter extends LlmAdapter {
|
|
|
190
268
|
discover(ids: readonly string[], metadata?: ReadonlyMap<string, GrokCliMetadata>): void;
|
|
191
269
|
/** The fast/lightspeed variant wire id for a base model, when discovery reported one. */
|
|
192
270
|
fastVariant(baseId: string): string | undefined;
|
|
271
|
+
/** The fast pair one picker id belongs to, from either side. */
|
|
272
|
+
fastPairOf(id: string): {
|
|
273
|
+
baseId: string;
|
|
274
|
+
wireId: string;
|
|
275
|
+
} | undefined;
|
|
193
276
|
/** The image-generation model id, when discovery reported one. */
|
|
194
277
|
imageModelId(): string | undefined;
|
|
195
278
|
/** The curated catalog, for the Settings page's model list. */
|
|
@@ -197,6 +280,12 @@ export declare class GrokAdapter extends LlmAdapter {
|
|
|
197
280
|
/** What this route itself serves, without the ids added by hand. */
|
|
198
281
|
ownCatalogEntries(): readonly CatalogEntry[];
|
|
199
282
|
/** Build and send one request for one model. */
|
|
283
|
+
/** The default context variant per base model, set during discovery. */
|
|
284
|
+
private defaultContext;
|
|
285
|
+
/** Resolve a model id to the wire id the endpoint accepts (largest context). */
|
|
286
|
+
resolveModelId(model: string): string;
|
|
287
|
+
/** Record one default-context mapping. */
|
|
288
|
+
private noteContextVariant;
|
|
200
289
|
private request;
|
|
201
290
|
/** Resolve image blocks through the attachment service, when it is present. */
|
|
202
291
|
private imageResolver;
|
|
@@ -206,8 +295,25 @@ export declare class GrokAdapter extends LlmAdapter {
|
|
|
206
295
|
* @returns the model ids, or undefined when discovery is off or unavailable.
|
|
207
296
|
*/
|
|
208
297
|
fetchCatalog(accessToken: string, signal?: AbortSignal): Promise<readonly string[] | undefined>;
|
|
209
|
-
/**
|
|
210
|
-
|
|
298
|
+
/**
|
|
299
|
+
* Fold the fast and context variants of one id list into their base models.
|
|
300
|
+
*
|
|
301
|
+
* @param ids - wire ids to classify.
|
|
302
|
+
*/
|
|
303
|
+
private noteWireVariants;
|
|
304
|
+
/**
|
|
305
|
+
* Read per-model capabilities from the CLI catalog; failures are silent.
|
|
306
|
+
*
|
|
307
|
+
* The catalog answers only for the signed-in account's own bearer — an anonymous
|
|
308
|
+
* request is refused — and it, unlike the public `/models` list, names the account's
|
|
309
|
+
* fast variant.
|
|
310
|
+
*
|
|
311
|
+
* @param fetchFn - fetch implementation.
|
|
312
|
+
* @param signal - caller cancellation.
|
|
313
|
+
* @param accessToken - the account's bearer.
|
|
314
|
+
* @returns the capability metadata and every id the catalog named.
|
|
315
|
+
*/
|
|
316
|
+
private readCliCatalog;
|
|
211
317
|
}
|
|
212
318
|
/** Everything the `grok` route needs from the plugin configuration. */
|
|
213
319
|
export interface GrokProviderOptions {
|
package/lib/providers/grok.js
CHANGED
|
@@ -268,15 +268,152 @@ const IMAGE_MODEL = /(?:^|[-_/])(?:image|imagine|draw|pic|photo)(?:[-_/]|$)/i;
|
|
|
268
268
|
export function isImageModel(id) {
|
|
269
269
|
return IMAGE_MODEL.test(id);
|
|
270
270
|
}
|
|
271
|
-
/**
|
|
272
|
-
|
|
271
|
+
/**
|
|
272
|
+
* Model ids that are the fast/lightspeed variant of a base model, matched per base.
|
|
273
|
+
*
|
|
274
|
+
* The vocabulary is the providers' own: xAI says `fast` (`grok-4.7-build-fast`), the
|
|
275
|
+
* Claude/Codex world says `lightspeed` or `turbo`, and Kimi says `highspeed`
|
|
276
|
+
* (`kimi-for-coding-highspeed`). A word has to stand on its own, so `highspeed` never
|
|
277
|
+
* matches inside another word.
|
|
278
|
+
*/
|
|
279
|
+
const FAST_VARIANT = /(?:^|[-_@])(?:fast|lightspeed|turbo|quick|highspeed)(?=[-_@]|$)/i;
|
|
273
280
|
/** True when a model id names a fast/lightspeed variant of a base model. */
|
|
274
281
|
export function isFastVariant(id) {
|
|
275
282
|
return FAST_VARIANT.test(id);
|
|
276
283
|
}
|
|
277
|
-
/**
|
|
284
|
+
/**
|
|
285
|
+
* Every prefix of one model id, longest first, down to its first token.
|
|
286
|
+
*
|
|
287
|
+
* `grok-4.7-build-fast` → [`grok-4.7-build`, `grok-4.7`, `grok`]. A fast variant pairs
|
|
288
|
+
* with the longest prefix that is itself a listed model id, which is how
|
|
289
|
+
* `grok-4.7-build-fast` lands on `grok-4.7` (its own prefix `grok-4.7-build` is not a
|
|
290
|
+
* model) instead of inventing a base that no catalog row serves.
|
|
291
|
+
*
|
|
292
|
+
* @param id - model id.
|
|
293
|
+
* @returns the candidate bases, longest first.
|
|
294
|
+
*/
|
|
295
|
+
export function baseCandidatesOf(id) {
|
|
296
|
+
const out = [];
|
|
297
|
+
let at = id.length;
|
|
298
|
+
while (at > 0) {
|
|
299
|
+
at = id.lastIndexOf('-', at - 1);
|
|
300
|
+
if (at <= 0)
|
|
301
|
+
break;
|
|
302
|
+
out.push(id.slice(0, at));
|
|
303
|
+
}
|
|
304
|
+
return out;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* The base model id a fast variant belongs to, derived only from its own name.
|
|
308
|
+
*
|
|
309
|
+
* The fast token is removed, then any trailing generation qualifier (`build`, `beta`,
|
|
310
|
+
* `rc`, …) left behind by that removal, then any `@Nk` context suffix. What remains is
|
|
311
|
+
* the base (`grok-4.7-build-fast@500k` → `grok-4.7`, `kimi-for-coding-highspeed` →
|
|
312
|
+
* `kimi-for-coding`). Whether the base is a real catalog row is the index's job, not
|
|
313
|
+
* this function's.
|
|
314
|
+
*/
|
|
278
315
|
export function baseModelOf(id) {
|
|
279
|
-
return id
|
|
316
|
+
return id
|
|
317
|
+
.replace(FAST_VARIANT, '')
|
|
318
|
+
.replace(/@\d+k$/i, '')
|
|
319
|
+
.replace(/[-_]$/, '')
|
|
320
|
+
.replace(/-(?:build|beta|alpha|rc|stable)$/i, '')
|
|
321
|
+
.replace(/[-_]$/, '');
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* The fast variant of one picker row, from either side of the pair.
|
|
325
|
+
*
|
|
326
|
+
* Shared by every route that discovers fast ids, so the composer's quick-mode button
|
|
327
|
+
* behaves the same wherever a fast model is identifiable: it finds the pair when asked
|
|
328
|
+
* about the base row, and when asked about the fast id itself — which is what the
|
|
329
|
+
* selection becomes once the mode is on — so it can switch back off again.
|
|
330
|
+
*/
|
|
331
|
+
export class FastVariantIndex {
|
|
332
|
+
byBase = new Map();
|
|
333
|
+
rowOfVariant = new Map();
|
|
334
|
+
knownIds = new Set();
|
|
335
|
+
/** Forget every pair and every known id, before re-reading a catalog. */
|
|
336
|
+
clear() {
|
|
337
|
+
this.byBase.clear();
|
|
338
|
+
this.rowOfVariant.clear();
|
|
339
|
+
this.knownIds.clear();
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Record one id the catalog listed.
|
|
343
|
+
*
|
|
344
|
+
* Listed ids are what a variant may pair with: the pair is the longest listed prefix
|
|
345
|
+
* of the variant's own name, so nothing is invented that no row actually serves.
|
|
346
|
+
*
|
|
347
|
+
* @param id - a wire id from a catalog.
|
|
348
|
+
*/
|
|
349
|
+
noteListed(id) {
|
|
350
|
+
this.knownIds.add(id);
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Pair one fast id with its base, purely from its own name.
|
|
354
|
+
*
|
|
355
|
+
* Every listed prefix of the id is a candidate base, longest first; the first one
|
|
356
|
+
* that is itself a listed model wins. No curated alias or hardcoded map is needed:
|
|
357
|
+
* a provider that names its variants after the base model pairs them automatically.
|
|
358
|
+
*
|
|
359
|
+
* @param id - a wire id the catalog named.
|
|
360
|
+
* @returns the base id, or undefined when no listed prefix names one.
|
|
361
|
+
*/
|
|
362
|
+
pair(id) {
|
|
363
|
+
if (!isFastVariant(id))
|
|
364
|
+
return undefined;
|
|
365
|
+
for (const base of baseCandidatesOf(id)) {
|
|
366
|
+
if (this.knownIds.has(base))
|
|
367
|
+
return base;
|
|
368
|
+
}
|
|
369
|
+
return undefined;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Record one id, if it names a fast variant.
|
|
373
|
+
*
|
|
374
|
+
* The first variant named for a row wins: a catalog that lists two spellings of the
|
|
375
|
+
* same variant (`kimi-for-coding-highspeed` and `kimi-k2.7-code-highspeed`) offers
|
|
376
|
+
* one button, and the earlier entry is the more specific one.
|
|
377
|
+
*
|
|
378
|
+
* @param id - a wire id from a catalog.
|
|
379
|
+
* @param rowOf - maps a base id to the picker row that serves it, when the catalog
|
|
380
|
+
* spells the base differently from the variant's own prefix.
|
|
381
|
+
*/
|
|
382
|
+
note(id, rowOf) {
|
|
383
|
+
if (!isFastVariant(id))
|
|
384
|
+
return;
|
|
385
|
+
const base = baseModelOf(id);
|
|
386
|
+
if (base.length === 0)
|
|
387
|
+
return;
|
|
388
|
+
const row = rowOf?.(base) ?? base;
|
|
389
|
+
if (!this.byBase.has(row))
|
|
390
|
+
this.byBase.set(row, id);
|
|
391
|
+
if (!this.rowOfVariant.has(id))
|
|
392
|
+
this.rowOfVariant.set(id, row);
|
|
393
|
+
}
|
|
394
|
+
/** The fast variant's wire id for one picker row, when the catalog named one. */
|
|
395
|
+
variantOf(baseId) {
|
|
396
|
+
return this.byBase.get(baseId);
|
|
397
|
+
}
|
|
398
|
+
/** The pair one picker id belongs to, from either side. */
|
|
399
|
+
pairOf(id) {
|
|
400
|
+
const direct = this.byBase.get(id);
|
|
401
|
+
if (direct !== undefined)
|
|
402
|
+
return { baseId: id, wireId: direct };
|
|
403
|
+
const row = this.rowOfVariant.get(id);
|
|
404
|
+
return row === undefined ? undefined : { baseId: row, wireId: id };
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
/** A context-size suffix like `@500k` on a model id. */
|
|
408
|
+
const CONTEXT_SUFFIX = /@(\d+)k$/i;
|
|
409
|
+
/** Extract the context size from a model id's `@Nk` suffix, or undefined. */
|
|
410
|
+
export function contextOf(id) {
|
|
411
|
+
const match = CONTEXT_SUFFIX.exec(id);
|
|
412
|
+
return match ? parseInt(match[1], 10) : undefined;
|
|
413
|
+
}
|
|
414
|
+
/** Strip the `@Nk` context suffix from a model id. */
|
|
415
|
+
export function stripContext(id) {
|
|
416
|
+
return id.replace(CONTEXT_SUFFIX, '');
|
|
280
417
|
}
|
|
281
418
|
/** Grok wire adapter: one instance serves the `grok` provider route. */
|
|
282
419
|
export class GrokAdapter extends LlmAdapter {
|
|
@@ -286,7 +423,7 @@ export class GrokAdapter extends LlmAdapter {
|
|
|
286
423
|
/** Capability metadata from the CLI catalog, keyed by model id. */
|
|
287
424
|
metadata = new Map();
|
|
288
425
|
/** Fast-variant wire id per base model, for the picker's quick-mode button. */
|
|
289
|
-
fastVariants = new
|
|
426
|
+
fastVariants = new FastVariantIndex();
|
|
290
427
|
/** Image-generation model id, when discovery reported one. */
|
|
291
428
|
imageModel;
|
|
292
429
|
/** Ids the user added by hand, cached so the sync catalog can name them. */
|
|
@@ -309,15 +446,25 @@ export class GrokAdapter extends LlmAdapter {
|
|
|
309
446
|
return [];
|
|
310
447
|
await this.syncUserModels();
|
|
311
448
|
const hidden = await this.hidden();
|
|
312
|
-
//
|
|
449
|
+
// A fast variant is not a picker row, but the host validates a GUI selection
|
|
450
|
+
// against the exact list `listModels` returns, so the variant must appear there
|
|
451
|
+
// or selecting it is refused with `session/model-unavailable`. The picker's
|
|
452
|
+
// menu collapses entries that share one `group` value into a single choice,
|
|
453
|
+
// so the variant rides with its base id as the group: the host can name and
|
|
454
|
+
// select it, and the picker still shows one row per model.
|
|
313
455
|
const imageless = this.catalog().filter((entry) => !isImageModel(entry.id));
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
456
|
+
const listed = resolveCatalog(imageless, [], hidden).entries.flatMap((entry) => {
|
|
457
|
+
const fast = this.fastVariants.variantOf(entry.id);
|
|
458
|
+
const base = {
|
|
459
|
+
provider: GROK_PROVIDER_ID,
|
|
460
|
+
id: entry.id,
|
|
461
|
+
name: entry.name,
|
|
462
|
+
...entry.description === undefined ? {} : { description: entry.description },
|
|
463
|
+
...entry.inputModalities === undefined ? {} : { inputModalities: entry.inputModalities },
|
|
464
|
+
};
|
|
465
|
+
return fast === undefined ? [base] : [base, { provider: GROK_PROVIDER_ID, id: fast, name: entry.name, group: entry.id, description: 'Fast variant', ...entry.inputModalities === undefined ? {} : { inputModalities: entry.inputModalities } }];
|
|
466
|
+
});
|
|
467
|
+
return listed;
|
|
321
468
|
}
|
|
322
469
|
async hidden() {
|
|
323
470
|
if (this.options.hiddenModels === undefined)
|
|
@@ -332,7 +479,12 @@ export class GrokAdapter extends LlmAdapter {
|
|
|
332
479
|
}
|
|
333
480
|
async resolveModel(_provider, model) {
|
|
334
481
|
await this.syncUserModels();
|
|
335
|
-
|
|
482
|
+
// A fast variant is not a catalog row of its own: it answers with its base model's
|
|
483
|
+
// metadata — the same 500k window, name and ladder the picker shows — while the id
|
|
484
|
+
// stays the fast wire id the request must send.
|
|
485
|
+
const pair = this.fastPairOf(model);
|
|
486
|
+
const entry = findEntry(this.catalog(), model)
|
|
487
|
+
?? (pair === undefined ? undefined : findEntry(this.catalog(), pair.baseId));
|
|
336
488
|
if (entry === undefined) {
|
|
337
489
|
const template = findEntry(GROK_MODELS, 'grok-4.6');
|
|
338
490
|
const reasoning = template === undefined ? undefined : reasoningInfo(template);
|
|
@@ -348,7 +500,7 @@ export class GrokAdapter extends LlmAdapter {
|
|
|
348
500
|
const reasoning = reasoningInfo(entry);
|
|
349
501
|
return {
|
|
350
502
|
provider: GROK_PROVIDER_ID,
|
|
351
|
-
id:
|
|
503
|
+
id: model,
|
|
352
504
|
name: entry.name,
|
|
353
505
|
...entry.description === undefined ? {} : { description: entry.description },
|
|
354
506
|
...entry.inputModalities === undefined ? {} : { inputModalities: entry.inputModalities },
|
|
@@ -358,7 +510,9 @@ export class GrokAdapter extends LlmAdapter {
|
|
|
358
510
|
};
|
|
359
511
|
}
|
|
360
512
|
stream(options) {
|
|
361
|
-
|
|
513
|
+
// Resolve @Nk context suffixes to the largest variant the endpoint offers.
|
|
514
|
+
const model = this.resolveModelId(options.model);
|
|
515
|
+
return streamProviderResponses({ ...options, model }, {
|
|
362
516
|
label: 'xAI API',
|
|
363
517
|
tokens: this.options.tokens,
|
|
364
518
|
request: (call, model, accessToken, signal) => this.request(call, model, accessToken, signal),
|
|
@@ -409,14 +563,17 @@ export class GrokAdapter extends LlmAdapter {
|
|
|
409
563
|
...meta?.defaultEffort === undefined ? {} : { defaultEffort: meta.defaultEffort },
|
|
410
564
|
});
|
|
411
565
|
}
|
|
412
|
-
// The seeds also pick up live metadata (
|
|
566
|
+
// The seeds also pick up live metadata (reasoning ladder, default effort). The
|
|
567
|
+
// curated context window is never narrowed by a live figure: the CLI catalog states
|
|
568
|
+
// 256k for `grok-4.7`, which serves 500k, and a live read may only widen what this
|
|
569
|
+
// build ships.
|
|
413
570
|
const seeded = GROK_MODELS.map((entry) => {
|
|
414
571
|
const meta = this.metadata.get(entry.id);
|
|
415
572
|
if (meta === undefined)
|
|
416
573
|
return entry;
|
|
417
574
|
return {
|
|
418
575
|
...entry,
|
|
419
|
-
contextWindow: meta.contextWindow ??
|
|
576
|
+
contextWindow: Math.max(entry.contextWindow, meta.contextWindow ?? 0),
|
|
420
577
|
...meta.reasoningEfforts === undefined ? {} : { reasoningEfforts: meta.reasoningEfforts },
|
|
421
578
|
...meta.defaultEffort === undefined ? {} : { defaultEffort: meta.defaultEffort },
|
|
422
579
|
};
|
|
@@ -459,7 +616,11 @@ export class GrokAdapter extends LlmAdapter {
|
|
|
459
616
|
}
|
|
460
617
|
/** The fast/lightspeed variant wire id for a base model, when discovery reported one. */
|
|
461
618
|
fastVariant(baseId) {
|
|
462
|
-
return this.fastVariants.
|
|
619
|
+
return this.fastVariants.variantOf(baseId);
|
|
620
|
+
}
|
|
621
|
+
/** The fast pair one picker id belongs to, from either side. */
|
|
622
|
+
fastPairOf(id) {
|
|
623
|
+
return this.fastVariants.pairOf(id);
|
|
463
624
|
}
|
|
464
625
|
/** The image-generation model id, when discovery reported one. */
|
|
465
626
|
imageModelId() {
|
|
@@ -474,6 +635,22 @@ export class GrokAdapter extends LlmAdapter {
|
|
|
474
635
|
return this.shippedCatalog();
|
|
475
636
|
}
|
|
476
637
|
/** Build and send one request for one model. */
|
|
638
|
+
/** The default context variant per base model, set during discovery. */
|
|
639
|
+
defaultContext = new Map();
|
|
640
|
+
/** Resolve a model id to the wire id the endpoint accepts (largest context). */
|
|
641
|
+
resolveModelId(model) {
|
|
642
|
+
return this.defaultContext.get(model) ?? model;
|
|
643
|
+
}
|
|
644
|
+
/** Record one default-context mapping. */
|
|
645
|
+
noteContextVariant(base, context, wireId) {
|
|
646
|
+
const existing = this.defaultContext.get(base);
|
|
647
|
+
if (existing !== undefined) {
|
|
648
|
+
const existingCtx = contextOf(existing);
|
|
649
|
+
if (existingCtx !== undefined && existingCtx >= context)
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
this.defaultContext.set(base, wireId);
|
|
653
|
+
}
|
|
477
654
|
async request(options, model, accessToken, signal) {
|
|
478
655
|
const resolved = await toResponsesInput(options.messages, options.system, this.imageResolver(signal));
|
|
479
656
|
const body = {
|
|
@@ -552,24 +729,37 @@ export class GrokAdapter extends LlmAdapter {
|
|
|
552
729
|
const rawIds = allIds.filter((id) => !NON_CHAT_ID.test(id));
|
|
553
730
|
// Fast/lightspeed variants ride with their base model: they share the base's
|
|
554
731
|
// visibility switch and are reached by a picker button, not a separate row.
|
|
732
|
+
// Context variants (@500k) also fold into the base; the largest context wins.
|
|
555
733
|
this.fastVariants.clear();
|
|
734
|
+
this.defaultContext.clear();
|
|
556
735
|
for (const id of rawIds) {
|
|
557
|
-
|
|
558
|
-
continue;
|
|
559
|
-
const base = baseModelOf(id);
|
|
560
|
-
if (!this.fastVariants.has(base))
|
|
561
|
-
this.fastVariants.set(base, id);
|
|
736
|
+
this.fastVariants.noteListed(id);
|
|
562
737
|
}
|
|
738
|
+
this.noteWireVariants(rawIds);
|
|
563
739
|
const ids = rawIds
|
|
564
|
-
.map((id) =>
|
|
740
|
+
.map((id) => {
|
|
741
|
+
if (isFastVariant(id))
|
|
742
|
+
return this.fastVariants.pair(id) ?? baseModelOf(id);
|
|
743
|
+
const ctx = contextOf(id);
|
|
744
|
+
if (ctx !== undefined)
|
|
745
|
+
return stripContext(id);
|
|
746
|
+
return id;
|
|
747
|
+
})
|
|
565
748
|
.filter((id, index, list) => list.indexOf(id) === index);
|
|
566
749
|
if (ids.length === 0) {
|
|
567
750
|
this.options.onWarn?.('xAI model discovery returned an empty catalog; using the built-in catalog');
|
|
568
751
|
return undefined;
|
|
569
752
|
}
|
|
570
|
-
const
|
|
571
|
-
for (const [id, meta] of metadata)
|
|
753
|
+
const cli = await this.readCliCatalog(fetchFn, signal, accessToken);
|
|
754
|
+
for (const [id, meta] of cli.metadata)
|
|
572
755
|
this.metadata.set(id, meta);
|
|
756
|
+
// The account's own CLI catalog is the only surface that names a fast variant:
|
|
757
|
+
// the public `/models` list omits `grok-4.7-build-fast` entirely. Its ids fold
|
|
758
|
+
// into the same base rows, and are never added as picker rows of their own.
|
|
759
|
+
for (const id of cli.ids) {
|
|
760
|
+
this.fastVariants.noteListed(id);
|
|
761
|
+
}
|
|
762
|
+
this.noteWireVariants(cli.ids);
|
|
573
763
|
return ids;
|
|
574
764
|
}
|
|
575
765
|
catch (error) {
|
|
@@ -579,21 +769,55 @@ export class GrokAdapter extends LlmAdapter {
|
|
|
579
769
|
return undefined;
|
|
580
770
|
}
|
|
581
771
|
}
|
|
582
|
-
/**
|
|
583
|
-
|
|
772
|
+
/**
|
|
773
|
+
* Fold the fast and context variants of one id list into their base models.
|
|
774
|
+
*
|
|
775
|
+
* @param ids - wire ids to classify.
|
|
776
|
+
*/
|
|
777
|
+
noteWireVariants(ids) {
|
|
778
|
+
for (const id of ids) {
|
|
779
|
+
if (NON_CHAT_ID.test(id) || isImageModel(id))
|
|
780
|
+
continue;
|
|
781
|
+
if (isFastVariant(id)) {
|
|
782
|
+
// Pair with the longest listed prefix, not a derived string: the prefix is a
|
|
783
|
+
// model the account actually serves, so the button always targets a real row.
|
|
784
|
+
const base = this.fastVariants.pair(id);
|
|
785
|
+
this.fastVariants.note(id, () => base);
|
|
786
|
+
continue;
|
|
787
|
+
}
|
|
788
|
+
const ctx = contextOf(id);
|
|
789
|
+
if (ctx !== undefined)
|
|
790
|
+
this.noteContextVariant(stripContext(id), ctx, id);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Read per-model capabilities from the CLI catalog; failures are silent.
|
|
795
|
+
*
|
|
796
|
+
* The catalog answers only for the signed-in account's own bearer — an anonymous
|
|
797
|
+
* request is refused — and it, unlike the public `/models` list, names the account's
|
|
798
|
+
* fast variant.
|
|
799
|
+
*
|
|
800
|
+
* @param fetchFn - fetch implementation.
|
|
801
|
+
* @param signal - caller cancellation.
|
|
802
|
+
* @param accessToken - the account's bearer.
|
|
803
|
+
* @returns the capability metadata and every id the catalog named.
|
|
804
|
+
*/
|
|
805
|
+
async readCliCatalog(fetchFn, signal, accessToken) {
|
|
584
806
|
const result = new Map();
|
|
807
|
+
const ids = [];
|
|
585
808
|
try {
|
|
586
809
|
const response = await fetchFn(GROK_CLI_MODELS_URL, {
|
|
587
|
-
headers: attributedHeaders({ 'authorization':
|
|
810
|
+
headers: attributedHeaders({ 'authorization': `Bearer ${accessToken}` }),
|
|
588
811
|
...signal === undefined ? {} : { signal },
|
|
589
812
|
});
|
|
590
813
|
if (!response.ok)
|
|
591
|
-
return result;
|
|
814
|
+
return { metadata: result, ids };
|
|
592
815
|
const payload = await response.json();
|
|
593
816
|
for (const entry of payload.data ?? []) {
|
|
594
817
|
const id = typeof entry.id === 'string' && entry.id.length > 0 ? entry.id : undefined;
|
|
595
818
|
if (id === undefined)
|
|
596
819
|
continue;
|
|
820
|
+
ids.push(id);
|
|
597
821
|
const contextWindow = typeof entry.context_window === 'number' && Number.isFinite(entry.context_window)
|
|
598
822
|
? entry.context_window
|
|
599
823
|
: undefined;
|
|
@@ -617,7 +841,7 @@ export class GrokAdapter extends LlmAdapter {
|
|
|
617
841
|
catch {
|
|
618
842
|
// Capability metadata is a bonus; the id list is what matters.
|
|
619
843
|
}
|
|
620
|
-
return result;
|
|
844
|
+
return { metadata: result, ids };
|
|
621
845
|
}
|
|
622
846
|
}
|
|
623
847
|
/**
|
|
@@ -759,10 +983,10 @@ export function createGrokProvider(options) {
|
|
|
759
983
|
usage: (force) => controller.usage(force),
|
|
760
984
|
reload: () => controller.reload(),
|
|
761
985
|
modelVariants: (id) => {
|
|
762
|
-
const
|
|
986
|
+
const pair = adapter.fastPairOf(id);
|
|
763
987
|
const image = adapter.imageModelId();
|
|
764
988
|
return {
|
|
765
|
-
...
|
|
989
|
+
...pair === undefined ? {} : { fast: pair.wireId, fastBase: pair.baseId },
|
|
766
990
|
...image === undefined ? {} : { image },
|
|
767
991
|
};
|
|
768
992
|
},
|
|
@@ -119,6 +119,7 @@ export function createKimiProvider(options) {
|
|
|
119
119
|
{ key: 'credentialFile', value: options.credentialFile },
|
|
120
120
|
],
|
|
121
121
|
applyDiscovery: (ids) => { adapter.discover(ids); },
|
|
122
|
+
fastVariant: (baseId) => adapter.fastVariant(baseId),
|
|
122
123
|
};
|
|
123
124
|
const controller = new ProviderController({
|
|
124
125
|
spec,
|
|
@@ -149,5 +150,13 @@ export function createKimiProvider(options) {
|
|
|
149
150
|
removeModel: (id) => controller.removeModel(id),
|
|
150
151
|
usage: (force) => controller.usage(force),
|
|
151
152
|
reload: () => controller.reload(),
|
|
153
|
+
modelVariants: (id) => {
|
|
154
|
+
const pair = adapter.fastPairOf(id);
|
|
155
|
+
const image = adapter.imageModelId();
|
|
156
|
+
return {
|
|
157
|
+
...pair === undefined ? {} : { fast: pair.wireId, fastBase: pair.baseId },
|
|
158
|
+
...image === undefined ? {} : { image },
|
|
159
|
+
};
|
|
160
|
+
},
|
|
152
161
|
};
|
|
153
162
|
}
|
package/lib/providers/kimi.d.ts
CHANGED
|
@@ -102,11 +102,35 @@ export declare class KimiAdapter extends LlmAdapter {
|
|
|
102
102
|
private readonly options;
|
|
103
103
|
/** Live catalog ids seen this session, used to accept renamed models. */
|
|
104
104
|
private discovered;
|
|
105
|
+
/** Image-generation model id, when discovery reported one. */
|
|
106
|
+
private imageModel;
|
|
107
|
+
/**
|
|
108
|
+
* Fast-variant wire id per picker row, for the composer's quick-mode button.
|
|
109
|
+
*
|
|
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.
|
|
113
|
+
*/
|
|
114
|
+
private readonly fastVariants;
|
|
105
115
|
/** Ids the user added by hand, cached so the sync catalog can name them. */
|
|
106
116
|
private userAddedIds;
|
|
107
117
|
/** Tools already reported as flattened, so each is stated once. */
|
|
108
118
|
private readonly flattenedTools;
|
|
109
119
|
constructor(options: KimiAdapterOptions);
|
|
120
|
+
/**
|
|
121
|
+
* Record the fast variants the curated catalog already names as aliases.
|
|
122
|
+
*
|
|
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.
|
|
127
|
+
*/
|
|
128
|
+
private seedCuratedFastVariants;
|
|
129
|
+
/** The fast pair one picker id belongs to, from either side. */
|
|
130
|
+
fastPairOf(id: string): {
|
|
131
|
+
baseId: string;
|
|
132
|
+
wireId: string;
|
|
133
|
+
} | undefined;
|
|
110
134
|
/**
|
|
111
135
|
* Tool schemas in the shape Moonshot accepts: no `$ref`, and under its size
|
|
112
136
|
* ceiling. A declaration too large to send keeps its arguments, and that is
|
|
@@ -116,6 +140,10 @@ export declare class KimiAdapter extends LlmAdapter {
|
|
|
116
140
|
providerInfo(provider: string): LlmProviderInfo;
|
|
117
141
|
providerRetryPolicy(): undefined;
|
|
118
142
|
listModels(_provider: string): Promise<readonly LlmModelInfo[]>;
|
|
143
|
+
/** The image-generation model id, when discovery reported one. */
|
|
144
|
+
imageModelId(): string | undefined;
|
|
145
|
+
/** The fast/lightspeed variant wire id for a picker row. */
|
|
146
|
+
fastVariant(baseId: string): string | undefined;
|
|
119
147
|
/** The ids the picker must currently omit. */
|
|
120
148
|
private hidden;
|
|
121
149
|
resolveModel(_provider: string, model: string): Promise<LlmResolvedModelInfo>;
|