@kenkaiiii/gg-core 4.4.0 → 4.5.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-USAVZGPP.js → chunk-LLWQ3Z76.js} +13 -1
- package/dist/chunk-LLWQ3Z76.js.map +1 -0
- package/dist/index.cjs +298 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +66 -2
- package/dist/index.d.ts +66 -2
- package/dist/index.js +276 -7
- package/dist/index.js.map +1 -1
- package/dist/model-registry.cjs +14 -0
- package/dist/model-registry.cjs.map +1 -1
- package/dist/model-registry.d.cts +19 -1
- package/dist/model-registry.d.ts +19 -1
- package/dist/model-registry.js +5 -1
- package/package.json +2 -2
- package/dist/chunk-USAVZGPP.js.map +0 -1
|
@@ -98,6 +98,7 @@ var MODELS = [
|
|
|
98
98
|
supportsThinking: true,
|
|
99
99
|
supportsImages: true,
|
|
100
100
|
supportsVideo: true,
|
|
101
|
+
maxVideoBytes: 20 * 1024 * 1024,
|
|
101
102
|
costTier: "low",
|
|
102
103
|
maxThinkingLevel: "high"
|
|
103
104
|
},
|
|
@@ -110,6 +111,7 @@ var MODELS = [
|
|
|
110
111
|
supportsThinking: true,
|
|
111
112
|
supportsImages: true,
|
|
112
113
|
supportsVideo: true,
|
|
114
|
+
maxVideoBytes: 20 * 1024 * 1024,
|
|
113
115
|
costTier: "low",
|
|
114
116
|
maxThinkingLevel: "high"
|
|
115
117
|
},
|
|
@@ -123,6 +125,7 @@ var MODELS = [
|
|
|
123
125
|
supportsThinking: true,
|
|
124
126
|
supportsImages: true,
|
|
125
127
|
supportsVideo: true,
|
|
128
|
+
maxVideoBytes: 100 * 1024 * 1024,
|
|
126
129
|
costTier: "medium",
|
|
127
130
|
maxThinkingLevel: "high"
|
|
128
131
|
},
|
|
@@ -173,6 +176,7 @@ var MODELS = [
|
|
|
173
176
|
supportsThinking: true,
|
|
174
177
|
supportsImages: true,
|
|
175
178
|
supportsVideo: true,
|
|
179
|
+
maxVideoBytes: 50 * 1024 * 1024,
|
|
176
180
|
costTier: "medium",
|
|
177
181
|
maxThinkingLevel: "high"
|
|
178
182
|
},
|
|
@@ -235,6 +239,12 @@ function getModel(id) {
|
|
|
235
239
|
function getModelsForProvider(provider) {
|
|
236
240
|
return MODELS.filter((m) => m.provider === provider);
|
|
237
241
|
}
|
|
242
|
+
var DEFAULT_MAX_VIDEO_BYTES = 20 * 1024 * 1024;
|
|
243
|
+
function getVideoByteLimit(modelId) {
|
|
244
|
+
const model = getModel(modelId);
|
|
245
|
+
if (!model?.supportsVideo) return void 0;
|
|
246
|
+
return model.maxVideoBytes ?? DEFAULT_MAX_VIDEO_BYTES;
|
|
247
|
+
}
|
|
238
248
|
function getDefaultModel(provider) {
|
|
239
249
|
if (provider === "xiaomi") return MODELS.find((m) => m.id === "mimo-v2-pro");
|
|
240
250
|
if (provider === "openai") return MODELS.find((m) => m.id === "gpt-5.5");
|
|
@@ -275,10 +285,12 @@ export {
|
|
|
275
285
|
MODELS,
|
|
276
286
|
getModel,
|
|
277
287
|
getModelsForProvider,
|
|
288
|
+
DEFAULT_MAX_VIDEO_BYTES,
|
|
289
|
+
getVideoByteLimit,
|
|
278
290
|
getDefaultModel,
|
|
279
291
|
usesOpenAICodexTransport,
|
|
280
292
|
getContextWindow,
|
|
281
293
|
getMaxThinkingLevel,
|
|
282
294
|
getSummaryModel
|
|
283
295
|
};
|
|
284
|
-
//# sourceMappingURL=chunk-
|
|
296
|
+
//# sourceMappingURL=chunk-LLWQ3Z76.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/model-registry.ts"],"sourcesContent":["import type { Provider, ThinkingLevel } from \"@kenkaiiii/gg-ai\";\n\nexport interface ModelInfo {\n id: string;\n name: string;\n provider: Provider;\n contextWindow: number;\n /**\n * ChatGPT Codex transport uses product-specific windows that can differ from\n * the public API model window. OpenAI OAuth requests include an accountId and\n * route through `/codex/responses`; API-key requests do not.\n */\n codexContextWindow?: number;\n maxOutputTokens: number;\n supportsThinking: boolean;\n supportsImages: boolean;\n supportsVideo: boolean;\n /**\n * Max video payload (bytes) this model's transport accepts, used to decide\n * when an attached/read video must be compressed before sending. Differs by\n * provider delivery mechanism:\n * - Moonshot/Kimi: 100 MB (file-service upload cap)\n * - MiniMax: 50 MB (Anthropic-compatible base64 inline cap)\n * - Gemini: 20 MB (inlineData per-request cap)\n * Only meaningful when `supportsVideo` is true.\n */\n maxVideoBytes?: number;\n costTier: \"low\" | \"medium\" | \"high\";\n /**\n * The top reasoning tier this model genuinely uses. Used when thinking is\n * enabled to pick the strongest setting per model:\n * - OpenAI GPT-5.5-era: `xhigh`\n * - OpenAI Pro/Codex/old: clamped to what the model accepts\n * - Claude Opus 4.8 / 4.7 / 4.6 and Sonnet 4.6: `max`\n * - Claude Haiku 4.5: `high` (no adaptive `max` tier)\n * - GLM / Moonshot / Xiaomi / MiniMax / Qwen: `high` — binary-thinking\n * providers ignore the level on the wire, so the value is cosmetic\n * - DeepSeek V4: `xhigh` (DeepSeek maps `xhigh` → its internal `max`)\n */\n maxThinkingLevel: ThinkingLevel;\n}\n\n// Provider display order — mirrors `PROVIDERS` in ui/login.tsx so the\n// /model selector and login selector sort models identically.\nexport const MODELS: ModelInfo[] = [\n // ── Anthropic ──────────────────────────────────────────\n {\n id: \"claude-opus-4-8\",\n name: \"Claude Opus 4.8\",\n provider: \"anthropic\",\n contextWindow: 1_000_000,\n maxOutputTokens: 128_000,\n supportsThinking: true,\n supportsImages: true,\n supportsVideo: false,\n costTier: \"high\",\n maxThinkingLevel: \"max\",\n },\n {\n id: \"claude-sonnet-4-6\",\n name: \"Claude Sonnet 4.6\",\n provider: \"anthropic\",\n contextWindow: 1_000_000,\n maxOutputTokens: 64_000,\n supportsThinking: true,\n supportsImages: true,\n supportsVideo: false,\n costTier: \"medium\",\n maxThinkingLevel: \"max\",\n },\n {\n id: \"claude-haiku-4-5-20251001\",\n name: \"Claude Haiku 4.5\",\n provider: \"anthropic\",\n contextWindow: 200_000,\n maxOutputTokens: 64_000,\n supportsThinking: true,\n supportsImages: true,\n supportsVideo: false,\n costTier: \"low\",\n maxThinkingLevel: \"high\",\n },\n // ── OpenAI (Codex) ─────────────────────────────────────\n {\n id: \"gpt-5.5\",\n name: \"GPT-5.5\",\n provider: \"openai\",\n contextWindow: 1_050_000,\n codexContextWindow: 272_000,\n maxOutputTokens: 128_000,\n supportsThinking: true,\n supportsImages: true,\n supportsVideo: false,\n costTier: \"high\",\n maxThinkingLevel: \"xhigh\",\n },\n {\n id: \"gpt-5.4\",\n name: \"GPT-5.4\",\n provider: \"openai\",\n contextWindow: 1_050_000,\n codexContextWindow: 272_000,\n maxOutputTokens: 128_000,\n supportsThinking: true,\n supportsImages: true,\n supportsVideo: false,\n costTier: \"high\",\n maxThinkingLevel: \"xhigh\",\n },\n {\n id: \"gpt-5.4-mini\",\n name: \"GPT-5.4 Mini\",\n provider: \"openai\",\n contextWindow: 400_000,\n maxOutputTokens: 128_000,\n supportsThinking: true,\n supportsImages: true,\n supportsVideo: false,\n costTier: \"low\",\n maxThinkingLevel: \"xhigh\",\n },\n {\n id: \"gpt-5.3-codex\",\n name: \"GPT-5.3 Codex\",\n provider: \"openai\",\n contextWindow: 400_000,\n maxOutputTokens: 128_000,\n supportsThinking: true,\n supportsImages: true,\n supportsVideo: false,\n costTier: \"high\",\n maxThinkingLevel: \"xhigh\",\n },\n // ── Gemini ─────────────────────────────────────────────\n {\n id: \"gemini-3.1-flash-lite-preview\",\n name: \"Gemini 3.1 Flash Lite Preview\",\n provider: \"gemini\",\n contextWindow: 1_048_576,\n maxOutputTokens: 65_536,\n supportsThinking: true,\n supportsImages: true,\n supportsVideo: true,\n maxVideoBytes: 20 * 1024 * 1024,\n costTier: \"low\",\n maxThinkingLevel: \"high\",\n },\n {\n id: \"gemini-3.5-flash\",\n name: \"Gemini 3.5 Flash\",\n provider: \"gemini\",\n contextWindow: 1_048_576,\n maxOutputTokens: 65_536,\n supportsThinking: true,\n supportsImages: true,\n supportsVideo: true,\n maxVideoBytes: 20 * 1024 * 1024,\n costTier: \"low\",\n maxThinkingLevel: \"high\",\n },\n // ── Moonshot (Kimi) ────────────────────────────────────\n {\n id: \"kimi-k2.6\",\n name: \"Kimi K2.6\",\n provider: \"moonshot\",\n contextWindow: 262_144,\n maxOutputTokens: 262_144,\n supportsThinking: true,\n supportsImages: true,\n supportsVideo: true,\n maxVideoBytes: 100 * 1024 * 1024,\n costTier: \"medium\",\n maxThinkingLevel: \"high\",\n },\n // ── Z.AI (GLM) ─────────────────────────────────────────\n {\n id: \"glm-5.1\",\n name: \"GLM-5.1\",\n provider: \"glm\",\n contextWindow: 204_800,\n maxOutputTokens: 131_072,\n supportsThinking: true,\n supportsImages: false,\n supportsVideo: false,\n costTier: \"medium\",\n maxThinkingLevel: \"high\",\n },\n {\n id: \"glm-4.7\",\n name: \"GLM-4.7\",\n provider: \"glm\",\n contextWindow: 200_000,\n maxOutputTokens: 131_072,\n supportsThinking: true,\n supportsImages: false,\n supportsVideo: false,\n costTier: \"low\",\n maxThinkingLevel: \"high\",\n },\n {\n id: \"glm-4.7-flash\",\n name: \"GLM-4.7 Flash\",\n provider: \"glm\",\n contextWindow: 200_000,\n maxOutputTokens: 131_072,\n supportsThinking: true,\n supportsImages: false,\n supportsVideo: false,\n costTier: \"low\",\n maxThinkingLevel: \"high\",\n },\n // ── MiniMax ────────────────────────────────────────────\n {\n id: \"MiniMax-M3\",\n name: \"MiniMax M3\",\n provider: \"minimax\",\n contextWindow: 1_000_000,\n maxOutputTokens: 131_072,\n supportsThinking: true,\n supportsImages: true,\n supportsVideo: true,\n maxVideoBytes: 50 * 1024 * 1024,\n costTier: \"medium\",\n maxThinkingLevel: \"high\",\n },\n // ── Xiaomi (MiMo) ──────────────────────────────────────\n {\n id: \"mimo-v2-pro\",\n name: \"MiMo-V2-Pro\",\n provider: \"xiaomi\",\n contextWindow: 1_000_000,\n maxOutputTokens: 131_072,\n supportsThinking: true,\n supportsImages: false,\n supportsVideo: false,\n costTier: \"medium\",\n maxThinkingLevel: \"high\",\n },\n // ── DeepSeek ───────────────────────────────────────────\n {\n id: \"deepseek-v4-pro\",\n name: \"DeepSeek V4 Pro\",\n provider: \"deepseek\",\n contextWindow: 1_048_576,\n maxOutputTokens: 384_000,\n supportsThinking: true,\n supportsImages: false,\n supportsVideo: false,\n costTier: \"high\",\n // DeepSeek V4 maps `xhigh` → its internal `max` tier.\n maxThinkingLevel: \"xhigh\",\n },\n {\n id: \"deepseek-v4-flash\",\n name: \"DeepSeek V4 Flash\",\n provider: \"deepseek\",\n contextWindow: 1_048_576,\n maxOutputTokens: 384_000,\n supportsThinking: true,\n supportsImages: false,\n supportsVideo: false,\n costTier: \"low\",\n maxThinkingLevel: \"xhigh\",\n },\n // ── OpenRouter ─────────────────────────────────────────\n {\n id: \"qwen/qwen3.6-plus\",\n name: \"Qwen3.6-Plus\",\n provider: \"openrouter\",\n contextWindow: 1_000_000,\n maxOutputTokens: 65_536,\n supportsThinking: true,\n supportsImages: false,\n supportsVideo: false,\n costTier: \"medium\",\n maxThinkingLevel: \"high\",\n },\n];\n\nexport function getModel(id: string): ModelInfo | undefined {\n return MODELS.find((m) => m.id === id);\n}\n\nexport function getModelsForProvider(provider: Provider): ModelInfo[] {\n return MODELS.filter((m) => m.provider === provider);\n}\n\n/** Default video payload cap (bytes) when a video model doesn't declare one. */\nexport const DEFAULT_MAX_VIDEO_BYTES = 20 * 1024 * 1024;\n\n/**\n * Max video payload (bytes) the given model's transport accepts before the clip\n * must be compressed. Returns `undefined` for models without video support, so\n * callers can skip the native-video path entirely.\n */\nexport function getVideoByteLimit(modelId: string): number | undefined {\n const model = getModel(modelId);\n if (!model?.supportsVideo) return undefined;\n return model.maxVideoBytes ?? DEFAULT_MAX_VIDEO_BYTES;\n}\n\nexport function getDefaultModel(provider: Provider): ModelInfo {\n if (provider === \"xiaomi\") return MODELS.find((m) => m.id === \"mimo-v2-pro\")!;\n if (provider === \"openai\") return MODELS.find((m) => m.id === \"gpt-5.5\")!;\n if (provider === \"gemini\") return MODELS.find((m) => m.id === \"gemini-3.1-flash-lite-preview\")!;\n if (provider === \"glm\") return MODELS.find((m) => m.id === \"glm-5.1\")!;\n if (provider === \"moonshot\") return MODELS.find((m) => m.id === \"kimi-k2.6\")!;\n if (provider === \"minimax\") return MODELS.find((m) => m.id === \"MiniMax-M3\")!;\n if (provider === \"deepseek\") return MODELS.find((m) => m.id === \"deepseek-v4-pro\")!;\n if (provider === \"openrouter\") return MODELS.find((m) => m.id === \"qwen/qwen3.6-plus\")!;\n return MODELS.find((m) => m.id === \"claude-sonnet-4-6\")!;\n}\n\nexport interface ContextWindowOptions {\n provider?: Provider;\n accountId?: string;\n}\n\nexport function usesOpenAICodexTransport(options?: ContextWindowOptions): boolean {\n return options?.provider === \"openai\" && Boolean(options.accountId);\n}\n\nexport function getContextWindow(modelId: string, options?: ContextWindowOptions): number {\n const model = getModel(modelId);\n if (!model) return 200_000;\n if (usesOpenAICodexTransport(options) && model.codexContextWindow) {\n return model.codexContextWindow;\n }\n return model.contextWindow;\n}\n\n/**\n * The strongest thinking level the given model genuinely uses. Falls back to\n * `\"high\"` for unknown models since every provider we ship accepts it.\n */\nexport function getMaxThinkingLevel(modelId: string): ThinkingLevel {\n return getModel(modelId)?.maxThinkingLevel ?? \"high\";\n}\n\n/**\n * Get the model to use for compaction summarization.\n * - Anthropic: always Sonnet 4.6\n * - OpenAI: cheapest (Codex Mini)\n * - Gemini: use the current model\n * - GLM: GLM-4.7 Flash (cheap alternative)\n * - Moonshot: use the current model (no cheap alternative)\n */\nexport function getSummaryModel(provider: Provider, currentModelId: string): ModelInfo {\n if (provider === \"anthropic\") {\n return MODELS.find((m) => m.id === \"claude-sonnet-4-6\")!;\n }\n if (provider === \"openai\" || provider === \"glm\" || provider === \"deepseek\") {\n const low = getModelsForProvider(provider).find((m) => m.costTier === \"low\");\n if (low) return low;\n }\n // Moonshot or fallback: use current model\n return getModel(currentModelId) ?? getDefaultModel(provider);\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.cjs
CHANGED
|
@@ -31,7 +31,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
AuthStorage: () => AuthStorage,
|
|
34
|
+
DEFAULT_MAX_VIDEO_BYTES: () => DEFAULT_MAX_VIDEO_BYTES,
|
|
34
35
|
MODELS: () => MODELS,
|
|
36
|
+
MOONSHOT_OAUTH_KEY: () => MOONSHOT_OAUTH_KEY,
|
|
35
37
|
NotLoggedInError: () => NotLoggedInError,
|
|
36
38
|
TelegramBot: () => TelegramBot,
|
|
37
39
|
closeLogger: () => closeLogger,
|
|
@@ -51,16 +53,22 @@ __export(index_exports, {
|
|
|
51
53
|
getSessionId: () => getSessionId,
|
|
52
54
|
getSummaryModel: () => getSummaryModel,
|
|
53
55
|
getSupportedThinkingLevels: () => getSupportedThinkingLevels,
|
|
56
|
+
getVideoByteLimit: () => getVideoByteLimit,
|
|
57
|
+
isKimiCodingEndpoint: () => isKimiCodingEndpoint,
|
|
54
58
|
isLoggerOpen: () => isLoggerOpen,
|
|
55
59
|
isModelLoaded: () => isModelLoaded,
|
|
56
60
|
isThinkingLevelSupported: () => isThinkingLevelSupported,
|
|
61
|
+
kimiCodeBaseUrl: () => kimiCodeBaseUrl,
|
|
62
|
+
kimiCodingHeaders: () => kimiCodingHeaders,
|
|
57
63
|
log: () => log,
|
|
58
64
|
loginAnthropic: () => loginAnthropic,
|
|
59
65
|
loginGemini: () => loginGemini,
|
|
66
|
+
loginKimi: () => loginKimi,
|
|
60
67
|
loginOpenAI: () => loginOpenAI,
|
|
61
68
|
openLog: () => openLog,
|
|
62
69
|
refreshAnthropicToken: () => refreshAnthropicToken,
|
|
63
70
|
refreshGeminiToken: () => refreshGeminiToken,
|
|
71
|
+
refreshKimiToken: () => refreshKimiToken,
|
|
64
72
|
refreshOpenAIToken: () => refreshOpenAIToken,
|
|
65
73
|
registerLogCleanup: () => registerLogCleanup,
|
|
66
74
|
resample: () => resample,
|
|
@@ -171,6 +179,7 @@ var MODELS = [
|
|
|
171
179
|
supportsThinking: true,
|
|
172
180
|
supportsImages: true,
|
|
173
181
|
supportsVideo: true,
|
|
182
|
+
maxVideoBytes: 20 * 1024 * 1024,
|
|
174
183
|
costTier: "low",
|
|
175
184
|
maxThinkingLevel: "high"
|
|
176
185
|
},
|
|
@@ -183,6 +192,7 @@ var MODELS = [
|
|
|
183
192
|
supportsThinking: true,
|
|
184
193
|
supportsImages: true,
|
|
185
194
|
supportsVideo: true,
|
|
195
|
+
maxVideoBytes: 20 * 1024 * 1024,
|
|
186
196
|
costTier: "low",
|
|
187
197
|
maxThinkingLevel: "high"
|
|
188
198
|
},
|
|
@@ -196,6 +206,7 @@ var MODELS = [
|
|
|
196
206
|
supportsThinking: true,
|
|
197
207
|
supportsImages: true,
|
|
198
208
|
supportsVideo: true,
|
|
209
|
+
maxVideoBytes: 100 * 1024 * 1024,
|
|
199
210
|
costTier: "medium",
|
|
200
211
|
maxThinkingLevel: "high"
|
|
201
212
|
},
|
|
@@ -246,6 +257,7 @@ var MODELS = [
|
|
|
246
257
|
supportsThinking: true,
|
|
247
258
|
supportsImages: true,
|
|
248
259
|
supportsVideo: true,
|
|
260
|
+
maxVideoBytes: 50 * 1024 * 1024,
|
|
249
261
|
costTier: "medium",
|
|
250
262
|
maxThinkingLevel: "high"
|
|
251
263
|
},
|
|
@@ -308,6 +320,12 @@ function getModel(id) {
|
|
|
308
320
|
function getModelsForProvider(provider) {
|
|
309
321
|
return MODELS.filter((m) => m.provider === provider);
|
|
310
322
|
}
|
|
323
|
+
var DEFAULT_MAX_VIDEO_BYTES = 20 * 1024 * 1024;
|
|
324
|
+
function getVideoByteLimit(modelId) {
|
|
325
|
+
const model = getModel(modelId);
|
|
326
|
+
if (!model?.supportsVideo) return void 0;
|
|
327
|
+
return model.maxVideoBytes ?? DEFAULT_MAX_VIDEO_BYTES;
|
|
328
|
+
}
|
|
311
329
|
function getDefaultModel(provider) {
|
|
312
330
|
if (provider === "xiaomi") return MODELS.find((m) => m.id === "mimo-v2-pro");
|
|
313
331
|
if (provider === "openai") return MODELS.find((m) => m.id === "gpt-5.5");
|
|
@@ -648,7 +666,7 @@ async function getClaudeCliUserAgent() {
|
|
|
648
666
|
|
|
649
667
|
// src/auth-storage.ts
|
|
650
668
|
var import_promises4 = __toESM(require("fs/promises"), 1);
|
|
651
|
-
var
|
|
669
|
+
var import_node_crypto6 = __toESM(require("crypto"), 1);
|
|
652
670
|
|
|
653
671
|
// src/oauth/anthropic.ts
|
|
654
672
|
var import_node_crypto2 = __toESM(require("crypto"), 1);
|
|
@@ -1303,7 +1321,232 @@ function codeAssistHeaders(accessToken) {
|
|
|
1303
1321
|
};
|
|
1304
1322
|
}
|
|
1305
1323
|
|
|
1324
|
+
// src/oauth/kimi.ts
|
|
1325
|
+
var import_node_child_process = require("child_process");
|
|
1326
|
+
var import_node_crypto5 = require("crypto");
|
|
1327
|
+
var import_node_fs2 = require("fs");
|
|
1328
|
+
var import_node_os2 = require("os");
|
|
1329
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
1330
|
+
var CLIENT_ID3 = "17e5f671-d194-4dfb-9706-5516cb48c098";
|
|
1331
|
+
var DEFAULT_OAUTH_HOST = "https://auth.kimi.com";
|
|
1332
|
+
var DEFAULT_CODING_BASE_URL = "https://api.kimi.com/coding/v1";
|
|
1333
|
+
var KIMI_PLATFORM = "kimi_code_cli";
|
|
1334
|
+
var DEFAULT_KIMI_VERSION = "1.0.11";
|
|
1335
|
+
var DEVICE_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
1336
|
+
function oauthHost() {
|
|
1337
|
+
const host = process.env.KIMI_CODE_OAUTH_HOST ?? process.env.KIMI_OAUTH_HOST ?? DEFAULT_OAUTH_HOST;
|
|
1338
|
+
return host.replace(/\/+$/, "");
|
|
1339
|
+
}
|
|
1340
|
+
function kimiCodeBaseUrl() {
|
|
1341
|
+
return (process.env.KIMI_CODE_BASE_URL ?? DEFAULT_CODING_BASE_URL).replace(/\/+$/, "");
|
|
1342
|
+
}
|
|
1343
|
+
function kimiVersion() {
|
|
1344
|
+
const v = process.env.KIMI_CODE_VERSION ?? DEFAULT_KIMI_VERSION;
|
|
1345
|
+
return asciiHeader(v, DEFAULT_KIMI_VERSION);
|
|
1346
|
+
}
|
|
1347
|
+
function asciiHeader(value, fallback = "unknown") {
|
|
1348
|
+
const cleaned = value.replace(/[^\u0020-\u007E]/g, "").trim();
|
|
1349
|
+
return cleaned.length > 0 ? cleaned : fallback;
|
|
1350
|
+
}
|
|
1351
|
+
function macOsProductVersion() {
|
|
1352
|
+
try {
|
|
1353
|
+
const version = (0, import_node_child_process.execFileSync)("/usr/bin/sw_vers", ["-productVersion"], {
|
|
1354
|
+
encoding: "utf-8",
|
|
1355
|
+
timeout: 1e3
|
|
1356
|
+
}).trim();
|
|
1357
|
+
return version.length > 0 ? version : void 0;
|
|
1358
|
+
} catch {
|
|
1359
|
+
return void 0;
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
function deviceModel() {
|
|
1363
|
+
const os2 = (0, import_node_os2.type)();
|
|
1364
|
+
const version = (0, import_node_os2.release)();
|
|
1365
|
+
const osArch = (0, import_node_os2.arch)();
|
|
1366
|
+
if (os2 === "Darwin") return `macOS ${macOsProductVersion() ?? version} ${osArch}`;
|
|
1367
|
+
if (os2 === "Windows_NT") return `Windows ${version} ${osArch}`;
|
|
1368
|
+
return `${os2} ${version} ${osArch}`.trim();
|
|
1369
|
+
}
|
|
1370
|
+
function deviceId() {
|
|
1371
|
+
const idPath = import_node_path4.default.join(getAppPaths().agentDir, "kimi_device_id");
|
|
1372
|
+
if ((0, import_node_fs2.existsSync)(idPath)) {
|
|
1373
|
+
try {
|
|
1374
|
+
const text = (0, import_node_fs2.readFileSync)(idPath, "utf-8").trim();
|
|
1375
|
+
if (text.length > 0) return text;
|
|
1376
|
+
} catch {
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
const id = (0, import_node_crypto5.randomUUID)();
|
|
1380
|
+
try {
|
|
1381
|
+
(0, import_node_fs2.mkdirSync)(getAppPaths().agentDir, { recursive: true, mode: 448 });
|
|
1382
|
+
(0, import_node_fs2.writeFileSync)(idPath, id, { encoding: "utf-8", mode: 384 });
|
|
1383
|
+
} catch {
|
|
1384
|
+
}
|
|
1385
|
+
return id;
|
|
1386
|
+
}
|
|
1387
|
+
function deviceHeaders() {
|
|
1388
|
+
return {
|
|
1389
|
+
"X-Msh-Platform": KIMI_PLATFORM,
|
|
1390
|
+
"X-Msh-Version": kimiVersion(),
|
|
1391
|
+
"X-Msh-Device-Name": asciiHeader((0, import_node_os2.hostname)()),
|
|
1392
|
+
"X-Msh-Device-Model": asciiHeader(deviceModel()),
|
|
1393
|
+
"X-Msh-Os-Version": asciiHeader((0, import_node_os2.release)()),
|
|
1394
|
+
"X-Msh-Device-Id": deviceId()
|
|
1395
|
+
};
|
|
1396
|
+
}
|
|
1397
|
+
function kimiCodingHeaders() {
|
|
1398
|
+
return {
|
|
1399
|
+
"User-Agent": `kimi-code-cli/${kimiVersion()}`,
|
|
1400
|
+
...deviceHeaders()
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
function isKimiCodingEndpoint(baseUrl) {
|
|
1404
|
+
if (typeof baseUrl !== "string" || baseUrl.length === 0) return false;
|
|
1405
|
+
const normalized = baseUrl.replace(/\/+$/, "");
|
|
1406
|
+
return normalized === kimiCodeBaseUrl() || /(^|\.)kimi\.com/i.test(normalized);
|
|
1407
|
+
}
|
|
1408
|
+
async function postForm(endpoint, params) {
|
|
1409
|
+
const response = await fetch(`${oauthHost()}${endpoint}`, {
|
|
1410
|
+
method: "POST",
|
|
1411
|
+
headers: {
|
|
1412
|
+
...deviceHeaders(),
|
|
1413
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
1414
|
+
Accept: "application/json"
|
|
1415
|
+
},
|
|
1416
|
+
body: new URLSearchParams(params).toString()
|
|
1417
|
+
});
|
|
1418
|
+
let data = {};
|
|
1419
|
+
try {
|
|
1420
|
+
const parsed = await response.json();
|
|
1421
|
+
if (parsed && typeof parsed === "object") data = parsed;
|
|
1422
|
+
} catch {
|
|
1423
|
+
}
|
|
1424
|
+
return { status: response.status, data };
|
|
1425
|
+
}
|
|
1426
|
+
function errorDetail(data) {
|
|
1427
|
+
const desc = data.error_description ?? data.message ?? data.error;
|
|
1428
|
+
return typeof desc === "string" && desc.length > 0 ? desc : "unknown error";
|
|
1429
|
+
}
|
|
1430
|
+
function credsFromTokenResponse(data) {
|
|
1431
|
+
const accessToken = data.access_token;
|
|
1432
|
+
const refreshToken = data.refresh_token;
|
|
1433
|
+
const expiresIn = Number(data.expires_in);
|
|
1434
|
+
if (typeof accessToken !== "string" || accessToken.length === 0) {
|
|
1435
|
+
throw new Error("Kimi OAuth response missing access_token.");
|
|
1436
|
+
}
|
|
1437
|
+
if (typeof refreshToken !== "string" || refreshToken.length === 0) {
|
|
1438
|
+
throw new Error("Kimi OAuth response missing refresh_token.");
|
|
1439
|
+
}
|
|
1440
|
+
if (!Number.isFinite(expiresIn) || expiresIn <= 0) {
|
|
1441
|
+
throw new Error("Kimi OAuth response missing or invalid expires_in.");
|
|
1442
|
+
}
|
|
1443
|
+
return {
|
|
1444
|
+
accessToken,
|
|
1445
|
+
refreshToken,
|
|
1446
|
+
expiresAt: Date.now() + expiresIn * 1e3,
|
|
1447
|
+
baseUrl: kimiCodeBaseUrl()
|
|
1448
|
+
};
|
|
1449
|
+
}
|
|
1450
|
+
async function requestDeviceAuthorization() {
|
|
1451
|
+
const { status, data } = await postForm("/api/oauth/device_authorization", {
|
|
1452
|
+
client_id: CLIENT_ID3
|
|
1453
|
+
});
|
|
1454
|
+
if (status !== 200) {
|
|
1455
|
+
throw new Error(`Kimi device authorization failed (${status}): ${errorDetail(data)}`);
|
|
1456
|
+
}
|
|
1457
|
+
const userCode = data.user_code;
|
|
1458
|
+
const deviceCode = data.device_code;
|
|
1459
|
+
const verificationUriComplete = data.verification_uri_complete;
|
|
1460
|
+
if (typeof userCode !== "string" || typeof deviceCode !== "string") {
|
|
1461
|
+
throw new Error("Kimi device authorization response missing user_code/device_code.");
|
|
1462
|
+
}
|
|
1463
|
+
return {
|
|
1464
|
+
userCode,
|
|
1465
|
+
deviceCode,
|
|
1466
|
+
verificationUri: typeof data.verification_uri === "string" ? data.verification_uri : "",
|
|
1467
|
+
verificationUriComplete: typeof verificationUriComplete === "string" ? verificationUriComplete : "",
|
|
1468
|
+
interval: Number(data.interval ?? 5) || 5
|
|
1469
|
+
};
|
|
1470
|
+
}
|
|
1471
|
+
async function pollDeviceToken(deviceCode) {
|
|
1472
|
+
const { status, data } = await postForm("/api/oauth/token", {
|
|
1473
|
+
client_id: CLIENT_ID3,
|
|
1474
|
+
device_code: deviceCode,
|
|
1475
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code"
|
|
1476
|
+
});
|
|
1477
|
+
if (status === 200 && typeof data.access_token === "string") {
|
|
1478
|
+
return { kind: "success", creds: credsFromTokenResponse(data) };
|
|
1479
|
+
}
|
|
1480
|
+
if (status >= 500) {
|
|
1481
|
+
throw new Error(`Kimi token polling server error (${status}): ${errorDetail(data)}`);
|
|
1482
|
+
}
|
|
1483
|
+
const errorCode = typeof data.error === "string" ? data.error : "unknown_error";
|
|
1484
|
+
switch (errorCode) {
|
|
1485
|
+
case "authorization_pending":
|
|
1486
|
+
return { kind: "pending" };
|
|
1487
|
+
case "slow_down":
|
|
1488
|
+
return { kind: "slow_down" };
|
|
1489
|
+
case "expired_token":
|
|
1490
|
+
return { kind: "expired" };
|
|
1491
|
+
case "access_denied":
|
|
1492
|
+
return { kind: "denied" };
|
|
1493
|
+
default:
|
|
1494
|
+
throw new Error(`Kimi token polling failed (${status}): ${errorDetail(data)}`);
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
function sleep(ms) {
|
|
1498
|
+
return new Promise((resolve) => {
|
|
1499
|
+
setTimeout(resolve, ms);
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1502
|
+
async function loginKimi(callbacks) {
|
|
1503
|
+
const auth = await requestDeviceAuthorization();
|
|
1504
|
+
callbacks.onStatus(
|
|
1505
|
+
`Visit ${auth.verificationUri || auth.verificationUriComplete} and enter code: ${auth.userCode}`
|
|
1506
|
+
);
|
|
1507
|
+
callbacks.onOpenUrl(auth.verificationUriComplete || auth.verificationUri);
|
|
1508
|
+
callbacks.onStatus("Waiting for you to authorize in the browser...");
|
|
1509
|
+
const deadline = Date.now() + DEVICE_TIMEOUT_MS;
|
|
1510
|
+
let interval = Math.max(auth.interval, 1);
|
|
1511
|
+
while (Date.now() < deadline) {
|
|
1512
|
+
await sleep(interval * 1e3);
|
|
1513
|
+
const result = await pollDeviceToken(auth.deviceCode);
|
|
1514
|
+
if (result.kind === "success") return result.creds;
|
|
1515
|
+
if (result.kind === "denied") {
|
|
1516
|
+
throw new Error("Kimi authorization was denied.");
|
|
1517
|
+
}
|
|
1518
|
+
if (result.kind === "expired") {
|
|
1519
|
+
throw new Error("Kimi device code expired. Please run login again.");
|
|
1520
|
+
}
|
|
1521
|
+
if (result.kind === "slow_down") {
|
|
1522
|
+
interval += 5;
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
throw new Error("Kimi login timed out. Please run login again.");
|
|
1526
|
+
}
|
|
1527
|
+
async function refreshKimiToken(refreshToken) {
|
|
1528
|
+
const { status, data } = await postForm("/api/oauth/token", {
|
|
1529
|
+
client_id: CLIENT_ID3,
|
|
1530
|
+
grant_type: "refresh_token",
|
|
1531
|
+
refresh_token: refreshToken
|
|
1532
|
+
});
|
|
1533
|
+
if (status === 200 && typeof data.access_token === "string") {
|
|
1534
|
+
return credsFromTokenResponse(data);
|
|
1535
|
+
}
|
|
1536
|
+
const errorCode = typeof data.error === "string" ? data.error : "";
|
|
1537
|
+
throw new Error(`Kimi token refresh failed (${status}): ${errorCode || errorDetail(data)}`);
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1306
1540
|
// src/auth-storage.ts
|
|
1541
|
+
var MOONSHOT_OAUTH_KEY = "moonshot-oauth";
|
|
1542
|
+
var STATIC_API_KEY_PROVIDERS = /* @__PURE__ */ new Set([
|
|
1543
|
+
"glm",
|
|
1544
|
+
"moonshot",
|
|
1545
|
+
"xiaomi",
|
|
1546
|
+
"minimax",
|
|
1547
|
+
"deepseek",
|
|
1548
|
+
"openrouter"
|
|
1549
|
+
]);
|
|
1307
1550
|
var AuthStorage = class {
|
|
1308
1551
|
data = {};
|
|
1309
1552
|
filePath;
|
|
@@ -1327,6 +1570,30 @@ var AuthStorage = class {
|
|
|
1327
1570
|
await this.ensureLoaded();
|
|
1328
1571
|
return Boolean(this.data[provider]);
|
|
1329
1572
|
}
|
|
1573
|
+
/**
|
|
1574
|
+
* True if the user has any usable auth for the logical provider. For
|
|
1575
|
+
* `moonshot` this is satisfied by either the Kimi OAuth credential or the
|
|
1576
|
+
* Moonshot API key.
|
|
1577
|
+
*/
|
|
1578
|
+
async hasProviderAuth(provider) {
|
|
1579
|
+
await this.ensureLoaded();
|
|
1580
|
+
if (provider === "moonshot") {
|
|
1581
|
+
return Boolean(this.data[MOONSHOT_OAUTH_KEY] || this.data["moonshot"]);
|
|
1582
|
+
}
|
|
1583
|
+
return Boolean(this.data[provider]);
|
|
1584
|
+
}
|
|
1585
|
+
/**
|
|
1586
|
+
* True if the active credential for `provider` is a static API key with no
|
|
1587
|
+
* refresh mechanism. For `moonshot` this is only true when the Kimi OAuth
|
|
1588
|
+
* credential is absent (a present OAuth credential is refreshable).
|
|
1589
|
+
*/
|
|
1590
|
+
async isStaticApiKey(provider) {
|
|
1591
|
+
await this.ensureLoaded();
|
|
1592
|
+
if (provider === "moonshot" && this.data[MOONSHOT_OAUTH_KEY]) {
|
|
1593
|
+
return false;
|
|
1594
|
+
}
|
|
1595
|
+
return STATIC_API_KEY_PROVIDERS.has(provider);
|
|
1596
|
+
}
|
|
1330
1597
|
async load() {
|
|
1331
1598
|
await withFileLock(this.filePath, async () => {
|
|
1332
1599
|
try {
|
|
@@ -1381,11 +1648,21 @@ var AuthStorage = class {
|
|
|
1381
1648
|
*/
|
|
1382
1649
|
async resolveCredentials(provider, opts) {
|
|
1383
1650
|
await this.ensureLoaded();
|
|
1651
|
+
if (provider === "moonshot" && this.data[MOONSHOT_OAUTH_KEY]) {
|
|
1652
|
+
try {
|
|
1653
|
+
return await this.resolveCredentials(MOONSHOT_OAUTH_KEY, opts);
|
|
1654
|
+
} catch (err) {
|
|
1655
|
+
if (err instanceof NotLoggedInError && this.data["moonshot"]) {
|
|
1656
|
+
return this.data["moonshot"];
|
|
1657
|
+
}
|
|
1658
|
+
throw err;
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1384
1661
|
const creds = this.data[provider];
|
|
1385
1662
|
if (!creds) {
|
|
1386
1663
|
throw new NotLoggedInError(provider);
|
|
1387
1664
|
}
|
|
1388
|
-
if (provider
|
|
1665
|
+
if (STATIC_API_KEY_PROVIDERS.has(provider)) {
|
|
1389
1666
|
return creds;
|
|
1390
1667
|
}
|
|
1391
1668
|
if (!opts?.forceRefresh && Date.now() < creds.expiresAt) {
|
|
@@ -1404,7 +1681,7 @@ var AuthStorage = class {
|
|
|
1404
1681
|
}
|
|
1405
1682
|
} catch {
|
|
1406
1683
|
}
|
|
1407
|
-
const refreshFn = provider === "anthropic" ? refreshAnthropicToken : provider === "gemini" ? refreshGeminiToken : refreshOpenAIToken;
|
|
1684
|
+
const refreshFn = provider === "anthropic" ? refreshAnthropicToken : provider === "gemini" ? refreshGeminiToken : provider === MOONSHOT_OAUTH_KEY ? refreshKimiToken : refreshOpenAIToken;
|
|
1408
1685
|
let refreshed;
|
|
1409
1686
|
try {
|
|
1410
1687
|
refreshed = await refreshFn(creds.refreshToken);
|
|
@@ -1450,7 +1727,7 @@ var AuthStorage = class {
|
|
|
1450
1727
|
}
|
|
1451
1728
|
};
|
|
1452
1729
|
async function atomicWriteFile(filePath, content) {
|
|
1453
|
-
const tmpPath = `${filePath}.${process.pid}.${Date.now()}.${
|
|
1730
|
+
const tmpPath = `${filePath}.${process.pid}.${Date.now()}.${import_node_crypto6.default.randomUUID().slice(0, 8)}.tmp`;
|
|
1454
1731
|
try {
|
|
1455
1732
|
await import_promises4.default.writeFile(tmpPath, content, { encoding: "utf-8", mode: 384 });
|
|
1456
1733
|
await import_promises4.default.rename(tmpPath, filePath);
|
|
@@ -1522,7 +1799,7 @@ var TelegramBot = class {
|
|
|
1522
1799
|
} catch (err) {
|
|
1523
1800
|
if (!this.running) break;
|
|
1524
1801
|
console.error(`[telegram] Poll error: ${err instanceof Error ? err.message : err}`);
|
|
1525
|
-
await
|
|
1802
|
+
await sleep2(3e3);
|
|
1526
1803
|
}
|
|
1527
1804
|
}
|
|
1528
1805
|
}
|
|
@@ -1692,7 +1969,7 @@ function splitMessage(text) {
|
|
|
1692
1969
|
}
|
|
1693
1970
|
return chunks;
|
|
1694
1971
|
}
|
|
1695
|
-
function
|
|
1972
|
+
function sleep2(ms) {
|
|
1696
1973
|
return new Promise((r) => setTimeout(r, ms));
|
|
1697
1974
|
}
|
|
1698
1975
|
|
|
@@ -1777,9 +2054,9 @@ async function transcribeVoice(fileUrl) {
|
|
|
1777
2054
|
}
|
|
1778
2055
|
|
|
1779
2056
|
// src/auto-update.ts
|
|
1780
|
-
var
|
|
1781
|
-
var
|
|
1782
|
-
var
|
|
2057
|
+
var import_node_child_process2 = require("child_process");
|
|
2058
|
+
var import_node_fs3 = __toESM(require("fs"), 1);
|
|
2059
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
1783
2060
|
var CHECK_INTERVAL_MS = 60 * 60 * 1e3;
|
|
1784
2061
|
var FETCH_TIMEOUT_MS2 = 1e4;
|
|
1785
2062
|
function compareVersions(a, b) {
|
|
@@ -1794,7 +2071,7 @@ function compareVersions(a, b) {
|
|
|
1794
2071
|
function performUpdateInBackground(command) {
|
|
1795
2072
|
try {
|
|
1796
2073
|
const parts = command.split(" ");
|
|
1797
|
-
const child = (0,
|
|
2074
|
+
const child = (0, import_node_child_process2.spawn)(parts[0], parts.slice(1), {
|
|
1798
2075
|
detached: true,
|
|
1799
2076
|
stdio: "ignore",
|
|
1800
2077
|
env: { ...process.env, npm_config_loglevel: "silent" }
|
|
@@ -1812,7 +2089,7 @@ function createAutoUpdater(config) {
|
|
|
1812
2089
|
}
|
|
1813
2090
|
function readState() {
|
|
1814
2091
|
try {
|
|
1815
|
-
const raw =
|
|
2092
|
+
const raw = import_node_fs3.default.readFileSync(stateFilePath(), "utf-8");
|
|
1816
2093
|
return JSON.parse(raw);
|
|
1817
2094
|
} catch {
|
|
1818
2095
|
return null;
|
|
@@ -1821,8 +2098,8 @@ function createAutoUpdater(config) {
|
|
|
1821
2098
|
function writeState(state) {
|
|
1822
2099
|
try {
|
|
1823
2100
|
const filePath = stateFilePath();
|
|
1824
|
-
|
|
1825
|
-
|
|
2101
|
+
import_node_fs3.default.mkdirSync(import_node_path5.default.dirname(filePath), { recursive: true, mode: 448 });
|
|
2102
|
+
import_node_fs3.default.writeFileSync(filePath, JSON.stringify(state));
|
|
1826
2103
|
} catch {
|
|
1827
2104
|
}
|
|
1828
2105
|
}
|
|
@@ -1947,7 +2224,9 @@ function createAutoUpdater(config) {
|
|
|
1947
2224
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1948
2225
|
0 && (module.exports = {
|
|
1949
2226
|
AuthStorage,
|
|
2227
|
+
DEFAULT_MAX_VIDEO_BYTES,
|
|
1950
2228
|
MODELS,
|
|
2229
|
+
MOONSHOT_OAUTH_KEY,
|
|
1951
2230
|
NotLoggedInError,
|
|
1952
2231
|
TelegramBot,
|
|
1953
2232
|
closeLogger,
|
|
@@ -1967,16 +2246,22 @@ function createAutoUpdater(config) {
|
|
|
1967
2246
|
getSessionId,
|
|
1968
2247
|
getSummaryModel,
|
|
1969
2248
|
getSupportedThinkingLevels,
|
|
2249
|
+
getVideoByteLimit,
|
|
2250
|
+
isKimiCodingEndpoint,
|
|
1970
2251
|
isLoggerOpen,
|
|
1971
2252
|
isModelLoaded,
|
|
1972
2253
|
isThinkingLevelSupported,
|
|
2254
|
+
kimiCodeBaseUrl,
|
|
2255
|
+
kimiCodingHeaders,
|
|
1973
2256
|
log,
|
|
1974
2257
|
loginAnthropic,
|
|
1975
2258
|
loginGemini,
|
|
2259
|
+
loginKimi,
|
|
1976
2260
|
loginOpenAI,
|
|
1977
2261
|
openLog,
|
|
1978
2262
|
refreshAnthropicToken,
|
|
1979
2263
|
refreshGeminiToken,
|
|
2264
|
+
refreshKimiToken,
|
|
1980
2265
|
refreshOpenAIToken,
|
|
1981
2266
|
registerLogCleanup,
|
|
1982
2267
|
resample,
|