@kenkaiiii/gg-core 5.20.4 → 5.21.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.cjs CHANGED
@@ -51,6 +51,7 @@ __export(index_exports, {
51
51
  getClaudeCodeVersion: () => getClaudeCodeVersion,
52
52
  getContextWindow: () => getContextWindow,
53
53
  getDefaultModel: () => getDefaultModel,
54
+ getDefaultThinkingLevel: () => getDefaultThinkingLevel,
54
55
  getFastModel: () => getFastModel,
55
56
  getMaxThinkingLevel: () => getMaxThinkingLevel,
56
57
  getModel: () => getModel,
@@ -73,6 +74,7 @@ __export(index_exports, {
73
74
  loginKimi: () => loginKimi,
74
75
  loginOpenAI: () => loginOpenAI,
75
76
  openLog: () => openLog,
77
+ readStoredBaseUrlSync: () => readStoredBaseUrlSync,
76
78
  refreshAnthropicToken: () => refreshAnthropicToken,
77
79
  refreshGeminiToken: () => refreshGeminiToken,
78
80
  refreshKimiToken: () => refreshKimiToken,
@@ -86,9 +88,12 @@ __export(index_exports, {
86
88
  });
87
89
  module.exports = __toCommonJS(index_exports);
88
90
 
89
- // src/auth-storage.ts
90
- var import_promises4 = __toESM(require("fs/promises"), 1);
91
- var import_node_crypto6 = __toESM(require("crypto"), 1);
91
+ // src/oauth/kimi.ts
92
+ var import_node_child_process = require("child_process");
93
+ var import_node_crypto = require("crypto");
94
+ var import_node_fs = require("fs");
95
+ var import_node_os2 = require("os");
96
+ var import_node_path2 = __toESM(require("path"), 1);
92
97
 
93
98
  // src/paths.ts
94
99
  var import_node_path = __toESM(require("path"), 1);
@@ -115,8 +120,225 @@ function getAppPaths() {
115
120
  };
116
121
  }
117
122
 
123
+ // src/oauth/kimi.ts
124
+ var CLIENT_ID = "17e5f671-d194-4dfb-9706-5516cb48c098";
125
+ var DEFAULT_OAUTH_HOST = "https://auth.kimi.com";
126
+ var DEFAULT_CODING_BASE_URL = "https://api.kimi.com/coding/v1";
127
+ var KIMI_PLATFORM = "kimi_code_cli";
128
+ var DEFAULT_KIMI_VERSION = "1.0.11";
129
+ var DEVICE_TIMEOUT_MS = 15 * 60 * 1e3;
130
+ function oauthHost() {
131
+ const host = process.env.KIMI_CODE_OAUTH_HOST ?? process.env.KIMI_OAUTH_HOST ?? DEFAULT_OAUTH_HOST;
132
+ return host.replace(/\/+$/, "");
133
+ }
134
+ function kimiCodeBaseUrl() {
135
+ return (process.env.KIMI_CODE_BASE_URL ?? DEFAULT_CODING_BASE_URL).replace(/\/+$/, "");
136
+ }
137
+ function kimiVersion() {
138
+ const v = process.env.KIMI_CODE_VERSION ?? DEFAULT_KIMI_VERSION;
139
+ return asciiHeader(v, DEFAULT_KIMI_VERSION);
140
+ }
141
+ function asciiHeader(value, fallback = "unknown") {
142
+ const cleaned = value.replace(/[^\u0020-\u007E]/g, "").trim();
143
+ return cleaned.length > 0 ? cleaned : fallback;
144
+ }
145
+ function macOsProductVersion() {
146
+ try {
147
+ const version = (0, import_node_child_process.execFileSync)("/usr/bin/sw_vers", ["-productVersion"], {
148
+ encoding: "utf-8",
149
+ timeout: 1e3
150
+ }).trim();
151
+ return version.length > 0 ? version : void 0;
152
+ } catch {
153
+ return void 0;
154
+ }
155
+ }
156
+ function deviceModel() {
157
+ const os2 = (0, import_node_os2.type)();
158
+ const version = (0, import_node_os2.release)();
159
+ const osArch = (0, import_node_os2.arch)();
160
+ if (os2 === "Darwin") return `macOS ${macOsProductVersion() ?? version} ${osArch}`;
161
+ if (os2 === "Windows_NT") return `Windows ${version} ${osArch}`;
162
+ return `${os2} ${version} ${osArch}`.trim();
163
+ }
164
+ function deviceId() {
165
+ const idPath = import_node_path2.default.join(getAppPaths().agentDir, "kimi_device_id");
166
+ if ((0, import_node_fs.existsSync)(idPath)) {
167
+ try {
168
+ const text = (0, import_node_fs.readFileSync)(idPath, "utf-8").trim();
169
+ if (text.length > 0) return text;
170
+ } catch {
171
+ }
172
+ }
173
+ const id = (0, import_node_crypto.randomUUID)();
174
+ try {
175
+ (0, import_node_fs.mkdirSync)(getAppPaths().agentDir, { recursive: true, mode: 448 });
176
+ (0, import_node_fs.writeFileSync)(idPath, id, { encoding: "utf-8", mode: 384 });
177
+ } catch {
178
+ }
179
+ return id;
180
+ }
181
+ function deviceHeaders() {
182
+ return {
183
+ "X-Msh-Platform": KIMI_PLATFORM,
184
+ "X-Msh-Version": kimiVersion(),
185
+ "X-Msh-Device-Name": asciiHeader((0, import_node_os2.hostname)()),
186
+ "X-Msh-Device-Model": asciiHeader(deviceModel()),
187
+ "X-Msh-Os-Version": asciiHeader((0, import_node_os2.release)()),
188
+ "X-Msh-Device-Id": deviceId()
189
+ };
190
+ }
191
+ function kimiCodingHeaders() {
192
+ return {
193
+ "User-Agent": `kimi-code-cli/${kimiVersion()}`,
194
+ ...deviceHeaders()
195
+ };
196
+ }
197
+ function isKimiCodingEndpoint(baseUrl) {
198
+ if (typeof baseUrl !== "string" || baseUrl.length === 0) return false;
199
+ const normalized = baseUrl.replace(/\/+$/, "");
200
+ return normalized === kimiCodeBaseUrl() || /(^|\.)kimi\.com/i.test(normalized);
201
+ }
202
+ async function postForm(endpoint, params) {
203
+ const response = await fetch(`${oauthHost()}${endpoint}`, {
204
+ method: "POST",
205
+ headers: {
206
+ ...deviceHeaders(),
207
+ "Content-Type": "application/x-www-form-urlencoded",
208
+ Accept: "application/json"
209
+ },
210
+ body: new URLSearchParams(params).toString()
211
+ });
212
+ let data = {};
213
+ try {
214
+ const parsed = await response.json();
215
+ if (parsed && typeof parsed === "object") data = parsed;
216
+ } catch {
217
+ }
218
+ return { status: response.status, data };
219
+ }
220
+ function errorDetail(data) {
221
+ const desc = data.error_description ?? data.message ?? data.error;
222
+ return typeof desc === "string" && desc.length > 0 ? desc : "unknown error";
223
+ }
224
+ function credsFromTokenResponse(data, opts) {
225
+ const accessToken = data.access_token;
226
+ const responseRefreshToken = data.refresh_token;
227
+ const expiresIn = Number(data.expires_in);
228
+ if (typeof accessToken !== "string" || accessToken.length === 0) {
229
+ throw new Error("Kimi OAuth response missing access_token.");
230
+ }
231
+ const refreshToken = typeof responseRefreshToken === "string" && responseRefreshToken.length > 0 ? responseRefreshToken : opts?.fallbackRefreshToken ?? "";
232
+ if (refreshToken.length === 0) {
233
+ throw new Error("Kimi OAuth response missing refresh_token.");
234
+ }
235
+ if (!Number.isFinite(expiresIn) || expiresIn <= 0) {
236
+ throw new Error("Kimi OAuth response missing or invalid expires_in.");
237
+ }
238
+ return {
239
+ accessToken,
240
+ refreshToken,
241
+ expiresAt: Date.now() + expiresIn * 1e3,
242
+ baseUrl: kimiCodeBaseUrl()
243
+ };
244
+ }
245
+ async function requestDeviceAuthorization() {
246
+ const { status, data } = await postForm("/api/oauth/device_authorization", {
247
+ client_id: CLIENT_ID
248
+ });
249
+ if (status !== 200) {
250
+ throw new Error(`Kimi device authorization failed (${status}): ${errorDetail(data)}`);
251
+ }
252
+ const userCode = data.user_code;
253
+ const deviceCode = data.device_code;
254
+ const verificationUriComplete = data.verification_uri_complete;
255
+ if (typeof userCode !== "string" || typeof deviceCode !== "string") {
256
+ throw new Error("Kimi device authorization response missing user_code/device_code.");
257
+ }
258
+ return {
259
+ userCode,
260
+ deviceCode,
261
+ verificationUri: typeof data.verification_uri === "string" ? data.verification_uri : "",
262
+ verificationUriComplete: typeof verificationUriComplete === "string" ? verificationUriComplete : "",
263
+ interval: Number(data.interval ?? 5) || 5
264
+ };
265
+ }
266
+ async function pollDeviceToken(deviceCode) {
267
+ const { status, data } = await postForm("/api/oauth/token", {
268
+ client_id: CLIENT_ID,
269
+ device_code: deviceCode,
270
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code"
271
+ });
272
+ if (status === 200 && typeof data.access_token === "string") {
273
+ return { kind: "success", creds: credsFromTokenResponse(data) };
274
+ }
275
+ if (status >= 500) {
276
+ throw new Error(`Kimi token polling server error (${status}): ${errorDetail(data)}`);
277
+ }
278
+ const errorCode = typeof data.error === "string" ? data.error : "unknown_error";
279
+ switch (errorCode) {
280
+ case "authorization_pending":
281
+ return { kind: "pending" };
282
+ case "slow_down":
283
+ return { kind: "slow_down" };
284
+ case "expired_token":
285
+ return { kind: "expired" };
286
+ case "access_denied":
287
+ return { kind: "denied" };
288
+ default:
289
+ throw new Error(`Kimi token polling failed (${status}): ${errorDetail(data)}`);
290
+ }
291
+ }
292
+ function sleep(ms) {
293
+ return new Promise((resolve) => {
294
+ setTimeout(resolve, ms);
295
+ });
296
+ }
297
+ async function loginKimi(callbacks) {
298
+ const auth = await requestDeviceAuthorization();
299
+ callbacks.onStatus(
300
+ `Visit ${auth.verificationUri || auth.verificationUriComplete} and enter code: ${auth.userCode}`
301
+ );
302
+ callbacks.onOpenUrl(auth.verificationUriComplete || auth.verificationUri);
303
+ callbacks.onStatus("Waiting for you to authorize in the browser...");
304
+ const deadline = Date.now() + DEVICE_TIMEOUT_MS;
305
+ let interval = Math.max(auth.interval, 1);
306
+ while (Date.now() < deadline) {
307
+ await sleep(interval * 1e3);
308
+ const result = await pollDeviceToken(auth.deviceCode);
309
+ if (result.kind === "success") return result.creds;
310
+ if (result.kind === "denied") {
311
+ throw new Error("Kimi authorization was denied.");
312
+ }
313
+ if (result.kind === "expired") {
314
+ throw new Error("Kimi device code expired. Please run login again.");
315
+ }
316
+ if (result.kind === "slow_down") {
317
+ interval += 5;
318
+ }
319
+ }
320
+ throw new Error("Kimi login timed out. Please run login again.");
321
+ }
322
+ async function refreshKimiToken(refreshToken) {
323
+ const { status, data } = await postForm("/api/oauth/token", {
324
+ client_id: CLIENT_ID,
325
+ grant_type: "refresh_token",
326
+ refresh_token: refreshToken
327
+ });
328
+ if (status === 200 && typeof data.access_token === "string") {
329
+ return credsFromTokenResponse(data, { fallbackRefreshToken: refreshToken });
330
+ }
331
+ const errorCode = typeof data.error === "string" ? data.error : "";
332
+ throw new Error(`Kimi token refresh failed (${status}): ${errorCode || errorDetail(data)}`);
333
+ }
334
+
335
+ // src/auth-storage.ts
336
+ var import_promises4 = __toESM(require("fs/promises"), 1);
337
+ var import_node_fs3 = require("fs");
338
+ var import_node_crypto6 = __toESM(require("crypto"), 1);
339
+
118
340
  // src/oauth/anthropic.ts
119
- var import_node_crypto2 = __toESM(require("crypto"), 1);
341
+ var import_node_crypto3 = __toESM(require("crypto"), 1);
120
342
 
121
343
  // src/oauth/pkce.ts
122
344
  function base64urlEncode(bytes) {
@@ -138,12 +360,12 @@ async function generatePKCE() {
138
360
 
139
361
  // src/claude-code-version.ts
140
362
  var import_promises = __toESM(require("fs/promises"), 1);
141
- var import_node_path3 = __toESM(require("path"), 1);
363
+ var import_node_path4 = __toESM(require("path"), 1);
142
364
 
143
365
  // src/logger.ts
144
- var import_node_fs = __toESM(require("fs"), 1);
145
- var import_node_path2 = __toESM(require("path"), 1);
146
- var import_node_crypto = require("crypto");
366
+ var import_node_fs2 = __toESM(require("fs"), 1);
367
+ var import_node_path3 = __toESM(require("path"), 1);
368
+ var import_node_crypto2 = require("crypto");
147
369
  var import_gg_ai = require("@kenkaiiii/gg-ai");
148
370
  var MAX_BYTES = 10 * 1024 * 1024;
149
371
  var fd = null;
@@ -155,14 +377,14 @@ var cleanups = [];
155
377
  var exactSecrets = [];
156
378
  function rotateIfNeeded(filePath) {
157
379
  try {
158
- const st = import_node_fs.default.statSync(filePath);
380
+ const st = import_node_fs2.default.statSync(filePath);
159
381
  if (st.size < MAX_BYTES) return;
160
382
  const rotated = `${filePath}.1`;
161
383
  try {
162
- import_node_fs.default.unlinkSync(rotated);
384
+ import_node_fs2.default.unlinkSync(rotated);
163
385
  } catch {
164
386
  }
165
- import_node_fs.default.renameSync(filePath, rotated);
387
+ import_node_fs2.default.renameSync(filePath, rotated);
166
388
  } catch {
167
389
  }
168
390
  }
@@ -171,32 +393,32 @@ function openLog(filePath, name) {
171
393
  appName = name;
172
394
  exactSecrets = (0, import_gg_ai.environmentSecrets)(process.env);
173
395
  try {
174
- import_node_fs.default.mkdirSync(import_node_path2.default.dirname(filePath), { recursive: true, mode: 448 });
396
+ import_node_fs2.default.mkdirSync(import_node_path3.default.dirname(filePath), { recursive: true, mode: 448 });
175
397
  } catch {
176
398
  }
177
399
  rotateIfNeeded(filePath);
178
400
  try {
179
- fd = import_node_fs.default.openSync(filePath, "a");
401
+ fd = import_node_fs2.default.openSync(filePath, "a");
180
402
  } catch {
181
403
  fd = null;
182
404
  bytesWritten = 0;
183
405
  return false;
184
406
  }
185
407
  try {
186
- bytesWritten = import_node_fs.default.fstatSync(fd).size;
408
+ bytesWritten = import_node_fs2.default.fstatSync(fd).size;
187
409
  } catch {
188
410
  try {
189
- import_node_fs.default.closeSync(fd);
411
+ import_node_fs2.default.closeSync(fd);
190
412
  } catch {
191
413
  }
192
414
  fd = null;
193
415
  bytesWritten = 0;
194
416
  return false;
195
417
  }
196
- sessionId = (0, import_node_crypto.randomBytes)(4).toString("hex");
418
+ sessionId = (0, import_node_crypto2.randomBytes)(4).toString("hex");
197
419
  try {
198
420
  if (bytesWritten < MAX_BYTES) {
199
- bytesWritten += import_node_fs.default.writeSync(fd, "\n");
421
+ bytesWritten += import_node_fs2.default.writeSync(fd, "\n");
200
422
  }
201
423
  } catch {
202
424
  }
@@ -229,9 +451,9 @@ function log(level, category, message, data) {
229
451
  `;
230
452
  try {
231
453
  if (bytesWritten + Buffer.byteLength(capLine) <= MAX_BYTES) {
232
- bytesWritten += import_node_fs.default.writeSync(fd, capLine);
454
+ bytesWritten += import_node_fs2.default.writeSync(fd, capLine);
233
455
  }
234
- import_node_fs.default.closeSync(fd);
456
+ import_node_fs2.default.closeSync(fd);
235
457
  } catch {
236
458
  }
237
459
  fd = null;
@@ -239,7 +461,7 @@ function log(level, category, message, data) {
239
461
  return;
240
462
  }
241
463
  try {
242
- bytesWritten += import_node_fs.default.writeSync(fd, line);
464
+ bytesWritten += import_node_fs2.default.writeSync(fd, line);
243
465
  } catch {
244
466
  }
245
467
  }
@@ -250,7 +472,7 @@ function closeLogger(opts) {
250
472
  if (fd !== null) {
251
473
  if (opts?.shutdownLine !== false) log("INFO", "shutdown", `${appName} shutting down`);
252
474
  try {
253
- if (fd !== null) import_node_fs.default.closeSync(fd);
475
+ if (fd !== null) import_node_fs2.default.closeSync(fd);
254
476
  } catch {
255
477
  }
256
478
  }
@@ -270,7 +492,7 @@ var FALLBACK_VERSION = "2.1.88";
270
492
  var memoryCache = null;
271
493
  var inflight = null;
272
494
  function cachePath() {
273
- return import_node_path3.default.join(getAppPaths().agentDir, "claude-code-version.json");
495
+ return import_node_path4.default.join(getAppPaths().agentDir, "claude-code-version.json");
274
496
  }
275
497
  async function readDiskCache() {
276
498
  try {
@@ -352,7 +574,7 @@ async function getClaudeCliUserAgent() {
352
574
  }
353
575
 
354
576
  // src/oauth/anthropic.ts
355
- var CLIENT_ID = atob("OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl");
577
+ var CLIENT_ID2 = atob("OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl");
356
578
  var AUTHORIZE_URL = "https://claude.ai/oauth/authorize";
357
579
  var TOKEN_URLS = [
358
580
  "https://platform.claude.com/v1/oauth/token",
@@ -396,10 +618,10 @@ function toCredentials(data) {
396
618
  }
397
619
  async function loginAnthropic(callbacks) {
398
620
  const { verifier, challenge } = await generatePKCE();
399
- const state = import_node_crypto2.default.randomBytes(16).toString("hex");
621
+ const state = import_node_crypto3.default.randomBytes(16).toString("hex");
400
622
  const params = new URLSearchParams({
401
623
  code: "true",
402
- client_id: CLIENT_ID,
624
+ client_id: CLIENT_ID2,
403
625
  response_type: "code",
404
626
  redirect_uri: REDIRECT_URI,
405
627
  scope: SCOPES,
@@ -420,7 +642,7 @@ async function exchangeAnthropicCode(code, state, verifier) {
420
642
  const data = await postTokenRequest(
421
643
  {
422
644
  grant_type: "authorization_code",
423
- client_id: CLIENT_ID,
645
+ client_id: CLIENT_ID2,
424
646
  code,
425
647
  state,
426
648
  redirect_uri: REDIRECT_URI,
@@ -434,7 +656,7 @@ async function refreshAnthropicToken(refreshToken) {
434
656
  const data = await postTokenRequest(
435
657
  {
436
658
  grant_type: "refresh_token",
437
- client_id: CLIENT_ID,
659
+ client_id: CLIENT_ID2,
438
660
  refresh_token: refreshToken
439
661
  },
440
662
  "token refresh"
@@ -444,8 +666,8 @@ async function refreshAnthropicToken(refreshToken) {
444
666
 
445
667
  // src/oauth/openai.ts
446
668
  var import_node_http = __toESM(require("http"), 1);
447
- var import_node_crypto3 = __toESM(require("crypto"), 1);
448
- var CLIENT_ID2 = "app_EMoamEEZ73f0CkXaXp7hrann";
669
+ var import_node_crypto4 = __toESM(require("crypto"), 1);
670
+ var CLIENT_ID3 = "app_EMoamEEZ73f0CkXaXp7hrann";
449
671
  var AUTHORIZE_URL2 = "https://auth.openai.com/oauth/authorize";
450
672
  var TOKEN_URL = "https://auth.openai.com/oauth/token";
451
673
  var REDIRECT_URI2 = "http://localhost:1455/auth/callback";
@@ -453,10 +675,10 @@ var SCOPE = "openid profile email offline_access api.connectors.read api.connect
453
675
  var JWT_CLAIM_PATH = "https://api.openai.com/auth";
454
676
  async function loginOpenAI(callbacks) {
455
677
  const { verifier, challenge } = await generatePKCE();
456
- const state = import_node_crypto3.default.randomBytes(16).toString("hex");
678
+ const state = import_node_crypto4.default.randomBytes(16).toString("hex");
457
679
  const url = new URL(AUTHORIZE_URL2);
458
680
  url.searchParams.set("response_type", "code");
459
- url.searchParams.set("client_id", CLIENT_ID2);
681
+ url.searchParams.set("client_id", CLIENT_ID3);
460
682
  url.searchParams.set("redirect_uri", REDIRECT_URI2);
461
683
  url.searchParams.set("scope", SCOPE);
462
684
  url.searchParams.set("code_challenge", challenge);
@@ -577,7 +799,7 @@ async function exchangeOpenAICode(code, verifier) {
577
799
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
578
800
  body: new URLSearchParams({
579
801
  grant_type: "authorization_code",
580
- client_id: CLIENT_ID2,
802
+ client_id: CLIENT_ID3,
581
803
  code,
582
804
  redirect_uri: REDIRECT_URI2,
583
805
  code_verifier: verifier
@@ -601,7 +823,7 @@ async function refreshOpenAIToken(refreshToken) {
601
823
  body: new URLSearchParams({
602
824
  grant_type: "refresh_token",
603
825
  refresh_token: refreshToken,
604
- client_id: CLIENT_ID2
826
+ client_id: CLIENT_ID3
605
827
  })
606
828
  });
607
829
  if (!response.ok) {
@@ -623,7 +845,7 @@ async function refreshOpenAIToken(refreshToken) {
623
845
 
624
846
  // src/oauth/gemini.ts
625
847
  var import_node_http2 = __toESM(require("http"), 1);
626
- var import_node_crypto4 = __toESM(require("crypto"), 1);
848
+ var import_node_crypto5 = __toESM(require("crypto"), 1);
627
849
  var CLIENT_ID_ENV = "GGCODER_GEMINI_OAUTH_CLIENT_ID";
628
850
  var CLIENT_SECRET_ENV = "GGCODER_GEMINI_OAUTH_CLIENT_SECRET";
629
851
  var DEFAULT_CLIENT_ID = "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com";
@@ -657,7 +879,7 @@ var CodeAssistHttpError = class extends Error {
657
879
  async function loginGemini(callbacks) {
658
880
  const { clientId, clientSecret } = getGeminiOAuthClientCredentials();
659
881
  const { verifier, challenge } = await generatePKCE();
660
- const state = import_node_crypto4.default.randomBytes(32).toString("hex");
882
+ const state = import_node_crypto5.default.randomBytes(32).toString("hex");
661
883
  const redirectUri = await getLoopbackRedirectUri();
662
884
  const url = new URL(AUTHORIZE_URL3);
663
885
  url.searchParams.set("response_type", "code");
@@ -984,223 +1206,6 @@ function codeAssistHeaders(accessToken) {
984
1206
  };
985
1207
  }
986
1208
 
987
- // src/oauth/kimi.ts
988
- var import_node_child_process = require("child_process");
989
- var import_node_crypto5 = require("crypto");
990
- var import_node_fs2 = require("fs");
991
- var import_node_os2 = require("os");
992
- var import_node_path4 = __toESM(require("path"), 1);
993
- var CLIENT_ID3 = "17e5f671-d194-4dfb-9706-5516cb48c098";
994
- var DEFAULT_OAUTH_HOST = "https://auth.kimi.com";
995
- var DEFAULT_CODING_BASE_URL = "https://api.kimi.com/coding/v1";
996
- var KIMI_PLATFORM = "kimi_code_cli";
997
- var DEFAULT_KIMI_VERSION = "1.0.11";
998
- var DEVICE_TIMEOUT_MS = 15 * 60 * 1e3;
999
- function oauthHost() {
1000
- const host = process.env.KIMI_CODE_OAUTH_HOST ?? process.env.KIMI_OAUTH_HOST ?? DEFAULT_OAUTH_HOST;
1001
- return host.replace(/\/+$/, "");
1002
- }
1003
- function kimiCodeBaseUrl() {
1004
- return (process.env.KIMI_CODE_BASE_URL ?? DEFAULT_CODING_BASE_URL).replace(/\/+$/, "");
1005
- }
1006
- function kimiVersion() {
1007
- const v = process.env.KIMI_CODE_VERSION ?? DEFAULT_KIMI_VERSION;
1008
- return asciiHeader(v, DEFAULT_KIMI_VERSION);
1009
- }
1010
- function asciiHeader(value, fallback = "unknown") {
1011
- const cleaned = value.replace(/[^\u0020-\u007E]/g, "").trim();
1012
- return cleaned.length > 0 ? cleaned : fallback;
1013
- }
1014
- function macOsProductVersion() {
1015
- try {
1016
- const version = (0, import_node_child_process.execFileSync)("/usr/bin/sw_vers", ["-productVersion"], {
1017
- encoding: "utf-8",
1018
- timeout: 1e3
1019
- }).trim();
1020
- return version.length > 0 ? version : void 0;
1021
- } catch {
1022
- return void 0;
1023
- }
1024
- }
1025
- function deviceModel() {
1026
- const os2 = (0, import_node_os2.type)();
1027
- const version = (0, import_node_os2.release)();
1028
- const osArch = (0, import_node_os2.arch)();
1029
- if (os2 === "Darwin") return `macOS ${macOsProductVersion() ?? version} ${osArch}`;
1030
- if (os2 === "Windows_NT") return `Windows ${version} ${osArch}`;
1031
- return `${os2} ${version} ${osArch}`.trim();
1032
- }
1033
- function deviceId() {
1034
- const idPath = import_node_path4.default.join(getAppPaths().agentDir, "kimi_device_id");
1035
- if ((0, import_node_fs2.existsSync)(idPath)) {
1036
- try {
1037
- const text = (0, import_node_fs2.readFileSync)(idPath, "utf-8").trim();
1038
- if (text.length > 0) return text;
1039
- } catch {
1040
- }
1041
- }
1042
- const id = (0, import_node_crypto5.randomUUID)();
1043
- try {
1044
- (0, import_node_fs2.mkdirSync)(getAppPaths().agentDir, { recursive: true, mode: 448 });
1045
- (0, import_node_fs2.writeFileSync)(idPath, id, { encoding: "utf-8", mode: 384 });
1046
- } catch {
1047
- }
1048
- return id;
1049
- }
1050
- function deviceHeaders() {
1051
- return {
1052
- "X-Msh-Platform": KIMI_PLATFORM,
1053
- "X-Msh-Version": kimiVersion(),
1054
- "X-Msh-Device-Name": asciiHeader((0, import_node_os2.hostname)()),
1055
- "X-Msh-Device-Model": asciiHeader(deviceModel()),
1056
- "X-Msh-Os-Version": asciiHeader((0, import_node_os2.release)()),
1057
- "X-Msh-Device-Id": deviceId()
1058
- };
1059
- }
1060
- function kimiCodingHeaders() {
1061
- return {
1062
- "User-Agent": `kimi-code-cli/${kimiVersion()}`,
1063
- ...deviceHeaders()
1064
- };
1065
- }
1066
- function isKimiCodingEndpoint(baseUrl) {
1067
- if (typeof baseUrl !== "string" || baseUrl.length === 0) return false;
1068
- const normalized = baseUrl.replace(/\/+$/, "");
1069
- return normalized === kimiCodeBaseUrl() || /(^|\.)kimi\.com/i.test(normalized);
1070
- }
1071
- async function postForm(endpoint, params) {
1072
- const response = await fetch(`${oauthHost()}${endpoint}`, {
1073
- method: "POST",
1074
- headers: {
1075
- ...deviceHeaders(),
1076
- "Content-Type": "application/x-www-form-urlencoded",
1077
- Accept: "application/json"
1078
- },
1079
- body: new URLSearchParams(params).toString()
1080
- });
1081
- let data = {};
1082
- try {
1083
- const parsed = await response.json();
1084
- if (parsed && typeof parsed === "object") data = parsed;
1085
- } catch {
1086
- }
1087
- return { status: response.status, data };
1088
- }
1089
- function errorDetail(data) {
1090
- const desc = data.error_description ?? data.message ?? data.error;
1091
- return typeof desc === "string" && desc.length > 0 ? desc : "unknown error";
1092
- }
1093
- function credsFromTokenResponse(data, opts) {
1094
- const accessToken = data.access_token;
1095
- const responseRefreshToken = data.refresh_token;
1096
- const expiresIn = Number(data.expires_in);
1097
- if (typeof accessToken !== "string" || accessToken.length === 0) {
1098
- throw new Error("Kimi OAuth response missing access_token.");
1099
- }
1100
- const refreshToken = typeof responseRefreshToken === "string" && responseRefreshToken.length > 0 ? responseRefreshToken : opts?.fallbackRefreshToken ?? "";
1101
- if (refreshToken.length === 0) {
1102
- throw new Error("Kimi OAuth response missing refresh_token.");
1103
- }
1104
- if (!Number.isFinite(expiresIn) || expiresIn <= 0) {
1105
- throw new Error("Kimi OAuth response missing or invalid expires_in.");
1106
- }
1107
- return {
1108
- accessToken,
1109
- refreshToken,
1110
- expiresAt: Date.now() + expiresIn * 1e3,
1111
- baseUrl: kimiCodeBaseUrl()
1112
- };
1113
- }
1114
- async function requestDeviceAuthorization() {
1115
- const { status, data } = await postForm("/api/oauth/device_authorization", {
1116
- client_id: CLIENT_ID3
1117
- });
1118
- if (status !== 200) {
1119
- throw new Error(`Kimi device authorization failed (${status}): ${errorDetail(data)}`);
1120
- }
1121
- const userCode = data.user_code;
1122
- const deviceCode = data.device_code;
1123
- const verificationUriComplete = data.verification_uri_complete;
1124
- if (typeof userCode !== "string" || typeof deviceCode !== "string") {
1125
- throw new Error("Kimi device authorization response missing user_code/device_code.");
1126
- }
1127
- return {
1128
- userCode,
1129
- deviceCode,
1130
- verificationUri: typeof data.verification_uri === "string" ? data.verification_uri : "",
1131
- verificationUriComplete: typeof verificationUriComplete === "string" ? verificationUriComplete : "",
1132
- interval: Number(data.interval ?? 5) || 5
1133
- };
1134
- }
1135
- async function pollDeviceToken(deviceCode) {
1136
- const { status, data } = await postForm("/api/oauth/token", {
1137
- client_id: CLIENT_ID3,
1138
- device_code: deviceCode,
1139
- grant_type: "urn:ietf:params:oauth:grant-type:device_code"
1140
- });
1141
- if (status === 200 && typeof data.access_token === "string") {
1142
- return { kind: "success", creds: credsFromTokenResponse(data) };
1143
- }
1144
- if (status >= 500) {
1145
- throw new Error(`Kimi token polling server error (${status}): ${errorDetail(data)}`);
1146
- }
1147
- const errorCode = typeof data.error === "string" ? data.error : "unknown_error";
1148
- switch (errorCode) {
1149
- case "authorization_pending":
1150
- return { kind: "pending" };
1151
- case "slow_down":
1152
- return { kind: "slow_down" };
1153
- case "expired_token":
1154
- return { kind: "expired" };
1155
- case "access_denied":
1156
- return { kind: "denied" };
1157
- default:
1158
- throw new Error(`Kimi token polling failed (${status}): ${errorDetail(data)}`);
1159
- }
1160
- }
1161
- function sleep(ms) {
1162
- return new Promise((resolve) => {
1163
- setTimeout(resolve, ms);
1164
- });
1165
- }
1166
- async function loginKimi(callbacks) {
1167
- const auth = await requestDeviceAuthorization();
1168
- callbacks.onStatus(
1169
- `Visit ${auth.verificationUri || auth.verificationUriComplete} and enter code: ${auth.userCode}`
1170
- );
1171
- callbacks.onOpenUrl(auth.verificationUriComplete || auth.verificationUri);
1172
- callbacks.onStatus("Waiting for you to authorize in the browser...");
1173
- const deadline = Date.now() + DEVICE_TIMEOUT_MS;
1174
- let interval = Math.max(auth.interval, 1);
1175
- while (Date.now() < deadline) {
1176
- await sleep(interval * 1e3);
1177
- const result = await pollDeviceToken(auth.deviceCode);
1178
- if (result.kind === "success") return result.creds;
1179
- if (result.kind === "denied") {
1180
- throw new Error("Kimi authorization was denied.");
1181
- }
1182
- if (result.kind === "expired") {
1183
- throw new Error("Kimi device code expired. Please run login again.");
1184
- }
1185
- if (result.kind === "slow_down") {
1186
- interval += 5;
1187
- }
1188
- }
1189
- throw new Error("Kimi login timed out. Please run login again.");
1190
- }
1191
- async function refreshKimiToken(refreshToken) {
1192
- const { status, data } = await postForm("/api/oauth/token", {
1193
- client_id: CLIENT_ID3,
1194
- grant_type: "refresh_token",
1195
- refresh_token: refreshToken
1196
- });
1197
- if (status === 200 && typeof data.access_token === "string") {
1198
- return credsFromTokenResponse(data, { fallbackRefreshToken: refreshToken });
1199
- }
1200
- const errorCode = typeof data.error === "string" ? data.error : "";
1201
- throw new Error(`Kimi token refresh failed (${status}): ${errorCode || errorDetail(data)}`);
1202
- }
1203
-
1204
1209
  // src/file-lock.ts
1205
1210
  var import_promises2 = __toESM(require("fs/promises"), 1);
1206
1211
  var import_promises3 = require("timers/promises");
@@ -1266,6 +1271,26 @@ function isAlive(pid) {
1266
1271
  // src/auth-storage.ts
1267
1272
  var MOONSHOT_OAUTH_KEY = "moonshot-oauth";
1268
1273
  var XIAOMI_CREDITS_KEY = "xiaomi-credits";
1274
+ function activeBaseUrlEntry(data, provider) {
1275
+ if (provider === "moonshot") {
1276
+ const oauth = data[MOONSHOT_OAUTH_KEY];
1277
+ if (oauth) {
1278
+ const exhaustedUntil = oauth.usageExhaustedUntil ?? 0;
1279
+ if (Date.now() < exhaustedUntil && data["moonshot"]) return data["moonshot"];
1280
+ return oauth;
1281
+ }
1282
+ return data["moonshot"];
1283
+ }
1284
+ return data[provider];
1285
+ }
1286
+ function readStoredBaseUrlSync(authFile, provider) {
1287
+ try {
1288
+ const data = JSON.parse((0, import_node_fs3.readFileSync)(authFile, "utf-8"));
1289
+ return activeBaseUrlEntry(data, provider)?.baseUrl;
1290
+ } catch {
1291
+ return void 0;
1292
+ }
1293
+ }
1269
1294
  var REFRESH_SKEW_MS = 6e4;
1270
1295
  var USAGE_EXHAUSTED_DEFAULT_MS = 15 * 60 * 1e3;
1271
1296
  var STATIC_API_KEY_PROVIDERS = /* @__PURE__ */ new Set([
@@ -1341,6 +1366,16 @@ var AuthStorage = class {
1341
1366
  }
1342
1367
  return STATIC_API_KEY_PROVIDERS.has(provider);
1343
1368
  }
1369
+ /**
1370
+ * The base URL on the credential that is active right now, if any.
1371
+ * Synchronous — call only after load()/resolveCredentials() populated the
1372
+ * snapshot. For `moonshot` this is the Kimi For Coding URL whenever the
1373
+ * OAuth entry is the one resolveCredentials would serve (i.e. not currently
1374
+ * usage-exhausted with an API key configured).
1375
+ */
1376
+ getStoredBaseUrl(provider) {
1377
+ return activeBaseUrlEntry(this.data, provider)?.baseUrl;
1378
+ }
1344
1379
  async load() {
1345
1380
  await withFileLock(this.filePath, async () => {
1346
1381
  try {
@@ -1369,19 +1404,40 @@ var AuthStorage = class {
1369
1404
  async ensureLoaded() {
1370
1405
  if (!this.loaded) await this.load();
1371
1406
  }
1407
+ /**
1408
+ * Apply one provider-scoped mutation to the latest on-disk snapshot.
1409
+ * AuthStorage instances live in every app session/process, so writing this
1410
+ * instance's cached snapshot can erase credentials another instance just
1411
+ * added. The file lock only serializes writers; the re-read prevents stale
1412
+ * full-file overwrites.
1413
+ */
1414
+ async mutateLatest(mutator) {
1415
+ await this.ensureLoaded();
1416
+ await withFileLock(this.filePath, async () => {
1417
+ const latest = await readAuthData(this.filePath);
1418
+ mutator(latest);
1419
+ await atomicWriteFile(this.filePath, JSON.stringify(latest, null, 2));
1420
+ this.data = latest;
1421
+ });
1422
+ }
1423
+ async reloadLatest() {
1424
+ await withFileLock(this.filePath, async () => {
1425
+ this.data = await readAuthData(this.filePath);
1426
+ });
1427
+ }
1372
1428
  async getCredentials(provider) {
1373
1429
  await this.ensureLoaded();
1374
1430
  return this.data[provider];
1375
1431
  }
1376
1432
  async setCredentials(provider, creds) {
1377
- await this.ensureLoaded();
1378
- this.data[provider] = creds;
1379
- await this.save();
1433
+ await this.mutateLatest((latest) => {
1434
+ latest[provider] = creds;
1435
+ });
1380
1436
  }
1381
1437
  async clearCredentials(provider) {
1382
- await this.ensureLoaded();
1383
- delete this.data[provider];
1384
- await this.save();
1438
+ await this.mutateLatest((latest) => {
1439
+ delete latest[provider];
1440
+ });
1385
1441
  }
1386
1442
  /**
1387
1443
  * Mark the credential stored under `storageKey` as usage-exhausted until
@@ -1395,12 +1451,15 @@ var AuthStorage = class {
1395
1451
  * nothing is stored under `storageKey`.
1396
1452
  */
1397
1453
  async markUsageExhausted(storageKey, resetsAt) {
1398
- await this.ensureLoaded();
1399
- const creds = this.data[storageKey];
1400
- if (!creds) return;
1401
1454
  const until = resetsAt !== void 0 && resetsAt * 1e3 > Date.now() ? resetsAt * 1e3 : Date.now() + USAGE_EXHAUSTED_DEFAULT_MS;
1402
- creds.usageExhaustedUntil = until;
1403
- await this.save();
1455
+ let marked = false;
1456
+ await this.mutateLatest((latest) => {
1457
+ const creds = latest[storageKey];
1458
+ if (!creds) return;
1459
+ creds.usageExhaustedUntil = until;
1460
+ marked = true;
1461
+ });
1462
+ if (!marked) return;
1404
1463
  log(
1405
1464
  "WARN",
1406
1465
  "auth",
@@ -1408,8 +1467,11 @@ var AuthStorage = class {
1408
1467
  );
1409
1468
  }
1410
1469
  async clearAll() {
1411
- this.data = {};
1412
- await this.save();
1470
+ await this.ensureLoaded();
1471
+ await withFileLock(this.filePath, async () => {
1472
+ this.data = {};
1473
+ await atomicWriteFile(this.filePath, JSON.stringify(this.data, null, 2));
1474
+ });
1413
1475
  }
1414
1476
  /**
1415
1477
  * Returns valid credentials, auto-refreshing if expired.
@@ -1419,6 +1481,10 @@ var AuthStorage = class {
1419
1481
  */
1420
1482
  async resolveCredentials(provider, opts) {
1421
1483
  await this.ensureLoaded();
1484
+ const directStorageKeys = opts?.storageKeys && !(opts.storageKeys.length === 1 && opts.storageKeys[0] === provider) ? opts.storageKeys : provider === "moonshot" ? [MOONSHOT_OAUTH_KEY, "moonshot"] : [provider];
1485
+ if (!directStorageKeys.some((key) => Boolean(this.data[key]))) {
1486
+ await this.reloadLatest();
1487
+ }
1422
1488
  if (opts?.storageKeys && !(opts.storageKeys.length === 1 && opts.storageKeys[0] === provider)) {
1423
1489
  for (const key of opts.storageKeys) {
1424
1490
  const creds2 = this.data[key];
@@ -1465,41 +1531,44 @@ var AuthStorage = class {
1465
1531
  const existing = this.refreshLocks.get(provider);
1466
1532
  if (existing) return existing;
1467
1533
  const refreshPromise = withFileLock(this.filePath, async () => {
1468
- try {
1469
- const content = await import_promises4.default.readFile(this.filePath, "utf-8");
1470
- const freshData = JSON.parse(content);
1471
- const freshCreds = freshData[provider];
1472
- if (freshCreds && !opts?.forceRefresh && Date.now() < freshCreds.expiresAt - REFRESH_SKEW_MS) {
1473
- this.data[provider] = freshCreds;
1474
- return freshCreds;
1475
- }
1476
- } catch {
1534
+ const latest = await readAuthData(this.filePath);
1535
+ const latestCreds = latest[provider];
1536
+ if (!latestCreds) {
1537
+ this.data = latest;
1538
+ throw new NotLoggedInError(provider);
1539
+ }
1540
+ const credentialWasReplaced = latestCreds.accessToken !== creds.accessToken || latestCreds.refreshToken !== creds.refreshToken || latestCreds.expiresAt !== creds.expiresAt;
1541
+ if (credentialWasReplaced || !opts?.forceRefresh && Date.now() < latestCreds.expiresAt - REFRESH_SKEW_MS) {
1542
+ this.data = latest;
1543
+ return latestCreds;
1477
1544
  }
1478
1545
  const refreshFn = provider === "anthropic" ? refreshAnthropicToken : provider === "gemini" ? refreshGeminiToken : provider === MOONSHOT_OAUTH_KEY ? refreshKimiToken : refreshOpenAIToken;
1479
1546
  let refreshed;
1480
1547
  try {
1481
- refreshed = await refreshFn(creds.refreshToken);
1548
+ refreshed = await refreshFn(latestCreds.refreshToken);
1482
1549
  } catch (err) {
1483
1550
  const msg = err instanceof Error ? err.message : String(err);
1484
1551
  const isAuthFailure = /\((401|400)\)/.test(msg) || /invalid_grant|invalid_token|invalid.*refresh/i.test(msg) || /unauthorized/i.test(msg);
1485
1552
  if (isAuthFailure) {
1486
- delete this.data[provider];
1487
- await atomicWriteFile(this.filePath, JSON.stringify(this.data, null, 2));
1553
+ delete latest[provider];
1554
+ this.data = latest;
1555
+ await atomicWriteFile(this.filePath, JSON.stringify(latest, null, 2));
1488
1556
  throw new NotLoggedInError(provider);
1489
1557
  }
1490
1558
  throw err;
1491
1559
  }
1492
- if (!refreshed.accountId && creds.accountId) {
1493
- refreshed.accountId = creds.accountId;
1560
+ if (!refreshed.accountId && latestCreds.accountId) {
1561
+ refreshed.accountId = latestCreds.accountId;
1494
1562
  }
1495
- if (!refreshed.projectId && creds.projectId) {
1496
- refreshed.projectId = creds.projectId;
1563
+ if (!refreshed.projectId && latestCreds.projectId) {
1564
+ refreshed.projectId = latestCreds.projectId;
1497
1565
  }
1498
- if (!refreshed.baseUrl && creds.baseUrl) {
1499
- refreshed.baseUrl = creds.baseUrl;
1566
+ if (!refreshed.baseUrl && latestCreds.baseUrl) {
1567
+ refreshed.baseUrl = latestCreds.baseUrl;
1500
1568
  }
1501
- this.data[provider] = refreshed;
1502
- await atomicWriteFile(this.filePath, JSON.stringify(this.data, null, 2));
1569
+ latest[provider] = refreshed;
1570
+ this.data = latest;
1571
+ await atomicWriteFile(this.filePath, JSON.stringify(latest, null, 2));
1503
1572
  return refreshed;
1504
1573
  });
1505
1574
  this.refreshLocks.set(provider, refreshPromise);
@@ -1517,12 +1586,16 @@ var AuthStorage = class {
1517
1586
  const creds = await this.resolveCredentials(provider);
1518
1587
  return creds.accessToken;
1519
1588
  }
1520
- async save() {
1521
- await withFileLock(this.filePath, async () => {
1522
- await atomicWriteFile(this.filePath, JSON.stringify(this.data, null, 2));
1523
- });
1524
- }
1525
1589
  };
1590
+ async function readAuthData(filePath) {
1591
+ try {
1592
+ const content = await import_promises4.default.readFile(filePath, "utf-8");
1593
+ return JSON.parse(content);
1594
+ } catch (error) {
1595
+ if (error.code === "ENOENT") return {};
1596
+ throw error;
1597
+ }
1598
+ }
1526
1599
  async function atomicWriteFile(filePath, content) {
1527
1600
  const tmpPath = `${filePath}.${process.pid}.${Date.now()}.${import_node_crypto6.default.randomUUID().slice(0, 8)}.tmp`;
1528
1601
  try {
@@ -1777,8 +1850,9 @@ var MODELS = [
1777
1850
  },
1778
1851
  // ── Moonshot (Kimi) ────────────────────────────────────
1779
1852
  // K3 is Kimi's 2.8T-parameter flagship for long-horizon coding, knowledge
1780
- // work, and deep reasoning. It always reasons at the `max` effort; the public
1781
- // API uses `reasoning_effort`, while Kimi Code OAuth keeps its managed wire shape.
1853
+ // work, and deep reasoning. Its effort ladder is server-declared as
1854
+ // low/high/max on both the public API (default max) and the Kimi For Coding
1855
+ // OAuth endpoint (default high); thinking can also be fully disabled.
1782
1856
  {
1783
1857
  id: "kimi-k3",
1784
1858
  name: "Kimi K3",
@@ -2012,6 +2086,11 @@ function getContextWindow(modelId, options) {
2012
2086
  function getMaxThinkingLevel(modelId) {
2013
2087
  return getModel(modelId)?.maxThinkingLevel ?? "high";
2014
2088
  }
2089
+ function getDefaultThinkingLevel(modelId, options) {
2090
+ const model = getModel(modelId);
2091
+ if (model?.id === "kimi-k3" && isKimiCodingEndpoint(options?.baseUrl)) return "high";
2092
+ return model?.maxThinkingLevel ?? "high";
2093
+ }
2015
2094
  function getSummaryModel(provider, currentModelId) {
2016
2095
  if (provider === "anthropic") {
2017
2096
  return MODELS.find((m) => m.id === "claude-sonnet-5");
@@ -2052,6 +2131,7 @@ var ANTHROPIC_ADAPTIVE_THINKING_LEVELS = [
2052
2131
  "high",
2053
2132
  "max"
2054
2133
  ];
2134
+ var MOONSHOT_K3_THINKING_LEVELS = ["low", "high", "max"];
2055
2135
  function isOpenAIGptModel(provider, model) {
2056
2136
  return provider === "openai" && model.startsWith("gpt-");
2057
2137
  }
@@ -2061,6 +2141,9 @@ function isSakanaModel(provider) {
2061
2141
  function isXaiModel(provider) {
2062
2142
  return provider === "xai";
2063
2143
  }
2144
+ function isMoonshotK3Model(provider, model) {
2145
+ return provider === "moonshot" && model === "kimi-k3";
2146
+ }
2064
2147
  function isAnthropicOpus48Or47Model(provider, model) {
2065
2148
  return provider === "anthropic" && /opus-4-8|opus-4-7/.test(model);
2066
2149
  }
@@ -2085,6 +2168,7 @@ function getSupportedThinkingLevels(provider, model) {
2085
2168
  if (maxIndex2 === -1) return XAI_THINKING_LEVELS;
2086
2169
  return XAI_THINKING_LEVELS.slice(0, maxIndex2 + 1);
2087
2170
  }
2171
+ if (isMoonshotK3Model(provider, model)) return MOONSHOT_K3_THINKING_LEVELS;
2088
2172
  if (!isOpenAIGptModel(provider, model)) return [maxLevel];
2089
2173
  const levels = model.startsWith("gpt-5.6-") ? OPENAI_GPT_56_THINKING_LEVELS : OPENAI_GPT_THINKING_LEVELS;
2090
2174
  const maxIndex = levels.indexOf(maxLevel);
@@ -2096,7 +2180,7 @@ function isThinkingLevelSupported(provider, model, level) {
2096
2180
  }
2097
2181
  function getNextThinkingLevel(provider, model, current) {
2098
2182
  const supportedLevels = getSupportedThinkingLevels(provider, model);
2099
- const shouldCycleLevels = isOpenAIGptModel(provider, model) || isAnthropicAdaptiveModel(provider, model) || isSakanaModel(provider) || isXaiModel(provider);
2183
+ const shouldCycleLevels = isOpenAIGptModel(provider, model) || isAnthropicAdaptiveModel(provider, model) || isSakanaModel(provider) || isXaiModel(provider) || isMoonshotK3Model(provider, model);
2100
2184
  if (!shouldCycleLevels) {
2101
2185
  return current ? void 0 : supportedLevels[0];
2102
2186
  }
@@ -2560,7 +2644,7 @@ async function transcribeVoice(fileUrl) {
2560
2644
 
2561
2645
  // src/auto-update.ts
2562
2646
  var import_node_child_process2 = require("child_process");
2563
- var import_node_fs3 = __toESM(require("fs"), 1);
2647
+ var import_node_fs4 = __toESM(require("fs"), 1);
2564
2648
  var import_node_path5 = __toESM(require("path"), 1);
2565
2649
  var CHECK_INTERVAL_MS = 60 * 60 * 1e3;
2566
2650
  var FETCH_TIMEOUT_MS2 = 1e4;
@@ -2594,7 +2678,7 @@ function createAutoUpdater(config) {
2594
2678
  }
2595
2679
  function readState() {
2596
2680
  try {
2597
- const raw = import_node_fs3.default.readFileSync(stateFilePath(), "utf-8");
2681
+ const raw = import_node_fs4.default.readFileSync(stateFilePath(), "utf-8");
2598
2682
  return JSON.parse(raw);
2599
2683
  } catch {
2600
2684
  return null;
@@ -2603,8 +2687,8 @@ function createAutoUpdater(config) {
2603
2687
  function writeState(state) {
2604
2688
  try {
2605
2689
  const filePath = stateFilePath();
2606
- import_node_fs3.default.mkdirSync(import_node_path5.default.dirname(filePath), { recursive: true, mode: 448 });
2607
- import_node_fs3.default.writeFileSync(filePath, JSON.stringify(state));
2690
+ import_node_fs4.default.mkdirSync(import_node_path5.default.dirname(filePath), { recursive: true, mode: 448 });
2691
+ import_node_fs4.default.writeFileSync(filePath, JSON.stringify(state));
2608
2692
  } catch {
2609
2693
  }
2610
2694
  }
@@ -2749,6 +2833,7 @@ function createAutoUpdater(config) {
2749
2833
  getClaudeCodeVersion,
2750
2834
  getContextWindow,
2751
2835
  getDefaultModel,
2836
+ getDefaultThinkingLevel,
2752
2837
  getFastModel,
2753
2838
  getMaxThinkingLevel,
2754
2839
  getModel,
@@ -2771,6 +2856,7 @@ function createAutoUpdater(config) {
2771
2856
  loginKimi,
2772
2857
  loginOpenAI,
2773
2858
  openLog,
2859
+ readStoredBaseUrlSync,
2774
2860
  refreshAnthropicToken,
2775
2861
  refreshGeminiToken,
2776
2862
  refreshKimiToken,