dsh-plugin-subscription-oauth 0.8.12 → 0.8.14

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/protocol.d.ts CHANGED
@@ -12,7 +12,7 @@
12
12
  /** Prefix of every RPC method this plugin serves. */
13
13
  export declare const RPC_PREFIX = "subscription-oauth.";
14
14
  /** Endpoints the Settings page may call. */
15
- export declare const RPC_ENDPOINTS: readonly ["status", "login", "cancel", "logout", "setDefault", "refresh", "discover", "setModelVisible", "setModelOrder", "addModel", "removeModel", "usage", "reload", "deepseek-balance", "ccswitch-balance"];
15
+ export declare const RPC_ENDPOINTS: readonly ["status", "login", "cancel", "logout", "setDefault", "refresh", "discover", "setModelVisible", "setModelOrder", "addModel", "removeModel", "usage", "reload", "deepseek-balance", "ccswitch-balance", "model-variants"];
16
16
  /** One endpoint name. */
17
17
  export type RpcEndpoint = typeof RPC_ENDPOINTS[number];
18
18
  /** Client → host envelope. */
@@ -120,6 +120,8 @@ export interface ModelSummary {
120
120
  * hidden or moved; the page renders it without those controls.
121
121
  */
122
122
  pinned?: boolean;
123
+ /** Fast/lightspeed variant wire id, when the provider reported one for this base. */
124
+ fastVariant?: string;
123
125
  }
124
126
  /** One metered allowance of a subscription plan. */
125
127
  export interface UsageWindow {
@@ -321,6 +323,10 @@ export interface RpcMap {
321
323
  payload: CcSwitchBalanceRequest;
322
324
  value: CcSwitchBalanceResult;
323
325
  };
326
+ 'model-variants': {
327
+ payload: DiscoverRequest;
328
+ value: ModelVariantsResult;
329
+ };
324
330
  }
325
331
  /** One currency's wallet balance, as the platform reports it. */
326
332
  export interface WalletBalance {
@@ -347,6 +353,15 @@ export type BalanceResult =
347
353
  | {
348
354
  ok: false;
349
355
  };
356
+ /** One model's fast and image variants, as discovery reported them. */
357
+ export interface ModelVariants {
358
+ /** Fast/lightspeed variant wire id, when the provider reported one. */
359
+ fast?: string;
360
+ /** Image-generation model wire id, when the provider reported one. */
361
+ image?: string;
362
+ }
363
+ /** Result of `model-variants`: the variants for one model id. */
364
+ export type ModelVariantsResult = ModelVariants | undefined;
350
365
  /** Payload of `deepseek-balance`. */
351
366
  export interface DeepSeekBalanceRequest {
352
367
  /** Client metadata the host's account service expects. */
package/lib/protocol.js CHANGED
@@ -28,4 +28,5 @@ export const RPC_ENDPOINTS = [
28
28
  'reload',
29
29
  'deepseek-balance',
30
30
  'ccswitch-balance',
31
+ 'model-variants',
31
32
  ];
@@ -170,5 +170,9 @@ export function createArkProvider(options) {
170
170
  removeModel: (id) => controller.removeModel(id),
171
171
  usage: (force) => controller.usage(force),
172
172
  reload: () => controller.reload(),
173
+ modelVariants: (id) => {
174
+ const image = adapter.imageModelId();
175
+ return image === undefined ? undefined : { image };
176
+ },
173
177
  };
174
178
  }
@@ -100,10 +100,14 @@ export interface ArkAdapterOptions {
100
100
  export declare class ArkAdapter extends LlmAdapter {
101
101
  private readonly options;
102
102
  private live;
103
+ /** Image-generation model id, when discovery reported one. */
104
+ private imageModel;
103
105
  constructor(options: ArkAdapterOptions);
104
106
  providerInfo(provider: string): LlmProviderInfo;
105
107
  providerRetryPolicy(): undefined;
106
108
  listModels(_provider: string): Promise<readonly LlmModelInfo[]>;
109
+ /** The image-generation model id, when discovery reported one. */
110
+ imageModelId(): string | undefined;
107
111
  resolveModel(_provider: string, model: string): Promise<LlmResolvedModelInfo>;
108
112
  stream(options: GenerateOptions): AsyncIterable<StreamChunk>;
109
113
  /** Translate an auth failure into the message a user can act on. */
@@ -23,6 +23,9 @@ import { proxiedFetch } from '../http.js';
23
23
  import { findEntry, resolveCatalog } from './catalog.js';
24
24
  import { streamProviderResponses, accountPoolHooks } from './responses-stream.js';
25
25
  import { toResponsesInput, toResponsesTools } from '../translate/responses.js';
26
+ import { isImageModel } from './grok.js';
27
+ /** Model ids that are clearly not chat models. */
28
+ const NON_CHAT_ID = /(?:^|[-_/])(?:image|video|imagine|embed|embedding|whisper|tts|vision-only)/i;
26
29
  /** Provider route this module serves. */
27
30
  export const ARK_PROVIDER_ID = 'ark';
28
31
  /** Display name for the picker group and the Settings card. */
@@ -113,6 +116,8 @@ function extraEntry(id) {
113
116
  export class ArkAdapter extends LlmAdapter {
114
117
  options;
115
118
  live;
119
+ /** Image-generation model id, when discovery reported one. */
120
+ imageModel;
116
121
  constructor(options) {
117
122
  super();
118
123
  this.options = options;
@@ -129,7 +134,9 @@ export class ArkAdapter extends LlmAdapter {
129
134
  if (await this.options.tokens.session() === undefined)
130
135
  return [];
131
136
  const hidden = await this.hidden();
132
- return resolveCatalog(this.catalog(), [], hidden).entries.map((entry) => ({
137
+ // Image models are never picker rows: they are agent-called, always on.
138
+ const imageless = this.catalog().filter((entry) => !isImageModel(entry.id));
139
+ return resolveCatalog(imageless, [], hidden).entries.map((entry) => ({
133
140
  provider: ARK_PROVIDER_ID,
134
141
  id: entry.id,
135
142
  name: entry.name,
@@ -137,6 +144,10 @@ export class ArkAdapter extends LlmAdapter {
137
144
  ...entry.inputModalities === undefined ? {} : { inputModalities: entry.inputModalities },
138
145
  }));
139
146
  }
147
+ /** The image-generation model id, when discovery reported one. */
148
+ imageModelId() {
149
+ return this.imageModel;
150
+ }
140
151
  async resolveModel(_provider, model) {
141
152
  const entry = findEntry(this.catalog(), model);
142
153
  if (entry === undefined) {
@@ -246,9 +257,12 @@ export class ArkAdapter extends LlmAdapter {
246
257
  return undefined;
247
258
  }
248
259
  const body = await response.json();
249
- const ids = (body.data ?? [])
260
+ const allIds = (body.data ?? [])
250
261
  .map((entry) => (typeof entry?.id === 'string' ? entry.id.trim() : ''))
251
262
  .filter((id) => id !== '');
263
+ // Image models are never picker rows: they are agent-called, always on.
264
+ this.imageModel = allIds.find((id) => isImageModel(id));
265
+ const ids = allIds.filter((id) => !NON_CHAT_ID.test(id));
252
266
  return ids.length === 0 ? undefined : ids;
253
267
  }
254
268
  catch (error) {
@@ -166,5 +166,9 @@ export function createGlmProvider(options) {
166
166
  removeModel: (id) => controller.removeModel(id),
167
167
  usage: (force) => controller.usage(force),
168
168
  reload: () => controller.reload(),
169
+ modelVariants: (id) => {
170
+ const image = adapter.imageModelId();
171
+ return image === undefined ? undefined : { image };
172
+ },
169
173
  };
170
174
  }
@@ -120,6 +120,8 @@ export declare class GlmAdapter extends LlmAdapter {
120
120
  private readonly options;
121
121
  /** Live catalog ids, once discovery succeeded this session. */
122
122
  private live;
123
+ /** Image-generation model id, when discovery reported one. */
124
+ private imageModel;
123
125
  constructor(options: GlmAdapterOptions);
124
126
  providerInfo(provider: string): LlmProviderInfo;
125
127
  providerRetryPolicy(): undefined;
@@ -134,6 +136,8 @@ export declare class GlmAdapter extends LlmAdapter {
134
136
  private shippedCatalog;
135
137
  /** Ids the user published by hand that this route does not already serve. */
136
138
  private addedEntries;
139
+ /** The image-generation model id, when discovery reported one. */
140
+ imageModelId(): string | undefined;
137
141
  /** The ids the picker must currently omit. */
138
142
  private hidden;
139
143
  /**
@@ -15,6 +15,9 @@ import { proxiedFetch } from '../http.js';
15
15
  import { findEntry, resolveCatalog } from './catalog.js';
16
16
  import { streamProviderResponses, accountPoolHooks } from './responses-stream.js';
17
17
  import { toResponsesInput, toResponsesTools } from '../translate/responses.js';
18
+ import { isImageModel } from './grok.js';
19
+ /** Model ids that are clearly not chat models. */
20
+ const NON_CHAT_ID = /(?:^|[-_/])(?:image|video|imagine|embed|embedding|whisper|tts|vision-only)/i;
18
21
  /** Provider route this module serves. */
19
22
  export const GLM_PROVIDER_ID = 'glm';
20
23
  /** Display name for the picker group and the Settings card. */
@@ -220,6 +223,8 @@ export class GlmAdapter extends LlmAdapter {
220
223
  options;
221
224
  /** Live catalog ids, once discovery succeeded this session. */
222
225
  live;
226
+ /** Image-generation model id, when discovery reported one. */
227
+ imageModel;
223
228
  constructor(options) {
224
229
  super();
225
230
  this.options = options;
@@ -238,7 +243,9 @@ export class GlmAdapter extends LlmAdapter {
238
243
  if (await this.options.tokens.session() === undefined)
239
244
  return [];
240
245
  const hidden = await this.hidden();
241
- return resolveCatalog(this.catalog(), [], hidden).entries.map((entry) => ({
246
+ // Image models are never picker rows: they are agent-called, always on.
247
+ const imageless = this.catalog().filter((entry) => !isImageModel(entry.id));
248
+ return resolveCatalog(imageless, [], hidden).entries.map((entry) => ({
242
249
  provider: GLM_PROVIDER_ID,
243
250
  id: entry.id,
244
251
  name: entry.name,
@@ -326,6 +333,10 @@ export class GlmAdapter extends LlmAdapter {
326
333
  .filter((id) => findEntry(own, id) === undefined)
327
334
  .map((id) => extraEntry(id));
328
335
  }
336
+ /** The image-generation model id, when discovery reported one. */
337
+ imageModelId() {
338
+ return this.imageModel;
339
+ }
329
340
  /** The ids the picker must currently omit. */
330
341
  async hidden() {
331
342
  if (this.options.hiddenModels === undefined)
@@ -367,9 +378,12 @@ export class GlmAdapter extends LlmAdapter {
367
378
  return undefined;
368
379
  }
369
380
  const body = await response.json();
370
- const ids = (body.data ?? [])
381
+ const allIds = (body.data ?? [])
371
382
  .map((entry) => (typeof entry?.id === 'string' ? entry.id.trim() : ''))
372
383
  .filter((id) => id !== '');
384
+ // Image models are never picker rows: they are agent-called, always on.
385
+ this.imageModel = allIds.find((id) => isImageModel(id));
386
+ const ids = allIds.filter((id) => !NON_CHAT_ID.test(id));
373
387
  return ids.length === 0 ? undefined : ids;
374
388
  }
375
389
  catch (error) {
@@ -112,6 +112,8 @@ interface GrokCliMetadata {
112
112
  reasoningEfforts?: readonly string[];
113
113
  defaultEffort?: string;
114
114
  }
115
+ /** True when a model id names an image-generation model. */
116
+ export declare function isImageModel(id: string): boolean;
115
117
  /** True when a model id names a fast/lightspeed variant of a base model. */
116
118
  export declare function isFastVariant(id: string): boolean;
117
119
  /** The base model id a fast variant belongs to (`grok-4.7-fast` → `grok-4.7`). */
@@ -150,6 +152,10 @@ export declare class GrokAdapter extends LlmAdapter {
150
152
  private discovered;
151
153
  /** Capability metadata from the CLI catalog, keyed by model id. */
152
154
  private readonly metadata;
155
+ /** Fast-variant wire id per base model, for the picker's quick-mode button. */
156
+ private readonly fastVariants;
157
+ /** Image-generation model id, when discovery reported one. */
158
+ private imageModel;
153
159
  /** Ids the user added by hand, cached so the sync catalog can name them. */
154
160
  private userAddedIds;
155
161
  constructor(options: GrokAdapterOptions);
@@ -182,6 +188,10 @@ export declare class GrokAdapter extends LlmAdapter {
182
188
  private addedEntries;
183
189
  /** Record the live catalog for the picker. */
184
190
  discover(ids: readonly string[], metadata?: ReadonlyMap<string, GrokCliMetadata>): void;
191
+ /** The fast/lightspeed variant wire id for a base model, when discovery reported one. */
192
+ fastVariant(baseId: string): string | undefined;
193
+ /** The image-generation model id, when discovery reported one. */
194
+ imageModelId(): string | undefined;
185
195
  /** The curated catalog, for the Settings page's model list. */
186
196
  catalogEntries(): readonly CatalogEntry[];
187
197
  /** What this route itself serves, without the ids added by hand. */
@@ -262,6 +262,12 @@ export async function refreshGrokToken(input) {
262
262
  }
263
263
  /** Model ids that are clearly not chat models. */
264
264
  const NON_CHAT_ID = /(?:^|[-_/])(?:image|video|imagine|embed|embedding|whisper|tts|vision-only)/i;
265
+ /** Model ids that are image-generation models, matched per provider's naming. */
266
+ const IMAGE_MODEL = /(?:^|[-_/])(?:image|imagine|draw|pic|photo)(?:[-_/]|$)/i;
267
+ /** True when a model id names an image-generation model. */
268
+ export function isImageModel(id) {
269
+ return IMAGE_MODEL.test(id);
270
+ }
265
271
  /** Model ids that are the fast/lightspeed variant of a base model, matched per base. */
266
272
  const FAST_VARIANT = /(?:^|[-_])(?:fast|lightspeed|turbo|quick)$/i;
267
273
  /** True when a model id names a fast/lightspeed variant of a base model. */
@@ -279,6 +285,10 @@ export class GrokAdapter extends LlmAdapter {
279
285
  discovered;
280
286
  /** Capability metadata from the CLI catalog, keyed by model id. */
281
287
  metadata = new Map();
288
+ /** Fast-variant wire id per base model, for the picker's quick-mode button. */
289
+ fastVariants = new Map();
290
+ /** Image-generation model id, when discovery reported one. */
291
+ imageModel;
282
292
  /** Ids the user added by hand, cached so the sync catalog can name them. */
283
293
  userAddedIds = [];
284
294
  constructor(options) {
@@ -299,7 +309,9 @@ export class GrokAdapter extends LlmAdapter {
299
309
  return [];
300
310
  await this.syncUserModels();
301
311
  const hidden = await this.hidden();
302
- return resolveCatalog(this.catalog(), [], hidden).entries.map((entry) => ({
312
+ // Image models are never picker rows: they are agent-called, always on.
313
+ const imageless = this.catalog().filter((entry) => !isImageModel(entry.id));
314
+ return resolveCatalog(imageless, [], hidden).entries.map((entry) => ({
303
315
  provider: GROK_PROVIDER_ID,
304
316
  id: entry.id,
305
317
  name: entry.name,
@@ -445,6 +457,14 @@ export class GrokAdapter extends LlmAdapter {
445
457
  for (const [id, meta] of metadata)
446
458
  this.metadata.set(id, meta);
447
459
  }
460
+ /** The fast/lightspeed variant wire id for a base model, when discovery reported one. */
461
+ fastVariant(baseId) {
462
+ return this.fastVariants.get(baseId);
463
+ }
464
+ /** The image-generation model id, when discovery reported one. */
465
+ imageModelId() {
466
+ return this.imageModel;
467
+ }
448
468
  /** The curated catalog, for the Settings page's model list. */
449
469
  catalogEntries() {
450
470
  return this.catalog();
@@ -524,18 +544,29 @@ export class GrokAdapter extends LlmAdapter {
524
544
  return undefined;
525
545
  }
526
546
  const payload = await response.json();
547
+ const allIds = (payload.data ?? [])
548
+ .map((entry) => entry.id)
549
+ .filter((id) => typeof id === 'string' && id.length > 0);
550
+ // Image models are not chat models; they are picked by an agent, not the picker.
551
+ this.imageModel = allIds.find((id) => isImageModel(id));
552
+ const rawIds = allIds.filter((id) => !NON_CHAT_ID.test(id));
527
553
  // Fast/lightspeed variants ride with their base model: they share the base's
528
554
  // visibility switch and are reached by a picker button, not a separate row.
529
- const ids = (payload.data ?? [])
530
- .map((entry) => entry.id)
531
- .filter((id) => typeof id === 'string' && id.length > 0 && !NON_CHAT_ID.test(id))
555
+ this.fastVariants.clear();
556
+ for (const id of rawIds) {
557
+ if (!isFastVariant(id))
558
+ continue;
559
+ const base = baseModelOf(id);
560
+ if (!this.fastVariants.has(base))
561
+ this.fastVariants.set(base, id);
562
+ }
563
+ const ids = rawIds
532
564
  .map((id) => (isFastVariant(id) ? baseModelOf(id) : id))
533
565
  .filter((id, index, list) => list.indexOf(id) === index);
534
566
  if (ids.length === 0) {
535
567
  this.options.onWarn?.('xAI model discovery returned an empty catalog; using the built-in catalog');
536
568
  return undefined;
537
569
  }
538
- // Keep the fast-variant ids discoverable for the picker button, keyed by their base.
539
570
  const metadata = await this.fetchCliMetadata(fetchFn, signal);
540
571
  for (const [id, meta] of metadata)
541
572
  this.metadata.set(id, meta);
@@ -698,6 +729,7 @@ export function createGrokProvider(options) {
698
729
  { key: 'credentialFile', value: options.credentialFile },
699
730
  ],
700
731
  applyDiscovery: (ids) => { adapter.discover(ids); },
732
+ fastVariant: (baseId) => adapter.fastVariant(baseId),
701
733
  };
702
734
  const controller = new ProviderController({
703
735
  spec,
@@ -726,5 +758,13 @@ export function createGrokProvider(options) {
726
758
  removeModel: (id) => controller.removeModel(id),
727
759
  usage: (force) => controller.usage(force),
728
760
  reload: () => controller.reload(),
761
+ modelVariants: (id) => {
762
+ const fast = adapter.fastVariant(id);
763
+ const image = adapter.imageModelId();
764
+ return {
765
+ ...fast === undefined ? {} : { fast },
766
+ ...image === undefined ? {} : { image },
767
+ };
768
+ },
729
769
  };
730
770
  }
@@ -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 fast = adapter.fastVariant(id);
155
+ const image = adapter.imageModelId();
156
+ return {
157
+ ...fast === undefined ? {} : { fast },
158
+ ...image === undefined ? {} : { image },
159
+ };
160
+ },
152
161
  };
153
162
  }
@@ -102,6 +102,10 @@ 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
+ /** Fast-variant wire id per base model, for the picker's quick-mode button. */
108
+ private readonly fastVariants;
105
109
  /** Ids the user added by hand, cached so the sync catalog can name them. */
106
110
  private userAddedIds;
107
111
  /** Tools already reported as flattened, so each is stated once. */
@@ -116,6 +120,10 @@ export declare class KimiAdapter extends LlmAdapter {
116
120
  providerInfo(provider: string): LlmProviderInfo;
117
121
  providerRetryPolicy(): undefined;
118
122
  listModels(_provider: string): Promise<readonly LlmModelInfo[]>;
123
+ /** The image-generation model id, when discovery reported one. */
124
+ imageModelId(): string | undefined;
125
+ /** The fast/lightspeed variant wire id for a base model, when discovery reported one. */
126
+ fastVariant(baseId: string): string | undefined;
119
127
  /** The ids the picker must currently omit. */
120
128
  private hidden;
121
129
  resolveModel(_provider: string, model: string): Promise<LlmResolvedModelInfo>;
@@ -15,6 +15,9 @@ import { streamProviderResponses, accountPoolHooks } from './responses-stream.js
15
15
  import { fallbackEntry, findEntry, resolveCatalog } from './catalog.js';
16
16
  import { streamResponses, toResponsesInput, toResponsesTools } from '../translate/responses.js';
17
17
  import { prepareMoonshotTool } from '../translate/moonshot-schema.js';
18
+ import { isImageModel, isFastVariant, baseModelOf } from './grok.js';
19
+ /** Model ids that are clearly not chat models. */
20
+ const NON_CHAT_ID = /(?:^|[-_/])(?:image|video|imagine|embed|embedding|whisper|tts|vision-only)/i;
18
21
  /**
19
22
  * Coerce one decoded credential entry into a Kimi session.
20
23
  * @param value - decoded JSON value for one account.
@@ -129,6 +132,10 @@ export class KimiAdapter extends LlmAdapter {
129
132
  options;
130
133
  /** Live catalog ids seen this session, used to accept renamed models. */
131
134
  discovered;
135
+ /** Image-generation model id, when discovery reported one. */
136
+ imageModel;
137
+ /** Fast-variant wire id per base model, for the picker's quick-mode button. */
138
+ fastVariants = new Map();
132
139
  /** Ids the user added by hand, cached so the sync catalog can name them. */
133
140
  userAddedIds = [];
134
141
  /** Tools already reported as flattened, so each is stated once. */
@@ -171,7 +178,9 @@ export class KimiAdapter extends LlmAdapter {
171
178
  return [];
172
179
  await this.syncUserModels();
173
180
  const hidden = await this.hidden();
174
- return resolveCatalog(this.catalog(), [], hidden).entries.map((entry) => ({
181
+ // Image models are never picker rows: they are agent-called, always on.
182
+ const imageless = this.catalog().filter((entry) => !isImageModel(entry.id));
183
+ return resolveCatalog(imageless, [], hidden).entries.map((entry) => ({
175
184
  provider: KIMI_PROVIDER_ID,
176
185
  id: entry.id,
177
186
  name: entry.name,
@@ -179,6 +188,14 @@ export class KimiAdapter extends LlmAdapter {
179
188
  ...entry.inputModalities === undefined ? {} : { inputModalities: entry.inputModalities },
180
189
  }));
181
190
  }
191
+ /** The image-generation model id, when discovery reported one. */
192
+ imageModelId() {
193
+ return this.imageModel;
194
+ }
195
+ /** The fast/lightspeed variant wire id for a base model, when discovery reported one. */
196
+ fastVariant(baseId) {
197
+ return this.fastVariants.get(baseId);
198
+ }
182
199
  /** The ids the picker must currently omit. */
183
200
  async hidden() {
184
201
  if (this.options.hiddenModels === undefined)
@@ -414,9 +431,22 @@ export class KimiAdapter extends LlmAdapter {
414
431
  return undefined;
415
432
  }
416
433
  const payload = await response.json();
417
- const ids = (payload.data ?? [])
434
+ const allIds = (payload.data ?? [])
418
435
  .map((entry) => entry.id)
419
436
  .filter((id) => typeof id === 'string' && id.length > 0);
437
+ // Image models are never picker rows: they are agent-called, always on.
438
+ this.imageModel = allIds.find((id) => isImageModel(id));
439
+ // Fast/lightspeed variants ride with their base model: they share the base's
440
+ // visibility switch and are reached by a picker button, not a separate row.
441
+ this.fastVariants.clear();
442
+ for (const id of allIds) {
443
+ if (!isFastVariant(id))
444
+ continue;
445
+ const base = baseModelOf(id);
446
+ if (!this.fastVariants.has(base))
447
+ this.fastVariants.set(base, id);
448
+ }
449
+ const ids = allIds.filter((id) => !NON_CHAT_ID.test(id));
420
450
  if (ids.length === 0) {
421
451
  this.options.onWarn?.('Kimi model discovery returned an empty catalog; using the built-in catalog');
422
452
  return undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-subscription-oauth",
3
- "version": "0.8.12",
3
+ "version": "0.8.14",
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",