@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.
@@ -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-USAVZGPP.js.map
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 import_node_crypto5 = __toESM(require("crypto"), 1);
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 === "glm" || provider === "moonshot" || provider === "xiaomi" || provider === "minimax" || provider === "deepseek" || provider === "openrouter") {
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()}.${import_node_crypto5.default.randomUUID().slice(0, 8)}.tmp`;
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 sleep(3e3);
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 sleep(ms) {
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 import_node_child_process = require("child_process");
1781
- var import_node_fs2 = __toESM(require("fs"), 1);
1782
- var import_node_path4 = __toESM(require("path"), 1);
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, import_node_child_process.spawn)(parts[0], parts.slice(1), {
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 = import_node_fs2.default.readFileSync(stateFilePath(), "utf-8");
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
- import_node_fs2.default.mkdirSync(import_node_path4.default.dirname(filePath), { recursive: true, mode: 448 });
1825
- import_node_fs2.default.writeFileSync(filePath, JSON.stringify(state));
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,