dsh-plugin-subscription-oauth 0.17.0 → 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.
- package/lib/client/FastModeButton.d.ts +0 -1
- package/lib/client/FastModeButton.js +48 -11
- package/lib/client.js +32 -9
- package/lib/client.js.map +1 -1
- package/lib/protocol.d.ts +9 -0
- package/lib/providers/ark-provider.js +10 -2
- package/lib/providers/ark.d.ts +8 -0
- package/lib/providers/ark.js +10 -0
- package/lib/providers/catalog.d.ts +2 -1
- package/lib/providers/catalog.js +2 -1
- package/lib/providers/glm-provider.js +10 -2
- package/lib/providers/glm.d.ts +8 -0
- package/lib/providers/glm.js +10 -0
- package/lib/providers/grok.d.ts +8 -0
- package/lib/providers/grok.js +18 -1
- package/lib/providers/kimi-provider.js +8 -1
- package/lib/providers/kimi.d.ts +18 -0
- package/lib/providers/kimi.js +54 -2
- package/package.json +1 -1
package/lib/protocol.d.ts
CHANGED
|
@@ -397,6 +397,15 @@ export interface ModelVariants {
|
|
|
397
397
|
fastRung?: string;
|
|
398
398
|
/** Image-generation model wire id, when the provider reported one. */
|
|
399
399
|
image?: string;
|
|
400
|
+
/**
|
|
401
|
+
* The route has not read its model listing yet, so "no variant" is not yet an answer.
|
|
402
|
+
*
|
|
403
|
+
* A listing is read once per session and its variants are derived from it, so an early
|
|
404
|
+
* read of this endpoint cannot tell "this model has no fast variant" from "the route has
|
|
405
|
+
* not looked yet". Saying so lets the caller ask again later instead of hiding a control
|
|
406
|
+
* that should be there — and, once a listing has been read, lets it stop asking.
|
|
407
|
+
*/
|
|
408
|
+
pending?: boolean;
|
|
400
409
|
}
|
|
401
410
|
/** Result of `model-variants`: the variants for one model id. */
|
|
402
411
|
export type ModelVariantsResult = ModelVariants | undefined;
|
|
@@ -176,9 +176,17 @@ export function createArkProvider(options) {
|
|
|
176
176
|
removeModel: (id) => controller.removeModel(id),
|
|
177
177
|
usage: (force) => controller.usage(force),
|
|
178
178
|
reload: () => controller.reload(),
|
|
179
|
-
modelVariants: (id) => {
|
|
179
|
+
modelVariants: async (id) => {
|
|
180
|
+
// The image model is a row of the listing, so the read is awaited before answering:
|
|
181
|
+
// the composer asks once, and "no image model" must mean there is none.
|
|
182
|
+
void id;
|
|
183
|
+
await adapter.hydrate();
|
|
180
184
|
const image = adapter.imageModelId();
|
|
181
|
-
return
|
|
185
|
+
return {
|
|
186
|
+
...image === undefined ? {} : { image },
|
|
187
|
+
// Nothing read yet: the answer above is provisional, and the caller is told so.
|
|
188
|
+
...adapter.hasListing() ? {} : { pending: true },
|
|
189
|
+
};
|
|
182
190
|
},
|
|
183
191
|
};
|
|
184
192
|
}
|
package/lib/providers/ark.d.ts
CHANGED
|
@@ -163,6 +163,14 @@ export declare class ArkAdapter extends LlmAdapter {
|
|
|
163
163
|
listModels(_provider: string): Promise<readonly LlmModelInfo[]>;
|
|
164
164
|
/** The image-generation model id, when discovery reported one. */
|
|
165
165
|
imageModelId(): string | undefined;
|
|
166
|
+
/**
|
|
167
|
+
* Whether this route has read a model listing yet.
|
|
168
|
+
*
|
|
169
|
+
* The image model is a row of the listing, so until one has been read "there is no image
|
|
170
|
+
* model" and "the listing has not arrived" look identical from outside; a caller that asks
|
|
171
|
+
* once needs to tell them apart.
|
|
172
|
+
*/
|
|
173
|
+
hasListing(): boolean;
|
|
166
174
|
resolveModel(_provider: string, model: string): Promise<LlmResolvedModelInfo>;
|
|
167
175
|
stream(options: GenerateOptions): AsyncIterable<StreamChunk>;
|
|
168
176
|
/** Translate an auth failure into the message a user can act on. */
|
package/lib/providers/ark.js
CHANGED
|
@@ -228,6 +228,16 @@ export class ArkAdapter extends LlmAdapter {
|
|
|
228
228
|
imageModelId() {
|
|
229
229
|
return this.imageModel;
|
|
230
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* Whether this route has read a model listing yet.
|
|
233
|
+
*
|
|
234
|
+
* The image model is a row of the listing, so until one has been read "there is no image
|
|
235
|
+
* model" and "the listing has not arrived" look identical from outside; a caller that asks
|
|
236
|
+
* once needs to tell them apart.
|
|
237
|
+
*/
|
|
238
|
+
hasListing() {
|
|
239
|
+
return this.live !== undefined;
|
|
240
|
+
}
|
|
231
241
|
async resolveModel(_provider, model) {
|
|
232
242
|
await this.hydrate();
|
|
233
243
|
const entry = findEntry(this.catalog(), model);
|
|
@@ -88,7 +88,8 @@ export declare function liveModelFacts(row: unknown): LiveModelFacts | undefined
|
|
|
88
88
|
* What the endpoint stated wins; the curated table fills only what the listing was
|
|
89
89
|
* silent about, so a live figure — the window a model actually serves today — is
|
|
90
90
|
* never overridden by a shipped guess, and a retired figure never survives a live
|
|
91
|
-
* read that contradicts it.
|
|
91
|
+
* read that contradicts it. A route whose ids are stable aliases the service re-points
|
|
92
|
+
* per release keeps its own labels instead (see the kimi route's alias labels).
|
|
92
93
|
*
|
|
93
94
|
* @param facts - what the listing stated for this id.
|
|
94
95
|
* @param curated - the curated metadata table.
|
package/lib/providers/catalog.js
CHANGED
|
@@ -163,7 +163,8 @@ export function liveModelFacts(row) {
|
|
|
163
163
|
* What the endpoint stated wins; the curated table fills only what the listing was
|
|
164
164
|
* silent about, so a live figure — the window a model actually serves today — is
|
|
165
165
|
* never overridden by a shipped guess, and a retired figure never survives a live
|
|
166
|
-
* read that contradicts it.
|
|
166
|
+
* read that contradicts it. A route whose ids are stable aliases the service re-points
|
|
167
|
+
* per release keeps its own labels instead (see the kimi route's alias labels).
|
|
167
168
|
*
|
|
168
169
|
* @param facts - what the listing stated for this id.
|
|
169
170
|
* @param curated - the curated metadata table.
|
|
@@ -172,9 +172,17 @@ export function createGlmProvider(options) {
|
|
|
172
172
|
removeModel: (id) => controller.removeModel(id),
|
|
173
173
|
usage: (force) => controller.usage(force),
|
|
174
174
|
reload: () => controller.reload(),
|
|
175
|
-
modelVariants: (id) => {
|
|
175
|
+
modelVariants: async (id) => {
|
|
176
|
+
// The image model is a row of the listing, so the read is awaited before answering:
|
|
177
|
+
// the composer asks once, and "no image model" must mean there is none.
|
|
178
|
+
void id;
|
|
179
|
+
await adapter.hydrate();
|
|
176
180
|
const image = adapter.imageModelId();
|
|
177
|
-
return
|
|
181
|
+
return {
|
|
182
|
+
...image === undefined ? {} : { image },
|
|
183
|
+
// Nothing read yet: the answer above is provisional, and the caller is told so.
|
|
184
|
+
...adapter.hasListing() ? {} : { pending: true },
|
|
185
|
+
};
|
|
178
186
|
},
|
|
179
187
|
};
|
|
180
188
|
}
|
package/lib/providers/glm.d.ts
CHANGED
|
@@ -200,6 +200,14 @@ export declare class GlmAdapter extends LlmAdapter {
|
|
|
200
200
|
private addedEntries;
|
|
201
201
|
/** The image-generation model id, when discovery reported one. */
|
|
202
202
|
imageModelId(): string | undefined;
|
|
203
|
+
/**
|
|
204
|
+
* Whether this route has read a model listing yet.
|
|
205
|
+
*
|
|
206
|
+
* The image model is a row of the listing, so until one has been read "there is no image
|
|
207
|
+
* model" and "the listing has not arrived" look identical from outside; a caller that asks
|
|
208
|
+
* once needs to tell them apart.
|
|
209
|
+
*/
|
|
210
|
+
hasListing(): boolean;
|
|
203
211
|
/** The ids the picker must currently omit. */
|
|
204
212
|
private hidden;
|
|
205
213
|
/**
|
package/lib/providers/glm.js
CHANGED
|
@@ -380,6 +380,16 @@ export class GlmAdapter extends LlmAdapter {
|
|
|
380
380
|
imageModelId() {
|
|
381
381
|
return this.imageModel;
|
|
382
382
|
}
|
|
383
|
+
/**
|
|
384
|
+
* Whether this route has read a model listing yet.
|
|
385
|
+
*
|
|
386
|
+
* The image model is a row of the listing, so until one has been read "there is no image
|
|
387
|
+
* model" and "the listing has not arrived" look identical from outside; a caller that asks
|
|
388
|
+
* once needs to tell them apart.
|
|
389
|
+
*/
|
|
390
|
+
hasListing() {
|
|
391
|
+
return this.live !== undefined;
|
|
392
|
+
}
|
|
383
393
|
/** The ids the picker must currently omit. */
|
|
384
394
|
async hidden() {
|
|
385
395
|
if (this.options.hiddenModels === undefined)
|
package/lib/providers/grok.d.ts
CHANGED
|
@@ -337,6 +337,14 @@ export declare class GrokAdapter extends LlmAdapter {
|
|
|
337
337
|
} | undefined;
|
|
338
338
|
/** The image-generation model id, when discovery reported one. */
|
|
339
339
|
imageModelId(): string | undefined;
|
|
340
|
+
/**
|
|
341
|
+
* Whether this route has read a model listing yet.
|
|
342
|
+
*
|
|
343
|
+
* A variant is derived from the listing, so until one has been read "this model has no
|
|
344
|
+
* variant" and "the listing has not arrived" look identical from outside; a caller that
|
|
345
|
+
* asks once (the composer's quick-mode button) needs to tell them apart.
|
|
346
|
+
*/
|
|
347
|
+
hasListing(): boolean;
|
|
340
348
|
/** The curated catalog, for the Settings page's model list. */
|
|
341
349
|
catalogEntries(): readonly CatalogEntry[];
|
|
342
350
|
/** What this route itself serves, without the ids added by hand. */
|
package/lib/providers/grok.js
CHANGED
|
@@ -868,6 +868,16 @@ export class GrokAdapter extends LlmAdapter {
|
|
|
868
868
|
imageModelId() {
|
|
869
869
|
return this.imageModel;
|
|
870
870
|
}
|
|
871
|
+
/**
|
|
872
|
+
* Whether this route has read a model listing yet.
|
|
873
|
+
*
|
|
874
|
+
* A variant is derived from the listing, so until one has been read "this model has no
|
|
875
|
+
* variant" and "the listing has not arrived" look identical from outside; a caller that
|
|
876
|
+
* asks once (the composer's quick-mode button) needs to tell them apart.
|
|
877
|
+
*/
|
|
878
|
+
hasListing() {
|
|
879
|
+
return this.live !== undefined;
|
|
880
|
+
}
|
|
871
881
|
/** The curated catalog, for the Settings page's model list. */
|
|
872
882
|
catalogEntries() {
|
|
873
883
|
return this.catalog();
|
|
@@ -1193,12 +1203,19 @@ export function createGrokProvider(options) {
|
|
|
1193
1203
|
removeModel: (id) => controller.removeModel(id),
|
|
1194
1204
|
usage: (force) => controller.usage(force),
|
|
1195
1205
|
reload: () => controller.reload(),
|
|
1196
|
-
modelVariants: (id) => {
|
|
1206
|
+
modelVariants: async (id) => {
|
|
1207
|
+
// A variant is known only once the route has read its listing, whose rows name it.
|
|
1208
|
+
// The composer asks exactly once, so the read is awaited here: "no fast variant"
|
|
1209
|
+
// must mean the route really has none, not that its table was still loading.
|
|
1210
|
+
await adapter.hydrate();
|
|
1197
1211
|
const pair = adapter.fastPairOf(id);
|
|
1198
1212
|
const image = adapter.imageModelId();
|
|
1199
1213
|
return {
|
|
1200
1214
|
...pair === undefined ? {} : { fast: pair.wireId, fastBase: pair.baseId, fastRung: fastWordOf(pair.wireId) },
|
|
1201
1215
|
...image === undefined ? {} : { image },
|
|
1216
|
+
// Nothing read yet: the answer above is provisional, and the caller is told so
|
|
1217
|
+
// rather than being left to read silence as "this model has no variant".
|
|
1218
|
+
...adapter.hasListing() ? {} : { pending: true },
|
|
1202
1219
|
};
|
|
1203
1220
|
},
|
|
1204
1221
|
};
|
|
@@ -156,12 +156,19 @@ export function createKimiProvider(options) {
|
|
|
156
156
|
removeModel: (id) => controller.removeModel(id),
|
|
157
157
|
usage: (force) => controller.usage(force),
|
|
158
158
|
reload: () => controller.reload(),
|
|
159
|
-
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();
|
|
160
164
|
const pair = adapter.fastPairOf(id);
|
|
161
165
|
const image = adapter.imageModelId();
|
|
162
166
|
return {
|
|
163
167
|
...pair === undefined ? {} : { fast: pair.wireId, fastBase: pair.baseId, fastRung: fastWordOf(pair.wireId) },
|
|
164
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 },
|
|
165
172
|
};
|
|
166
173
|
},
|
|
167
174
|
};
|
package/lib/providers/kimi.d.ts
CHANGED
|
@@ -161,6 +161,16 @@ export declare class KimiAdapter extends LlmAdapter {
|
|
|
161
161
|
* @returns the entries to publish, in picker order.
|
|
162
162
|
*/
|
|
163
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;
|
|
164
174
|
/**
|
|
165
175
|
* Read the cached listing, once, so the picker works without asking the endpoint.
|
|
166
176
|
*
|
|
@@ -173,6 +183,14 @@ export declare class KimiAdapter extends LlmAdapter {
|
|
|
173
183
|
baseId: string;
|
|
174
184
|
wireId: string;
|
|
175
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;
|
|
176
194
|
/**
|
|
177
195
|
* Tool schemas in the shape Moonshot accepts: no `$ref`, and under its size
|
|
178
196
|
* ceiling. A declaration too large to send keeps its arguments, and that is
|
package/lib/providers/kimi.js
CHANGED
|
@@ -71,6 +71,35 @@ const EFFORT_LABELS = {
|
|
|
71
71
|
// is "highspeed", which is what the rung is named here.
|
|
72
72
|
[FAST_RUNG]: { name: 'Highspeed', description: 'Kimi highspeed variant of this model' },
|
|
73
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* Stable labels for the ids this route is known for.
|
|
76
|
+
*
|
|
77
|
+
* Labels, not a roster: nothing here decides which models exist or what they serve —
|
|
78
|
+
* membership, windows, ladders and modalities are the endpoint's listing. What it fixes is
|
|
79
|
+
* the one thing the listing cannot answer, because the id does not name it: `kimi-for-coding`
|
|
80
|
+
* is the subscription alias the service re-points at each coding release, so its
|
|
81
|
+
* `display_name` names the release of the moment (`K2.8 Preview` the week K2.8 ships) while
|
|
82
|
+
* the id the user selected stays the same. Labelling that row by release would rename the
|
|
83
|
+
* user's saved selection overnight, so the alias keeps its own name — and the endpoint's
|
|
84
|
+
* release name is deliberately not shown, because the row is the alias, not the version.
|
|
85
|
+
*
|
|
86
|
+
* A model the endpoint adds that this map does not name is published exactly as the
|
|
87
|
+
* endpoint describes it.
|
|
88
|
+
*/
|
|
89
|
+
const STABLE_MODEL_LABELS = {
|
|
90
|
+
'kimi-for-coding': {
|
|
91
|
+
name: 'Kimi for Coding',
|
|
92
|
+
description: 'Subscription alias — the endpoint re-points it at the current coding release',
|
|
93
|
+
},
|
|
94
|
+
'k3': {
|
|
95
|
+
name: 'Kimi K3',
|
|
96
|
+
description: 'Flagship reasoning model',
|
|
97
|
+
},
|
|
98
|
+
'k3-256k': {
|
|
99
|
+
name: 'Kimi K3 (256K)',
|
|
100
|
+
description: 'Flagship reasoning model pinned to the 256K-token window',
|
|
101
|
+
},
|
|
102
|
+
};
|
|
74
103
|
/**
|
|
75
104
|
* Spellings the endpoint has retired, and the model each one became.
|
|
76
105
|
*
|
|
@@ -185,7 +214,20 @@ export class KimiAdapter extends LlmAdapter {
|
|
|
185
214
|
if (id === fact.id || !byId.has(id))
|
|
186
215
|
byId.set(id, { ...fact, id });
|
|
187
216
|
}
|
|
188
|
-
return [...byId.values()].map((fact) => liveEntry(fact, [], KIMI_CONTEXT_WINDOW, 'Reported by the Kimi Code model list'));
|
|
217
|
+
return [...byId.values()].map((fact) => this.labelled(liveEntry(fact, [], KIMI_CONTEXT_WINDOW, 'Reported by the Kimi Code model list')));
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Put this route's stable label on one entry, when the id has one.
|
|
221
|
+
*
|
|
222
|
+
* The listing states what the model *is*; the label states what the *id* is, which only
|
|
223
|
+
* this route knows (see {@link STABLE_MODEL_LABELS}).
|
|
224
|
+
*
|
|
225
|
+
* @param entry - the entry built from the listing.
|
|
226
|
+
* @returns the entry, relabelled when its id has a stable label.
|
|
227
|
+
*/
|
|
228
|
+
labelled(entry) {
|
|
229
|
+
const stable = STABLE_MODEL_LABELS[entry.id];
|
|
230
|
+
return stable === undefined ? entry : { ...entry, name: stable.name, description: stable.description };
|
|
189
231
|
}
|
|
190
232
|
/**
|
|
191
233
|
* Read the cached listing, once, so the picker works without asking the endpoint.
|
|
@@ -212,6 +254,16 @@ export class KimiAdapter extends LlmAdapter {
|
|
|
212
254
|
fastPairOf(id) {
|
|
213
255
|
return this.fastVariants.pairOf(id);
|
|
214
256
|
}
|
|
257
|
+
/**
|
|
258
|
+
* Whether this route has read a model listing yet.
|
|
259
|
+
*
|
|
260
|
+
* A variant is derived from the listing, so until one has been read "this model has no
|
|
261
|
+
* variant" and "the listing has not arrived" look identical from outside; a caller that
|
|
262
|
+
* asks once (the composer's quick-mode button) needs to tell them apart.
|
|
263
|
+
*/
|
|
264
|
+
hasListing() {
|
|
265
|
+
return this.live !== undefined;
|
|
266
|
+
}
|
|
215
267
|
/**
|
|
216
268
|
* Tool schemas in the shape Moonshot accepts: no `$ref`, and under its size
|
|
217
269
|
* ceiling. A declaration too large to send keeps its arguments, and that is
|
|
@@ -465,7 +517,7 @@ export class KimiAdapter extends LlmAdapter {
|
|
|
465
517
|
discover(ids) {
|
|
466
518
|
const known = new Map((this.live ?? []).map((entry) => [entry.id, entry]));
|
|
467
519
|
this.live = ids.map((id) => known.get(id)
|
|
468
|
-
?? liveEntry({ id }, [], KIMI_CONTEXT_WINDOW, 'Reported by the Kimi Code model list'));
|
|
520
|
+
?? this.labelled(liveEntry({ id }, [], KIMI_CONTEXT_WINDOW, 'Reported by the Kimi Code model list')));
|
|
469
521
|
}
|
|
470
522
|
/** The catalog, for the Settings page's model list. */
|
|
471
523
|
catalogEntries() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-subscription-oauth",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"description": "Use subscription accounts as DeepSeek Harness LLM providers — Kimi Code (OAuth device flow), Grok / X Premium (OIDC + PKCE), Google Antigravity (Google OAuth + Cloud Code Assist) and GLM / BigModel (ZCode's browser sign-in) — with per-model visibility, drag-to-reorder Auto fallback and plan quotas from the web Settings page",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "EricFL1998",
|