@botiverse/kimi-code-sdk 0.9.3 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1026,6 +1026,19 @@ function createToolMessage(toolCallId, output) {
1026
1026
  toolCallId
1027
1027
  };
1028
1028
  }
1029
+ /**
1030
+ * Shared read-only default returned when a provider has not catalogued a
1031
+ * given model. Frozen so accidental mutation at one call site cannot leak
1032
+ * into another.
1033
+ */
1034
+ const UNKNOWN_CAPABILITY = Object.freeze(Object.defineProperty({
1035
+ image_in: false,
1036
+ video_in: false,
1037
+ audio_in: false,
1038
+ thinking: false,
1039
+ tool_use: false,
1040
+ max_context_tokens: 0
1041
+ }, Symbol.for("moonshot-ai.kosong.UNKNOWN_CAPABILITY"), { value: true }));
1029
1042
  //#endregion
1030
1043
  //#region ../kosong/src/errors.ts
1031
1044
  /**
@@ -8623,179 +8636,6 @@ Anthropic.Completions = Completions$2;
8623
8636
  Anthropic.Messages = Messages$2;
8624
8637
  Anthropic.Models = Models$2;
8625
8638
  Anthropic.Beta = Beta$1;
8626
- /**
8627
- * Shared read-only default returned when a provider has not catalogued a
8628
- * given model. Frozen so accidental mutation at one call site cannot leak
8629
- * into another.
8630
- */
8631
- const UNKNOWN_CAPABILITY = Object.freeze(Object.defineProperty({
8632
- image_in: false,
8633
- video_in: false,
8634
- audio_in: false,
8635
- thinking: false,
8636
- tool_use: false,
8637
- max_context_tokens: 0
8638
- }, Symbol.for("moonshot-ai.kosong.UNKNOWN_CAPABILITY"), { value: true }));
8639
- //#endregion
8640
- //#region ../kosong/src/providers/capability-registry.ts
8641
- const OPENAI_RESPONSES_DEVELOPER_ROLE_MODELS = new Set([
8642
- "gpt-4.1",
8643
- "gpt-4.1-mini",
8644
- "gpt-4.1-nano",
8645
- "gpt-5-codex",
8646
- "o1",
8647
- "o1-mini",
8648
- "o1-pro",
8649
- "o3",
8650
- "o3-mini",
8651
- "o3-pro",
8652
- "o4-mini"
8653
- ]);
8654
- const OPENAI_VISION_TOOL_PREFIXES = [
8655
- "gpt-4o",
8656
- "gpt-4-turbo",
8657
- "gpt-4.1",
8658
- "gpt-4.5"
8659
- ];
8660
- const CLAUDE_VISION_TOOL_PREFIXES = [
8661
- "claude-3-",
8662
- "claude-3.5-",
8663
- "claude-3.7-"
8664
- ];
8665
- const CLAUDE_THINKING_VISION_TOOL_PREFIXES = [
8666
- "claude-opus-4",
8667
- "claude-sonnet-4",
8668
- "claude-haiku-4",
8669
- "claude-fable"
8670
- ];
8671
- const GEMINI_CATALOGUED_PREFIXES = [
8672
- "gemini-1.5-pro",
8673
- "gemini-1.5-flash",
8674
- "gemini-2.0-flash",
8675
- "gemini-2.0-pro",
8676
- "gemini-2.5-pro",
8677
- "gemini-2.5-flash"
8678
- ];
8679
- const OPENAI_REASONING_CAPABILITY = Object.freeze({
8680
- image_in: false,
8681
- video_in: false,
8682
- audio_in: false,
8683
- thinking: true,
8684
- tool_use: true,
8685
- max_context_tokens: 0
8686
- });
8687
- const OPENAI_VISION_TOOL_CAPABILITY = Object.freeze({
8688
- image_in: true,
8689
- video_in: false,
8690
- audio_in: false,
8691
- thinking: false,
8692
- tool_use: true,
8693
- max_context_tokens: 0
8694
- });
8695
- const OPENAI_TEXT_TOOL_CAPABILITY = Object.freeze({
8696
- image_in: false,
8697
- video_in: false,
8698
- audio_in: false,
8699
- thinking: false,
8700
- tool_use: true,
8701
- max_context_tokens: 0
8702
- });
8703
- const ANTHROPIC_VISION_TOOL_CAPABILITY = Object.freeze({
8704
- image_in: true,
8705
- video_in: false,
8706
- audio_in: false,
8707
- thinking: false,
8708
- tool_use: true,
8709
- max_context_tokens: 0
8710
- });
8711
- const ANTHROPIC_THINKING_VISION_TOOL_CAPABILITY = Object.freeze({
8712
- image_in: true,
8713
- video_in: false,
8714
- audio_in: false,
8715
- thinking: true,
8716
- tool_use: true,
8717
- max_context_tokens: 0
8718
- });
8719
- const GEMINI_MULTIMODAL_TOOL_CAPABILITY = Object.freeze({
8720
- image_in: true,
8721
- video_in: true,
8722
- audio_in: true,
8723
- thinking: false,
8724
- tool_use: true,
8725
- max_context_tokens: 0
8726
- });
8727
- const GEMINI_THINKING_MULTIMODAL_TOOL_CAPABILITY = Object.freeze({
8728
- image_in: true,
8729
- video_in: true,
8730
- audio_in: true,
8731
- thinking: true,
8732
- tool_use: true,
8733
- max_context_tokens: 0
8734
- });
8735
- const OPENAI_LEGACY_CAPABILITY_CATALOG = [
8736
- {
8737
- matches: isOpenAIReasoningModel,
8738
- capability: OPENAI_REASONING_CAPABILITY
8739
- },
8740
- {
8741
- matches: (name) => hasPrefix(name, OPENAI_VISION_TOOL_PREFIXES),
8742
- capability: OPENAI_VISION_TOOL_CAPABILITY
8743
- },
8744
- {
8745
- matches: (name) => name.startsWith("gpt-3.5-turbo"),
8746
- capability: OPENAI_TEXT_TOOL_CAPABILITY
8747
- }
8748
- ];
8749
- const OPENAI_RESPONSES_CAPABILITY_CATALOG = [{
8750
- matches: isOpenAIReasoningModel,
8751
- capability: OPENAI_REASONING_CAPABILITY
8752
- }, {
8753
- matches: (name) => hasPrefix(name, OPENAI_VISION_TOOL_PREFIXES),
8754
- capability: OPENAI_VISION_TOOL_CAPABILITY
8755
- }];
8756
- const ANTHROPIC_CAPABILITY_CATALOG = [{
8757
- matches: (name) => hasPrefix(name, CLAUDE_VISION_TOOL_PREFIXES),
8758
- capability: ANTHROPIC_VISION_TOOL_CAPABILITY
8759
- }, {
8760
- matches: (name) => hasPrefix(name, CLAUDE_THINKING_VISION_TOOL_PREFIXES),
8761
- capability: ANTHROPIC_THINKING_VISION_TOOL_CAPABILITY
8762
- }];
8763
- function normalizeModelName(modelName) {
8764
- return modelName.toLowerCase();
8765
- }
8766
- function hasPrefix(modelName, prefixes) {
8767
- return prefixes.some((prefix) => modelName.startsWith(prefix));
8768
- }
8769
- function isOpenAIReasoningModel(modelName) {
8770
- return /^o\d/.test(modelName);
8771
- }
8772
- function capabilityFromCatalog(modelName, catalog) {
8773
- const normalized = normalizeModelName(modelName);
8774
- for (const entry of catalog) if (entry.matches(normalized)) return entry.capability;
8775
- return UNKNOWN_CAPABILITY;
8776
- }
8777
- function getOpenAILegacyModelCapability(modelName) {
8778
- return capabilityFromCatalog(modelName, OPENAI_LEGACY_CAPABILITY_CATALOG);
8779
- }
8780
- function getOpenAIResponsesModelCapability(modelName) {
8781
- return capabilityFromCatalog(modelName, OPENAI_RESPONSES_CAPABILITY_CATALOG);
8782
- }
8783
- function getAnthropicModelCapability(modelName) {
8784
- return capabilityFromCatalog(modelName, ANTHROPIC_CAPABILITY_CATALOG);
8785
- }
8786
- function getGoogleGenAIModelCapability(modelName) {
8787
- const normalized = normalizeModelName(modelName);
8788
- if (!normalized.startsWith("gemini-")) return UNKNOWN_CAPABILITY;
8789
- if (!hasPrefix(normalized, GEMINI_CATALOGUED_PREFIXES)) return UNKNOWN_CAPABILITY;
8790
- if (normalized.startsWith("gemini-2.5-") || normalized.includes("thinking")) return GEMINI_THINKING_MULTIMODAL_TOOL_CAPABILITY;
8791
- return GEMINI_MULTIMODAL_TOOL_CAPABILITY;
8792
- }
8793
- function usesOpenAIResponsesDeveloperRole(modelName) {
8794
- const normalized = normalizeModelName(modelName);
8795
- if (OPENAI_RESPONSES_DEVELOPER_ROLE_MODELS.has(normalized)) return true;
8796
- for (const cataloguedModel of OPENAI_RESPONSES_DEVELOPER_ROLE_MODELS) if (normalized.startsWith(cataloguedModel + "-")) return true;
8797
- return false;
8798
- }
8799
8639
  //#endregion
8800
8640
  //#region ../kosong/src/providers/request-auth.ts
8801
8641
  function requireProviderApiKey(providerName, auth, defaultApiKey) {
@@ -9552,9 +9392,6 @@ var AnthropicChatProvider = class {
9552
9392
  ...this._generationKwargs
9553
9393
  };
9554
9394
  }
9555
- getCapability(model) {
9556
- return getAnthropicModelCapability(model ?? this._model);
9557
- }
9558
9395
  async generate(systemPrompt, tools, history, options) {
9559
9396
  const system = systemPrompt ? [{
9560
9397
  type: "text",
@@ -9695,6 +9532,166 @@ var AnthropicChatProvider = class {
9695
9532
  }
9696
9533
  };
9697
9534
  //#endregion
9535
+ //#region ../kosong/src/providers/capability-registry.ts
9536
+ const OPENAI_RESPONSES_DEVELOPER_ROLE_MODELS = new Set([
9537
+ "gpt-4.1",
9538
+ "gpt-4.1-mini",
9539
+ "gpt-4.1-nano",
9540
+ "gpt-5-codex",
9541
+ "o1",
9542
+ "o1-mini",
9543
+ "o1-pro",
9544
+ "o3",
9545
+ "o3-mini",
9546
+ "o3-pro",
9547
+ "o4-mini"
9548
+ ]);
9549
+ const OPENAI_VISION_TOOL_PREFIXES = [
9550
+ "gpt-4o",
9551
+ "gpt-4-turbo",
9552
+ "gpt-4.1",
9553
+ "gpt-4.5"
9554
+ ];
9555
+ const CLAUDE_VISION_TOOL_PREFIXES = [
9556
+ "claude-3-",
9557
+ "claude-3.5-",
9558
+ "claude-3.7-"
9559
+ ];
9560
+ const CLAUDE_THINKING_VISION_TOOL_PREFIXES = [
9561
+ "claude-opus-4",
9562
+ "claude-sonnet-4",
9563
+ "claude-haiku-4",
9564
+ "claude-fable"
9565
+ ];
9566
+ const GEMINI_CATALOGUED_PREFIXES = [
9567
+ "gemini-1.5-pro",
9568
+ "gemini-1.5-flash",
9569
+ "gemini-2.0-flash",
9570
+ "gemini-2.0-pro",
9571
+ "gemini-2.5-pro",
9572
+ "gemini-2.5-flash"
9573
+ ];
9574
+ const OPENAI_REASONING_CAPABILITY = Object.freeze({
9575
+ image_in: false,
9576
+ video_in: false,
9577
+ audio_in: false,
9578
+ thinking: true,
9579
+ tool_use: true,
9580
+ max_context_tokens: 0
9581
+ });
9582
+ const OPENAI_VISION_TOOL_CAPABILITY = Object.freeze({
9583
+ image_in: true,
9584
+ video_in: false,
9585
+ audio_in: false,
9586
+ thinking: false,
9587
+ tool_use: true,
9588
+ max_context_tokens: 0
9589
+ });
9590
+ const OPENAI_TEXT_TOOL_CAPABILITY = Object.freeze({
9591
+ image_in: false,
9592
+ video_in: false,
9593
+ audio_in: false,
9594
+ thinking: false,
9595
+ tool_use: true,
9596
+ max_context_tokens: 0
9597
+ });
9598
+ const ANTHROPIC_VISION_TOOL_CAPABILITY = Object.freeze({
9599
+ image_in: true,
9600
+ video_in: false,
9601
+ audio_in: false,
9602
+ thinking: false,
9603
+ tool_use: true,
9604
+ max_context_tokens: 0
9605
+ });
9606
+ const ANTHROPIC_THINKING_VISION_TOOL_CAPABILITY = Object.freeze({
9607
+ image_in: true,
9608
+ video_in: false,
9609
+ audio_in: false,
9610
+ thinking: true,
9611
+ tool_use: true,
9612
+ max_context_tokens: 0
9613
+ });
9614
+ const GEMINI_MULTIMODAL_TOOL_CAPABILITY = Object.freeze({
9615
+ image_in: true,
9616
+ video_in: true,
9617
+ audio_in: true,
9618
+ thinking: false,
9619
+ tool_use: true,
9620
+ max_context_tokens: 0
9621
+ });
9622
+ const GEMINI_THINKING_MULTIMODAL_TOOL_CAPABILITY = Object.freeze({
9623
+ image_in: true,
9624
+ video_in: true,
9625
+ audio_in: true,
9626
+ thinking: true,
9627
+ tool_use: true,
9628
+ max_context_tokens: 0
9629
+ });
9630
+ const OPENAI_LEGACY_CAPABILITY_CATALOG = [
9631
+ {
9632
+ matches: isOpenAIReasoningModel,
9633
+ capability: OPENAI_REASONING_CAPABILITY
9634
+ },
9635
+ {
9636
+ matches: (name) => hasPrefix(name, OPENAI_VISION_TOOL_PREFIXES),
9637
+ capability: OPENAI_VISION_TOOL_CAPABILITY
9638
+ },
9639
+ {
9640
+ matches: (name) => name.startsWith("gpt-3.5-turbo"),
9641
+ capability: OPENAI_TEXT_TOOL_CAPABILITY
9642
+ }
9643
+ ];
9644
+ const OPENAI_RESPONSES_CAPABILITY_CATALOG = [{
9645
+ matches: isOpenAIReasoningModel,
9646
+ capability: OPENAI_REASONING_CAPABILITY
9647
+ }, {
9648
+ matches: (name) => hasPrefix(name, OPENAI_VISION_TOOL_PREFIXES),
9649
+ capability: OPENAI_VISION_TOOL_CAPABILITY
9650
+ }];
9651
+ const ANTHROPIC_CAPABILITY_CATALOG = [{
9652
+ matches: (name) => hasPrefix(name, CLAUDE_VISION_TOOL_PREFIXES),
9653
+ capability: ANTHROPIC_VISION_TOOL_CAPABILITY
9654
+ }, {
9655
+ matches: (name) => hasPrefix(name, CLAUDE_THINKING_VISION_TOOL_PREFIXES),
9656
+ capability: ANTHROPIC_THINKING_VISION_TOOL_CAPABILITY
9657
+ }];
9658
+ function normalizeModelName(modelName) {
9659
+ return modelName.toLowerCase();
9660
+ }
9661
+ function hasPrefix(modelName, prefixes) {
9662
+ return prefixes.some((prefix) => modelName.startsWith(prefix));
9663
+ }
9664
+ function isOpenAIReasoningModel(modelName) {
9665
+ return /^o\d/.test(modelName);
9666
+ }
9667
+ function capabilityFromCatalog(modelName, catalog) {
9668
+ const normalized = normalizeModelName(modelName);
9669
+ for (const entry of catalog) if (entry.matches(normalized)) return entry.capability;
9670
+ return UNKNOWN_CAPABILITY;
9671
+ }
9672
+ function getOpenAILegacyModelCapability(modelName) {
9673
+ return capabilityFromCatalog(modelName, OPENAI_LEGACY_CAPABILITY_CATALOG);
9674
+ }
9675
+ function getOpenAIResponsesModelCapability(modelName) {
9676
+ return capabilityFromCatalog(modelName, OPENAI_RESPONSES_CAPABILITY_CATALOG);
9677
+ }
9678
+ function getAnthropicModelCapability(modelName) {
9679
+ return capabilityFromCatalog(modelName, ANTHROPIC_CAPABILITY_CATALOG);
9680
+ }
9681
+ function getGoogleGenAIModelCapability(modelName) {
9682
+ const normalized = normalizeModelName(modelName);
9683
+ if (!normalized.startsWith("gemini-")) return UNKNOWN_CAPABILITY;
9684
+ if (!hasPrefix(normalized, GEMINI_CATALOGUED_PREFIXES)) return UNKNOWN_CAPABILITY;
9685
+ if (normalized.startsWith("gemini-2.5-") || normalized.includes("thinking")) return GEMINI_THINKING_MULTIMODAL_TOOL_CAPABILITY;
9686
+ return GEMINI_MULTIMODAL_TOOL_CAPABILITY;
9687
+ }
9688
+ function usesOpenAIResponsesDeveloperRole(modelName) {
9689
+ const normalized = normalizeModelName(modelName);
9690
+ if (OPENAI_RESPONSES_DEVELOPER_ROLE_MODELS.has(normalized)) return true;
9691
+ for (const cataloguedModel of OPENAI_RESPONSES_DEVELOPER_ROLE_MODELS) if (normalized.startsWith(cataloguedModel + "-")) return true;
9692
+ return false;
9693
+ }
9694
+ //#endregion
9698
9695
  //#region ../../node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry_operation.js
9699
9696
  var require_retry_operation$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9700
9697
  function RetryOperation(timeouts, options) {
@@ -38362,9 +38359,6 @@ var GoogleGenAIChatProvider = class {
38362
38359
  ...this._generationKwargs
38363
38360
  };
38364
38361
  }
38365
- getCapability(model) {
38366
- return getGoogleGenAIModelCapability(model ?? this._model);
38367
- }
38368
38362
  async generate(systemPrompt, tools, history, options) {
38369
38363
  if (options?.signal?.aborted === true) throw createAbortError();
38370
38364
  const contents = messagesToGoogleGenAIContents(history);
@@ -38746,9 +38740,29 @@ function normalizeProperty(node) {
38746
38740
  if (Array.isArray(enumValues) && enumValues.length > 0) node["type"] = inferTypeFromValues(enumValues);
38747
38741
  else if (hasOwn$2(node, "const")) node["type"] = inferTypeFromValues([node["const"]]);
38748
38742
  else node["type"] = inferTypeFromStructure(node);
38743
+ } else if (!hasAnyKey(node, TYPE_COMPLETION_SKIP_KEYS) && typeof node["type"] === "string") {
38744
+ const enumValues = node["enum"];
38745
+ if (Array.isArray(enumValues) && enumValues.length > 0) try {
38746
+ const inferred = inferTypeFromValues(enumValues);
38747
+ if (node["type"] !== inferred) {
38748
+ node["type"] = inferred;
38749
+ removeIrrelevantStructureKeys(node, inferred);
38750
+ }
38751
+ } catch {}
38752
+ else if (hasOwn$2(node, "const")) try {
38753
+ const inferred = inferTypeFromValues([node["const"]]);
38754
+ if (node["type"] !== inferred) {
38755
+ node["type"] = inferred;
38756
+ removeIrrelevantStructureKeys(node, inferred);
38757
+ }
38758
+ } catch {}
38749
38759
  }
38750
38760
  recurseSchema(node);
38751
38761
  }
38762
+ function removeIrrelevantStructureKeys(node, newType) {
38763
+ if (newType !== "object") for (const key of OBJECT_STRUCTURE_KEYS) delete node[key];
38764
+ if (newType !== "array") for (const key of ARRAY_STRUCTURE_KEYS) delete node[key];
38765
+ }
38752
38766
  function inferTypeFromStructure(schema) {
38753
38767
  if (hasAnyKey(schema, OBJECT_STRUCTURE_KEYS)) return "object";
38754
38768
  if (hasAnyKey(schema, ARRAY_STRUCTURE_KEYS)) return "array";
@@ -46219,9 +46233,6 @@ var KimiChatProvider = class {
46219
46233
  throw convertOpenAIError(error);
46220
46234
  }
46221
46235
  }
46222
- getCapability(_model) {
46223
- return UNKNOWN_CAPABILITY;
46224
- }
46225
46236
  withThinking(effort) {
46226
46237
  const thinking = { type: effort === "off" ? "disabled" : "enabled" };
46227
46238
  let reasoningEffort;
@@ -46526,9 +46537,6 @@ var OpenAILegacyChatProvider = class {
46526
46537
  ...normalizeGenerationKwargs(this._model, this._generationKwargs)
46527
46538
  };
46528
46539
  }
46529
- getCapability(model) {
46530
- return getOpenAILegacyModelCapability(model ?? this._model);
46531
- }
46532
46540
  async generate(systemPrompt, tools, history, options) {
46533
46541
  const messages = [];
46534
46542
  if (systemPrompt) messages.push({
@@ -47247,9 +47255,6 @@ var OpenAIResponsesChatProvider = class {
47247
47255
  ...this._generationKwargs
47248
47256
  };
47249
47257
  }
47250
- getCapability(model) {
47251
- return getOpenAIResponsesModelCapability(model ?? this._model);
47252
- }
47253
47258
  async generate(systemPrompt, tools, history, options) {
47254
47259
  const input = [];
47255
47260
  const normalizedHistory = normalizeToolCallIdsForProvider(history, OPENAI_RESPONSES_TOOL_CALL_ID_POLICY);
@@ -47337,6 +47342,25 @@ function createProvider(config) {
47337
47342
  default: throw new Error(`Unknown provider type: ${String(config)}`);
47338
47343
  }
47339
47344
  }
47345
+ /**
47346
+ * Look up the declared {@link ModelCapability} for a `(wire, model)` pair.
47347
+ *
47348
+ * This is a pure static table lookup — it does not instantiate a provider.
47349
+ * Unknown / uncatalogued models (and the Kimi wire, whose capabilities come
47350
+ * from the host's catalog/config rather than the model name) return
47351
+ * {@link UNKNOWN_CAPABILITY} so capability checks stay non-fatal.
47352
+ */
47353
+ function getModelCapability(wire, modelName) {
47354
+ switch (wire) {
47355
+ case "anthropic": return getAnthropicModelCapability(modelName);
47356
+ case "openai": return getOpenAILegacyModelCapability(modelName);
47357
+ case "openai_responses": return getOpenAIResponsesModelCapability(modelName);
47358
+ case "google-genai":
47359
+ case "vertexai": return getGoogleGenAIModelCapability(modelName);
47360
+ case "kimi": return UNKNOWN_CAPABILITY;
47361
+ default: return UNKNOWN_CAPABILITY;
47362
+ }
47363
+ }
47340
47364
  //#endregion
47341
47365
  //#region ../kosong/src/catalog.ts
47342
47366
  const KNOWN_WIRE_TYPES = [
@@ -54781,7 +54805,7 @@ function applyCompletionBudget(args) {
54781
54805
  }
54782
54806
  //#endregion
54783
54807
  //#region ../agent-core/src/agent/compaction/compaction-instruction.md?raw
54784
- var compaction_instruction_default = "\n--- This message is a direct task, not part of the above conversation ---\n\nYou are now given a task to compact this conversation context according to specific priorities and output requirements.\n\nOutput text only. DO NOT CALL ANY TOOLS. Calling tools will be rejected and fails the task. You already have all the information you need in the conversation history. You have only one chance.\n\nThe goal of compaction is to keep essential code patterns, technical details, and architectural decisions for continuing development without losing context after the above messages are cleared work.\n\n{{ customInstruction }}\n\n<!-- Compression Priorities (in order) -->\n\n1. **Current Task State**: What is being worked on RIGHT NOW\n2. **Errors & Solutions**: All encountered errors and their resolutions\n3. **Code Evolution**: Final working versions only (remove intermediate attempts)\n4. **System Context**: Project structure, dependencies, environment setup\n5. **Design Decisions**: Architectural choices and their rationale\n6. **TODO Items**: Unfinished tasks and known issues\n\n<!-- Required Output Structure -->\n\n## Current Focus\n\n[What we're working on now]\n\n## Environment\n\n- [Key setup/config points]\n- ...\n\n## Completed Tasks\n\n- [Task]: [Brief outcome]\n- ...\n\n## Active Issues\n\n- [Issue]: [Status/Next steps]\n- ...\n\n## Code State\n\n### [Critical file name]\n\n[Brief description of the file's purpose and current state]\n\n```\n[The latest version of critical code snippets in this file, <20 lines]\n```\n\n### [Critical file name]\n\n- [Useful classes/methods/functions]: [Brief description/usage]\n- ...\n\n<!-- Omit non-critical code, intermediate attempts, and resolved errors -->\n\n## Important Context\n\n- [Any crucial information not covered above]\n- ...\n\n## All User Messages\n\n- [Detailed non tool use user message]\n- ...\n";
54808
+ var compaction_instruction_default = "\n--- This message is a direct task, not part of the above conversation ---\n\nYou are now given a task to compact this conversation context according to specific priorities and output requirements.\n\nOutput text only. DO NOT CALL ANY TOOLS. Calling tools will be rejected and fails the task. You already have all the information you need in the conversation history. You have only one chance.\n\nThe goal of compaction is to keep essential code patterns, technical details, and architectural decisions for continuing development without losing context after the above messages are cleared work.\n\n{{ customInstruction }}\n\n<!-- Compression Priorities (in order) -->\n\n1. **Current Task State**: What is being worked on RIGHT NOW\n2. **Errors & Solutions**: All encountered errors and their resolutions\n3. **Code Evolution**: Final working versions only (remove intermediate attempts)\n4. **System Context**: Project structure, dependencies, environment setup\n5. **Design Decisions**: Architectural choices and their rationale\n6. **TODO Items**: Unfinished tasks and known issues\n\n<!-- Required Output Structure -->\n\n## Current Focus\n\n[What we're working on now]\n\n## Environment\n\n- [Key setup/config points]\n- ...\n\n## Completed Tasks\n\n- [Task]: [Brief outcome]\n- ...\n\n## Active Issues\n\n- [Issue]: [Status/Next steps]\n- ...\n\n## Code State\n\n### [Critical file name]\n\n[Brief description of the file's purpose and current state]\n\n```\n[The latest version of critical code snippets in this file, <20 lines]\n```\n\n### [Critical file name]\n\n- [Useful classes/methods/functions]: [Brief description/usage]\n- ...\n\n<!-- Omit non-critical code, intermediate attempts, and resolved errors -->\n\n## Important Context\n\n- [Any crucial information not covered above]\n- ...\n\n## All User Messages\n\n- [Detailed non tool use user message]\n- ...\n\n<!-- Must output a summary matching the above template in the **final answer**, not in thinking. -->\n";
54785
54809
  //#endregion
54786
54810
  //#region ../agent-core/src/agent/compaction/render-messages.ts
54787
54811
  function renderMessagesToText(messages) {
@@ -55074,7 +55098,9 @@ var DefaultCompactionStrategy = class {
55074
55098
  * results for one exchange land consecutively before the next non-tool
55075
55099
  * message. So if the suffix starts with a tool result, its `asst_w_tc`
55076
55100
  * must be in the compacted prefix, which would orphan that result
55077
- * (e.g. splitting between tool_a and tool_b of a parallel call).
55101
+ * (e.g. splitting between tool_a and tool_b of a parallel call), AND
55102
+ * - the compacted prefix itself does not end with an unresolved tool
55103
+ * exchange, because pending tool results must remain in the retained tail.
55078
55104
  */
55079
55105
  function canSplitAfter(messages, index) {
55080
55106
  const m = messages[index];
@@ -55082,8 +55108,23 @@ function canSplitAfter(messages, index) {
55082
55108
  if (m.role === "user") return false;
55083
55109
  if (m.role === "assistant" && m.toolCalls.length > 0) return false;
55084
55110
  if (messages[index + 1]?.role === "tool") return false;
55111
+ if (prefixEndsWithOpenToolExchange(messages, index)) return false;
55085
55112
  return true;
55086
55113
  }
55114
+ function prefixEndsWithOpenToolExchange(messages, index) {
55115
+ if (messages[index]?.role !== "tool") return false;
55116
+ let toolResultCount = 0;
55117
+ for (let i = index; i >= 0; i--) {
55118
+ const message = messages[i];
55119
+ if (message === void 0) return false;
55120
+ if (message.role === "tool") {
55121
+ toolResultCount++;
55122
+ continue;
55123
+ }
55124
+ return message.role === "assistant" && message.toolCalls.length > toolResultCount;
55125
+ }
55126
+ return false;
55127
+ }
55087
55128
  var CompactionTruncatedError = class extends Error {
55088
55129
  constructor() {
55089
55130
  super("Compaction response was truncated before producing a complete summary.");
@@ -56964,6 +57005,7 @@ const TOOL_ERROR_STATUS = "<system>ERROR: Tool execution failed.</system>";
56964
57005
  const TOOL_EMPTY_STATUS = "<system>Tool output is empty.</system>";
56965
57006
  const TOOL_EMPTY_ERROR_STATUS = "<system>ERROR: Tool execution failed. Tool output is empty.</system>";
56966
57007
  const TOOL_OUTPUT_EMPTY_TEXT = "Tool output is empty.";
57008
+ const TOOL_INTERRUPTED_ON_RESUME_OUTPUT = "Tool execution was interrupted before its result was recorded. Do not assume the tool completed successfully.";
56967
57009
  var ContextMemory = class {
56968
57010
  agent;
56969
57011
  _history = [];
@@ -57119,6 +57161,20 @@ var ContextMemory = class {
57119
57161
  this.clear();
57120
57162
  this.pushHistory(...trimTrailingOpenToolExchange(source.project(source.history)));
57121
57163
  }
57164
+ finishResume() {
57165
+ const interruptedToolCallIds = [...this.pendingToolResultIds];
57166
+ this.openSteps.clear();
57167
+ if (interruptedToolCallIds.length === 0) return;
57168
+ for (const toolCallId of interruptedToolCallIds) this.appendLoopEvent({
57169
+ type: "tool.result",
57170
+ parentUuid: toolCallId,
57171
+ toolCallId,
57172
+ result: {
57173
+ output: TOOL_INTERRUPTED_ON_RESUME_OUTPUT,
57174
+ isError: true
57175
+ }
57176
+ });
57177
+ }
57122
57178
  appendLoopEvent(event) {
57123
57179
  this.agent.records.logRecord({
57124
57180
  type: "context.append_loop_event",
@@ -62456,8 +62512,7 @@ var AgentRecords = class {
62456
62512
  this.persistence.append({
62457
62513
  type: "metadata",
62458
62514
  protocol_version: "1.4",
62459
- created_at: Date.now(),
62460
- app_version: this.agent.appVersion
62515
+ created_at: Date.now()
62461
62516
  });
62462
62517
  this.metadataInitialized = true;
62463
62518
  }
@@ -62506,17 +62561,6 @@ var AgentRecords = class {
62506
62561
  await this.persistence.flush();
62507
62562
  }
62508
62563
  if (this.agent.blobStore !== void 0) for (const msg of this.agent.context.history) await this.agent.blobStore.rehydrateParts(msg.content);
62509
- const firstRecord = replayedRecords[0];
62510
- if (firstRecord?.type === "metadata" && firstRecord.app_version !== this.agent.appVersion) {
62511
- this.persistence.append({
62512
- type: "metadata",
62513
- protocol_version: "1.4",
62514
- created_at: Date.now(),
62515
- app_version: this.agent.appVersion,
62516
- resumed: true
62517
- });
62518
- await this.persistence.flush();
62519
- }
62520
62564
  return { warning };
62521
62565
  }
62522
62566
  async flush() {
@@ -62527,13 +62571,14 @@ var AgentRecords = class {
62527
62571
  //#region ../agent-core/src/agent/replay/index.ts
62528
62572
  var ReplayBuilder = class {
62529
62573
  agent;
62574
+ postRestoring = false;
62530
62575
  captureLiveRecords = false;
62531
62576
  records = [];
62532
62577
  constructor(agent) {
62533
62578
  this.agent = agent;
62534
62579
  }
62535
62580
  push(record) {
62536
- if (this.captureLiveRecords || this.agent.records.restoring) this.records.push({
62581
+ if (this.captureLiveRecords || this.agent.records.restoring || this.postRestoring) this.records.push({
62537
62582
  ...record,
62538
62583
  time: this.agent.records.restoring?.time ?? Date.now()
62539
62584
  });
@@ -66625,7 +66670,7 @@ function isWithin$1(child, parent) {
66625
66670
  //#endregion
66626
66671
  //#region ../agent-core/src/skill/registry.ts
66627
66672
  const LISTING_DESC_MAX = 250;
66628
- var SkillRegistry = class {
66673
+ var SessionSkillRegistry = class {
66629
66674
  byName = /* @__PURE__ */ new Map();
66630
66675
  byPluginAndName = /* @__PURE__ */ new Map();
66631
66676
  roots = [];
@@ -66789,6 +66834,7 @@ function renderSkillAttributes(input) {
66789
66834
  ["name", input.skillName],
66790
66835
  ["trigger", input.trigger],
66791
66836
  ["source", input.skillSource],
66837
+ ["dir", input.skillDir],
66792
66838
  ["args", input.skillArgs]
66793
66839
  ].filter((item) => item[1] !== void 0).map(([name, value]) => ` ${name}="${escapeXml(value)}"`).join("");
66794
66840
  }
@@ -66813,7 +66859,8 @@ var SkillManager = class {
66813
66859
  skillName: skill.name,
66814
66860
  skillArgs,
66815
66861
  skillContent,
66816
- skillSource: skill.source
66862
+ skillSource: skill.source,
66863
+ skillDir: skill.dir
66817
66864
  })
66818
66865
  }];
66819
66866
  this.recordActivation({
@@ -79838,7 +79885,7 @@ function stableHash8(input) {
79838
79885
  /**
79839
79886
  * Synthetic `mcp__<server>__authenticate` tool.
79840
79887
  *
79841
- * When an MCP HTTP server lands in the `needs-auth` state — i.e. its
79888
+ * When a remote MCP server lands in the `needs-auth` state — i.e. its
79842
79889
  * initial connection failed with a 401 / `UnauthorizedError` and no static
79843
79890
  * bearer token is configured — the {@link ToolManager} swaps the real MCP
79844
79891
  * tool list for this single tool. Calling it:
@@ -80195,12 +80242,15 @@ async function collectEntries(kaos, dirPath, maxWidth) {
80195
80242
  readable: true
80196
80243
  };
80197
80244
  }
80245
+ function shouldCollapseDirectory(entry, options) {
80246
+ return options.collapseHiddenDirs === true && entry.isDir && entry.name.startsWith(".");
80247
+ }
80198
80248
  /**
80199
80249
  * Return a 2-level tree listing of `workDir` suitable for inclusion in a
80200
80250
  * tool error message. Returns `"(empty directory)"` if the directory is
80201
80251
  * empty, or an error marker line if the directory itself is unreadable.
80202
80252
  */
80203
- async function listDirectory(kaos, workDir = kaos.getcwd()) {
80253
+ async function listDirectory(kaos, workDir = kaos.getcwd(), options = {}) {
80204
80254
  const lines = [];
80205
80255
  const { entries, total, readable } = await collectEntries(kaos, workDir, 30);
80206
80256
  if (!readable) return "[not readable]";
@@ -80213,6 +80263,7 @@ async function listDirectory(kaos, workDir = kaos.getcwd()) {
80213
80263
  const connector = isLast ? "└── " : "├── ";
80214
80264
  if (isDir) {
80215
80265
  lines.push(`${connector}${name}/`);
80266
+ if (shouldCollapseDirectory(entry, options)) continue;
80216
80267
  const childPrefix = isLast ? " " : "│ ";
80217
80268
  const child = await collectEntries(kaos, join$1(workDir, name), 10);
80218
80269
  if (!child.readable) {
@@ -80236,10 +80287,11 @@ async function listDirectory(kaos, workDir = kaos.getcwd()) {
80236
80287
  //#endregion
80237
80288
  //#region ../agent-core/src/profile/context.ts
80238
80289
  const AGENTS_MD_MAX_BYTES = 32 * 1024;
80290
+ const AGENTS_MD_TRUNCATION_MARKER = "<!-- Some AGENTS.md files were truncated or omitted to fit the 32 KB budget -->";
80239
80291
  const S_IFMT$3 = 61440;
80240
80292
  const S_IFREG$1 = 32768;
80241
80293
  async function prepareSystemPromptContext(kaos, brandHome) {
80242
- const [cwdListing, agentsMd] = await Promise.all([listDirectory(kaos), loadAgentsMd(kaos, brandHome)]);
80294
+ const [cwdListing, agentsMd] = await Promise.all([listDirectory(kaos, void 0, { collapseHiddenDirs: true }), loadAgentsMd(kaos, brandHome)]);
80243
80295
  return {
80244
80296
  cwdListing,
80245
80297
  agentsMd
@@ -80318,6 +80370,7 @@ async function isFile$2(kaos, path) {
80318
80370
  function renderAgentFiles(files) {
80319
80371
  if (files.length === 0) return "";
80320
80372
  let remaining = AGENTS_MD_MAX_BYTES;
80373
+ let didTruncate = false;
80321
80374
  const budgeted = Array.from({ length: files.length });
80322
80375
  for (let i = files.length - 1; i >= 0; i--) {
80323
80376
  const file = files[i];
@@ -80331,17 +80384,22 @@ function renderAgentFiles(files) {
80331
80384
  content: ""
80332
80385
  };
80333
80386
  remaining = 0;
80387
+ didTruncate = true;
80334
80388
  continue;
80335
80389
  }
80336
80390
  let content = file.content;
80337
- if (byteLength(content) > remaining) content = truncateUtf8(content, remaining).trim();
80391
+ if (byteLength(content) > remaining) {
80392
+ content = truncateUtf8(content, remaining).trim();
80393
+ didTruncate = true;
80394
+ }
80338
80395
  remaining -= byteLength(content);
80339
80396
  budgeted[i] = {
80340
80397
  path: file.path,
80341
80398
  content
80342
80399
  };
80343
80400
  }
80344
- return budgeted.filter((file) => file !== void 0 && file.content.length > 0).map((file) => `${annotationFor(file.path)}${file.content}`).join("\n\n");
80401
+ const rendered = budgeted.filter((file) => file !== void 0 && file.content.length > 0).map((file) => `${annotationFor(file.path)}${file.content}`).join("\n\n");
80402
+ return didTruncate ? `${AGENTS_MD_TRUNCATION_MARKER}\n${rendered}` : rendered;
80345
80403
  }
80346
80404
  function truncateUtf8(text, maxBytes) {
80347
80405
  let result = text;
@@ -80540,7 +80598,7 @@ const PROFILE_SOURCES = {
80540
80598
  "profile/default/coder.yaml": coder_default,
80541
80599
  "profile/default/explore.yaml": explore_default,
80542
80600
  "profile/default/plan.yaml": "extends: agent\nname: plan\npromptVars:\n roleAdditional: |\n You are now running as a subagent. All the `user` messages are sent by the main agent. The main agent cannot see your context, it can only see your last message when you finish the task. You must treat the parent agent as your caller. Do not directly ask the end user questions. If something is unclear, explain the ambiguity in your final summary to the parent agent.\n\n Before designing your implementation plan, consider whether you fully understand the codebase areas relevant to the task. If not, recommend the parent agent to use the explore agent (subagent_type=\"explore\") to investigate key questions first. In your response, clearly state:\n 1. What you already know from the information provided\n 2. What questions remain unanswered that would benefit from explore agent investigation\n 3. Your implementation plan (either preliminary if questions remain, or final if sufficient context exists)\nwhenToUse: |\n Use this agent when the parent agent needs a step-by-step implementation plan, key file identification, and architectural trade-off analysis before code changes are made.\ntools:\n - Read\n - ReadMediaFile\n - Glob\n - Grep\n - WebSearch\n - FetchURL\n",
80543
- "profile/default/system.md": "You are Kimi Code CLI, an interactive general AI agent running on a user's computer.\n\nYour primary goal is to help users with software engineering tasks by taking action — use the tools available to you to make real changes on the user's system. You should also answer questions when asked. Always adhere strictly to the following system instructions and the user's requirements.\n\n{{ ROLE_ADDITIONAL }}\n\n# Prompt and Tool Use\n\nThe user's messages may contain questions and/or task descriptions in natural language, code snippets, logs, file paths, or other forms of information. Read them, understand them and do what the user requested. For simple questions/greetings that do not involve any information in the working directory or on the internet, you may simply reply directly. For anything else, default to taking action with tools. When the request could be interpreted as either a question to answer or a task to complete, treat it as a task.\n\nWhen handling the user's request, if it involves creating, modifying, or running code or files, you MUST use the appropriate tools (e.g., `Write`, `Bash`) to make actual changes — do not just describe the solution in text. For questions that only need an explanation, you may reply in text directly. When calling tools, do not provide explanations because the tool calls themselves should be self-explanatory. You MUST follow the description of each tool and its parameters when calling tools.\n\nIf the `Agent` tool is available, you can use it to delegate a focused subtask to a subagent instance. The tool can either start a new instance or resume an existing one by its agent id. Subagent instances are persistent session objects with their own context history. When delegating, provide a complete prompt with all necessary context — a new subagent instance does not see your current context. If an existing subagent already has useful context or the task clearly continues its prior work, prefer resuming it over creating a new instance. Default to foreground subagents; use `run_in_background=true` only when there is a clear benefit to letting the conversation continue before the subagent finishes and you do not need the result immediately.\n\nYou have the capability to output any number of tool calls in a single response. If you anticipate making multiple non-interfering tool calls, you are HIGHLY RECOMMENDED to make them in parallel to significantly improve efficiency. This is very important to your performance.\n\nThe results of the tool calls will be returned to you in a tool message. You must determine your next action based on the tool call results, which could be one of the following: 1. Continue working on the task, 2. Inform the user that the task is completed or has failed, or 3. Ask the user for more information.\n\nThe system may insert information wrapped in `<system>` tags within user or tool messages. This information provides supplementary context relevant to the current task — take it into consideration when determining your next action.\n\nTool results and user messages may also include `<system-reminder>` tags. Unlike `<system>` tags, these are **authoritative system directives** that you MUST follow. They bear no direct relation to the specific tool results or user messages in which they appear. Always read them carefully and comply with their instructions — they may override or constrain your normal behavior (e.g., restricting you to read-only actions during plan mode).\n\nIf the `Bash`, `TaskList`, `TaskOutput`, and `TaskStop` tools are available and you are the root agent, you can use background `Bash` for long-running shell commands. Launch it via `Bash` with `run_in_background=true` and a short `description`. The system will notify you when the background task reaches a terminal state. Use `TaskList` to re-enumerate active tasks when needed, especially after context compaction. Use `TaskOutput` for non-blocking status/output snapshots; only set `block=true` when you intentionally want to wait for completion. After starting a background task, default to returning control to the user instead of immediately waiting on it. Use `TaskStop` only when you need to cancel the task. For human users in the interactive shell, the only task-management slash command is `/tasks`. Do not tell users to run `/task`, `/tasks list`, `/tasks output`, `/tasks stop`, or any other invented slash subcommands. If you are a subagent or these tools are not available, do not assume you can create or control background tasks.\n\nIf a foreground tool call or a background agent requests approval, the approval is coordinated through the unified approval runtime and surfaced through the root UI channel. Do not assume approvals are local to a single subagent turn.\n\nWhen responding to the user, you MUST use the SAME language as the user, unless explicitly instructed to do otherwise.\n\n# General Guidelines for Coding\n\nWhen building something from scratch, you should:\n\n- Understand the user's requirements.\n- Ask the user for clarification if there is anything unclear.\n- Design the architecture and make a plan for the implementation.\n- Write the code in a modular and maintainable way.\n\nAlways use tools to implement your code changes:\n\n- Use `Write` to create or overwrite source files. Code that only appears in your text response is NOT saved to the file system and will not take effect.\n- Use `Bash` to run and test your code after writing it.\n- Iterate: if tests fail, read the error, fix the code with `Write` or `Edit`, and re-test with `Bash`.\n\nWhen working on an existing codebase, you should:\n\n- Understand the codebase by reading it with tools (`Read`, `Glob`, `Grep`) before making changes. Identify the ultimate goal and the most important criteria to achieve the goal.\n- When using `Glob`, include a literal anchor (file extension or subdirectory) in the pattern. Pure wildcards like `*` or `**/*` are rejected by the tool.\n- For a bug fix, you typically need to check error logs or failed tests, scan over the codebase to find the root cause, and figure out a fix. If user mentioned any failed tests, you should make sure they pass after the changes.\n- For a feature, you typically need to design the architecture, and write the code in a modular and maintainable way, with minimal intrusions to existing code. Add new tests if the project already has tests.\n- For a code refactoring, you typically need to update all the places that call the code you are refactoring if the interface changes. DO NOT change any existing logic especially in tests, focus only on fixing any errors caused by the interface changes.\n- Make MINIMAL changes to achieve the goal. This is very important to your performance.\n- Follow the coding style of existing code in the project.\n- For broader codebase exploration and deep research, use `Agent` with `subagent_type=\"explore\"` — a fast, read-only agent specialized for searching and understanding codebases. Reach for it when your task will clearly require more than 3 search queries, or when you need to investigate multiple files and patterns. Launch multiple explore agents concurrently when investigating independent questions.\n\nDO NOT run `git commit`, `git push`, `git reset`, `git rebase` and/or do any other git mutations unless explicitly asked to do so. Ask for confirmation each time when you need to do git mutations, even if the user has confirmed in earlier conversations.\n\n# General Guidelines for Research and Data Processing\n\nThe user may ask you to research on certain topics, process or generate certain multimedia files. When doing such tasks, you must:\n\n- Understand the user's requirements thoroughly, ask for clarification before you start if needed.\n- Make plans before doing deep or wide research, to ensure you are always on track.\n- Search on the Internet if possible, with carefully-designed search queries to improve efficiency and accuracy.\n- Use proper tools or shell commands or Python packages to process or generate images, videos, PDFs, docs, spreadsheets, presentations, or other multimedia files. Detect if there are already such tools in the environment. If you have to install third-party tools/packages, you MUST ensure that they are installed in a virtual/isolated environment.\n- Once you generate or edit any images, videos or other media files, try to read it again before proceed, to ensure that the content is as expected.\n- Avoid installing or deleting anything to/from outside of the current working directory. If you have to do so, ask the user for confirmation.\n\n# Working Environment\n\n## Operating System\n\nYou are running on **{{ KIMI_OS }}**. The Bash tool executes commands using **{{ KIMI_SHELL }}**.\n{% if KIMI_OS == \"Windows\" %}\n\nIMPORTANT: You are on Windows. The Bash tool runs through Git Bash, so use Unix shell syntax inside Bash commands — `/dev/null` not `NUL`, and forward slashes in paths. For file operations, always prefer the built-in tools (Read, Write, Edit, Glob, Grep) over Bash commands — they work reliably across all platforms.\n{% endif %}\n\nThe operating environment is not in a sandbox. Any actions you do will immediately affect the user's system. So you MUST be extremely cautious. Unless being explicitly instructed to do so, you should never access (read/write/execute) files outside of the working directory.\n\n## Date and Time\n\nThe current date and time in ISO format is `{{ KIMI_NOW }}`. This is only a reference for you when searching the web, or checking file modification time, etc. If you need the exact time, use Bash tool with proper command.\n\n## Working Directory\n\nThe current working directory is `{{ KIMI_WORK_DIR }}`. This should be considered as the project root if you are instructed to perform tasks on the project. Every file system operation will be relative to the working directory if you do not explicitly specify the absolute path. Tools may require absolute paths for some parameters, IF SO, YOU MUST use absolute paths for these parameters.\n\nThe directory listing of current working directory is:\n\n```\n{{ KIMI_WORK_DIR_LS }}\n```\n\nUse this as your basic understanding of the project structure. The tree only shows the first two levels; entries marked \"... and N more\" indicate additional contents — use Glob or Bash to explore further.\n{% if KIMI_ADDITIONAL_DIRS_INFO %}\n\n## Additional Directories\n\nThe following directories have been added to the workspace. You can read, write, search, and glob files in these directories as part of your workspace scope.\n\n{{ KIMI_ADDITIONAL_DIRS_INFO }}\n{% endif %}\n\n# Project Information\n\nMarkdown files named `AGENTS.md` usually contain the background, structure, coding styles, user preferences and other relevant information about the project. You should use this information to understand the project and the user's preferences. `AGENTS.md` files may exist at different locations in the project, but typically there is one in the project root.\n\n> Why `AGENTS.md`?\n>\n> `README.md` files are for humans: quick starts, project descriptions, and contribution guidelines. `AGENTS.md` complements this by containing the extra, sometimes detailed context coding agents need: build steps, tests, and conventions that might clutter a README or aren’t relevant to human contributors.\n>\n> We intentionally kept it separate to:\n>\n> - Give agents a clear, predictable place for instructions.\n> - Keep `README`s concise and focused on human contributors.\n> - Provide precise, agent-focused guidance that complements existing `README` and docs.\n\nThe `AGENTS.md` instructions (merged from all applicable directories):\n\n`````````\n{{ KIMI_AGENTS_MD }}\n`````````\n\n`AGENTS.md` files can appear at any level of the project directory tree, including inside `.kimi-code/` directories. Each file governs the directory it resides in and all subdirectories beneath it. When multiple `AGENTS.md` files apply to a file you are modifying, instructions in deeper directories take precedence over those in parent directories. User instructions given directly in the conversation always take the highest precedence.\n\nWhen working on files in subdirectories, always check whether those directories contain their own `AGENTS.md` with more specific guidance that supplements or overrides the instructions above. You may also check `README`/`README.md` files for more information about the project.\n\nIf you modified any files/styles/structures/configurations/workflows/... mentioned in `AGENTS.md` files, you MUST update the corresponding `AGENTS.md` files to keep them up-to-date.\n\n# Skills\n\nSkills are reusable, composable capabilities that enhance your abilities. Each skill is either a self-contained directory with a `SKILL.md` file or a standalone `.md` file that contains instructions, examples, and/or reference material.\n\n## What are skills?\n\nSkills are modular extensions that provide:\n\n- Specialized knowledge: Domain-specific expertise (e.g., PDF processing, data analysis)\n- Workflow patterns: Best practices for common tasks\n- Tool integrations: Pre-configured tool chains for specific operations\n- Reference material: Documentation, templates, and examples\n\n## Available skills\n\nSkills are grouped by scope (`Project`, `User`, `Extra`, `Built-in`) so you can tell where each came from. When the user refers to \"the skill in this project\" or \"the user-scope skill\", use the scope heading to disambiguate. When multiple scopes define a skill with the same name, the more specific scope takes precedence: **Project overrides User overrides Extra overrides Built-in**.\n\n{{ KIMI_SKILLS }}\n\n## How to use skills\n\nIdentify the skills that are likely to be useful for the tasks you are currently working on, read the skill file for detailed instructions, guidelines, scripts and more.\n\nOnly read skill details when needed to conserve the context window.\n\n# Ultimate Reminders\n\nAt any time, you should be HELPFUL, CONCISE, and ACCURATE. Be thorough in your actions — test what you build, verify what you change — not in your explanations.\n\n- Never diverge from the requirements and the goals of the task you work on. Stay on track.\n- Never give the user more than what they want.\n- Try your best to avoid any hallucination. Do fact checking before providing any factual information.\n- Think about the best approach, then take action decisively.\n- Do not give up too early.\n- ALWAYS, keep it stupidly simple. Do not overcomplicate things.\n- When the task requires creating or modifying files, always use tools to do so. Never treat displaying code in your response as a substitute for actually writing it to the file system.\n"
80601
+ "profile/default/system.md": "You are Kimi Code CLI, an interactive general AI agent running on a user's computer.\n\nYour primary goal is to help users with software engineering tasks by taking action — use the tools available to you to make real changes on the user's system. You should also answer questions when asked. Always adhere strictly to the following system instructions and the user's requirements.\n\n{{ ROLE_ADDITIONAL }}\n\n# Prompt and Tool Use\n\nThe user's messages may contain questions and/or task descriptions in natural language, code snippets, logs, file paths, or other forms of information. Read them, understand them and do what the user requested. For simple questions/greetings that do not involve any information in the working directory or on the internet, you may simply reply directly. For anything else, default to taking action with tools. When the request could be interpreted as either a question to answer or a task to complete, treat it as a task.\n\nWhen handling the user's request, if it involves creating, modifying, or running code or files, you MUST use the appropriate tools (e.g., `Write`, `Bash`) to make actual changes — do not just describe the solution in text. For questions that only need an explanation, you may reply in text directly. When calling tools, do not provide detailed explanations or chain-of-thought. For simple requests, call tools directly. For non-trivial or multi-step tasks, first emit one short user-visible sentence in the same language as the user describing what you will do next, then call the tool(s). You MUST follow the description of each tool and its parameters when calling tools.\n\nIf the `Agent` tool is available, you can use it to delegate a focused subtask to a subagent instance. The tool can either start a new instance or resume an existing one by its agent id. Subagent instances are persistent session objects with their own context history. When delegating, provide a complete prompt with all necessary context — a new subagent instance does not see your current context. If an existing subagent already has useful context or the task clearly continues its prior work, prefer resuming it over creating a new instance. Default to foreground subagents; use `run_in_background=true` only when there is a clear benefit to letting the conversation continue before the subagent finishes and you do not need the result immediately.\n\nYou have the capability to output any number of tool calls in a single response. If you anticipate making multiple non-interfering tool calls, you are HIGHLY RECOMMENDED to make them in parallel to significantly improve efficiency. This is very important to your performance.\n\nThe results of the tool calls will be returned to you in a tool message. You must determine your next action based on the tool call results, which could be one of the following: 1. Continue working on the task, 2. Inform the user that the task is completed or has failed, or 3. Ask the user for more information.\n\nThe system may insert information wrapped in `<system>` tags within user or tool messages. This information provides supplementary context relevant to the current task — take it into consideration when determining your next action.\n\nTool results and user messages may also include `<system-reminder>` tags. Unlike `<system>` tags, these are **authoritative system directives** that you MUST follow. They bear no direct relation to the specific tool results or user messages in which they appear. Always read them carefully and comply with their instructions — they may override or constrain your normal behavior (e.g., restricting you to read-only actions during plan mode).\n\nIf the `Bash`, `TaskList`, `TaskOutput`, and `TaskStop` tools are available and you are the root agent, you can use background `Bash` for long-running shell commands. Launch it via `Bash` with `run_in_background=true` and a short `description`. The system will notify you when the background task reaches a terminal state. Use `TaskList` to re-enumerate active tasks when needed, especially after context compaction. Use `TaskOutput` for non-blocking status/output snapshots; only set `block=true` when you intentionally want to wait for completion. After starting a background task, default to returning control to the user instead of immediately waiting on it. Use `TaskStop` only when you need to cancel the task. For human users in the interactive shell, the only task-management slash command is `/tasks`. Do not tell users to run `/task`, `/tasks list`, `/tasks output`, `/tasks stop`, or any other invented slash subcommands. If you are a subagent or these tools are not available, do not assume you can create or control background tasks.\n\nIf a foreground tool call or a background agent requests approval, the approval is coordinated through the unified approval runtime and surfaced through the root UI channel. Do not assume approvals are local to a single subagent turn.\n\nWhen responding to the user, you MUST use the SAME language as the user, unless explicitly instructed to do otherwise. This applies to your reasoning and thinking as well, not just your final reply — think in the user's language, while keeping code, commands, identifiers, file paths, and technical terms in their original form.\n\n# General Guidelines for Coding\n\nWhen building something from scratch, you should:\n\n- Understand the user's requirements.\n- Ask the user for clarification if there is anything unclear.\n- Design the architecture and make a plan for the implementation.\n- Write the code in a modular and maintainable way.\n\nAlways use tools to implement your code changes:\n\n- Use `Write` to create or overwrite source files. Code that only appears in your text response is NOT saved to the file system and will not take effect.\n- Use `Bash` to run and test your code after writing it.\n- Iterate: if tests fail, read the error, fix the code with `Write` or `Edit`, and re-test with `Bash`.\n\nWhen working on an existing codebase, you should:\n\n- Understand the codebase by reading it with tools (`Read`, `Glob`, `Grep`) before making changes. Identify the ultimate goal and the most important criteria to achieve the goal.\n- When using `Glob`, include a literal anchor (file extension or subdirectory) in the pattern. Pure wildcards like `*` or `**/*` are rejected by the tool.\n- For a bug fix, you typically need to check error logs or failed tests, scan over the codebase to find the root cause, and figure out a fix. If user mentioned any failed tests, you should make sure they pass after the changes.\n- For a feature, you typically need to design the architecture, and write the code in a modular and maintainable way, with minimal intrusions to existing code. Add new tests if the project already has tests.\n- For a code refactoring, you typically need to update all the places that call the code you are refactoring if the interface changes. DO NOT change any existing logic especially in tests, focus only on fixing any errors caused by the interface changes.\n- Make MINIMAL changes to achieve the goal. This is very important to your performance.\n- Follow the coding style of existing code in the project.\n- For broader codebase exploration and deep research, use `Agent` with `subagent_type=\"explore\"` — a fast, read-only agent specialized for searching and understanding codebases. Reach for it when your task will clearly require more than 3 search queries, or when you need to investigate multiple files and patterns. Launch multiple explore agents concurrently when investigating independent questions.\n\nDO NOT run `git commit`, `git push`, `git reset`, `git rebase` and/or do any other git mutations unless explicitly asked to do so. Ask for confirmation each time when you need to do git mutations, even if the user has confirmed in earlier conversations.\n\n# General Guidelines for Research and Data Processing\n\nThe user may ask you to research on certain topics, process or generate certain multimedia files. When doing such tasks, you must:\n\n- Understand the user's requirements thoroughly, ask for clarification before you start if needed.\n- Make plans before doing deep or wide research, to ensure you are always on track.\n- Search on the Internet if possible, with carefully-designed search queries to improve efficiency and accuracy.\n- Use proper tools or shell commands or Python packages to process or generate images, videos, PDFs, docs, spreadsheets, presentations, or other multimedia files. Detect if there are already such tools in the environment. If you have to install third-party tools/packages, you MUST ensure that they are installed in a virtual/isolated environment.\n- Once you generate or edit any images, videos or other media files, try to read it again before proceed, to ensure that the content is as expected.\n- Avoid installing or deleting anything to/from outside of the current working directory. If you have to do so, ask the user for confirmation.\n\n# Working Environment\n\n## Operating System\n\nYou are running on **{{ KIMI_OS }}**. The Bash tool executes commands using **{{ KIMI_SHELL }}**.\n{% if KIMI_OS == \"Windows\" %}\n\nIMPORTANT: You are on Windows. The Bash tool runs through Git Bash, so use Unix shell syntax inside Bash commands — `/dev/null` not `NUL`, and forward slashes in paths. For file operations, always prefer the built-in tools (Read, Write, Edit, Glob, Grep) over Bash commands — they work reliably across all platforms.\n{% endif %}\n\nThe operating environment is not in a sandbox. Any actions you do will immediately affect the user's system. So you MUST be extremely cautious. Unless being explicitly instructed to do so, you should never access (read/write/execute) files outside of the working directory.\n\n## Date and Time\n\nThe current date and time in ISO format is `{{ KIMI_NOW }}`. This is only a reference for you when searching the web, or checking file modification time, etc. If you need the exact time, use Bash tool with proper command.\n\n## Working Directory\n\nThe current working directory is `{{ KIMI_WORK_DIR }}`. This should be considered as the project root if you are instructed to perform tasks on the project. Every file system operation will be relative to the working directory if you do not explicitly specify the absolute path. Tools may require absolute paths for some parameters, IF SO, YOU MUST use absolute paths for these parameters.\n\nUse this as your basic understanding of the project structure. The tree only shows the first two levels for normal directories; entries marked \"... and N more\" indicate additional contents. Hidden directories are shown as entries only; their contents are intentionally omitted to reduce noise.\n\nIf the task requires inspecting hidden paths, use `Glob` to discover them (for example `.*`, `.github/**`, `.agents/**`, or `.git/**`), use `Read` for known non-sensitive hidden files, and use `Grep` to search hidden file contents. `Grep` searches hidden files by default but excludes VCS metadata and sensitive files such as `.env`, credential stores, and SSH keys. Use `Bash` only for raw listings like `ls -A` when a dedicated tool is not appropriate.\n\nThe directory listing of current working directory is:\n\n```\n{{ KIMI_WORK_DIR_LS }}\n```\n{% if KIMI_ADDITIONAL_DIRS_INFO %}\n\n## Additional Directories\n\nThe following directories have been added to the workspace. You can read, write, search, and glob files in these directories as part of your workspace scope.\n\n{{ KIMI_ADDITIONAL_DIRS_INFO }}\n{% endif %}\n\n# Project Information\n\nMarkdown files named `AGENTS.md` contain agent-specific instructions such as project structure, build commands, coding style, testing expectations, and user preferences. `README.md` files are still useful for human-facing project context; `AGENTS.md` files are the focused instruction source for coding agents.\n\n`AGENTS.md` files can appear at any level of the project tree, including inside `.kimi-code/` directories. When multiple `AGENTS.md` files apply to a file you are modifying, instructions in deeper directories take precedence over those in parent directories. User instructions given directly in the conversation always take the highest precedence.\n\nWhen working on files in subdirectories, check whether those directories contain their own `AGENTS.md` with more specific guidance. You may also check `README`/`README.md` files for more information about the project. If you modified any files, styles, structures, configurations, workflows, or other conventions mentioned in `AGENTS.md` files, update the corresponding `AGENTS.md` files to keep them current.\n\nThe applicable `AGENTS.md` instructions are:\n\n```````\n{{ KIMI_AGENTS_MD }}\n```````\n\n# Skills\n\nSkills are reusable, composable capabilities that enhance your abilities. Each skill is either a self-contained directory with a `SKILL.md` file or a standalone `.md` file that contains instructions, examples, and/or reference material.\n\n## What are skills?\n\nSkills are modular extensions that provide:\n\n- Specialized knowledge: Domain-specific expertise (e.g., PDF processing, data analysis)\n- Workflow patterns: Best practices for common tasks\n- Tool integrations: Pre-configured tool chains for specific operations\n- Reference material: Documentation, templates, and examples\n\n## How to use skills\n\nIdentify the skills that are likely to be useful for the tasks you are currently working on, read the skill file for detailed instructions, guidelines, scripts and more.\n\nOnly read skill details when needed to conserve the context window.\n\n## Available skills\n\nSkills are grouped by scope (`Project`, `User`, `Extra`, `Built-in`) so you can tell where each came from. When the user refers to \"the skill in this project\" or \"the user-scope skill\", use the scope heading to disambiguate. When multiple scopes define a skill with the same name, the more specific scope takes precedence: **Project overrides User overrides Extra overrides Built-in**.\n\n{{ KIMI_SKILLS }}\n\n# Ultimate Reminders\n\nAt any time, you should be HELPFUL, CONCISE, and ACCURATE. Be thorough in your actions — test what you build, verify what you change — not in your explanations.\n\n- Never diverge from the requirements and the goals of the task you work on. Stay on track.\n- Never give the user more than what they want.\n- Try your best to avoid any hallucination. Do fact checking before providing any factual information.\n- Think about the best approach, then take action decisively.\n- Do not give up too early.\n- ALWAYS, keep it stupidly simple. Do not overcomplicate things.\n- When the task requires creating or modifying files, always use tools to do so. Never treat displaying code in your response as a substitute for actually writing it to the file system.\n"
80544
80602
  };
80545
80603
  const DEFAULT_INIT_PROMPT = init_default;
80546
80604
  const DEFAULT_AGENT_PROFILES = loadAgentProfilesFromSources([
@@ -82682,6 +82740,7 @@ var SkillTool = class SkillTool {
82682
82740
  skillArgs,
82683
82741
  skillContent,
82684
82742
  skillSource: skill.source,
82743
+ skillDir: skill.dir,
82685
82744
  trigger: promptTrigger
82686
82745
  })
82687
82746
  }], origin);
@@ -88517,7 +88576,7 @@ function getSuffix(path) {
88517
88576
  if (idx <= Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\")) + 1) return "";
88518
88577
  return path.slice(idx).toLowerCase();
88519
88578
  }
88520
- function detectFileType(path, header) {
88579
+ function detectFileType(path, header, type = "text") {
88521
88580
  const suffix = getSuffix(path);
88522
88581
  let mediaHint = null;
88523
88582
  if (suffix in TEXT_MIME_BY_SUFFIX) mediaHint = {
@@ -88536,6 +88595,7 @@ function detectFileType(path, header) {
88536
88595
  const buf = toBuffer(header);
88537
88596
  const sniffed = sniffMediaFromMagic(buf);
88538
88597
  if (sniffed) {
88598
+ if (type === "media") return sniffed;
88539
88599
  if (mediaHint) {
88540
88600
  if (sniffed.kind !== mediaHint.kind) return {
88541
88601
  kind: "unknown",
@@ -88545,6 +88605,7 @@ function detectFileType(path, header) {
88545
88605
  }
88546
88606
  return sniffed;
88547
88607
  }
88608
+ if (type === "media" && mediaHint !== null && mediaHint.kind !== "text") return mediaHint;
88548
88609
  if (buf.includes(0)) return {
88549
88610
  kind: "unknown",
88550
88611
  mimeType: ""
@@ -88952,7 +89013,7 @@ var ReadMediaFileTool = class {
88952
89013
  output: "File path cannot be empty."
88953
89014
  };
88954
89015
  try {
88955
- const fileType = detectFileType(safePath, await this.kaos.readBytes(safePath, 512));
89016
+ const fileType = detectFileType(safePath, await this.kaos.readBytes(safePath, 512), "media");
88956
89017
  if (fileType.kind === "text") return {
88957
89018
  isError: true,
88958
89019
  output: `"${args.path}" is a text file. Use Read to read text files.`
@@ -91258,7 +91319,7 @@ var ToolManager = class {
91258
91319
  registerNeedsAuthMcpServer(mcp, entry) {
91259
91320
  this.unregisterMcpServer(entry.name);
91260
91321
  const oauthService = mcp.oauthService;
91261
- const serverUrl = mcp.getHttpServerUrl(entry.name);
91322
+ const serverUrl = mcp.getRemoteServerUrl(entry.name);
91262
91323
  if (oauthService === void 0 || serverUrl === void 0) return;
91263
91324
  const tool = createMcpAuthTool({
91264
91325
  serverName: entry.name,
@@ -91379,6 +91440,9 @@ var ToolManager = class {
91379
91440
  toolServices?.urlFetcher && new FetchURLTool(toolServices.urlFetcher)
91380
91441
  ].filter((tool) => !!tool).map((tool) => [tool.name, tool]));
91381
91442
  }
91443
+ refreshBuiltinTools() {
91444
+ this.initializeBuiltinTools();
91445
+ }
91382
91446
  createVideoUploader(provider) {
91383
91447
  const uploadVideo = provider.uploadVideo?.bind(provider);
91384
91448
  if (uploadVideo === void 0) return void 0;
@@ -91629,7 +91693,6 @@ var Agent$1 = class {
91629
91693
  hooks;
91630
91694
  log;
91631
91695
  telemetry;
91632
- appVersion;
91633
91696
  experimentalFlags;
91634
91697
  blobStore;
91635
91698
  records;
@@ -91663,7 +91726,6 @@ var Agent$1 = class {
91663
91726
  this.subagentHost = options.subagentHost;
91664
91727
  this.mcp = options.mcp;
91665
91728
  this.hooks = options.hookEngine;
91666
- this.appVersion = options.appVersion;
91667
91729
  this.log = options.log ?? log;
91668
91730
  this.telemetry = options.telemetry ?? noopTelemetryClient;
91669
91731
  this.experimentalFlags = options.experimentalFlags ?? new FlagResolver();
@@ -91770,11 +91832,17 @@ var Agent$1 = class {
91770
91832
  }
91771
91833
  async resume() {
91772
91834
  const result = await this.records.replay();
91773
- this.goal.normalizeAfterReplay();
91774
- await this.background.loadFromDisk();
91775
- await this.background.reconcile();
91776
- await this.cron?.loadFromDisk();
91777
- this.turn.finishResume();
91835
+ try {
91836
+ this.replayBuilder.postRestoring = true;
91837
+ this.goal.normalizeAfterReplay();
91838
+ await this.background.loadFromDisk();
91839
+ await this.background.reconcile();
91840
+ await this.cron?.loadFromDisk();
91841
+ this.context.finishResume();
91842
+ this.turn.finishResume();
91843
+ } finally {
91844
+ this.replayBuilder.postRestoring = false;
91845
+ }
91778
91846
  return result;
91779
91847
  }
91780
91848
  get rpcMethods() {
@@ -92087,7 +92155,18 @@ const McpServerHttpConfigSchema = z.object({
92087
92155
  bearerTokenEnvVar: z.string().min(1).optional(),
92088
92156
  ...McpServerCommonFields
92089
92157
  });
92090
- const McpServerConfigDiscriminatedSchema = z.discriminatedUnion("transport", [McpServerStdioConfigSchema, McpServerHttpConfigSchema]);
92158
+ const McpServerSseConfigSchema = z.object({
92159
+ transport: z.literal("sse"),
92160
+ url: z.string().url(),
92161
+ headers: StringRecordSchema.optional(),
92162
+ bearerTokenEnvVar: z.string().min(1).optional(),
92163
+ ...McpServerCommonFields
92164
+ });
92165
+ const McpServerConfigDiscriminatedSchema = z.discriminatedUnion("transport", [
92166
+ McpServerStdioConfigSchema,
92167
+ McpServerHttpConfigSchema,
92168
+ McpServerSseConfigSchema
92169
+ ]);
92091
92170
  const McpServerConfigSchema = z.preprocess((raw) => {
92092
92171
  if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return raw;
92093
92172
  const obj = raw;
@@ -95046,6 +95125,21 @@ function toMcpToolResult(result) {
95046
95125
  };
95047
95126
  }
95048
95127
  //#endregion
95128
+ //#region ../agent-core/src/mcp/client-remote.ts
95129
+ function buildMcpRemoteHeaders(config, envLookup) {
95130
+ const headers = { ...config.headers };
95131
+ if (config.bearerTokenEnvVar !== void 0) {
95132
+ const token = envLookup(config.bearerTokenEnvVar);
95133
+ if (token === void 0 || token.length === 0) throw new KimiError(ErrorCodes.CONFIG_INVALID, `MCP ${config.transport.toUpperCase()} bearer token env var "${config.bearerTokenEnvVar}" is not set or is empty`);
95134
+ for (const key of Object.keys(headers)) if (key.toLowerCase() === "authorization") delete headers[key];
95135
+ headers["Authorization"] = `Bearer ${token}`;
95136
+ }
95137
+ return Object.keys(headers).length > 0 ? headers : void 0;
95138
+ }
95139
+ function isRemoteMcpConfig(config) {
95140
+ return config.transport === "http" || config.transport === "sse";
95141
+ }
95142
+ //#endregion
95049
95143
  //#region ../agent-core/src/mcp/client-http.ts
95050
95144
  /**
95051
95145
  * Wraps the SDK streamable-HTTP transport as a kosong {@link MCPClient}.
@@ -95174,14 +95268,520 @@ function isTerminalTransportError(error) {
95174
95268
  return false;
95175
95269
  }
95176
95270
  function buildMcpHttpHeaders(config, envLookup) {
95177
- const headers = { ...config.headers };
95178
- if (config.bearerTokenEnvVar !== void 0) {
95179
- const token = envLookup(config.bearerTokenEnvVar);
95180
- if (token === void 0 || token.length === 0) throw new KimiError(ErrorCodes.CONFIG_INVALID, `MCP HTTP bearer token env var "${config.bearerTokenEnvVar}" is not set or is empty`);
95181
- for (const key of Object.keys(headers)) if (key.toLowerCase() === "authorization") delete headers[key];
95182
- headers["Authorization"] = `Bearer ${token}`;
95271
+ return buildMcpRemoteHeaders(config, envLookup);
95272
+ }
95273
+ //#endregion
95274
+ //#region ../../node_modules/.pnpm/eventsource@3.0.7/node_modules/eventsource/dist/index.js
95275
+ var ErrorEvent = class extends Event {
95276
+ /**
95277
+ * Constructs a new `ErrorEvent` instance. This is typically not called directly,
95278
+ * but rather emitted by the `EventSource` object when an error occurs.
95279
+ *
95280
+ * @param type - The type of the event (should be "error")
95281
+ * @param errorEventInitDict - Optional properties to include in the error event
95282
+ */
95283
+ constructor(type, errorEventInitDict) {
95284
+ var _a, _b;
95285
+ super(type), this.code = (_a = errorEventInitDict == null ? void 0 : errorEventInitDict.code) != null ? _a : void 0, this.message = (_b = errorEventInitDict == null ? void 0 : errorEventInitDict.message) != null ? _b : void 0;
95183
95286
  }
95184
- return Object.keys(headers).length > 0 ? headers : void 0;
95287
+ /**
95288
+ * Node.js "hides" the `message` and `code` properties of the `ErrorEvent` instance,
95289
+ * when it is `console.log`'ed. This makes it harder to debug errors. To ease debugging,
95290
+ * we explicitly include the properties in the `inspect` method.
95291
+ *
95292
+ * This is automatically called by Node.js when you `console.log` an instance of this class.
95293
+ *
95294
+ * @param _depth - The current depth
95295
+ * @param options - The options passed to `util.inspect`
95296
+ * @param inspect - The inspect function to use (prevents having to import it from `util`)
95297
+ * @returns A string representation of the error
95298
+ */
95299
+ [Symbol.for("nodejs.util.inspect.custom")](_depth, options, inspect) {
95300
+ return inspect(inspectableError(this), options);
95301
+ }
95302
+ /**
95303
+ * Deno "hides" the `message` and `code` properties of the `ErrorEvent` instance,
95304
+ * when it is `console.log`'ed. This makes it harder to debug errors. To ease debugging,
95305
+ * we explicitly include the properties in the `inspect` method.
95306
+ *
95307
+ * This is automatically called by Deno when you `console.log` an instance of this class.
95308
+ *
95309
+ * @param inspect - The inspect function to use (prevents having to import it from `util`)
95310
+ * @param options - The options passed to `Deno.inspect`
95311
+ * @returns A string representation of the error
95312
+ */
95313
+ [Symbol.for("Deno.customInspect")](inspect, options) {
95314
+ return inspect(inspectableError(this), options);
95315
+ }
95316
+ };
95317
+ function syntaxError(message) {
95318
+ const DomException = globalThis.DOMException;
95319
+ return typeof DomException == "function" ? new DomException(message, "SyntaxError") : new SyntaxError(message);
95320
+ }
95321
+ function flattenError(err) {
95322
+ return err instanceof Error ? "errors" in err && Array.isArray(err.errors) ? err.errors.map(flattenError).join(", ") : "cause" in err && err.cause instanceof Error ? `${err}: ${flattenError(err.cause)}` : err.message : `${err}`;
95323
+ }
95324
+ function inspectableError(err) {
95325
+ return {
95326
+ type: err.type,
95327
+ message: err.message,
95328
+ code: err.code,
95329
+ defaultPrevented: err.defaultPrevented,
95330
+ cancelable: err.cancelable,
95331
+ timeStamp: err.timeStamp
95332
+ };
95333
+ }
95334
+ var __typeError = (msg) => {
95335
+ throw TypeError(msg);
95336
+ }, __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg), __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)), __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value), __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value), __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method), _readyState, _url, _redirectUrl, _withCredentials, _fetch, _reconnectInterval, _reconnectTimer, _lastEventId, _controller, _parser, _onError, _onMessage, _onOpen, _EventSource_instances, connect_fn, _onFetchResponse, _onFetchError, getRequestOptions_fn, _onEvent, _onRetryChange, failConnection_fn, scheduleReconnect_fn, _reconnect;
95337
+ var EventSource = class extends EventTarget {
95338
+ constructor(url, eventSourceInitDict) {
95339
+ var _a, _b;
95340
+ super(), __privateAdd(this, _EventSource_instances), this.CONNECTING = 0, this.OPEN = 1, this.CLOSED = 2, __privateAdd(this, _readyState), __privateAdd(this, _url), __privateAdd(this, _redirectUrl), __privateAdd(this, _withCredentials), __privateAdd(this, _fetch), __privateAdd(this, _reconnectInterval), __privateAdd(this, _reconnectTimer), __privateAdd(this, _lastEventId, null), __privateAdd(this, _controller), __privateAdd(this, _parser), __privateAdd(this, _onError, null), __privateAdd(this, _onMessage, null), __privateAdd(this, _onOpen, null), __privateAdd(this, _onFetchResponse, async (response) => {
95341
+ var _a2;
95342
+ __privateGet(this, _parser).reset();
95343
+ const { body, redirected, status, headers } = response;
95344
+ if (status === 204) {
95345
+ __privateMethod(this, _EventSource_instances, failConnection_fn).call(this, "Server sent HTTP 204, not reconnecting", 204), this.close();
95346
+ return;
95347
+ }
95348
+ if (redirected ? __privateSet(this, _redirectUrl, new URL(response.url)) : __privateSet(this, _redirectUrl, void 0), status !== 200) {
95349
+ __privateMethod(this, _EventSource_instances, failConnection_fn).call(this, `Non-200 status code (${status})`, status);
95350
+ return;
95351
+ }
95352
+ if (!(headers.get("content-type") || "").startsWith("text/event-stream")) {
95353
+ __privateMethod(this, _EventSource_instances, failConnection_fn).call(this, "Invalid content type, expected \"text/event-stream\"", status);
95354
+ return;
95355
+ }
95356
+ if (__privateGet(this, _readyState) === this.CLOSED) return;
95357
+ __privateSet(this, _readyState, this.OPEN);
95358
+ const openEvent = new Event("open");
95359
+ if ((_a2 = __privateGet(this, _onOpen)) == null || _a2.call(this, openEvent), this.dispatchEvent(openEvent), typeof body != "object" || !body || !("getReader" in body)) {
95360
+ __privateMethod(this, _EventSource_instances, failConnection_fn).call(this, "Invalid response body, expected a web ReadableStream", status), this.close();
95361
+ return;
95362
+ }
95363
+ const decoder = new TextDecoder(), reader = body.getReader();
95364
+ let open = !0;
95365
+ do {
95366
+ const { done, value } = await reader.read();
95367
+ value && __privateGet(this, _parser).feed(decoder.decode(value, { stream: !done })), done && (open = !1, __privateGet(this, _parser).reset(), __privateMethod(this, _EventSource_instances, scheduleReconnect_fn).call(this));
95368
+ } while (open);
95369
+ }), __privateAdd(this, _onFetchError, (err) => {
95370
+ __privateSet(this, _controller, void 0), !(err.name === "AbortError" || err.type === "aborted") && __privateMethod(this, _EventSource_instances, scheduleReconnect_fn).call(this, flattenError(err));
95371
+ }), __privateAdd(this, _onEvent, (event) => {
95372
+ typeof event.id == "string" && __privateSet(this, _lastEventId, event.id);
95373
+ const messageEvent = new MessageEvent(event.event || "message", {
95374
+ data: event.data,
95375
+ origin: __privateGet(this, _redirectUrl) ? __privateGet(this, _redirectUrl).origin : __privateGet(this, _url).origin,
95376
+ lastEventId: event.id || ""
95377
+ });
95378
+ __privateGet(this, _onMessage) && (!event.event || event.event === "message") && __privateGet(this, _onMessage).call(this, messageEvent), this.dispatchEvent(messageEvent);
95379
+ }), __privateAdd(this, _onRetryChange, (value) => {
95380
+ __privateSet(this, _reconnectInterval, value);
95381
+ }), __privateAdd(this, _reconnect, () => {
95382
+ __privateSet(this, _reconnectTimer, void 0), __privateGet(this, _readyState) === this.CONNECTING && __privateMethod(this, _EventSource_instances, connect_fn).call(this);
95383
+ });
95384
+ try {
95385
+ if (url instanceof URL) __privateSet(this, _url, url);
95386
+ else if (typeof url == "string") __privateSet(this, _url, new URL(url, getBaseURL()));
95387
+ else throw new Error("Invalid URL");
95388
+ } catch {
95389
+ throw syntaxError("An invalid or illegal string was specified");
95390
+ }
95391
+ __privateSet(this, _parser, createParser({
95392
+ onEvent: __privateGet(this, _onEvent),
95393
+ onRetry: __privateGet(this, _onRetryChange)
95394
+ })), __privateSet(this, _readyState, this.CONNECTING), __privateSet(this, _reconnectInterval, 3e3), __privateSet(this, _fetch, (_a = eventSourceInitDict == null ? void 0 : eventSourceInitDict.fetch) != null ? _a : globalThis.fetch), __privateSet(this, _withCredentials, (_b = eventSourceInitDict == null ? void 0 : eventSourceInitDict.withCredentials) != null ? _b : !1), __privateMethod(this, _EventSource_instances, connect_fn).call(this);
95395
+ }
95396
+ /**
95397
+ * Returns the state of this EventSource object's connection. It can have the values described below.
95398
+ *
95399
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/readyState)
95400
+ *
95401
+ * Note: typed as `number` instead of `0 | 1 | 2` for compatibility with the `EventSource` interface,
95402
+ * defined in the TypeScript `dom` library.
95403
+ *
95404
+ * @public
95405
+ */
95406
+ get readyState() {
95407
+ return __privateGet(this, _readyState);
95408
+ }
95409
+ /**
95410
+ * Returns the URL providing the event stream.
95411
+ *
95412
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/url)
95413
+ *
95414
+ * @public
95415
+ */
95416
+ get url() {
95417
+ return __privateGet(this, _url).href;
95418
+ }
95419
+ /**
95420
+ * Returns true if the credentials mode for connection requests to the URL providing the event stream is set to "include", and false otherwise.
95421
+ *
95422
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/withCredentials)
95423
+ */
95424
+ get withCredentials() {
95425
+ return __privateGet(this, _withCredentials);
95426
+ }
95427
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/error_event) */
95428
+ get onerror() {
95429
+ return __privateGet(this, _onError);
95430
+ }
95431
+ set onerror(value) {
95432
+ __privateSet(this, _onError, value);
95433
+ }
95434
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/message_event) */
95435
+ get onmessage() {
95436
+ return __privateGet(this, _onMessage);
95437
+ }
95438
+ set onmessage(value) {
95439
+ __privateSet(this, _onMessage, value);
95440
+ }
95441
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/open_event) */
95442
+ get onopen() {
95443
+ return __privateGet(this, _onOpen);
95444
+ }
95445
+ set onopen(value) {
95446
+ __privateSet(this, _onOpen, value);
95447
+ }
95448
+ addEventListener(type, listener, options) {
95449
+ const listen = listener;
95450
+ super.addEventListener(type, listen, options);
95451
+ }
95452
+ removeEventListener(type, listener, options) {
95453
+ const listen = listener;
95454
+ super.removeEventListener(type, listen, options);
95455
+ }
95456
+ /**
95457
+ * Aborts any instances of the fetch algorithm started for this EventSource object, and sets the readyState attribute to CLOSED.
95458
+ *
95459
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/close)
95460
+ *
95461
+ * @public
95462
+ */
95463
+ close() {
95464
+ __privateGet(this, _reconnectTimer) && clearTimeout(__privateGet(this, _reconnectTimer)), __privateGet(this, _readyState) !== this.CLOSED && (__privateGet(this, _controller) && __privateGet(this, _controller).abort(), __privateSet(this, _readyState, this.CLOSED), __privateSet(this, _controller, void 0));
95465
+ }
95466
+ };
95467
+ _readyState = /* @__PURE__ */ new WeakMap(), _url = /* @__PURE__ */ new WeakMap(), _redirectUrl = /* @__PURE__ */ new WeakMap(), _withCredentials = /* @__PURE__ */ new WeakMap(), _fetch = /* @__PURE__ */ new WeakMap(), _reconnectInterval = /* @__PURE__ */ new WeakMap(), _reconnectTimer = /* @__PURE__ */ new WeakMap(), _lastEventId = /* @__PURE__ */ new WeakMap(), _controller = /* @__PURE__ */ new WeakMap(), _parser = /* @__PURE__ */ new WeakMap(), _onError = /* @__PURE__ */ new WeakMap(), _onMessage = /* @__PURE__ */ new WeakMap(), _onOpen = /* @__PURE__ */ new WeakMap(), _EventSource_instances = /* @__PURE__ */ new WeakSet(), connect_fn = function() {
95468
+ __privateSet(this, _readyState, this.CONNECTING), __privateSet(this, _controller, new AbortController()), __privateGet(this, _fetch)(__privateGet(this, _url), __privateMethod(this, _EventSource_instances, getRequestOptions_fn).call(this)).then(__privateGet(this, _onFetchResponse)).catch(__privateGet(this, _onFetchError));
95469
+ }, _onFetchResponse = /* @__PURE__ */ new WeakMap(), _onFetchError = /* @__PURE__ */ new WeakMap(), getRequestOptions_fn = function() {
95470
+ var _a;
95471
+ const init = {
95472
+ mode: "cors",
95473
+ redirect: "follow",
95474
+ headers: {
95475
+ Accept: "text/event-stream",
95476
+ ...__privateGet(this, _lastEventId) ? { "Last-Event-ID": __privateGet(this, _lastEventId) } : void 0
95477
+ },
95478
+ cache: "no-store",
95479
+ signal: (_a = __privateGet(this, _controller)) == null ? void 0 : _a.signal
95480
+ };
95481
+ return "window" in globalThis && (init.credentials = this.withCredentials ? "include" : "same-origin"), init;
95482
+ }, _onEvent = /* @__PURE__ */ new WeakMap(), _onRetryChange = /* @__PURE__ */ new WeakMap(), failConnection_fn = function(message, code) {
95483
+ var _a;
95484
+ __privateGet(this, _readyState) !== this.CLOSED && __privateSet(this, _readyState, this.CLOSED);
95485
+ const errorEvent = new ErrorEvent("error", {
95486
+ code,
95487
+ message
95488
+ });
95489
+ (_a = __privateGet(this, _onError)) == null || _a.call(this, errorEvent), this.dispatchEvent(errorEvent);
95490
+ }, scheduleReconnect_fn = function(message, code) {
95491
+ var _a;
95492
+ if (__privateGet(this, _readyState) === this.CLOSED) return;
95493
+ __privateSet(this, _readyState, this.CONNECTING);
95494
+ const errorEvent = new ErrorEvent("error", {
95495
+ code,
95496
+ message
95497
+ });
95498
+ (_a = __privateGet(this, _onError)) == null || _a.call(this, errorEvent), this.dispatchEvent(errorEvent), __privateSet(this, _reconnectTimer, setTimeout(__privateGet(this, _reconnect), __privateGet(this, _reconnectInterval)));
95499
+ }, _reconnect = /* @__PURE__ */ new WeakMap(), EventSource.CONNECTING = 0, EventSource.OPEN = 1, EventSource.CLOSED = 2;
95500
+ function getBaseURL() {
95501
+ const doc = "document" in globalThis ? globalThis.document : void 0;
95502
+ return doc && typeof doc == "object" && "baseURI" in doc && typeof doc.baseURI == "string" ? doc.baseURI : void 0;
95503
+ }
95504
+ //#endregion
95505
+ //#region ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.3.6/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.js
95506
+ var SseError = class extends Error {
95507
+ constructor(code, message, event) {
95508
+ super(`SSE error: ${message}`);
95509
+ this.code = code;
95510
+ this.event = event;
95511
+ }
95512
+ };
95513
+ /**
95514
+ * Client transport for SSE: this will connect to a server using Server-Sent Events for receiving
95515
+ * messages and make separate POST requests for sending messages.
95516
+ * @deprecated SSEClientTransport is deprecated. Prefer to use StreamableHTTPClientTransport where possible instead. Note that because some servers are still using SSE, clients may need to support both transports during the migration period.
95517
+ */
95518
+ var SSEClientTransport = class {
95519
+ constructor(url, opts) {
95520
+ this._url = url;
95521
+ this._resourceMetadataUrl = void 0;
95522
+ this._scope = void 0;
95523
+ this._eventSourceInit = opts?.eventSourceInit;
95524
+ this._requestInit = opts?.requestInit;
95525
+ this._authProvider = opts?.authProvider;
95526
+ this._fetch = opts?.fetch;
95527
+ this._fetchWithInit = createFetchWithInit(opts?.fetch, opts?.requestInit);
95528
+ }
95529
+ async _authThenStart() {
95530
+ if (!this._authProvider) throw new UnauthorizedError("No auth provider");
95531
+ let result;
95532
+ try {
95533
+ result = await auth(this._authProvider, {
95534
+ serverUrl: this._url,
95535
+ resourceMetadataUrl: this._resourceMetadataUrl,
95536
+ scope: this._scope,
95537
+ fetchFn: this._fetchWithInit
95538
+ });
95539
+ } catch (error) {
95540
+ this.onerror?.(error);
95541
+ throw error;
95542
+ }
95543
+ if (result !== "AUTHORIZED") throw new UnauthorizedError();
95544
+ return await this._startOrAuth();
95545
+ }
95546
+ async _commonHeaders() {
95547
+ const headers = {};
95548
+ if (this._authProvider) {
95549
+ const tokens = await this._authProvider.tokens();
95550
+ if (tokens) headers["Authorization"] = `Bearer ${tokens.access_token}`;
95551
+ }
95552
+ if (this._protocolVersion) headers["mcp-protocol-version"] = this._protocolVersion;
95553
+ const extraHeaders = normalizeHeaders(this._requestInit?.headers);
95554
+ return new Headers({
95555
+ ...headers,
95556
+ ...extraHeaders
95557
+ });
95558
+ }
95559
+ _startOrAuth() {
95560
+ const fetchImpl = this?._eventSourceInit?.fetch ?? this._fetch ?? fetch;
95561
+ return new Promise((resolve, reject) => {
95562
+ this._eventSource = new EventSource(this._url.href, {
95563
+ ...this._eventSourceInit,
95564
+ fetch: async (url, init) => {
95565
+ const headers = await this._commonHeaders();
95566
+ headers.set("Accept", "text/event-stream");
95567
+ const response = await fetchImpl(url, {
95568
+ ...init,
95569
+ headers
95570
+ });
95571
+ if (response.status === 401 && response.headers.has("www-authenticate")) {
95572
+ const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
95573
+ this._resourceMetadataUrl = resourceMetadataUrl;
95574
+ this._scope = scope;
95575
+ }
95576
+ return response;
95577
+ }
95578
+ });
95579
+ this._abortController = new AbortController();
95580
+ this._eventSource.onerror = (event) => {
95581
+ if (event.code === 401 && this._authProvider) {
95582
+ this._authThenStart().then(resolve, reject);
95583
+ return;
95584
+ }
95585
+ const error = new SseError(event.code, event.message, event);
95586
+ reject(error);
95587
+ this.onerror?.(error);
95588
+ };
95589
+ this._eventSource.onopen = () => {};
95590
+ this._eventSource.addEventListener("endpoint", (event) => {
95591
+ const messageEvent = event;
95592
+ try {
95593
+ this._endpoint = new URL(messageEvent.data, this._url);
95594
+ if (this._endpoint.origin !== this._url.origin) throw new Error(`Endpoint origin does not match connection origin: ${this._endpoint.origin}`);
95595
+ } catch (error) {
95596
+ reject(error);
95597
+ this.onerror?.(error);
95598
+ this.close();
95599
+ return;
95600
+ }
95601
+ resolve();
95602
+ });
95603
+ this._eventSource.onmessage = (event) => {
95604
+ const messageEvent = event;
95605
+ let message;
95606
+ try {
95607
+ message = JSONRPCMessageSchema.parse(JSON.parse(messageEvent.data));
95608
+ } catch (error) {
95609
+ this.onerror?.(error);
95610
+ return;
95611
+ }
95612
+ this.onmessage?.(message);
95613
+ };
95614
+ });
95615
+ }
95616
+ async start() {
95617
+ if (this._eventSource) throw new Error("SSEClientTransport already started! If using Client class, note that connect() calls start() automatically.");
95618
+ return await this._startOrAuth();
95619
+ }
95620
+ /**
95621
+ * Call this method after the user has finished authorizing via their user agent and is redirected back to the MCP client application. This will exchange the authorization code for an access token, enabling the next connection attempt to successfully auth.
95622
+ */
95623
+ async finishAuth(authorizationCode) {
95624
+ if (!this._authProvider) throw new UnauthorizedError("No auth provider");
95625
+ if (await auth(this._authProvider, {
95626
+ serverUrl: this._url,
95627
+ authorizationCode,
95628
+ resourceMetadataUrl: this._resourceMetadataUrl,
95629
+ scope: this._scope,
95630
+ fetchFn: this._fetchWithInit
95631
+ }) !== "AUTHORIZED") throw new UnauthorizedError("Failed to authorize");
95632
+ }
95633
+ async close() {
95634
+ this._abortController?.abort();
95635
+ this._eventSource?.close();
95636
+ this.onclose?.();
95637
+ }
95638
+ async send(message) {
95639
+ if (!this._endpoint) throw new Error("Not connected");
95640
+ try {
95641
+ const headers = await this._commonHeaders();
95642
+ headers.set("content-type", "application/json");
95643
+ const init = {
95644
+ ...this._requestInit,
95645
+ method: "POST",
95646
+ headers,
95647
+ body: JSON.stringify(message),
95648
+ signal: this._abortController?.signal
95649
+ };
95650
+ const response = await (this._fetch ?? fetch)(this._endpoint, init);
95651
+ if (!response.ok) {
95652
+ const text = await response.text().catch(() => null);
95653
+ if (response.status === 401 && this._authProvider) {
95654
+ const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
95655
+ this._resourceMetadataUrl = resourceMetadataUrl;
95656
+ this._scope = scope;
95657
+ if (await auth(this._authProvider, {
95658
+ serverUrl: this._url,
95659
+ resourceMetadataUrl: this._resourceMetadataUrl,
95660
+ scope: this._scope,
95661
+ fetchFn: this._fetchWithInit
95662
+ }) !== "AUTHORIZED") throw new UnauthorizedError();
95663
+ return this.send(message);
95664
+ }
95665
+ throw new Error(`Error POSTing to endpoint (HTTP ${response.status}): ${text}`);
95666
+ }
95667
+ await response.body?.cancel();
95668
+ } catch (error) {
95669
+ this.onerror?.(error);
95670
+ throw error;
95671
+ }
95672
+ }
95673
+ setProtocolVersion(version) {
95674
+ this._protocolVersion = version;
95675
+ }
95676
+ };
95677
+ //#endregion
95678
+ //#region ../agent-core/src/mcp/client-sse.ts
95679
+ /**
95680
+ * Wraps the SDK's deprecated HTTP+SSE transport as a kosong
95681
+ * {@link MCPClient}. This exists for compatibility with older MCP servers;
95682
+ * new remote servers should prefer streamable HTTP.
95683
+ */
95684
+ var SseMcpClient = class {
95685
+ client;
95686
+ transport;
95687
+ toolCallTimeoutMs;
95688
+ started = false;
95689
+ closed = false;
95690
+ ready = false;
95691
+ hooksInstalled = false;
95692
+ unexpectedCloseListener;
95693
+ lastTransportError;
95694
+ pendingUnexpectedClose;
95695
+ unexpectedCloseFired = false;
95696
+ constructor(config, options = {}) {
95697
+ const headers = buildMcpRemoteHeaders(config, options.envLookup ?? ((name) => process.env[name]));
95698
+ this.transport = new SSEClientTransport(new URL(config.url), {
95699
+ requestInit: headers !== void 0 ? { headers } : void 0,
95700
+ fetch: options.fetch,
95701
+ authProvider: options.oauthProvider
95702
+ });
95703
+ this.client = new Client({
95704
+ name: options.clientName ?? "kimi-code",
95705
+ version: options.clientVersion ?? KIMI_MCP_CLIENT_VERSION
95706
+ });
95707
+ this.toolCallTimeoutMs = options.toolCallTimeoutMs;
95708
+ }
95709
+ async connect() {
95710
+ if (this.closed) throw new Error("MCP SSE client is closed");
95711
+ if (this.started) return;
95712
+ this.started = true;
95713
+ this.installTransportHooks();
95714
+ try {
95715
+ await this.client.connect(this.transport);
95716
+ } catch (error) {
95717
+ await this.closeStartedClient();
95718
+ throw error;
95719
+ }
95720
+ if (this.closed) {
95721
+ await this.closeStartedClient();
95722
+ throw new Error("MCP SSE client was closed during startup");
95723
+ }
95724
+ this.ready = true;
95725
+ }
95726
+ async close() {
95727
+ if (this.closed) return;
95728
+ this.closed = true;
95729
+ await this.closeStartedClient();
95730
+ }
95731
+ /**
95732
+ * Register a listener for unsolicited terminal transport drops. Brief SSE
95733
+ * stream flaps are left to EventSource's retry loop; terminal HTTP status
95734
+ * errors after startup remove the tools from the agent.
95735
+ */
95736
+ onUnexpectedClose(listener) {
95737
+ this.unexpectedCloseListener = listener;
95738
+ const pending = this.pendingUnexpectedClose;
95739
+ if (pending !== void 0) {
95740
+ this.pendingUnexpectedClose = void 0;
95741
+ listener(pending);
95742
+ }
95743
+ }
95744
+ async listTools() {
95745
+ return (await this.client.listTools()).tools.map(toMcpToolDefinition);
95746
+ }
95747
+ async callTool(name, args, signal) {
95748
+ const requestOptions = buildRequestOptions(this.toolCallTimeoutMs, signal);
95749
+ return toMcpToolResult(await this.client.callTool({
95750
+ name,
95751
+ arguments: args
95752
+ }, void 0, requestOptions));
95753
+ }
95754
+ async closeStartedClient() {
95755
+ if (!this.started) return;
95756
+ this.started = false;
95757
+ await this.client.close();
95758
+ }
95759
+ installTransportHooks() {
95760
+ if (this.hooksInstalled) return;
95761
+ this.hooksInstalled = true;
95762
+ this.client.onclose = () => {
95763
+ if (this.closed) return;
95764
+ if (!this.ready) return;
95765
+ this.fireUnexpectedClose({ error: this.lastTransportError });
95766
+ };
95767
+ this.client.onerror = (error) => {
95768
+ this.lastTransportError = error;
95769
+ if (this.closed) return;
95770
+ if (!this.ready) return;
95771
+ if (isTerminalSseTransportError(error)) this.fireUnexpectedClose({ error });
95772
+ };
95773
+ }
95774
+ fireUnexpectedClose(reason) {
95775
+ if (this.unexpectedCloseFired) return;
95776
+ this.unexpectedCloseFired = true;
95777
+ const listener = this.unexpectedCloseListener;
95778
+ if (listener !== void 0) listener(reason);
95779
+ else this.pendingUnexpectedClose = reason;
95780
+ }
95781
+ };
95782
+ function isTerminalSseTransportError(error) {
95783
+ if (error.name === "UnauthorizedError") return true;
95784
+ return error instanceof SseError && error.code !== void 0;
95185
95785
  }
95186
95786
  //#endregion
95187
95787
  //#region ../../node_modules/.pnpm/undici@7.27.1/node_modules/undici/lib/core/symbols.js
@@ -121737,16 +122337,23 @@ var McpConnectionManager = class {
121737
122337
  this.log = options.log ?? log;
121738
122338
  }
121739
122339
  /**
121740
- * Returns the URL of an HTTP MCP server by name, or `undefined` for
121741
- * unknown / non-HTTP / disabled entries. Used by the synthetic auth tool
122340
+ * Returns the URL of a remote MCP server by name, or `undefined` for
122341
+ * unknown / non-remote / disabled entries. Used by the synthetic auth tool
121742
122342
  * to drive OAuth discovery against the right base URL.
121743
122343
  */
121744
- getHttpServerUrl(name) {
122344
+ getRemoteServerUrl(name) {
121745
122345
  const entry = this.entries.get(name);
121746
122346
  if (entry === void 0) return void 0;
121747
- if (entry.config.transport !== "http") return void 0;
122347
+ if (!isRemoteMcpConfig(entry.config)) return void 0;
121748
122348
  return entry.config.url;
121749
122349
  }
122350
+ /**
122351
+ * @deprecated Use {@link getRemoteServerUrl}. Kept for in-repo callers that
122352
+ * were written before legacy SSE support shared the same OAuth path.
122353
+ */
122354
+ getHttpServerUrl(name) {
122355
+ return this.getRemoteServerUrl(name);
122356
+ }
121750
122357
  onStatusChange(listener) {
121751
122358
  this.listeners.add(listener);
121752
122359
  return () => {
@@ -121915,6 +122522,11 @@ var McpConnectionManager = class {
121915
122522
  createClient(config, name) {
121916
122523
  const toolCallTimeoutMs = config.toolTimeoutMs;
121917
122524
  if (config.transport === "stdio") return new StdioMcpClient(config, { toolCallTimeoutMs });
122525
+ if (config.transport === "sse") return new SseMcpClient(config, {
122526
+ toolCallTimeoutMs,
122527
+ envLookup: this.options.envLookup,
122528
+ oauthProvider: this.resolveOAuthProvider(config, name)
122529
+ });
121918
122530
  return new HttpMcpClient(config, {
121919
122531
  toolCallTimeoutMs,
121920
122532
  envLookup: this.options.envLookup,
@@ -121924,14 +122536,14 @@ var McpConnectionManager = class {
121924
122536
  resolveOAuthProvider(config, name) {
121925
122537
  const oauthService = this.oauthService;
121926
122538
  if (oauthService === void 0) return void 0;
121927
- if (config.transport !== "http") return void 0;
122539
+ if (!isRemoteMcpConfig(config)) return void 0;
121928
122540
  if (config.bearerTokenEnvVar !== void 0) return void 0;
121929
122541
  if (!oauthService.hasTokens(name, config.url)) return void 0;
121930
122542
  return oauthService.getProvider(name, config.url);
121931
122543
  }
121932
122544
  shouldMarkNeedsAuth(entry, error) {
121933
122545
  if (this.oauthService === void 0) return false;
121934
- if (entry.config.transport !== "http") return false;
122546
+ if (!isRemoteMcpConfig(entry.config)) return false;
121935
122547
  if (entry.config.bearerTokenEnvVar !== void 0) return false;
121936
122548
  if (entry.config.headers !== void 0) return false;
121937
122549
  return isUnauthorizedLikeError(error);
@@ -122215,7 +122827,7 @@ var Session$1 = class {
122215
122827
  this.telemetry = options.telemetry ?? noopTelemetryClient;
122216
122828
  this.toolKaos = options.kaos;
122217
122829
  this.persistenceKaos = options.persistenceKaos ?? options.kaos;
122218
- this.skills = new SkillRegistry({ sessionId: options.id });
122830
+ this.skills = new SessionSkillRegistry({ sessionId: options.id });
122219
122831
  this.mcp = new McpConnectionManager({
122220
122832
  oauthService: new McpOAuthService({ kimiHomeDir: options.kimiHomeDir }),
122221
122833
  log: this.log
@@ -122254,6 +122866,7 @@ var Session$1 = class {
122254
122866
  }
122255
122867
  async resume() {
122256
122868
  await this.skillsReady;
122869
+ this.log.info("session resume", { app_version: this.options.appVersion });
122257
122870
  const { agents } = await this.readMetadata();
122258
122871
  this.agents.clear();
122259
122872
  const { warning } = agents["main"] === void 0 ? { warning: void 0 } : await this.resumeAgent("main");
@@ -122508,7 +123121,6 @@ var Session$1 = class {
122508
123121
  telemetry: this.telemetry,
122509
123122
  log: this.log.createChild({ agentId: id }),
122510
123123
  pluginSessionStarts: type === "main" ? this.options.pluginSessionStarts : void 0,
122511
- appVersion: this.options.appVersion,
122512
123124
  experimentalFlags: this.experimentalFlags
122513
123125
  });
122514
123126
  }
@@ -122904,7 +123516,7 @@ async function readMcpServers(pluginRoot, raw, diagnostics) {
122904
123516
  }
122905
123517
  async function normalizePluginMcpServer(input) {
122906
123518
  const { config } = input;
122907
- if (config.transport === "http") return config;
123519
+ if (config.transport === "http" || config.transport === "sse") return config;
122908
123520
  let command = config.command;
122909
123521
  if (command.startsWith("./")) {
122910
123522
  const resolvedCommand = await resolvePluginPathField({
@@ -123684,11 +124296,11 @@ function pluginMcpServersInfo(record) {
123684
124296
  return Object.entries(record.manifest?.mcpServers ?? {}).map(([name, config]) => pluginMcpServerInfo(record, name, config)).toSorted((a, b) => a.name.localeCompare(b.name));
123685
124297
  }
123686
124298
  function pluginMcpServerInfo(record, name, config) {
123687
- if (config.transport === "http") return {
124299
+ if (config.transport === "http" || config.transport === "sse") return {
123688
124300
  name,
123689
124301
  runtimeName: pluginMcpRuntimeName(record.id, name),
123690
124302
  enabled: isMcpServerEnabled(record, name, config),
123691
- transport: "http",
124303
+ transport: config.transport,
123692
124304
  url: config.url,
123693
124305
  headerKeys: config.headers === void 0 ? void 0 : Object.keys(config.headers).toSorted()
123694
124306
  };
@@ -123713,7 +124325,7 @@ function pluginMcpRuntimeName(pluginId, serverName) {
123713
124325
  return `plugin-${pluginId}:${serverName}`;
123714
124326
  }
123715
124327
  function withPluginMcpRuntime(config, pluginRoot, kimiHomeDir) {
123716
- if (config.transport === "http") return config;
124328
+ if (config.transport === "http" || config.transport === "sse") return config;
123717
124329
  const env = {
123718
124330
  ...config.env,
123719
124331
  KIMI_CODE_HOME: kimiHomeDir,
@@ -136891,7 +137503,7 @@ var ProviderManager = class {
136891
137503
  };
136892
137504
  function resolveModelCapabilities(alias, provider) {
136893
137505
  const declared = new Set((alias.capabilities ?? []).map((c) => c.trim().toLowerCase()));
136894
- const detected = createProvider(providerForCapabilityProbe(provider)).getCapability?.(provider.model) ?? UNKNOWN_CAPABILITY;
137506
+ const detected = getModelCapability(provider.type, provider.model);
136895
137507
  return {
136896
137508
  image_in: declared.has("image_in") || detected.image_in,
136897
137509
  video_in: declared.has("video_in") || detected.video_in,
@@ -136964,20 +137576,6 @@ function defaultHeadersField(headers) {
136964
137576
  if (headers === void 0 || Object.keys(headers).length === 0) return {};
136965
137577
  return { defaultHeaders: { ...headers } };
136966
137578
  }
136967
- function providerForCapabilityProbe(provider) {
136968
- const apiKey = provider.apiKey && provider.apiKey.length > 0 ? provider.apiKey : "capability-probe";
136969
- if (provider.type === "vertexai") return {
136970
- ...provider,
136971
- vertexai: false,
136972
- project: void 0,
136973
- location: void 0,
136974
- apiKey
136975
- };
136976
- return {
136977
- ...provider,
136978
- apiKey
136979
- };
136980
- }
136981
137579
  function providerApiKey(provider) {
136982
137580
  switch (provider.type) {
136983
137581
  case "anthropic": return providerValue(provider.apiKey, provider.env, "ANTHROPIC_API_KEY");
@@ -141745,19 +142343,26 @@ var OAuthManager = class {
141745
142343
  * production state.
141746
142344
  */
141747
142345
  const KIMI_CODE_PLATFORM = "kimi_code_cli";
141748
- function createKimiDeviceId(homeDir, options = {}) {
142346
+ function readKimiDeviceId(homeDir) {
141749
142347
  const deviceIdPath = join(homeDir, "device_id");
141750
- if (existsSync(deviceIdPath)) try {
142348
+ if (!existsSync(deviceIdPath)) return null;
142349
+ try {
141751
142350
  const text = readFileSync(deviceIdPath, "utf-8").trim();
141752
- if (text.length > 0) return text;
141753
- } catch {}
142351
+ return text.length > 0 ? text : null;
142352
+ } catch {
142353
+ return null;
142354
+ }
142355
+ }
142356
+ function createKimiDeviceId(homeDir, options = {}) {
142357
+ const existing = readKimiDeviceId(homeDir);
142358
+ if (existing !== null) return existing;
141754
142359
  const id = randomUUID();
141755
142360
  try {
141756
142361
  mkdirSync(homeDir, {
141757
142362
  recursive: true,
141758
142363
  mode: 448
141759
142364
  });
141760
- writeFileSync(deviceIdPath, id, {
142365
+ writeFileSync(join(homeDir, "device_id"), id, {
141761
142366
  encoding: "utf-8",
141762
142367
  mode: 384
141763
142368
  });