@prestyj/core 5.8.0 → 5.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { ContextWindowOptions, DEFAULT_MAX_VIDEO_BYTES, MODELS, ModelInfo, getAuthStorageKey, getAuthStorageKeys, getContextWindow, getDefaultModel, getFastModel, getMaxThinkingLevel, getModel, getModelsForProvider, getSummaryModel, getToolResultCharLimit, getVideoByteLimit, usesOpenAICodexTransport } from './model-registry.cjs';
1
+ export { ContextWindowOptions, DEFAULT_MAX_VIDEO_BYTES, MODELS, ModelInfo, getAuthStorageKey, getAuthStorageKeys, getContextWindow, getDefaultModel, getDefaultThinkingLevel, getFastModel, getMaxThinkingLevel, getModel, getModelsForProvider, getSummaryModel, getToolResultCharLimit, getVideoByteLimit, usesOpenAICodexTransport } from './model-registry.cjs';
2
2
  import { Provider, ThinkingLevel } from '@prestyj/ai';
3
3
  export { AppPaths, getAppPaths } from './paths.cjs';
4
4
 
@@ -85,6 +85,14 @@ declare const MOONSHOT_OAUTH_KEY = "moonshot-oauth";
85
85
  * order, is decided per-model via `getAuthStorageKeys()` in model-registry.ts.
86
86
  */
87
87
  declare const XIAOMI_CREDITS_KEY = "xiaomi-credits";
88
+ /**
89
+ * Synchronous baseUrl read straight from the auth file, for boot paths that
90
+ * need the active endpoint before an AuthStorage instance exists (e.g. the
91
+ * CLI's sync main()). Missing/corrupt files yield undefined — callers treat
92
+ * that as the provider's public endpoint. Read-only: safe without the file
93
+ * lock (a torn mid-write read just falls back to undefined).
94
+ */
95
+ declare function readStoredBaseUrlSync(authFile: string, provider: string): string | undefined;
88
96
  declare class AuthStorage {
89
97
  private data;
90
98
  private filePath;
@@ -118,16 +126,31 @@ declare class AuthStorage {
118
126
  * credential is absent (a present OAuth credential is refreshable).
119
127
  */
120
128
  isStaticApiKey(provider: string): Promise<boolean>;
129
+ /**
130
+ * The base URL on the credential that is active right now, if any.
131
+ * Synchronous — call only after load()/resolveCredentials() populated the
132
+ * snapshot. For `moonshot` this is the Kimi For Coding URL whenever the
133
+ * OAuth entry is the one resolveCredentials would serve (i.e. not currently
134
+ * usage-exhausted with an API key configured).
135
+ */
136
+ getStoredBaseUrl(provider: string): string | undefined;
121
137
  load(): Promise<void>;
122
138
  private ensureLoaded;
123
139
  /**
124
140
  * Force a re-read from disk, discarding the in-memory cache. Needed when
125
141
  * another process mutates the auth file out-of-band — e.g. the desktop app
126
- * writes API keys natively (Rust → ~/.ezcoder/auth.json) without going through
127
- * this instance, so a long-lived daemon's cache would otherwise stay stale and
128
- * never see a newly added provider key.
142
+ * writes API keys natively without going through this instance.
129
143
  */
130
144
  reload(): Promise<void>;
145
+ /**
146
+ * Apply one provider-scoped mutation to the latest on-disk snapshot.
147
+ * AuthStorage instances live in every app session/process, so writing this
148
+ * instance's cached snapshot can erase credentials another instance just
149
+ * added. The file lock only serializes writers; the re-read prevents stale
150
+ * full-file overwrites.
151
+ */
152
+ private mutateLatest;
153
+ private reloadLatest;
131
154
  getCredentials(provider: string): Promise<OAuthCredentials | undefined>;
132
155
  setCredentials(provider: string, creds: OAuthCredentials): Promise<void>;
133
156
  clearCredentials(provider: string): Promise<void>;
@@ -159,14 +182,13 @@ declare class AuthStorage {
159
182
  * Throws if not logged in.
160
183
  */
161
184
  resolveToken(provider: string): Promise<string>;
162
- private save;
163
185
  }
164
186
  declare class NotLoggedInError extends Error {
165
187
  provider: string;
166
188
  constructor(provider: string);
167
189
  }
168
190
 
169
- type SubscriptionUsageProvider = "anthropic" | "openai";
191
+ type SubscriptionUsageProvider = "anthropic" | "openai" | "moonshot";
170
192
  interface SubscriptionUsageWindow {
171
193
  kind: "current" | "weekly";
172
194
  label: string;
@@ -182,7 +204,8 @@ interface SubscriptionUsageSnapshot {
182
204
  }
183
205
  declare class SubscriptionUsageError extends Error {
184
206
  readonly status?: number | undefined;
185
- constructor(message: string, status?: number | undefined);
207
+ readonly retryAfterMs?: number | undefined;
208
+ constructor(message: string, status?: number | undefined, retryAfterMs?: number | undefined);
186
209
  }
187
210
  type FetchFn = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
188
211
  interface FetchSubscriptionUsageOptions {
@@ -430,4 +453,4 @@ interface AutoUpdater {
430
453
  }
431
454
  declare function createAutoUpdater(config: AutoUpdateConfig): AutoUpdater;
432
455
 
433
- export { AuthStorage, type AutoUpdateConfig, type AutoUpdater, type InlineButton, type LogLevel, MOONSHOT_OAUTH_KEY, NotLoggedInError, type OAuthCredentials, type OAuthLoginCallbacks, type ProgressCallback, SubscriptionUsageError, type SubscriptionUsageProvider, type SubscriptionUsageSnapshot, type SubscriptionUsageWindow, TelegramBot, type TelegramConfig, type TelegramMessage, type TelegramUpdate, type TelegramVoiceMessage, XIAOMI_CREDITS_KEY, closeLogger, createAutoUpdater, decodeOggOpus, downmixToMono, fetchSubscriptionUsage, generatePKCE, getClaudeCliUserAgent, getClaudeCodeVersion, getNextThinkingLevel, getSessionId, getSupportedThinkingLevels, isKimiCodingEndpoint, isLoggerOpen, isModelLoaded, isThinkingLevelSupported, kimiCodeBaseUrl, kimiCodingHeaders, log, loginAnthropic, loginGemini, loginKimi, loginOpenAI, openLog, refreshAnthropicToken, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, registerLogCleanup, resample, setProgressCallback, transcribeVoice, withFileLock };
456
+ export { AuthStorage, type AutoUpdateConfig, type AutoUpdater, type InlineButton, type LogLevel, MOONSHOT_OAUTH_KEY, NotLoggedInError, type OAuthCredentials, type OAuthLoginCallbacks, type ProgressCallback, SubscriptionUsageError, type SubscriptionUsageProvider, type SubscriptionUsageSnapshot, type SubscriptionUsageWindow, TelegramBot, type TelegramConfig, type TelegramMessage, type TelegramUpdate, type TelegramVoiceMessage, XIAOMI_CREDITS_KEY, closeLogger, createAutoUpdater, decodeOggOpus, downmixToMono, fetchSubscriptionUsage, generatePKCE, getClaudeCliUserAgent, getClaudeCodeVersion, getNextThinkingLevel, getSessionId, getSupportedThinkingLevels, isKimiCodingEndpoint, isLoggerOpen, isModelLoaded, isThinkingLevelSupported, kimiCodeBaseUrl, kimiCodingHeaders, log, loginAnthropic, loginGemini, loginKimi, loginOpenAI, openLog, readStoredBaseUrlSync, refreshAnthropicToken, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, registerLogCleanup, resample, setProgressCallback, transcribeVoice, withFileLock };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { ContextWindowOptions, DEFAULT_MAX_VIDEO_BYTES, MODELS, ModelInfo, getAuthStorageKey, getAuthStorageKeys, getContextWindow, getDefaultModel, getFastModel, getMaxThinkingLevel, getModel, getModelsForProvider, getSummaryModel, getToolResultCharLimit, getVideoByteLimit, usesOpenAICodexTransport } from './model-registry.js';
1
+ export { ContextWindowOptions, DEFAULT_MAX_VIDEO_BYTES, MODELS, ModelInfo, getAuthStorageKey, getAuthStorageKeys, getContextWindow, getDefaultModel, getDefaultThinkingLevel, getFastModel, getMaxThinkingLevel, getModel, getModelsForProvider, getSummaryModel, getToolResultCharLimit, getVideoByteLimit, usesOpenAICodexTransport } from './model-registry.js';
2
2
  import { Provider, ThinkingLevel } from '@prestyj/ai';
3
3
  export { AppPaths, getAppPaths } from './paths.js';
4
4
 
@@ -85,6 +85,14 @@ declare const MOONSHOT_OAUTH_KEY = "moonshot-oauth";
85
85
  * order, is decided per-model via `getAuthStorageKeys()` in model-registry.ts.
86
86
  */
87
87
  declare const XIAOMI_CREDITS_KEY = "xiaomi-credits";
88
+ /**
89
+ * Synchronous baseUrl read straight from the auth file, for boot paths that
90
+ * need the active endpoint before an AuthStorage instance exists (e.g. the
91
+ * CLI's sync main()). Missing/corrupt files yield undefined — callers treat
92
+ * that as the provider's public endpoint. Read-only: safe without the file
93
+ * lock (a torn mid-write read just falls back to undefined).
94
+ */
95
+ declare function readStoredBaseUrlSync(authFile: string, provider: string): string | undefined;
88
96
  declare class AuthStorage {
89
97
  private data;
90
98
  private filePath;
@@ -118,16 +126,31 @@ declare class AuthStorage {
118
126
  * credential is absent (a present OAuth credential is refreshable).
119
127
  */
120
128
  isStaticApiKey(provider: string): Promise<boolean>;
129
+ /**
130
+ * The base URL on the credential that is active right now, if any.
131
+ * Synchronous — call only after load()/resolveCredentials() populated the
132
+ * snapshot. For `moonshot` this is the Kimi For Coding URL whenever the
133
+ * OAuth entry is the one resolveCredentials would serve (i.e. not currently
134
+ * usage-exhausted with an API key configured).
135
+ */
136
+ getStoredBaseUrl(provider: string): string | undefined;
121
137
  load(): Promise<void>;
122
138
  private ensureLoaded;
123
139
  /**
124
140
  * Force a re-read from disk, discarding the in-memory cache. Needed when
125
141
  * another process mutates the auth file out-of-band — e.g. the desktop app
126
- * writes API keys natively (Rust → ~/.ezcoder/auth.json) without going through
127
- * this instance, so a long-lived daemon's cache would otherwise stay stale and
128
- * never see a newly added provider key.
142
+ * writes API keys natively without going through this instance.
129
143
  */
130
144
  reload(): Promise<void>;
145
+ /**
146
+ * Apply one provider-scoped mutation to the latest on-disk snapshot.
147
+ * AuthStorage instances live in every app session/process, so writing this
148
+ * instance's cached snapshot can erase credentials another instance just
149
+ * added. The file lock only serializes writers; the re-read prevents stale
150
+ * full-file overwrites.
151
+ */
152
+ private mutateLatest;
153
+ private reloadLatest;
131
154
  getCredentials(provider: string): Promise<OAuthCredentials | undefined>;
132
155
  setCredentials(provider: string, creds: OAuthCredentials): Promise<void>;
133
156
  clearCredentials(provider: string): Promise<void>;
@@ -159,14 +182,13 @@ declare class AuthStorage {
159
182
  * Throws if not logged in.
160
183
  */
161
184
  resolveToken(provider: string): Promise<string>;
162
- private save;
163
185
  }
164
186
  declare class NotLoggedInError extends Error {
165
187
  provider: string;
166
188
  constructor(provider: string);
167
189
  }
168
190
 
169
- type SubscriptionUsageProvider = "anthropic" | "openai";
191
+ type SubscriptionUsageProvider = "anthropic" | "openai" | "moonshot";
170
192
  interface SubscriptionUsageWindow {
171
193
  kind: "current" | "weekly";
172
194
  label: string;
@@ -182,7 +204,8 @@ interface SubscriptionUsageSnapshot {
182
204
  }
183
205
  declare class SubscriptionUsageError extends Error {
184
206
  readonly status?: number | undefined;
185
- constructor(message: string, status?: number | undefined);
207
+ readonly retryAfterMs?: number | undefined;
208
+ constructor(message: string, status?: number | undefined, retryAfterMs?: number | undefined);
186
209
  }
187
210
  type FetchFn = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
188
211
  interface FetchSubscriptionUsageOptions {
@@ -430,4 +453,4 @@ interface AutoUpdater {
430
453
  }
431
454
  declare function createAutoUpdater(config: AutoUpdateConfig): AutoUpdater;
432
455
 
433
- export { AuthStorage, type AutoUpdateConfig, type AutoUpdater, type InlineButton, type LogLevel, MOONSHOT_OAUTH_KEY, NotLoggedInError, type OAuthCredentials, type OAuthLoginCallbacks, type ProgressCallback, SubscriptionUsageError, type SubscriptionUsageProvider, type SubscriptionUsageSnapshot, type SubscriptionUsageWindow, TelegramBot, type TelegramConfig, type TelegramMessage, type TelegramUpdate, type TelegramVoiceMessage, XIAOMI_CREDITS_KEY, closeLogger, createAutoUpdater, decodeOggOpus, downmixToMono, fetchSubscriptionUsage, generatePKCE, getClaudeCliUserAgent, getClaudeCodeVersion, getNextThinkingLevel, getSessionId, getSupportedThinkingLevels, isKimiCodingEndpoint, isLoggerOpen, isModelLoaded, isThinkingLevelSupported, kimiCodeBaseUrl, kimiCodingHeaders, log, loginAnthropic, loginGemini, loginKimi, loginOpenAI, openLog, refreshAnthropicToken, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, registerLogCleanup, resample, setProgressCallback, transcribeVoice, withFileLock };
456
+ export { AuthStorage, type AutoUpdateConfig, type AutoUpdater, type InlineButton, type LogLevel, MOONSHOT_OAUTH_KEY, NotLoggedInError, type OAuthCredentials, type OAuthLoginCallbacks, type ProgressCallback, SubscriptionUsageError, type SubscriptionUsageProvider, type SubscriptionUsageSnapshot, type SubscriptionUsageWindow, TelegramBot, type TelegramConfig, type TelegramMessage, type TelegramUpdate, type TelegramVoiceMessage, XIAOMI_CREDITS_KEY, closeLogger, createAutoUpdater, decodeOggOpus, downmixToMono, fetchSubscriptionUsage, generatePKCE, getClaudeCliUserAgent, getClaudeCodeVersion, getNextThinkingLevel, getSessionId, getSupportedThinkingLevels, isKimiCodingEndpoint, isLoggerOpen, isModelLoaded, isThinkingLevelSupported, kimiCodeBaseUrl, kimiCodingHeaders, log, loginAnthropic, loginGemini, loginKimi, loginOpenAI, openLog, readStoredBaseUrlSync, refreshAnthropicToken, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, registerLogCleanup, resample, setProgressCallback, transcribeVoice, withFileLock };
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  getClaudeCodeVersion,
14
14
  getContextWindow,
15
15
  getDefaultModel,
16
+ getDefaultThinkingLevel,
16
17
  getFastModel,
17
18
  getMaxThinkingLevel,
18
19
  getModel,
@@ -31,6 +32,7 @@ import {
31
32
  loginKimi,
32
33
  loginOpenAI,
33
34
  openLog,
35
+ readStoredBaseUrlSync,
34
36
  refreshAnthropicToken,
35
37
  refreshGeminiToken,
36
38
  refreshKimiToken,
@@ -38,7 +40,7 @@ import {
38
40
  registerLogCleanup,
39
41
  usesOpenAICodexTransport,
40
42
  withFileLock
41
- } from "./chunk-GMAX7TES.js";
43
+ } from "./chunk-JXPW4JKV.js";
42
44
  import {
43
45
  getAppPaths
44
46
  } from "./chunk-WCIV25KV.js";
@@ -68,6 +70,7 @@ var ANTHROPIC_ADAPTIVE_THINKING_LEVELS = [
68
70
  "high",
69
71
  "max"
70
72
  ];
73
+ var MOONSHOT_K3_THINKING_LEVELS = ["low", "high", "max"];
71
74
  function isOpenAIGptModel(provider, model) {
72
75
  return provider === "openai" && model.startsWith("gpt-");
73
76
  }
@@ -77,6 +80,9 @@ function isSakanaModel(provider) {
77
80
  function isXaiModel(provider) {
78
81
  return provider === "xai";
79
82
  }
83
+ function isMoonshotK3Model(provider, model) {
84
+ return provider === "moonshot" && model === "kimi-k3";
85
+ }
80
86
  function isAnthropicOpus48Or47Model(provider, model) {
81
87
  return provider === "anthropic" && /opus-4-8|opus-4-7/.test(model);
82
88
  }
@@ -101,6 +107,7 @@ function getSupportedThinkingLevels(provider, model) {
101
107
  if (maxIndex2 === -1) return XAI_THINKING_LEVELS;
102
108
  return XAI_THINKING_LEVELS.slice(0, maxIndex2 + 1);
103
109
  }
110
+ if (isMoonshotK3Model(provider, model)) return MOONSHOT_K3_THINKING_LEVELS;
104
111
  if (!isOpenAIGptModel(provider, model)) return [maxLevel];
105
112
  const levels = model.startsWith("gpt-5.6-") ? OPENAI_GPT_56_THINKING_LEVELS : OPENAI_GPT_THINKING_LEVELS;
106
113
  const maxIndex = levels.indexOf(maxLevel);
@@ -112,7 +119,7 @@ function isThinkingLevelSupported(provider, model, level) {
112
119
  }
113
120
  function getNextThinkingLevel(provider, model, current) {
114
121
  const supportedLevels = getSupportedThinkingLevels(provider, model);
115
- const shouldCycleLevels = isOpenAIGptModel(provider, model) || isAnthropicAdaptiveModel(provider, model) || isSakanaModel(provider) || isXaiModel(provider);
122
+ const shouldCycleLevels = isOpenAIGptModel(provider, model) || isAnthropicAdaptiveModel(provider, model) || isSakanaModel(provider) || isXaiModel(provider) || isMoonshotK3Model(provider, model);
116
123
  if (!shouldCycleLevels) {
117
124
  return current ? void 0 : supportedLevels[0];
118
125
  }
@@ -124,9 +131,10 @@ function getNextThinkingLevel(provider, model, current) {
124
131
 
125
132
  // src/provider-usage.ts
126
133
  var SubscriptionUsageError = class extends Error {
127
- constructor(message, status) {
134
+ constructor(message, status, retryAfterMs2) {
128
135
  super(message);
129
136
  this.status = status;
137
+ this.retryAfterMs = retryAfterMs2;
130
138
  this.name = "SubscriptionUsageError";
131
139
  }
132
140
  };
@@ -176,12 +184,20 @@ function normalizedCodexWindow(window, fallbackKind, now) {
176
184
  resetsAt: codexResetAt(window, now)
177
185
  };
178
186
  }
179
- async function readUsageResponse(response) {
187
+ function retryAfterMs(response, now) {
188
+ const value = response.headers.get("retry-after")?.trim();
189
+ if (!value) return void 0;
190
+ if (/^\d+(?:\.\d+)?$/.test(value)) return Math.ceil(Number(value) * 1e3);
191
+ const retryAt = Date.parse(value);
192
+ return Number.isFinite(retryAt) ? Math.max(0, retryAt - now) : void 0;
193
+ }
194
+ async function readUsageResponse(response, now) {
180
195
  const text = await response.text();
181
196
  if (!response.ok) {
182
197
  throw new SubscriptionUsageError(
183
198
  `Subscription usage request failed with HTTP ${response.status}`,
184
- response.status
199
+ response.status,
200
+ retryAfterMs(response, now)
185
201
  );
186
202
  }
187
203
  try {
@@ -202,7 +218,7 @@ async function fetchAnthropicUsage(credentials, fetchFn, signal, now) {
202
218
  "User-Agent": "ezcoder"
203
219
  }
204
220
  });
205
- const data = await readUsageResponse(response);
221
+ const data = await readUsageResponse(response, now());
206
222
  const windows = [];
207
223
  const currentPercent = clampPercent(data.five_hour?.utilization);
208
224
  if (currentPercent !== void 0) {
@@ -238,7 +254,7 @@ async function fetchCodexUsage(credentials, fetchFn, signal, now) {
238
254
  };
239
255
  if (credentials.accountId) headers["ChatGPT-Account-Id"] = credentials.accountId;
240
256
  const response = await fetchFn(CODEX_USAGE_URL, { method: "GET", signal, headers });
241
- const data = await readUsageResponse(response);
257
+ const data = await readUsageResponse(response, now());
242
258
  const windows = [
243
259
  normalizedCodexWindow(data.rate_limit?.primary_window, "current", now()),
244
260
  normalizedCodexWindow(data.rate_limit?.secondary_window, "weekly", now())
@@ -254,12 +270,97 @@ async function fetchCodexUsage(credentials, fetchFn, signal, now) {
254
270
  fetchedAt: now()
255
271
  };
256
272
  }
273
+ function kimiNumber(value) {
274
+ if (typeof value === "string" && value.trim()) {
275
+ const parsed = Number(value);
276
+ return Number.isFinite(parsed) ? parsed : void 0;
277
+ }
278
+ return finiteNumber(value);
279
+ }
280
+ function kimiUsagePercent(detail) {
281
+ const used = kimiNumber(detail?.used);
282
+ const limit = kimiNumber(detail?.limit);
283
+ if (used === void 0 || limit === void 0 || limit <= 0) return void 0;
284
+ return Math.min(100, Math.max(0, used / limit * 100));
285
+ }
286
+ function kimiWindowMinutes(window) {
287
+ const duration = kimiNumber(window?.duration);
288
+ if (duration === void 0 || duration <= 0) return void 0;
289
+ switch (window?.timeUnit) {
290
+ case "TIME_UNIT_SECOND":
291
+ return duration / 60;
292
+ case "TIME_UNIT_MINUTE":
293
+ return duration;
294
+ case "TIME_UNIT_HOUR":
295
+ return duration * 60;
296
+ case "TIME_UNIT_DAY":
297
+ return duration * 24 * 60;
298
+ default:
299
+ return void 0;
300
+ }
301
+ }
302
+ async function fetchKimiUsage(credentials, fetchFn, signal, now) {
303
+ const response = await fetchFn(`${kimiCodeBaseUrl()}/usages`, {
304
+ method: "GET",
305
+ signal,
306
+ headers: {
307
+ Authorization: "Bearer " + credentials.accessToken,
308
+ Accept: "application/json",
309
+ // The managed coding endpoint gates on the kimi-code-cli client identity,
310
+ // same as model requests.
311
+ ...kimiCodingHeaders()
312
+ }
313
+ });
314
+ const data = await readUsageResponse(response, now());
315
+ const windows = [];
316
+ const weeklyPercent = kimiUsagePercent(data.usage);
317
+ if (weeklyPercent !== void 0) {
318
+ windows.push({
319
+ kind: "weekly",
320
+ label: "Weekly",
321
+ usedPercent: weeklyPercent,
322
+ resetsAt: isoTimestamp(data.usage?.resetTime)
323
+ });
324
+ }
325
+ for (const limit of data.limits ?? []) {
326
+ const minutes = kimiWindowMinutes(limit?.window);
327
+ const percent = kimiUsagePercent(limit?.detail);
328
+ if (minutes === void 0 || percent === void 0) continue;
329
+ if (minutes >= 6 * 24 * 60) {
330
+ if (!windows.some((window) => window.kind === "weekly")) {
331
+ windows.push({
332
+ kind: "weekly",
333
+ label: "Weekly",
334
+ usedPercent: percent,
335
+ resetsAt: isoTimestamp(limit?.detail?.resetTime)
336
+ });
337
+ }
338
+ continue;
339
+ }
340
+ windows.push({
341
+ kind: "current",
342
+ label: `${Math.max(1, Math.round(minutes / 60))}-hour`,
343
+ usedPercent: percent,
344
+ resetsAt: isoTimestamp(limit?.detail?.resetTime)
345
+ });
346
+ }
347
+ windows.sort((left, right) => {
348
+ if (left.kind === right.kind) return 0;
349
+ return left.kind === "current" ? -1 : 1;
350
+ });
351
+ return {
352
+ provider: "moonshot",
353
+ displayName: "Kimi",
354
+ windows,
355
+ fetchedAt: now()
356
+ };
357
+ }
257
358
  async function fetchSubscriptionUsage(provider, credentials, options = {}) {
258
359
  const fetchFn = options.fetchFn ?? fetch;
259
360
  const now = options.now ?? Date.now;
260
361
  const signal = AbortSignal.timeout(options.timeoutMs ?? 8e3);
261
362
  try {
262
- return provider === "anthropic" ? await fetchAnthropicUsage(credentials, fetchFn, signal, now) : await fetchCodexUsage(credentials, fetchFn, signal, now);
363
+ return provider === "anthropic" ? await fetchAnthropicUsage(credentials, fetchFn, signal, now) : provider === "openai" ? await fetchCodexUsage(credentials, fetchFn, signal, now) : await fetchKimiUsage(credentials, fetchFn, signal, now);
263
364
  } catch (error) {
264
365
  if (error instanceof SubscriptionUsageError) throw error;
265
366
  const message = error instanceof Error ? error.message : String(error);
@@ -764,6 +865,7 @@ export {
764
865
  getClaudeCodeVersion,
765
866
  getContextWindow,
766
867
  getDefaultModel,
868
+ getDefaultThinkingLevel,
767
869
  getFastModel,
768
870
  getMaxThinkingLevel,
769
871
  getModel,
@@ -786,6 +888,7 @@ export {
786
888
  loginKimi,
787
889
  loginOpenAI,
788
890
  openLog,
891
+ readStoredBaseUrlSync,
789
892
  refreshAnthropicToken,
790
893
  refreshGeminiToken,
791
894
  refreshKimiToken,