@ycodium-ai/agent-kimi 0.2.2596 → 0.2.2658

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.
Files changed (2) hide show
  1. package/dist/index.js +309 -50
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -23521,11 +23521,21 @@ var AcpExecutorRequestError = class extends AcpExecutorError {
23521
23521
  }
23522
23522
  };
23523
23523
  var AcpConnectionClosedError = class extends Error {
23524
- constructor(message = "ACP connection closed") {
23525
- super(message);
23524
+ constructor(message = "ACP connection closed", options) {
23525
+ super(message, options);
23526
23526
  this.name = "AcpConnectionClosedError";
23527
23527
  }
23528
23528
  };
23529
+ async function withStartupStderr(error62, stderrTail) {
23530
+ if (!(error62 instanceof AcpConnectionClosedError) || stderrTail === void 0) return error62;
23531
+ const tail = await stderrTail();
23532
+ if (tail.length === 0) return error62;
23533
+ return new AcpConnectionClosedError(`${error62.message}
23534
+ Agent stderr (last lines):
23535
+ ${tail}`, {
23536
+ cause: error62
23537
+ });
23538
+ }
23529
23539
 
23530
23540
  // ../../packages/ycodium-acp-executor/src/jsonrpc.ts
23531
23541
  function isRecord2(value) {
@@ -24800,7 +24810,7 @@ function extractModelConfigId(sessionResponse) {
24800
24810
  return opt.id.trim();
24801
24811
  }
24802
24812
  }
24803
- return void 0;
24813
+ return configOptions.find((opt) => opt.id.trim() === "model" && opt.type === "select") ? "model" : void 0;
24804
24814
  }
24805
24815
  function findSessionConfigOption(configOptions, configId) {
24806
24816
  if (!configOptions) {
@@ -25197,6 +25207,13 @@ function readAcpText(source, key) {
25197
25207
  const trimmed = value.trim();
25198
25208
  return trimmed.length > 0 ? trimmed : void 0;
25199
25209
  }
25210
+ function textFromContentBlocks(blocks) {
25211
+ const parts = blocks.flatMap(
25212
+ (block) => isRecord5(block) && block["type"] === "text" && typeof block["text"] === "string" ? [block["text"]] : []
25213
+ );
25214
+ const joined = parts.join("");
25215
+ return joined.trim().length > 0 ? joined : void 0;
25216
+ }
25200
25217
  function parseSessionUpdateEvent(params) {
25201
25218
  const upd = params.update;
25202
25219
  const events = [];
@@ -25280,6 +25297,28 @@ function parseSessionUpdateEvent(params) {
25280
25297
  }
25281
25298
  break;
25282
25299
  }
25300
+ case "compaction_update": {
25301
+ const compactionId = readAcpText(upd, "compactionId");
25302
+ const status = readAcpText(upd, "status");
25303
+ if (compactionId === void 0 || status === void 0) break;
25304
+ const rawSummary = upd["summary"];
25305
+ events.push({
25306
+ _tag: "CompactionUpdated",
25307
+ compactionId,
25308
+ status,
25309
+ summary: rawSummary === void 0 ? void 0 : Array.isArray(rawSummary) ? textFromContentBlocks(rawSummary) ?? null : null,
25310
+ error: readAcpText(upd, "error")
25311
+ });
25312
+ break;
25313
+ }
25314
+ case "compaction_summary_chunk": {
25315
+ const compactionId = readAcpText(upd, "compactionId");
25316
+ const content = isRecord5(upd["content"]) ? upd["content"] : void 0;
25317
+ const text = content?.["type"] === "text" ? content["text"] : void 0;
25318
+ if (compactionId === void 0 || typeof text !== "string" || text.length === 0) break;
25319
+ events.push({ _tag: "CompactionSummaryChunk", compactionId, text });
25320
+ break;
25321
+ }
25283
25322
  default:
25284
25323
  break;
25285
25324
  }
@@ -25376,6 +25415,97 @@ function createAcpExecutor(options) {
25376
25415
  if (settledPromptKeys.length > SETTLED_PROMPT_KEY_LIMIT) settledPromptKeys.shift();
25377
25416
  };
25378
25417
  const toolCalls = /* @__PURE__ */ new Map();
25418
+ const compactions = /* @__PURE__ */ new Map();
25419
+ let manualCompaction;
25420
+ const COMPACTION_SUMMARY_MAX_CHARS = 8e3;
25421
+ const nowMs = () => options.nowMs?.() ?? Date.now();
25422
+ const emitCompactionState = (record2, state) => {
25423
+ const summary = record2.summary?.trim() ?? "";
25424
+ const truncated = summary.length > COMPACTION_SUMMARY_MAX_CHARS;
25425
+ emit({
25426
+ type: "thread.state.changed",
25427
+ ...stamp(),
25428
+ provider: options.provider,
25429
+ threadId: options.threadId,
25430
+ ...activeTurnId !== void 0 ? { turnId: activeTurnId } : {},
25431
+ payload: {
25432
+ state,
25433
+ compaction: {
25434
+ compactionId: record2.snapshotId,
25435
+ trigger: record2.trigger,
25436
+ ...state === "compacted" ? { durationMs: Math.max(0, nowMs() - record2.startedAtMs) } : {},
25437
+ ...summary.length > 0 ? {
25438
+ summary: truncated ? summary.slice(0, COMPACTION_SUMMARY_MAX_CHARS) : summary,
25439
+ ...truncated ? { summaryTruncated: true } : {}
25440
+ } : {}
25441
+ }
25442
+ }
25443
+ });
25444
+ };
25445
+ const applyCompactionUpdate = (event) => {
25446
+ let record2 = compactions.get(event.compactionId);
25447
+ if (record2 === void 0) {
25448
+ if (manualCompaction !== void 0 && !manualCompaction.adopted) {
25449
+ manualCompaction.adopted = true;
25450
+ record2 = manualCompaction;
25451
+ } else {
25452
+ record2 = {
25453
+ snapshotId: randomId(),
25454
+ trigger: "automatic",
25455
+ startedAtMs: nowMs(),
25456
+ summary: void 0,
25457
+ announced: false,
25458
+ finished: false,
25459
+ adopted: false
25460
+ };
25461
+ }
25462
+ compactions.set(event.compactionId, record2);
25463
+ }
25464
+ if (event.summary !== void 0) record2.summary = event.summary ?? void 0;
25465
+ switch (event.status) {
25466
+ case "in_progress":
25467
+ if (!record2.announced) {
25468
+ record2.announced = true;
25469
+ emitCompactionState(record2, "compacting");
25470
+ }
25471
+ return;
25472
+ case "completed":
25473
+ record2.announced = true;
25474
+ record2.finished = true;
25475
+ compactions.delete(event.compactionId);
25476
+ emitCompactionState(record2, "compacted");
25477
+ return;
25478
+ case "failed":
25479
+ case "cancelled":
25480
+ record2.finished = true;
25481
+ compactions.delete(event.compactionId);
25482
+ emit({
25483
+ type: "runtime.warning",
25484
+ ...stamp(),
25485
+ provider: options.provider,
25486
+ threadId: options.threadId,
25487
+ ...activeTurnId !== void 0 ? { turnId: activeTurnId } : {},
25488
+ payload: {
25489
+ message: event.error ?? `Context compaction ${event.status}`,
25490
+ detail: { code: `context-compaction-${event.status}` }
25491
+ }
25492
+ });
25493
+ return;
25494
+ default:
25495
+ return;
25496
+ }
25497
+ };
25498
+ const shownToolCallIds = /* @__PURE__ */ new Set();
25499
+ const SHOWN_TOOL_CALL_LIMIT = 256;
25500
+ const rememberShownToolCall = (toolCallId) => {
25501
+ shownToolCallIds.add(toolCallId);
25502
+ if (shownToolCallIds.size <= SHOWN_TOOL_CALL_LIMIT) return;
25503
+ for (const id of shownToolCallIds) {
25504
+ if (toolCalls.has(id)) continue;
25505
+ shownToolCallIds.delete(id);
25506
+ return;
25507
+ }
25508
+ };
25379
25509
  let assistantSegment = { nextSegmentIndex: 0 };
25380
25510
  let modeState;
25381
25511
  let availableCommands = [];
@@ -25462,7 +25592,6 @@ function createAcpExecutor(options) {
25462
25592
  }
25463
25593
  for (const event of parsed.events) {
25464
25594
  if (event._tag === "ToolCallUpdated") {
25465
- closeActiveAssistantSegment(activeTurnId);
25466
25595
  const tracked = toolCalls.get(event.toolCall.toolCallId);
25467
25596
  const previous = tracked?.state;
25468
25597
  const nextToolCall = mergeToolCallState(previous, event.toolCall);
@@ -25481,9 +25610,35 @@ function createAcpExecutor(options) {
25481
25610
  skippedSinceEmit: decision.skippedSinceEmit
25482
25611
  });
25483
25612
  }
25484
- if (!decision.emit) {
25613
+ const hookResult = hooks.onToolCallUpdated?.({
25614
+ toolCallId: nextToolCall.toolCallId,
25615
+ status: nextToolCall.status,
25616
+ title: nextToolCall.title,
25617
+ kind: nextToolCall.kind,
25618
+ rawInput: nextToolCall.data["rawInput"],
25619
+ rawOutput: nextToolCall.data["rawOutput"],
25620
+ meta: params.update._meta,
25621
+ turnId: activeTurnId
25622
+ });
25623
+ const taskEvents = hookResult === void 0 ? [] : "events" in hookResult ? hookResult.events : hookResult;
25624
+ const handledByHook = hookResult !== void 0 && "events" in hookResult && hookResult.handled === true;
25625
+ for (const taskEvent of taskEvents) {
25626
+ emit({
25627
+ type: taskEvent.type,
25628
+ ...stamp(),
25629
+ provider: options.provider,
25630
+ threadId: options.threadId,
25631
+ ...taskEvent.turnId !== void 0 ? { turnId: taskEvent.turnId } : {},
25632
+ payload: taskEvent.payload
25633
+ });
25634
+ }
25635
+ if (handledByHook || !decision.emit) {
25485
25636
  continue;
25486
25637
  }
25638
+ if (!shownToolCallIds.has(nextToolCall.toolCallId)) {
25639
+ rememberShownToolCall(nextToolCall.toolCallId);
25640
+ closeActiveAssistantSegment(activeTurnId);
25641
+ }
25487
25642
  emit(
25488
25643
  makeAcpToolCallEvent({
25489
25644
  stamp: stamp(),
@@ -25496,7 +25651,21 @@ function createAcpExecutor(options) {
25496
25651
  );
25497
25652
  continue;
25498
25653
  }
25654
+ if (event._tag === "CompactionUpdated") {
25655
+ applyCompactionUpdate(event);
25656
+ continue;
25657
+ }
25658
+ if (event._tag === "CompactionSummaryChunk") {
25659
+ const record2 = compactions.get(event.compactionId);
25660
+ if (record2 !== void 0 && !record2.finished) {
25661
+ record2.summary = (record2.summary ?? "") + event.text;
25662
+ }
25663
+ continue;
25664
+ }
25499
25665
  if (event._tag === "ContentDelta") {
25666
+ if (manualCompaction !== void 0) {
25667
+ continue;
25668
+ }
25500
25669
  if (event.streamKind === "reasoning_text") {
25501
25670
  if (event.text.trim().length === 0) {
25502
25671
  continue;
@@ -25739,7 +25908,9 @@ function createAcpExecutor(options) {
25739
25908
  },
25740
25909
  onNotification: (notification) => {
25741
25910
  if (notification.method === "session/update") {
25742
- handleSessionUpdate(notification.params);
25911
+ const params = notification.params;
25912
+ const transformed = hooks.transformSessionUpdate ? hooks.transformSessionUpdate(params) : params;
25913
+ if (transformed !== void 0) handleSessionUpdate(transformed);
25743
25914
  return;
25744
25915
  }
25745
25916
  if (settleFromNotification(notification.method, notification.params)) return;
@@ -25873,13 +26044,15 @@ function createAcpExecutor(options) {
25873
26044
  options.mcpServers ?? [],
25874
26045
  initialized.agentCapabilities
25875
26046
  );
26047
+ const additionalDirectories = options.additionalDirectories !== void 0 && options.additionalDirectories.length > 0 ? { additionalDirectories: options.additionalDirectories } : {};
25876
26048
  let setup;
25877
26049
  let nextSessionId;
25878
26050
  if (options.resumeSessionId && options.resumeMethod === "session/resume") {
25879
26051
  setup = await connection.request("session/resume", {
25880
26052
  sessionId: options.resumeSessionId,
25881
26053
  cwd: options.cwd,
25882
- mcpServers
26054
+ mcpServers,
26055
+ ...additionalDirectories
25883
26056
  });
25884
26057
  nextSessionId = options.resumeSessionId;
25885
26058
  } else if (options.resumeSessionId) {
@@ -25888,7 +26061,8 @@ function createAcpExecutor(options) {
25888
26061
  setup = await connection.request("session/load", {
25889
26062
  sessionId: options.resumeSessionId,
25890
26063
  cwd: options.cwd,
25891
- mcpServers
26064
+ mcpServers,
26065
+ ...additionalDirectories
25892
26066
  });
25893
26067
  } finally {
25894
26068
  sessionLoadInFlight = false;
@@ -25901,7 +26075,8 @@ function createAcpExecutor(options) {
25901
26075
  } else {
25902
26076
  const created = await connection.request("session/new", {
25903
26077
  cwd: options.cwd,
25904
- mcpServers
26078
+ mcpServers,
26079
+ ...additionalDirectories
25905
26080
  });
25906
26081
  nextSessionId = created.sessionId;
25907
26082
  setup = created;
@@ -25975,13 +26150,13 @@ function createAcpExecutor(options) {
25975
26150
  startInFlight = void 0;
25976
26151
  return result;
25977
26152
  },
25978
- (error62) => {
26153
+ async (error62) => {
25979
26154
  startInFlight = void 0;
25980
26155
  if (isLive(expectedGeneration) && !startResult) {
25981
26156
  status = "idle";
25982
26157
  generation = expectedGeneration;
25983
26158
  }
25984
- throw error62;
26159
+ throw await withStartupStderr(error62, options.stderrTail);
25985
26160
  }
25986
26161
  );
25987
26162
  return startInFlight;
@@ -26049,6 +26224,36 @@ function createAcpExecutor(options) {
26049
26224
  interruptedTurnIds.delete(input2.turnId);
26050
26225
  }
26051
26226
  };
26227
+ const sendPromptRpc = async (sessionId2, promptParts) => {
26228
+ const settlementHooks = hooks.promptSettlement;
26229
+ const promptKey = settlementHooks === void 0 ? void 0 : randomId();
26230
+ const promptRpc = connection.request("session/prompt", {
26231
+ sessionId: sessionId2,
26232
+ prompt: promptParts,
26233
+ ...settlementHooks !== void 0 && promptKey !== void 0 ? settlementHooks.requestFields(promptKey) : {}
26234
+ });
26235
+ if (settlementHooks === void 0 || promptKey === void 0) {
26236
+ return await promptRpc;
26237
+ } else {
26238
+ const { promise: early, resolve: settleEarly } = Promise.withResolvers();
26239
+ pendingSettlement = { promptKey, sessionId: sessionId2, settle: settleEarly };
26240
+ try {
26241
+ const outcome = await Promise.race([
26242
+ promptRpc.then((value) => {
26243
+ const key = settlementHooks.responseKey?.(value);
26244
+ if (key !== void 0) rememberSettledPromptKey(key);
26245
+ return { response: value };
26246
+ }),
26247
+ early
26248
+ ]);
26249
+ if (outcome.error !== void 0) throw outcome.error;
26250
+ return outcome.response;
26251
+ } finally {
26252
+ pendingSettlement = void 0;
26253
+ void promptRpc.catch(() => void 0);
26254
+ }
26255
+ }
26256
+ };
26052
26257
  const prompt = async (input2) => {
26053
26258
  failIfDisposed();
26054
26259
  const started = requireStarted();
@@ -26099,35 +26304,8 @@ function createAcpExecutor(options) {
26099
26304
  expectedGeneration: started.generation
26100
26305
  });
26101
26306
  closeActiveAssistantSegment(turnId);
26102
- const settlementHooks = hooks.promptSettlement;
26103
- const promptKey = settlementHooks === void 0 ? void 0 : randomId();
26104
- const promptRpc = connection.request("session/prompt", {
26105
- sessionId: started.sessionId,
26106
- prompt: promptParts,
26107
- ...settlementHooks !== void 0 && promptKey !== void 0 ? settlementHooks.requestFields(promptKey) : {}
26108
- });
26109
26307
  try {
26110
- if (settlementHooks === void 0 || promptKey === void 0) {
26111
- response = await promptRpc;
26112
- } else {
26113
- const { promise: early, resolve: settleEarly } = Promise.withResolvers();
26114
- pendingSettlement = { promptKey, sessionId: started.sessionId, settle: settleEarly };
26115
- try {
26116
- const outcome = await Promise.race([
26117
- promptRpc.then((value) => {
26118
- const key = settlementHooks.responseKey?.(value);
26119
- if (key !== void 0) rememberSettledPromptKey(key);
26120
- return { response: value };
26121
- }),
26122
- early
26123
- ]);
26124
- if (outcome.error !== void 0) throw outcome.error;
26125
- response = outcome.response;
26126
- } finally {
26127
- pendingSettlement = void 0;
26128
- void promptRpc.catch(() => void 0);
26129
- }
26130
- }
26308
+ response = await sendPromptRpc(started.sessionId, promptParts);
26131
26309
  } catch (error62) {
26132
26310
  if (disposed) {
26133
26311
  throw new AcpExecutorDisposedError();
@@ -26291,6 +26469,74 @@ function createAcpExecutor(options) {
26291
26469
  };
26292
26470
  apply();
26293
26471
  };
26472
+ const compact = async (input2) => {
26473
+ failIfDisposed();
26474
+ const started = requireStarted();
26475
+ const trimmedName = input2.commandName.trim();
26476
+ const commandName = trimmedName.startsWith("/") ? trimmedName.slice(1) : trimmedName;
26477
+ if (!availableCommands.some((command) => command.name === commandName)) {
26478
+ throw new AcpExecutorError(
26479
+ "command-unavailable",
26480
+ `The agent has not advertised the /${commandName} command`
26481
+ );
26482
+ }
26483
+ if (promptsInFlight > 0 || promptMutex.isLocked || manualCompaction !== void 0) {
26484
+ throw new AcpExecutorError(
26485
+ "busy",
26486
+ "Cannot compact while a turn or another compaction is running"
26487
+ );
26488
+ }
26489
+ const record2 = {
26490
+ snapshotId: randomId(),
26491
+ trigger: "manual",
26492
+ startedAtMs: nowMs(),
26493
+ summary: void 0,
26494
+ announced: true,
26495
+ finished: false,
26496
+ adopted: false
26497
+ };
26498
+ await promptMutex.acquire();
26499
+ manualCompaction = record2;
26500
+ const emitSessionState = (state) => {
26501
+ emit({
26502
+ type: "session.state.changed",
26503
+ ...stamp(),
26504
+ provider: options.provider,
26505
+ threadId: options.threadId,
26506
+ payload: { state, reason: "compaction" }
26507
+ });
26508
+ };
26509
+ try {
26510
+ failIfDisposed();
26511
+ emitSessionState("compacting");
26512
+ emitCompactionState(record2, "compacting");
26513
+ let response;
26514
+ try {
26515
+ response = await sendPromptRpc(started.sessionId, [
26516
+ { type: "text", text: `/${commandName}` }
26517
+ ]);
26518
+ } catch (error62) {
26519
+ if (disposed) throw new AcpExecutorDisposedError();
26520
+ throw error62;
26521
+ }
26522
+ await connection.awaitInboundIdle();
26523
+ if (response.stopReason === "cancelled") {
26524
+ return;
26525
+ }
26526
+ if (!record2.finished) {
26527
+ record2.finished = true;
26528
+ emitCompactionState(record2, "compacted");
26529
+ }
26530
+ } finally {
26531
+ for (const [agentId, tracked] of compactions) {
26532
+ if (tracked === record2) compactions.delete(agentId);
26533
+ }
26534
+ manualCompaction = void 0;
26535
+ promptMutex.release();
26536
+ notifyPromptSettled();
26537
+ if (!disposed) emitSessionState("ready");
26538
+ }
26539
+ };
26294
26540
  const setNativeMode = async (modeId) => {
26295
26541
  failIfDisposed();
26296
26542
  const started = startResult;
@@ -26378,6 +26624,7 @@ function createAcpExecutor(options) {
26378
26624
  respondToRequest,
26379
26625
  respondToUserInput,
26380
26626
  setNativeMode,
26627
+ compact,
26381
26628
  dispose
26382
26629
  };
26383
26630
  }
@@ -26572,6 +26819,11 @@ function tokenizeLaunchArgs(value) {
26572
26819
  import * as NodeFS from "node:fs";
26573
26820
  import * as NodePath from "node:path";
26574
26821
  var KIMI_USER_INPUT_TITLES = /* @__PURE__ */ new Set(["AskUserQuestion", "ExitPlanMode"]);
26822
+ var KIMI_PLAN_ACTIONS = {
26823
+ plan_approve: "approve",
26824
+ plan_revise: "revise",
26825
+ plan_reject_and_exit: "stop"
26826
+ };
26575
26827
  var isRecord7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
26576
26828
  function questionTextFromContent(content) {
26577
26829
  if (!Array.isArray(content)) return "";
@@ -26588,6 +26840,7 @@ function questionTextFromContent(content) {
26588
26840
  function kimiPermissionUserInput(request) {
26589
26841
  const title = request.toolCall.title;
26590
26842
  if (typeof title !== "string" || !KIMI_USER_INPUT_TITLES.has(title)) return void 0;
26843
+ const isPlan = title === "ExitPlanMode";
26591
26844
  const ids = new Set(request.options.map((option) => option.optionId));
26592
26845
  if (request.options.length === 0 || ids.size !== request.options.length) {
26593
26846
  throw new Error("Kimi interaction must provide distinct response options.");
@@ -26600,14 +26853,18 @@ function kimiPermissionUserInput(request) {
26600
26853
  id: request.toolCall.toolCallId,
26601
26854
  header: title,
26602
26855
  question,
26603
- kind: title === "ExitPlanMode" ? "plan" : "question",
26856
+ kind: isPlan ? "plan" : "question",
26604
26857
  allowFreeform: false,
26605
26858
  multiSelect: false,
26606
- options: request.options.map((option) => ({
26607
- id: option.optionId,
26608
- label: option.name,
26609
- description: ""
26610
- }))
26859
+ options: request.options.map((option) => {
26860
+ const planAction = isPlan ? KIMI_PLAN_ACTIONS[option.optionId] : void 0;
26861
+ return {
26862
+ id: option.optionId,
26863
+ label: option.name,
26864
+ description: "",
26865
+ ...planAction !== void 0 ? { planAction } : {}
26866
+ };
26867
+ })
26611
26868
  };
26612
26869
  }
26613
26870
  var WIRE_LOG_SEGMENTS = ["agents", "main", "wire.jsonl"];
@@ -26716,6 +26973,7 @@ function readKimiAuthState(resolvedHomePath) {
26716
26973
 
26717
26974
  // src/kimiModels.ts
26718
26975
  import {
26976
+ describeExecutorSpawnFailure,
26719
26977
  ExecutorSpawnRefusedError
26720
26978
  } from "@ycodium-ai/plugin-api/executor";
26721
26979
 
@@ -26775,7 +27033,7 @@ async function probeKimiModels(input2) {
26775
27033
  });
26776
27034
  } catch (error62) {
26777
27035
  if (error62 instanceof ExecutorSpawnRefusedError) throw error62;
26778
- return { kind: "not-started", detail: probeFailureDetail(error62) };
27036
+ return { kind: "not-started", ...describeExecutorSpawnFailure(error62) };
26779
27037
  }
26780
27038
  try {
26781
27039
  const run = await collectProbeProcess(handle, {
@@ -26816,7 +27074,7 @@ async function probeKimi(input2) {
26816
27074
  const [listed, version2] = await Promise.all([probeKimiModels(input2), probeKimiVersion(input2)]);
26817
27075
  switch (listed.kind) {
26818
27076
  case "not-started":
26819
- return { kind: "not-started", detail: listed.detail };
27077
+ return { kind: "not-started", readiness: listed.readiness, detail: listed.detail };
26820
27078
  case "failed":
26821
27079
  return { kind: "failed", detail: listed.detail, version: version2 };
26822
27080
  case "answered":
@@ -26952,7 +27210,7 @@ var createKimiInstance = (config2, host) => {
26952
27210
  return {
26953
27211
  installed: false,
26954
27212
  version: null,
26955
- readiness: "error",
27213
+ readiness: "not-installed",
26956
27214
  auth: { status: "unknown" },
26957
27215
  detail: "Kimi Code program path is not configured"
26958
27216
  };
@@ -26974,7 +27232,7 @@ var createKimiInstance = (config2, host) => {
26974
27232
  return {
26975
27233
  installed: false,
26976
27234
  version: null,
26977
- readiness: "error",
27235
+ readiness: outcome.readiness,
26978
27236
  auth: { status: "unknown" },
26979
27237
  ...outcome.detail === void 0 ? {} : { detail: outcome.detail }
26980
27238
  };
@@ -27031,7 +27289,7 @@ var createKimiInstance = (config2, host) => {
27031
27289
  owner: { bindingId: host.bindingId },
27032
27290
  ...Object.keys(env).length > 0 ? { env } : {}
27033
27291
  });
27034
- const { readable, writable } = nodeStreamsFromHandle(handle);
27292
+ const { readable, writable, stderrTail } = nodeStreamsFromHandle(handle);
27035
27293
  const resume = input2.discardResumeCursor === true ? void 0 : parseAcpResumeCursor(input2.resumeCursor, RESUME_SCHEMA_VERSION);
27036
27294
  const requestedModelId = modelIdFromSelection(input2.modelSelection);
27037
27295
  const requestedEffort = modelSelectionStringOption(
@@ -27046,6 +27304,7 @@ var createKimiInstance = (config2, host) => {
27046
27304
  const executor = createAcpExecutor({
27047
27305
  readable,
27048
27306
  writable,
27307
+ stderrTail,
27049
27308
  ...requestedEffort === void 0 ? {} : { requestedEffort },
27050
27309
  cwd,
27051
27310
  threadId: input2.threadId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ycodium-ai/agent-kimi",
3
- "version": "0.2.2596",
3
+ "version": "0.2.2658",
4
4
  "description": "Kimi Code executor: runs `kimi acp` over Agent Client Protocol stdio.",
5
5
  "keywords": [
6
6
  "ycodium",
@@ -21,9 +21,9 @@
21
21
  "@types/node": "24.12.4",
22
22
  "esbuild": "0.28.1",
23
23
  "vite-plus": "0.2.2",
24
- "@ycodium-ai/plugin-api": "0.2.2596",
24
+ "@ycodium-ai/plugin-api": "0.2.2658",
25
25
  "ycodium-executor-testing": "0.0.0",
26
- "ycodium-acp-executor": "0.2.2596"
26
+ "ycodium-acp-executor": "0.2.2658"
27
27
  },
28
28
  "ycodium": {
29
29
  "plugin": "./dist/index.js",