@kenkaiiii/gg-core 5.20.5 → 5.22.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/{chunk-GMBEO4JX.js → chunk-TST5LJWL.js} +352 -275
- package/dist/chunk-TST5LJWL.js.map +1 -0
- package/dist/index.cjs +542 -371
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -4
- package/dist/index.d.ts +28 -4
- package/dist/index.js +97 -3
- package/dist/index.js.map +1 -1
- package/dist/model-registry.cjs +40 -20
- package/dist/model-registry.cjs.map +1 -1
- package/dist/model-registry.d.cts +14 -1
- package/dist/model-registry.d.ts +14 -1
- package/dist/model-registry.js +3 -1
- package/package.json +2 -2
- package/dist/chunk-GMBEO4JX.js.map +0 -1
|
@@ -2,8 +2,226 @@ import {
|
|
|
2
2
|
getAppPaths
|
|
3
3
|
} from "./chunk-QNR6SNB2.js";
|
|
4
4
|
|
|
5
|
+
// src/oauth/kimi.ts
|
|
6
|
+
import { execFileSync } from "child_process";
|
|
7
|
+
import { randomUUID } from "crypto";
|
|
8
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
9
|
+
import { arch, hostname, release, type } from "os";
|
|
10
|
+
import path from "path";
|
|
11
|
+
var CLIENT_ID = "17e5f671-d194-4dfb-9706-5516cb48c098";
|
|
12
|
+
var DEFAULT_OAUTH_HOST = "https://auth.kimi.com";
|
|
13
|
+
var DEFAULT_CODING_BASE_URL = "https://api.kimi.com/coding/v1";
|
|
14
|
+
var KIMI_PLATFORM = "kimi_code_cli";
|
|
15
|
+
var DEFAULT_KIMI_VERSION = "1.0.11";
|
|
16
|
+
var DEVICE_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
17
|
+
function oauthHost() {
|
|
18
|
+
const host = process.env.KIMI_CODE_OAUTH_HOST ?? process.env.KIMI_OAUTH_HOST ?? DEFAULT_OAUTH_HOST;
|
|
19
|
+
return host.replace(/\/+$/, "");
|
|
20
|
+
}
|
|
21
|
+
function kimiCodeBaseUrl() {
|
|
22
|
+
return (process.env.KIMI_CODE_BASE_URL ?? DEFAULT_CODING_BASE_URL).replace(/\/+$/, "");
|
|
23
|
+
}
|
|
24
|
+
function kimiVersion() {
|
|
25
|
+
const v = process.env.KIMI_CODE_VERSION ?? DEFAULT_KIMI_VERSION;
|
|
26
|
+
return asciiHeader(v, DEFAULT_KIMI_VERSION);
|
|
27
|
+
}
|
|
28
|
+
function asciiHeader(value, fallback = "unknown") {
|
|
29
|
+
const cleaned = value.replace(/[^\u0020-\u007E]/g, "").trim();
|
|
30
|
+
return cleaned.length > 0 ? cleaned : fallback;
|
|
31
|
+
}
|
|
32
|
+
function macOsProductVersion() {
|
|
33
|
+
try {
|
|
34
|
+
const version = execFileSync("/usr/bin/sw_vers", ["-productVersion"], {
|
|
35
|
+
encoding: "utf-8",
|
|
36
|
+
timeout: 1e3
|
|
37
|
+
}).trim();
|
|
38
|
+
return version.length > 0 ? version : void 0;
|
|
39
|
+
} catch {
|
|
40
|
+
return void 0;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function deviceModel() {
|
|
44
|
+
const os = type();
|
|
45
|
+
const version = release();
|
|
46
|
+
const osArch = arch();
|
|
47
|
+
if (os === "Darwin") return `macOS ${macOsProductVersion() ?? version} ${osArch}`;
|
|
48
|
+
if (os === "Windows_NT") return `Windows ${version} ${osArch}`;
|
|
49
|
+
return `${os} ${version} ${osArch}`.trim();
|
|
50
|
+
}
|
|
51
|
+
function deviceId() {
|
|
52
|
+
const idPath = path.join(getAppPaths().agentDir, "kimi_device_id");
|
|
53
|
+
if (existsSync(idPath)) {
|
|
54
|
+
try {
|
|
55
|
+
const text = readFileSync(idPath, "utf-8").trim();
|
|
56
|
+
if (text.length > 0) return text;
|
|
57
|
+
} catch {
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const id = randomUUID();
|
|
61
|
+
try {
|
|
62
|
+
mkdirSync(getAppPaths().agentDir, { recursive: true, mode: 448 });
|
|
63
|
+
writeFileSync(idPath, id, { encoding: "utf-8", mode: 384 });
|
|
64
|
+
} catch {
|
|
65
|
+
}
|
|
66
|
+
return id;
|
|
67
|
+
}
|
|
68
|
+
function deviceHeaders() {
|
|
69
|
+
return {
|
|
70
|
+
"X-Msh-Platform": KIMI_PLATFORM,
|
|
71
|
+
"X-Msh-Version": kimiVersion(),
|
|
72
|
+
"X-Msh-Device-Name": asciiHeader(hostname()),
|
|
73
|
+
"X-Msh-Device-Model": asciiHeader(deviceModel()),
|
|
74
|
+
"X-Msh-Os-Version": asciiHeader(release()),
|
|
75
|
+
"X-Msh-Device-Id": deviceId()
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function kimiCodingHeaders() {
|
|
79
|
+
return {
|
|
80
|
+
"User-Agent": `kimi-code-cli/${kimiVersion()}`,
|
|
81
|
+
...deviceHeaders()
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function isKimiCodingEndpoint(baseUrl) {
|
|
85
|
+
if (typeof baseUrl !== "string" || baseUrl.length === 0) return false;
|
|
86
|
+
const normalized = baseUrl.replace(/\/+$/, "");
|
|
87
|
+
return normalized === kimiCodeBaseUrl() || /(^|\.)kimi\.com/i.test(normalized);
|
|
88
|
+
}
|
|
89
|
+
async function postForm(endpoint, params) {
|
|
90
|
+
const response = await fetch(`${oauthHost()}${endpoint}`, {
|
|
91
|
+
method: "POST",
|
|
92
|
+
headers: {
|
|
93
|
+
...deviceHeaders(),
|
|
94
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
95
|
+
Accept: "application/json"
|
|
96
|
+
},
|
|
97
|
+
body: new URLSearchParams(params).toString()
|
|
98
|
+
});
|
|
99
|
+
let data = {};
|
|
100
|
+
try {
|
|
101
|
+
const parsed = await response.json();
|
|
102
|
+
if (parsed && typeof parsed === "object") data = parsed;
|
|
103
|
+
} catch {
|
|
104
|
+
}
|
|
105
|
+
return { status: response.status, data };
|
|
106
|
+
}
|
|
107
|
+
function errorDetail(data) {
|
|
108
|
+
const desc = data.error_description ?? data.message ?? data.error;
|
|
109
|
+
return typeof desc === "string" && desc.length > 0 ? desc : "unknown error";
|
|
110
|
+
}
|
|
111
|
+
function credsFromTokenResponse(data, opts) {
|
|
112
|
+
const accessToken = data.access_token;
|
|
113
|
+
const responseRefreshToken = data.refresh_token;
|
|
114
|
+
const expiresIn = Number(data.expires_in);
|
|
115
|
+
if (typeof accessToken !== "string" || accessToken.length === 0) {
|
|
116
|
+
throw new Error("Kimi OAuth response missing access_token.");
|
|
117
|
+
}
|
|
118
|
+
const refreshToken = typeof responseRefreshToken === "string" && responseRefreshToken.length > 0 ? responseRefreshToken : opts?.fallbackRefreshToken ?? "";
|
|
119
|
+
if (refreshToken.length === 0) {
|
|
120
|
+
throw new Error("Kimi OAuth response missing refresh_token.");
|
|
121
|
+
}
|
|
122
|
+
if (!Number.isFinite(expiresIn) || expiresIn <= 0) {
|
|
123
|
+
throw new Error("Kimi OAuth response missing or invalid expires_in.");
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
accessToken,
|
|
127
|
+
refreshToken,
|
|
128
|
+
expiresAt: Date.now() + expiresIn * 1e3,
|
|
129
|
+
baseUrl: kimiCodeBaseUrl()
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
async function requestDeviceAuthorization() {
|
|
133
|
+
const { status, data } = await postForm("/api/oauth/device_authorization", {
|
|
134
|
+
client_id: CLIENT_ID
|
|
135
|
+
});
|
|
136
|
+
if (status !== 200) {
|
|
137
|
+
throw new Error(`Kimi device authorization failed (${status}): ${errorDetail(data)}`);
|
|
138
|
+
}
|
|
139
|
+
const userCode = data.user_code;
|
|
140
|
+
const deviceCode = data.device_code;
|
|
141
|
+
const verificationUriComplete = data.verification_uri_complete;
|
|
142
|
+
if (typeof userCode !== "string" || typeof deviceCode !== "string") {
|
|
143
|
+
throw new Error("Kimi device authorization response missing user_code/device_code.");
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
userCode,
|
|
147
|
+
deviceCode,
|
|
148
|
+
verificationUri: typeof data.verification_uri === "string" ? data.verification_uri : "",
|
|
149
|
+
verificationUriComplete: typeof verificationUriComplete === "string" ? verificationUriComplete : "",
|
|
150
|
+
interval: Number(data.interval ?? 5) || 5
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
async function pollDeviceToken(deviceCode) {
|
|
154
|
+
const { status, data } = await postForm("/api/oauth/token", {
|
|
155
|
+
client_id: CLIENT_ID,
|
|
156
|
+
device_code: deviceCode,
|
|
157
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code"
|
|
158
|
+
});
|
|
159
|
+
if (status === 200 && typeof data.access_token === "string") {
|
|
160
|
+
return { kind: "success", creds: credsFromTokenResponse(data) };
|
|
161
|
+
}
|
|
162
|
+
if (status >= 500) {
|
|
163
|
+
throw new Error(`Kimi token polling server error (${status}): ${errorDetail(data)}`);
|
|
164
|
+
}
|
|
165
|
+
const errorCode = typeof data.error === "string" ? data.error : "unknown_error";
|
|
166
|
+
switch (errorCode) {
|
|
167
|
+
case "authorization_pending":
|
|
168
|
+
return { kind: "pending" };
|
|
169
|
+
case "slow_down":
|
|
170
|
+
return { kind: "slow_down" };
|
|
171
|
+
case "expired_token":
|
|
172
|
+
return { kind: "expired" };
|
|
173
|
+
case "access_denied":
|
|
174
|
+
return { kind: "denied" };
|
|
175
|
+
default:
|
|
176
|
+
throw new Error(`Kimi token polling failed (${status}): ${errorDetail(data)}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function sleep(ms) {
|
|
180
|
+
return new Promise((resolve) => {
|
|
181
|
+
setTimeout(resolve, ms);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
async function loginKimi(callbacks) {
|
|
185
|
+
const auth = await requestDeviceAuthorization();
|
|
186
|
+
callbacks.onStatus(
|
|
187
|
+
`Visit ${auth.verificationUri || auth.verificationUriComplete} and enter code: ${auth.userCode}`
|
|
188
|
+
);
|
|
189
|
+
callbacks.onOpenUrl(auth.verificationUriComplete || auth.verificationUri);
|
|
190
|
+
callbacks.onStatus("Waiting for you to authorize in the browser...");
|
|
191
|
+
const deadline = Date.now() + DEVICE_TIMEOUT_MS;
|
|
192
|
+
let interval = Math.max(auth.interval, 1);
|
|
193
|
+
while (Date.now() < deadline) {
|
|
194
|
+
await sleep(interval * 1e3);
|
|
195
|
+
const result = await pollDeviceToken(auth.deviceCode);
|
|
196
|
+
if (result.kind === "success") return result.creds;
|
|
197
|
+
if (result.kind === "denied") {
|
|
198
|
+
throw new Error("Kimi authorization was denied.");
|
|
199
|
+
}
|
|
200
|
+
if (result.kind === "expired") {
|
|
201
|
+
throw new Error("Kimi device code expired. Please run login again.");
|
|
202
|
+
}
|
|
203
|
+
if (result.kind === "slow_down") {
|
|
204
|
+
interval += 5;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
throw new Error("Kimi login timed out. Please run login again.");
|
|
208
|
+
}
|
|
209
|
+
async function refreshKimiToken(refreshToken) {
|
|
210
|
+
const { status, data } = await postForm("/api/oauth/token", {
|
|
211
|
+
client_id: CLIENT_ID,
|
|
212
|
+
grant_type: "refresh_token",
|
|
213
|
+
refresh_token: refreshToken
|
|
214
|
+
});
|
|
215
|
+
if (status === 200 && typeof data.access_token === "string") {
|
|
216
|
+
return credsFromTokenResponse(data, { fallbackRefreshToken: refreshToken });
|
|
217
|
+
}
|
|
218
|
+
const errorCode = typeof data.error === "string" ? data.error : "";
|
|
219
|
+
throw new Error(`Kimi token refresh failed (${status}): ${errorCode || errorDetail(data)}`);
|
|
220
|
+
}
|
|
221
|
+
|
|
5
222
|
// src/auth-storage.ts
|
|
6
223
|
import fs4 from "fs/promises";
|
|
224
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
7
225
|
import crypto5 from "crypto";
|
|
8
226
|
|
|
9
227
|
// src/oauth/anthropic.ts
|
|
@@ -29,11 +247,11 @@ async function generatePKCE() {
|
|
|
29
247
|
|
|
30
248
|
// src/claude-code-version.ts
|
|
31
249
|
import fs2 from "fs/promises";
|
|
32
|
-
import
|
|
250
|
+
import path3 from "path";
|
|
33
251
|
|
|
34
252
|
// src/logger.ts
|
|
35
253
|
import fs from "fs";
|
|
36
|
-
import
|
|
254
|
+
import path2 from "path";
|
|
37
255
|
import { randomBytes } from "crypto";
|
|
38
256
|
import { environmentSecrets, redactText, redactValue } from "@kenkaiiii/gg-ai";
|
|
39
257
|
var MAX_BYTES = 10 * 1024 * 1024;
|
|
@@ -62,7 +280,7 @@ function openLog(filePath, name) {
|
|
|
62
280
|
appName = name;
|
|
63
281
|
exactSecrets = environmentSecrets(process.env);
|
|
64
282
|
try {
|
|
65
|
-
fs.mkdirSync(
|
|
283
|
+
fs.mkdirSync(path2.dirname(filePath), { recursive: true, mode: 448 });
|
|
66
284
|
} catch {
|
|
67
285
|
}
|
|
68
286
|
rotateIfNeeded(filePath);
|
|
@@ -161,7 +379,7 @@ var FALLBACK_VERSION = "2.1.88";
|
|
|
161
379
|
var memoryCache = null;
|
|
162
380
|
var inflight = null;
|
|
163
381
|
function cachePath() {
|
|
164
|
-
return
|
|
382
|
+
return path3.join(getAppPaths().agentDir, "claude-code-version.json");
|
|
165
383
|
}
|
|
166
384
|
async function readDiskCache() {
|
|
167
385
|
try {
|
|
@@ -243,7 +461,7 @@ async function getClaudeCliUserAgent() {
|
|
|
243
461
|
}
|
|
244
462
|
|
|
245
463
|
// src/oauth/anthropic.ts
|
|
246
|
-
var
|
|
464
|
+
var CLIENT_ID2 = atob("OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl");
|
|
247
465
|
var AUTHORIZE_URL = "https://claude.ai/oauth/authorize";
|
|
248
466
|
var TOKEN_URLS = [
|
|
249
467
|
"https://platform.claude.com/v1/oauth/token",
|
|
@@ -290,7 +508,7 @@ async function loginAnthropic(callbacks) {
|
|
|
290
508
|
const state = crypto2.randomBytes(16).toString("hex");
|
|
291
509
|
const params = new URLSearchParams({
|
|
292
510
|
code: "true",
|
|
293
|
-
client_id:
|
|
511
|
+
client_id: CLIENT_ID2,
|
|
294
512
|
response_type: "code",
|
|
295
513
|
redirect_uri: REDIRECT_URI,
|
|
296
514
|
scope: SCOPES,
|
|
@@ -311,7 +529,7 @@ async function exchangeAnthropicCode(code, state, verifier) {
|
|
|
311
529
|
const data = await postTokenRequest(
|
|
312
530
|
{
|
|
313
531
|
grant_type: "authorization_code",
|
|
314
|
-
client_id:
|
|
532
|
+
client_id: CLIENT_ID2,
|
|
315
533
|
code,
|
|
316
534
|
state,
|
|
317
535
|
redirect_uri: REDIRECT_URI,
|
|
@@ -325,7 +543,7 @@ async function refreshAnthropicToken(refreshToken) {
|
|
|
325
543
|
const data = await postTokenRequest(
|
|
326
544
|
{
|
|
327
545
|
grant_type: "refresh_token",
|
|
328
|
-
client_id:
|
|
546
|
+
client_id: CLIENT_ID2,
|
|
329
547
|
refresh_token: refreshToken
|
|
330
548
|
},
|
|
331
549
|
"token refresh"
|
|
@@ -336,7 +554,7 @@ async function refreshAnthropicToken(refreshToken) {
|
|
|
336
554
|
// src/oauth/openai.ts
|
|
337
555
|
import http from "http";
|
|
338
556
|
import crypto3 from "crypto";
|
|
339
|
-
var
|
|
557
|
+
var CLIENT_ID3 = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
340
558
|
var AUTHORIZE_URL2 = "https://auth.openai.com/oauth/authorize";
|
|
341
559
|
var TOKEN_URL = "https://auth.openai.com/oauth/token";
|
|
342
560
|
var REDIRECT_URI2 = "http://localhost:1455/auth/callback";
|
|
@@ -347,7 +565,7 @@ async function loginOpenAI(callbacks) {
|
|
|
347
565
|
const state = crypto3.randomBytes(16).toString("hex");
|
|
348
566
|
const url = new URL(AUTHORIZE_URL2);
|
|
349
567
|
url.searchParams.set("response_type", "code");
|
|
350
|
-
url.searchParams.set("client_id",
|
|
568
|
+
url.searchParams.set("client_id", CLIENT_ID3);
|
|
351
569
|
url.searchParams.set("redirect_uri", REDIRECT_URI2);
|
|
352
570
|
url.searchParams.set("scope", SCOPE);
|
|
353
571
|
url.searchParams.set("code_challenge", challenge);
|
|
@@ -468,7 +686,7 @@ async function exchangeOpenAICode(code, verifier) {
|
|
|
468
686
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
469
687
|
body: new URLSearchParams({
|
|
470
688
|
grant_type: "authorization_code",
|
|
471
|
-
client_id:
|
|
689
|
+
client_id: CLIENT_ID3,
|
|
472
690
|
code,
|
|
473
691
|
redirect_uri: REDIRECT_URI2,
|
|
474
692
|
code_verifier: verifier
|
|
@@ -492,7 +710,7 @@ async function refreshOpenAIToken(refreshToken) {
|
|
|
492
710
|
body: new URLSearchParams({
|
|
493
711
|
grant_type: "refresh_token",
|
|
494
712
|
refresh_token: refreshToken,
|
|
495
|
-
client_id:
|
|
713
|
+
client_id: CLIENT_ID3
|
|
496
714
|
})
|
|
497
715
|
});
|
|
498
716
|
if (!response.ok) {
|
|
@@ -875,223 +1093,6 @@ function codeAssistHeaders(accessToken) {
|
|
|
875
1093
|
};
|
|
876
1094
|
}
|
|
877
1095
|
|
|
878
|
-
// src/oauth/kimi.ts
|
|
879
|
-
import { execFileSync } from "child_process";
|
|
880
|
-
import { randomUUID } from "crypto";
|
|
881
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
882
|
-
import { arch, hostname, release, type } from "os";
|
|
883
|
-
import path3 from "path";
|
|
884
|
-
var CLIENT_ID3 = "17e5f671-d194-4dfb-9706-5516cb48c098";
|
|
885
|
-
var DEFAULT_OAUTH_HOST = "https://auth.kimi.com";
|
|
886
|
-
var DEFAULT_CODING_BASE_URL = "https://api.kimi.com/coding/v1";
|
|
887
|
-
var KIMI_PLATFORM = "kimi_code_cli";
|
|
888
|
-
var DEFAULT_KIMI_VERSION = "1.0.11";
|
|
889
|
-
var DEVICE_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
890
|
-
function oauthHost() {
|
|
891
|
-
const host = process.env.KIMI_CODE_OAUTH_HOST ?? process.env.KIMI_OAUTH_HOST ?? DEFAULT_OAUTH_HOST;
|
|
892
|
-
return host.replace(/\/+$/, "");
|
|
893
|
-
}
|
|
894
|
-
function kimiCodeBaseUrl() {
|
|
895
|
-
return (process.env.KIMI_CODE_BASE_URL ?? DEFAULT_CODING_BASE_URL).replace(/\/+$/, "");
|
|
896
|
-
}
|
|
897
|
-
function kimiVersion() {
|
|
898
|
-
const v = process.env.KIMI_CODE_VERSION ?? DEFAULT_KIMI_VERSION;
|
|
899
|
-
return asciiHeader(v, DEFAULT_KIMI_VERSION);
|
|
900
|
-
}
|
|
901
|
-
function asciiHeader(value, fallback = "unknown") {
|
|
902
|
-
const cleaned = value.replace(/[^\u0020-\u007E]/g, "").trim();
|
|
903
|
-
return cleaned.length > 0 ? cleaned : fallback;
|
|
904
|
-
}
|
|
905
|
-
function macOsProductVersion() {
|
|
906
|
-
try {
|
|
907
|
-
const version = execFileSync("/usr/bin/sw_vers", ["-productVersion"], {
|
|
908
|
-
encoding: "utf-8",
|
|
909
|
-
timeout: 1e3
|
|
910
|
-
}).trim();
|
|
911
|
-
return version.length > 0 ? version : void 0;
|
|
912
|
-
} catch {
|
|
913
|
-
return void 0;
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
function deviceModel() {
|
|
917
|
-
const os = type();
|
|
918
|
-
const version = release();
|
|
919
|
-
const osArch = arch();
|
|
920
|
-
if (os === "Darwin") return `macOS ${macOsProductVersion() ?? version} ${osArch}`;
|
|
921
|
-
if (os === "Windows_NT") return `Windows ${version} ${osArch}`;
|
|
922
|
-
return `${os} ${version} ${osArch}`.trim();
|
|
923
|
-
}
|
|
924
|
-
function deviceId() {
|
|
925
|
-
const idPath = path3.join(getAppPaths().agentDir, "kimi_device_id");
|
|
926
|
-
if (existsSync(idPath)) {
|
|
927
|
-
try {
|
|
928
|
-
const text = readFileSync(idPath, "utf-8").trim();
|
|
929
|
-
if (text.length > 0) return text;
|
|
930
|
-
} catch {
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
const id = randomUUID();
|
|
934
|
-
try {
|
|
935
|
-
mkdirSync(getAppPaths().agentDir, { recursive: true, mode: 448 });
|
|
936
|
-
writeFileSync(idPath, id, { encoding: "utf-8", mode: 384 });
|
|
937
|
-
} catch {
|
|
938
|
-
}
|
|
939
|
-
return id;
|
|
940
|
-
}
|
|
941
|
-
function deviceHeaders() {
|
|
942
|
-
return {
|
|
943
|
-
"X-Msh-Platform": KIMI_PLATFORM,
|
|
944
|
-
"X-Msh-Version": kimiVersion(),
|
|
945
|
-
"X-Msh-Device-Name": asciiHeader(hostname()),
|
|
946
|
-
"X-Msh-Device-Model": asciiHeader(deviceModel()),
|
|
947
|
-
"X-Msh-Os-Version": asciiHeader(release()),
|
|
948
|
-
"X-Msh-Device-Id": deviceId()
|
|
949
|
-
};
|
|
950
|
-
}
|
|
951
|
-
function kimiCodingHeaders() {
|
|
952
|
-
return {
|
|
953
|
-
"User-Agent": `kimi-code-cli/${kimiVersion()}`,
|
|
954
|
-
...deviceHeaders()
|
|
955
|
-
};
|
|
956
|
-
}
|
|
957
|
-
function isKimiCodingEndpoint(baseUrl) {
|
|
958
|
-
if (typeof baseUrl !== "string" || baseUrl.length === 0) return false;
|
|
959
|
-
const normalized = baseUrl.replace(/\/+$/, "");
|
|
960
|
-
return normalized === kimiCodeBaseUrl() || /(^|\.)kimi\.com/i.test(normalized);
|
|
961
|
-
}
|
|
962
|
-
async function postForm(endpoint, params) {
|
|
963
|
-
const response = await fetch(`${oauthHost()}${endpoint}`, {
|
|
964
|
-
method: "POST",
|
|
965
|
-
headers: {
|
|
966
|
-
...deviceHeaders(),
|
|
967
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
968
|
-
Accept: "application/json"
|
|
969
|
-
},
|
|
970
|
-
body: new URLSearchParams(params).toString()
|
|
971
|
-
});
|
|
972
|
-
let data = {};
|
|
973
|
-
try {
|
|
974
|
-
const parsed = await response.json();
|
|
975
|
-
if (parsed && typeof parsed === "object") data = parsed;
|
|
976
|
-
} catch {
|
|
977
|
-
}
|
|
978
|
-
return { status: response.status, data };
|
|
979
|
-
}
|
|
980
|
-
function errorDetail(data) {
|
|
981
|
-
const desc = data.error_description ?? data.message ?? data.error;
|
|
982
|
-
return typeof desc === "string" && desc.length > 0 ? desc : "unknown error";
|
|
983
|
-
}
|
|
984
|
-
function credsFromTokenResponse(data, opts) {
|
|
985
|
-
const accessToken = data.access_token;
|
|
986
|
-
const responseRefreshToken = data.refresh_token;
|
|
987
|
-
const expiresIn = Number(data.expires_in);
|
|
988
|
-
if (typeof accessToken !== "string" || accessToken.length === 0) {
|
|
989
|
-
throw new Error("Kimi OAuth response missing access_token.");
|
|
990
|
-
}
|
|
991
|
-
const refreshToken = typeof responseRefreshToken === "string" && responseRefreshToken.length > 0 ? responseRefreshToken : opts?.fallbackRefreshToken ?? "";
|
|
992
|
-
if (refreshToken.length === 0) {
|
|
993
|
-
throw new Error("Kimi OAuth response missing refresh_token.");
|
|
994
|
-
}
|
|
995
|
-
if (!Number.isFinite(expiresIn) || expiresIn <= 0) {
|
|
996
|
-
throw new Error("Kimi OAuth response missing or invalid expires_in.");
|
|
997
|
-
}
|
|
998
|
-
return {
|
|
999
|
-
accessToken,
|
|
1000
|
-
refreshToken,
|
|
1001
|
-
expiresAt: Date.now() + expiresIn * 1e3,
|
|
1002
|
-
baseUrl: kimiCodeBaseUrl()
|
|
1003
|
-
};
|
|
1004
|
-
}
|
|
1005
|
-
async function requestDeviceAuthorization() {
|
|
1006
|
-
const { status, data } = await postForm("/api/oauth/device_authorization", {
|
|
1007
|
-
client_id: CLIENT_ID3
|
|
1008
|
-
});
|
|
1009
|
-
if (status !== 200) {
|
|
1010
|
-
throw new Error(`Kimi device authorization failed (${status}): ${errorDetail(data)}`);
|
|
1011
|
-
}
|
|
1012
|
-
const userCode = data.user_code;
|
|
1013
|
-
const deviceCode = data.device_code;
|
|
1014
|
-
const verificationUriComplete = data.verification_uri_complete;
|
|
1015
|
-
if (typeof userCode !== "string" || typeof deviceCode !== "string") {
|
|
1016
|
-
throw new Error("Kimi device authorization response missing user_code/device_code.");
|
|
1017
|
-
}
|
|
1018
|
-
return {
|
|
1019
|
-
userCode,
|
|
1020
|
-
deviceCode,
|
|
1021
|
-
verificationUri: typeof data.verification_uri === "string" ? data.verification_uri : "",
|
|
1022
|
-
verificationUriComplete: typeof verificationUriComplete === "string" ? verificationUriComplete : "",
|
|
1023
|
-
interval: Number(data.interval ?? 5) || 5
|
|
1024
|
-
};
|
|
1025
|
-
}
|
|
1026
|
-
async function pollDeviceToken(deviceCode) {
|
|
1027
|
-
const { status, data } = await postForm("/api/oauth/token", {
|
|
1028
|
-
client_id: CLIENT_ID3,
|
|
1029
|
-
device_code: deviceCode,
|
|
1030
|
-
grant_type: "urn:ietf:params:oauth:grant-type:device_code"
|
|
1031
|
-
});
|
|
1032
|
-
if (status === 200 && typeof data.access_token === "string") {
|
|
1033
|
-
return { kind: "success", creds: credsFromTokenResponse(data) };
|
|
1034
|
-
}
|
|
1035
|
-
if (status >= 500) {
|
|
1036
|
-
throw new Error(`Kimi token polling server error (${status}): ${errorDetail(data)}`);
|
|
1037
|
-
}
|
|
1038
|
-
const errorCode = typeof data.error === "string" ? data.error : "unknown_error";
|
|
1039
|
-
switch (errorCode) {
|
|
1040
|
-
case "authorization_pending":
|
|
1041
|
-
return { kind: "pending" };
|
|
1042
|
-
case "slow_down":
|
|
1043
|
-
return { kind: "slow_down" };
|
|
1044
|
-
case "expired_token":
|
|
1045
|
-
return { kind: "expired" };
|
|
1046
|
-
case "access_denied":
|
|
1047
|
-
return { kind: "denied" };
|
|
1048
|
-
default:
|
|
1049
|
-
throw new Error(`Kimi token polling failed (${status}): ${errorDetail(data)}`);
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1052
|
-
function sleep(ms) {
|
|
1053
|
-
return new Promise((resolve) => {
|
|
1054
|
-
setTimeout(resolve, ms);
|
|
1055
|
-
});
|
|
1056
|
-
}
|
|
1057
|
-
async function loginKimi(callbacks) {
|
|
1058
|
-
const auth = await requestDeviceAuthorization();
|
|
1059
|
-
callbacks.onStatus(
|
|
1060
|
-
`Visit ${auth.verificationUri || auth.verificationUriComplete} and enter code: ${auth.userCode}`
|
|
1061
|
-
);
|
|
1062
|
-
callbacks.onOpenUrl(auth.verificationUriComplete || auth.verificationUri);
|
|
1063
|
-
callbacks.onStatus("Waiting for you to authorize in the browser...");
|
|
1064
|
-
const deadline = Date.now() + DEVICE_TIMEOUT_MS;
|
|
1065
|
-
let interval = Math.max(auth.interval, 1);
|
|
1066
|
-
while (Date.now() < deadline) {
|
|
1067
|
-
await sleep(interval * 1e3);
|
|
1068
|
-
const result = await pollDeviceToken(auth.deviceCode);
|
|
1069
|
-
if (result.kind === "success") return result.creds;
|
|
1070
|
-
if (result.kind === "denied") {
|
|
1071
|
-
throw new Error("Kimi authorization was denied.");
|
|
1072
|
-
}
|
|
1073
|
-
if (result.kind === "expired") {
|
|
1074
|
-
throw new Error("Kimi device code expired. Please run login again.");
|
|
1075
|
-
}
|
|
1076
|
-
if (result.kind === "slow_down") {
|
|
1077
|
-
interval += 5;
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
throw new Error("Kimi login timed out. Please run login again.");
|
|
1081
|
-
}
|
|
1082
|
-
async function refreshKimiToken(refreshToken) {
|
|
1083
|
-
const { status, data } = await postForm("/api/oauth/token", {
|
|
1084
|
-
client_id: CLIENT_ID3,
|
|
1085
|
-
grant_type: "refresh_token",
|
|
1086
|
-
refresh_token: refreshToken
|
|
1087
|
-
});
|
|
1088
|
-
if (status === 200 && typeof data.access_token === "string") {
|
|
1089
|
-
return credsFromTokenResponse(data, { fallbackRefreshToken: refreshToken });
|
|
1090
|
-
}
|
|
1091
|
-
const errorCode = typeof data.error === "string" ? data.error : "";
|
|
1092
|
-
throw new Error(`Kimi token refresh failed (${status}): ${errorCode || errorDetail(data)}`);
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
1096
|
// src/file-lock.ts
|
|
1096
1097
|
import fs3 from "fs/promises";
|
|
1097
1098
|
import { setTimeout as setTimeout2 } from "timers/promises";
|
|
@@ -1157,6 +1158,26 @@ function isAlive(pid) {
|
|
|
1157
1158
|
// src/auth-storage.ts
|
|
1158
1159
|
var MOONSHOT_OAUTH_KEY = "moonshot-oauth";
|
|
1159
1160
|
var XIAOMI_CREDITS_KEY = "xiaomi-credits";
|
|
1161
|
+
function activeBaseUrlEntry(data, provider) {
|
|
1162
|
+
if (provider === "moonshot") {
|
|
1163
|
+
const oauth = data[MOONSHOT_OAUTH_KEY];
|
|
1164
|
+
if (oauth) {
|
|
1165
|
+
const exhaustedUntil = oauth.usageExhaustedUntil ?? 0;
|
|
1166
|
+
if (Date.now() < exhaustedUntil && data["moonshot"]) return data["moonshot"];
|
|
1167
|
+
return oauth;
|
|
1168
|
+
}
|
|
1169
|
+
return data["moonshot"];
|
|
1170
|
+
}
|
|
1171
|
+
return data[provider];
|
|
1172
|
+
}
|
|
1173
|
+
function readStoredBaseUrlSync(authFile, provider) {
|
|
1174
|
+
try {
|
|
1175
|
+
const data = JSON.parse(readFileSync2(authFile, "utf-8"));
|
|
1176
|
+
return activeBaseUrlEntry(data, provider)?.baseUrl;
|
|
1177
|
+
} catch {
|
|
1178
|
+
return void 0;
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1160
1181
|
var REFRESH_SKEW_MS = 6e4;
|
|
1161
1182
|
var USAGE_EXHAUSTED_DEFAULT_MS = 15 * 60 * 1e3;
|
|
1162
1183
|
var STATIC_API_KEY_PROVIDERS = /* @__PURE__ */ new Set([
|
|
@@ -1232,6 +1253,16 @@ var AuthStorage = class {
|
|
|
1232
1253
|
}
|
|
1233
1254
|
return STATIC_API_KEY_PROVIDERS.has(provider);
|
|
1234
1255
|
}
|
|
1256
|
+
/**
|
|
1257
|
+
* The base URL on the credential that is active right now, if any.
|
|
1258
|
+
* Synchronous — call only after load()/resolveCredentials() populated the
|
|
1259
|
+
* snapshot. For `moonshot` this is the Kimi For Coding URL whenever the
|
|
1260
|
+
* OAuth entry is the one resolveCredentials would serve (i.e. not currently
|
|
1261
|
+
* usage-exhausted with an API key configured).
|
|
1262
|
+
*/
|
|
1263
|
+
getStoredBaseUrl(provider) {
|
|
1264
|
+
return activeBaseUrlEntry(this.data, provider)?.baseUrl;
|
|
1265
|
+
}
|
|
1235
1266
|
async load() {
|
|
1236
1267
|
await withFileLock(this.filePath, async () => {
|
|
1237
1268
|
try {
|
|
@@ -1260,19 +1291,40 @@ var AuthStorage = class {
|
|
|
1260
1291
|
async ensureLoaded() {
|
|
1261
1292
|
if (!this.loaded) await this.load();
|
|
1262
1293
|
}
|
|
1294
|
+
/**
|
|
1295
|
+
* Apply one provider-scoped mutation to the latest on-disk snapshot.
|
|
1296
|
+
* AuthStorage instances live in every app session/process, so writing this
|
|
1297
|
+
* instance's cached snapshot can erase credentials another instance just
|
|
1298
|
+
* added. The file lock only serializes writers; the re-read prevents stale
|
|
1299
|
+
* full-file overwrites.
|
|
1300
|
+
*/
|
|
1301
|
+
async mutateLatest(mutator) {
|
|
1302
|
+
await this.ensureLoaded();
|
|
1303
|
+
await withFileLock(this.filePath, async () => {
|
|
1304
|
+
const latest = await readAuthData(this.filePath);
|
|
1305
|
+
mutator(latest);
|
|
1306
|
+
await atomicWriteFile(this.filePath, JSON.stringify(latest, null, 2));
|
|
1307
|
+
this.data = latest;
|
|
1308
|
+
});
|
|
1309
|
+
}
|
|
1310
|
+
async reloadLatest() {
|
|
1311
|
+
await withFileLock(this.filePath, async () => {
|
|
1312
|
+
this.data = await readAuthData(this.filePath);
|
|
1313
|
+
});
|
|
1314
|
+
}
|
|
1263
1315
|
async getCredentials(provider) {
|
|
1264
1316
|
await this.ensureLoaded();
|
|
1265
1317
|
return this.data[provider];
|
|
1266
1318
|
}
|
|
1267
1319
|
async setCredentials(provider, creds) {
|
|
1268
|
-
await this.
|
|
1269
|
-
|
|
1270
|
-
|
|
1320
|
+
await this.mutateLatest((latest) => {
|
|
1321
|
+
latest[provider] = creds;
|
|
1322
|
+
});
|
|
1271
1323
|
}
|
|
1272
1324
|
async clearCredentials(provider) {
|
|
1273
|
-
await this.
|
|
1274
|
-
|
|
1275
|
-
|
|
1325
|
+
await this.mutateLatest((latest) => {
|
|
1326
|
+
delete latest[provider];
|
|
1327
|
+
});
|
|
1276
1328
|
}
|
|
1277
1329
|
/**
|
|
1278
1330
|
* Mark the credential stored under `storageKey` as usage-exhausted until
|
|
@@ -1286,12 +1338,15 @@ var AuthStorage = class {
|
|
|
1286
1338
|
* nothing is stored under `storageKey`.
|
|
1287
1339
|
*/
|
|
1288
1340
|
async markUsageExhausted(storageKey, resetsAt) {
|
|
1289
|
-
await this.ensureLoaded();
|
|
1290
|
-
const creds = this.data[storageKey];
|
|
1291
|
-
if (!creds) return;
|
|
1292
1341
|
const until = resetsAt !== void 0 && resetsAt * 1e3 > Date.now() ? resetsAt * 1e3 : Date.now() + USAGE_EXHAUSTED_DEFAULT_MS;
|
|
1293
|
-
|
|
1294
|
-
await this.
|
|
1342
|
+
let marked = false;
|
|
1343
|
+
await this.mutateLatest((latest) => {
|
|
1344
|
+
const creds = latest[storageKey];
|
|
1345
|
+
if (!creds) return;
|
|
1346
|
+
creds.usageExhaustedUntil = until;
|
|
1347
|
+
marked = true;
|
|
1348
|
+
});
|
|
1349
|
+
if (!marked) return;
|
|
1295
1350
|
log(
|
|
1296
1351
|
"WARN",
|
|
1297
1352
|
"auth",
|
|
@@ -1299,8 +1354,11 @@ var AuthStorage = class {
|
|
|
1299
1354
|
);
|
|
1300
1355
|
}
|
|
1301
1356
|
async clearAll() {
|
|
1302
|
-
this.
|
|
1303
|
-
await this.
|
|
1357
|
+
await this.ensureLoaded();
|
|
1358
|
+
await withFileLock(this.filePath, async () => {
|
|
1359
|
+
this.data = {};
|
|
1360
|
+
await atomicWriteFile(this.filePath, JSON.stringify(this.data, null, 2));
|
|
1361
|
+
});
|
|
1304
1362
|
}
|
|
1305
1363
|
/**
|
|
1306
1364
|
* Returns valid credentials, auto-refreshing if expired.
|
|
@@ -1310,6 +1368,10 @@ var AuthStorage = class {
|
|
|
1310
1368
|
*/
|
|
1311
1369
|
async resolveCredentials(provider, opts) {
|
|
1312
1370
|
await this.ensureLoaded();
|
|
1371
|
+
const directStorageKeys = opts?.storageKeys && !(opts.storageKeys.length === 1 && opts.storageKeys[0] === provider) ? opts.storageKeys : provider === "moonshot" ? [MOONSHOT_OAUTH_KEY, "moonshot"] : [provider];
|
|
1372
|
+
if (!directStorageKeys.some((key) => Boolean(this.data[key]))) {
|
|
1373
|
+
await this.reloadLatest();
|
|
1374
|
+
}
|
|
1313
1375
|
if (opts?.storageKeys && !(opts.storageKeys.length === 1 && opts.storageKeys[0] === provider)) {
|
|
1314
1376
|
for (const key of opts.storageKeys) {
|
|
1315
1377
|
const creds2 = this.data[key];
|
|
@@ -1356,41 +1418,44 @@ var AuthStorage = class {
|
|
|
1356
1418
|
const existing = this.refreshLocks.get(provider);
|
|
1357
1419
|
if (existing) return existing;
|
|
1358
1420
|
const refreshPromise = withFileLock(this.filePath, async () => {
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1421
|
+
const latest = await readAuthData(this.filePath);
|
|
1422
|
+
const latestCreds = latest[provider];
|
|
1423
|
+
if (!latestCreds) {
|
|
1424
|
+
this.data = latest;
|
|
1425
|
+
throw new NotLoggedInError(provider);
|
|
1426
|
+
}
|
|
1427
|
+
const credentialWasReplaced = latestCreds.accessToken !== creds.accessToken || latestCreds.refreshToken !== creds.refreshToken || latestCreds.expiresAt !== creds.expiresAt;
|
|
1428
|
+
if (credentialWasReplaced || !opts?.forceRefresh && Date.now() < latestCreds.expiresAt - REFRESH_SKEW_MS) {
|
|
1429
|
+
this.data = latest;
|
|
1430
|
+
return latestCreds;
|
|
1368
1431
|
}
|
|
1369
1432
|
const refreshFn = provider === "anthropic" ? refreshAnthropicToken : provider === "gemini" ? refreshGeminiToken : provider === MOONSHOT_OAUTH_KEY ? refreshKimiToken : refreshOpenAIToken;
|
|
1370
1433
|
let refreshed;
|
|
1371
1434
|
try {
|
|
1372
|
-
refreshed = await refreshFn(
|
|
1435
|
+
refreshed = await refreshFn(latestCreds.refreshToken);
|
|
1373
1436
|
} catch (err) {
|
|
1374
1437
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1375
1438
|
const isAuthFailure = /\((401|400)\)/.test(msg) || /invalid_grant|invalid_token|invalid.*refresh/i.test(msg) || /unauthorized/i.test(msg);
|
|
1376
1439
|
if (isAuthFailure) {
|
|
1377
|
-
delete
|
|
1378
|
-
|
|
1440
|
+
delete latest[provider];
|
|
1441
|
+
this.data = latest;
|
|
1442
|
+
await atomicWriteFile(this.filePath, JSON.stringify(latest, null, 2));
|
|
1379
1443
|
throw new NotLoggedInError(provider);
|
|
1380
1444
|
}
|
|
1381
1445
|
throw err;
|
|
1382
1446
|
}
|
|
1383
|
-
if (!refreshed.accountId &&
|
|
1384
|
-
refreshed.accountId =
|
|
1447
|
+
if (!refreshed.accountId && latestCreds.accountId) {
|
|
1448
|
+
refreshed.accountId = latestCreds.accountId;
|
|
1385
1449
|
}
|
|
1386
|
-
if (!refreshed.projectId &&
|
|
1387
|
-
refreshed.projectId =
|
|
1450
|
+
if (!refreshed.projectId && latestCreds.projectId) {
|
|
1451
|
+
refreshed.projectId = latestCreds.projectId;
|
|
1388
1452
|
}
|
|
1389
|
-
if (!refreshed.baseUrl &&
|
|
1390
|
-
refreshed.baseUrl =
|
|
1453
|
+
if (!refreshed.baseUrl && latestCreds.baseUrl) {
|
|
1454
|
+
refreshed.baseUrl = latestCreds.baseUrl;
|
|
1391
1455
|
}
|
|
1392
|
-
|
|
1393
|
-
|
|
1456
|
+
latest[provider] = refreshed;
|
|
1457
|
+
this.data = latest;
|
|
1458
|
+
await atomicWriteFile(this.filePath, JSON.stringify(latest, null, 2));
|
|
1394
1459
|
return refreshed;
|
|
1395
1460
|
});
|
|
1396
1461
|
this.refreshLocks.set(provider, refreshPromise);
|
|
@@ -1408,12 +1473,16 @@ var AuthStorage = class {
|
|
|
1408
1473
|
const creds = await this.resolveCredentials(provider);
|
|
1409
1474
|
return creds.accessToken;
|
|
1410
1475
|
}
|
|
1411
|
-
async save() {
|
|
1412
|
-
await withFileLock(this.filePath, async () => {
|
|
1413
|
-
await atomicWriteFile(this.filePath, JSON.stringify(this.data, null, 2));
|
|
1414
|
-
});
|
|
1415
|
-
}
|
|
1416
1476
|
};
|
|
1477
|
+
async function readAuthData(filePath) {
|
|
1478
|
+
try {
|
|
1479
|
+
const content = await fs4.readFile(filePath, "utf-8");
|
|
1480
|
+
return JSON.parse(content);
|
|
1481
|
+
} catch (error) {
|
|
1482
|
+
if (error.code === "ENOENT") return {};
|
|
1483
|
+
throw error;
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1417
1486
|
async function atomicWriteFile(filePath, content) {
|
|
1418
1487
|
const tmpPath = `${filePath}.${process.pid}.${Date.now()}.${crypto5.randomUUID().slice(0, 8)}.tmp`;
|
|
1419
1488
|
try {
|
|
@@ -1668,8 +1737,9 @@ var MODELS = [
|
|
|
1668
1737
|
},
|
|
1669
1738
|
// ── Moonshot (Kimi) ────────────────────────────────────
|
|
1670
1739
|
// K3 is Kimi's 2.8T-parameter flagship for long-horizon coding, knowledge
|
|
1671
|
-
// work, and deep reasoning.
|
|
1672
|
-
//
|
|
1740
|
+
// work, and deep reasoning. Its effort ladder is server-declared as
|
|
1741
|
+
// low/high/max on both the public API (default max) and the Kimi For Coding
|
|
1742
|
+
// OAuth endpoint (default high); thinking can also be fully disabled.
|
|
1673
1743
|
{
|
|
1674
1744
|
id: "kimi-k3",
|
|
1675
1745
|
name: "Kimi K3",
|
|
@@ -1903,6 +1973,11 @@ function getContextWindow(modelId, options) {
|
|
|
1903
1973
|
function getMaxThinkingLevel(modelId) {
|
|
1904
1974
|
return getModel(modelId)?.maxThinkingLevel ?? "high";
|
|
1905
1975
|
}
|
|
1976
|
+
function getDefaultThinkingLevel(modelId, options) {
|
|
1977
|
+
const model = getModel(modelId);
|
|
1978
|
+
if (model?.id === "kimi-k3" && isKimiCodingEndpoint(options?.baseUrl)) return "high";
|
|
1979
|
+
return model?.maxThinkingLevel ?? "high";
|
|
1980
|
+
}
|
|
1906
1981
|
function getSummaryModel(provider, currentModelId) {
|
|
1907
1982
|
if (provider === "anthropic") {
|
|
1908
1983
|
return MODELS.find((m) => m.id === "claude-sonnet-5");
|
|
@@ -1919,6 +1994,11 @@ function getFastModel(provider, currentModelId) {
|
|
|
1919
1994
|
}
|
|
1920
1995
|
|
|
1921
1996
|
export {
|
|
1997
|
+
kimiCodeBaseUrl,
|
|
1998
|
+
kimiCodingHeaders,
|
|
1999
|
+
isKimiCodingEndpoint,
|
|
2000
|
+
loginKimi,
|
|
2001
|
+
refreshKimiToken,
|
|
1922
2002
|
generatePKCE,
|
|
1923
2003
|
openLog,
|
|
1924
2004
|
getSessionId,
|
|
@@ -1934,14 +2014,10 @@ export {
|
|
|
1934
2014
|
refreshOpenAIToken,
|
|
1935
2015
|
loginGemini,
|
|
1936
2016
|
refreshGeminiToken,
|
|
1937
|
-
kimiCodeBaseUrl,
|
|
1938
|
-
kimiCodingHeaders,
|
|
1939
|
-
isKimiCodingEndpoint,
|
|
1940
|
-
loginKimi,
|
|
1941
|
-
refreshKimiToken,
|
|
1942
2017
|
withFileLock,
|
|
1943
2018
|
MOONSHOT_OAUTH_KEY,
|
|
1944
2019
|
XIAOMI_CREDITS_KEY,
|
|
2020
|
+
readStoredBaseUrlSync,
|
|
1945
2021
|
AuthStorage,
|
|
1946
2022
|
NotLoggedInError,
|
|
1947
2023
|
MODELS,
|
|
@@ -1956,7 +2032,8 @@ export {
|
|
|
1956
2032
|
getToolResultCharLimit,
|
|
1957
2033
|
getContextWindow,
|
|
1958
2034
|
getMaxThinkingLevel,
|
|
2035
|
+
getDefaultThinkingLevel,
|
|
1959
2036
|
getSummaryModel,
|
|
1960
2037
|
getFastModel
|
|
1961
2038
|
};
|
|
1962
|
-
//# sourceMappingURL=chunk-
|
|
2039
|
+
//# sourceMappingURL=chunk-TST5LJWL.js.map
|