kimiflare 0.52.0 → 0.54.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.js CHANGED
@@ -1948,24 +1948,40 @@ ${jsCode}
1948
1948
  }
1949
1949
  return { output: logs.join("\n"), logs, toolCalls, warnings };
1950
1950
  }
1951
+ function buildFallbackWarning(errMessage) {
1952
+ let reason;
1953
+ let fix;
1954
+ if (errMessage.includes("Cannot find module") || errMessage.includes("isolated-vm")) {
1955
+ reason = "The optional dependency `isolated-vm` is not installed.";
1956
+ fix = "Run `npm install isolated-vm` in your project (or `npm install -g isolated-vm` if KimiFlare is installed globally).";
1957
+ } else if (errMessage.includes("bindings") || errMessage.includes(".node")) {
1958
+ reason = "The `isolated-vm` native bindings are incompatible with this Node version or architecture.";
1959
+ fix = "Try `npm rebuild isolated-vm`, or switch to Node 22 LTS if you're on Apple Silicon.";
1960
+ } else {
1961
+ reason = "The secure sandbox (`isolated-vm`) could not be loaded.";
1962
+ fix = "Ensure build tools are installed, then run `npm install isolated-vm`.";
1963
+ }
1964
+ return `Code Mode is using the built-in Node.js sandbox. Tool execution works normally, but without memory limits or full process isolation. ${reason} ${fix}`;
1965
+ }
1951
1966
  async function runInSandbox(opts2) {
1952
1967
  try {
1953
1968
  return await runWithIsolatedVm(opts2);
1954
1969
  } catch (err) {
1955
1970
  const message2 = err instanceof Error ? err.message : String(err);
1956
- if (message2.includes("isolated-vm") || message2.includes("Cannot find module") || message2.includes("bindings")) {
1957
- const result2 = await runWithNodeVm(opts2);
1958
- return { ...result2, warnings: [ISOLATED_VM_FALLBACK_WARNING, ...result2.warnings ?? []] };
1959
- }
1960
1971
  const result = await runWithNodeVm(opts2);
1961
- return { ...result, warnings: [ISOLATED_VM_FALLBACK_WARNING, ...result.warnings ?? []] };
1972
+ if (!fallbackWarningShown) {
1973
+ fallbackWarningShown = true;
1974
+ const warning = buildFallbackWarning(message2);
1975
+ return { ...result, warnings: [warning, ...result.warnings ?? []] };
1976
+ }
1977
+ return result;
1962
1978
  }
1963
1979
  }
1964
- var ISOLATED_VM_FALLBACK_WARNING;
1980
+ var fallbackWarningShown;
1965
1981
  var init_sandbox = __esm({
1966
1982
  "src/code-mode/sandbox.ts"() {
1967
1983
  "use strict";
1968
- ISOLATED_VM_FALLBACK_WARNING = "\u26A0\uFE0F Code sandbox is running without memory limits or true process isolation (isolated-vm unavailable or failed to load). For a secure sandbox, install with Node 22 LTS: nvm install 22 && nvm use 22 && npm install -g kimiflare";
1984
+ fallbackWarningShown = false;
1969
1985
  }
1970
1986
  });
1971
1987
 
@@ -2774,13 +2790,15 @@ Use console.log() to return results. Only console.log output will be sent back t
2774
2790
  toolResults.push(toolResult);
2775
2791
  opts2.callbacks.onToolResult?.(toolResult);
2776
2792
  }
2777
- const warningPrefix = sandboxResult.warnings?.length ? `Warning: ${sandboxResult.warnings.join(" ")}
2778
-
2779
- ` : "";
2780
- let resultContent = sandboxResult.error ? `${warningPrefix}Error: ${sandboxResult.error}
2793
+ if (sandboxResult.warnings && sandboxResult.warnings.length > 0) {
2794
+ for (const w of sandboxResult.warnings) {
2795
+ opts2.callbacks.onWarning?.(w);
2796
+ }
2797
+ }
2798
+ let resultContent = sandboxResult.error ? `Error: ${sandboxResult.error}
2781
2799
 
2782
2800
  Output:
2783
- ${sandboxResult.output}` : `${warningPrefix}${sandboxResult.output}`;
2801
+ ${sandboxResult.output}` : sandboxResult.output;
2784
2802
  if (resultContent.length > MAX_TOOL_CONTENT_CHARS) {
2785
2803
  resultContent = resultContent.slice(0, MAX_TOOL_CONTENT_CHARS) + `
2786
2804
 
@@ -2803,6 +2821,7 @@ ${sandboxResult.output}` : `${warningPrefix}${sandboxResult.output}`;
2803
2821
  recentToolCalls.push(loopSignature);
2804
2822
  if (recentToolCalls.length > LOOP_WINDOW) recentToolCalls.shift();
2805
2823
  } else {
2824
+ opts2.callbacks.onToolWillExecute?.(tc.id, tc.function.name);
2806
2825
  logger.debug("turn:tool_start", { sessionId: opts2.sessionId, tool: tc.function.name, toolCallId: tc.id });
2807
2826
  const result = await opts2.executor.run(
2808
2827
  { id: tc.id, name: tc.function.name, arguments: tc.function.arguments },
@@ -9163,6 +9182,9 @@ var init_session = __esm({
9163
9182
  onTasks: (tasks) => {
9164
9183
  this.emit({ type: "tasks.update", tasks });
9165
9184
  },
9185
+ onWarning: (msg) => {
9186
+ this.emit({ type: "warning", message: msg });
9187
+ },
9166
9188
  askPermission: async (req) => {
9167
9189
  if (mode === "auto") return "allow";
9168
9190
  if (mode === "plan") {
@@ -10173,12 +10195,14 @@ var init_tool_view = __esm({
10173
10195
  const id = setInterval(() => setNow(Date.now()), 1e3);
10174
10196
  return () => clearInterval(id);
10175
10197
  }, [evt.status, evt.startedAt]);
10176
- const statusIcon = evt.status === "running" ? /* @__PURE__ */ jsx3(Text2, { color: theme.info.color, children: /* @__PURE__ */ jsx3(Spinner, { type: "dots" }) }) : evt.status === "error" ? /* @__PURE__ */ jsx3(Text2, { color: theme.palette.error, children: "\u2717" }) : /* @__PURE__ */ jsx3(Text2, { color: theme.palette.success, children: "\u2713" });
10198
+ const statusIcon = evt.status === "queued" ? /* @__PURE__ */ jsx3(Text2, { color: theme.muted?.color ?? theme.info.color, children: "[ ]" }) : evt.status === "running" ? /* @__PURE__ */ jsx3(Text2, { color: theme.info.color, children: /* @__PURE__ */ jsx3(Spinner, { type: "dots" }) }) : evt.status === "error" ? /* @__PURE__ */ jsx3(Text2, { color: theme.palette.error, children: "[err]" }) : evt.status === "cancelled" ? /* @__PURE__ */ jsx3(Text2, { color: theme.info.color, children: "[x]" }) : evt.status === "rejected" ? /* @__PURE__ */ jsx3(Text2, { color: theme.palette.error, children: "[!]" }) : /* @__PURE__ */ jsx3(Text2, { color: theme.palette.success, children: "[ok]" });
10177
10199
  const rawTitle = evt.render?.title ?? `${evt.name}(${compactArgs(evt.args)})`;
10178
10200
  let title = humanizeToolTitle(evt.name, rawTitle, intentTier);
10179
- if (evt.startedAt !== void 0) {
10201
+ if (evt.startedAt !== void 0 && (evt.status === "running" || evt.status === "done" || evt.status === "error")) {
10180
10202
  title += ` \xB7 ${formatElapsed(now2 - evt.startedAt)}`;
10181
10203
  }
10204
+ const statusLabel = evt.status === "rejected" ? /* @__PURE__ */ jsx3(Text2, { color: theme.palette.error, children: " rejected" }) : evt.status === "cancelled" ? /* @__PURE__ */ jsx3(Text2, { color: theme.info.color, children: " cancelled" }) : null;
10205
+ const showItalic = evt.status === "queued" || evt.status === "cancelled" || evt.status === "rejected";
10182
10206
  const expand = Boolean(evt.expanded || verbose);
10183
10207
  const lines = evt.result ? evt.result.split("\n") : [];
10184
10208
  const showLimit = verbose ? 200 : 20;
@@ -10186,8 +10210,9 @@ var init_tool_view = __esm({
10186
10210
  /* @__PURE__ */ jsxs2(Text2, { children: [
10187
10211
  statusIcon,
10188
10212
  " ",
10189
- /* @__PURE__ */ jsx3(Text2, { color: theme.info.color, children: title }),
10190
- isRepeated ? /* @__PURE__ */ jsx3(Text2, { color: theme.warn, children: " \u26A0 repeated" }) : null
10213
+ /* @__PURE__ */ jsx3(Text2, { color: theme.info.color, italic: showItalic, children: title }),
10214
+ statusLabel,
10215
+ isRepeated ? /* @__PURE__ */ jsx3(Text2, { color: theme.warn, children: " [warn] repeated" }) : null
10191
10216
  ] }),
10192
10217
  evt.render?.diff ? /* @__PURE__ */ jsx3(Box2, { marginLeft: 2, children: /* @__PURE__ */ jsx3(DiffView, { ...evt.render.diff }) }) : null,
10193
10218
  evt.result && expand ? /* @__PURE__ */ jsxs2(
@@ -10209,7 +10234,7 @@ var init_tool_view = __esm({
10209
10234
  ]
10210
10235
  }
10211
10236
  ) : null,
10212
- evt.result && !expand && evt.status !== "running" ? /* @__PURE__ */ jsxs2(Text2, { color: theme.info.color, children: [
10237
+ evt.result && !expand && evt.status !== "running" && evt.status !== "queued" && evt.status !== "cancelled" && evt.status !== "rejected" ? /* @__PURE__ */ jsxs2(Text2, { color: theme.info.color, children: [
10213
10238
  " ",
10214
10239
  firstLine(evt.result)
10215
10240
  ] }) : null
@@ -10735,7 +10760,8 @@ function StatusBar({ usage, sessionUsage, thinking, turnStartedAt, mode, context
10735
10760
  " \xB7 ",
10736
10761
  "\u26A0 KIMI.md stale \xB7 run /init"
10737
10762
  ] }) : null
10738
- ] })
10763
+ ] }),
10764
+ !thinking && /* @__PURE__ */ jsx7(Box6, { children: /* @__PURE__ */ jsx7(Text6, { color: theme.muted?.color ?? theme.info.color, dimColor: theme.muted?.dim, children: "tip: shift+tab cycles mode" }) })
10739
10765
  ] });
10740
10766
  }
10741
10767
  function buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMode, cloudBudget) {
@@ -17734,8 +17760,11 @@ ${wcagWarnings.join("\n")}` }
17734
17760
  isAbortingRef.current = true;
17735
17761
  supervisorRef.current.killTurn();
17736
17762
  activeScopeRef.current.abort("user_stopped");
17737
- setQueue([]);
17738
17763
  setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "(interrupted)" }]);
17764
+ for (const [toolId] of pendingToolCallsRef.current) {
17765
+ updateTool(toolId, { status: "cancelled" });
17766
+ }
17767
+ pendingToolCallsRef.current.clear();
17739
17768
  void saveSessionSafe();
17740
17769
  setTasks([]);
17741
17770
  setTasksStartedAt(null);
@@ -17765,8 +17794,11 @@ ${wcagWarnings.join("\n")}` }
17765
17794
  setLimitModal(null);
17766
17795
  }
17767
17796
  activeScopeRef.current.abort("user_stopped");
17768
- setQueue([]);
17769
17797
  setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "(interrupted)" }]);
17798
+ for (const [toolId] of pendingToolCallsRef.current) {
17799
+ updateTool(toolId, { status: "cancelled" });
17800
+ }
17801
+ pendingToolCallsRef.current.clear();
17770
17802
  setTasks([]);
17771
17803
  setTasksStartedAt(null);
17772
17804
  setTasksStartTokens(0);
@@ -17811,7 +17843,6 @@ ${wcagWarnings.join("\n")}` }
17811
17843
  isAbortingRef.current = true;
17812
17844
  supervisorRef.current.killTurn();
17813
17845
  activeScopeRef.current.abort("user_stopped");
17814
- setQueue([]);
17815
17846
  setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "(interrupted)" }]);
17816
17847
  void saveSessionSafe();
17817
17848
  setTasks([]);
@@ -18082,15 +18113,37 @@ ${wcagWarnings.join("\n")}` }
18082
18113
  id: call.id,
18083
18114
  name: call.function.name,
18084
18115
  args: call.function.arguments,
18085
- status: "running",
18116
+ status: "queued",
18086
18117
  render: renderMeta,
18087
18118
  expanded: false
18088
18119
  }
18089
18120
  ]);
18090
18121
  },
18122
+ onToolWillExecute: (id) => {
18123
+ setTurnPhase("executing");
18124
+ setCurrentToolName(pendingToolCallsRef.current.get(id) ?? null);
18125
+ setLastActivityAt(Date.now());
18126
+ updateTool(id, { status: "running", startedAt: Date.now() });
18127
+ },
18091
18128
  onToolResult: (r) => {
18092
18129
  pendingToolCallsRef.current.delete(r.tool_call_id);
18093
- updateTool(r.tool_call_id, { status: r.ok ? "done" : "error", result: r.content });
18130
+ setLastActivityAt(Date.now());
18131
+ if (pendingToolCallsRef.current.size === 0) {
18132
+ setTurnPhase("waiting");
18133
+ setCurrentToolName(null);
18134
+ }
18135
+ const isDenied = typeof r.content === "string" && r.content.startsWith("Permission denied");
18136
+ updateTool(r.tool_call_id, { status: isDenied ? "rejected" : r.ok ? "done" : "error", result: r.content });
18137
+ },
18138
+ onWarning: (msg) => {
18139
+ setEvents((e) => [
18140
+ ...e,
18141
+ {
18142
+ kind: "info",
18143
+ key: mkKey(),
18144
+ text: msg
18145
+ }
18146
+ ]);
18094
18147
  },
18095
18148
  onUsage: (u) => {
18096
18149
  usageRef.current = u;
@@ -19498,13 +19551,18 @@ ${lines.join("\n")}` }]);
19498
19551
  id: call.id,
19499
19552
  name: call.function.name,
19500
19553
  args: call.function.arguments,
19501
- status: "running",
19554
+ status: "queued",
19502
19555
  render: renderMeta,
19503
- expanded: false,
19504
- startedAt: Date.now()
19556
+ expanded: false
19505
19557
  }
19506
19558
  ]);
19507
19559
  },
19560
+ onToolWillExecute: (id, name) => {
19561
+ setTurnPhase("executing");
19562
+ setCurrentToolName(name);
19563
+ setLastActivityAt(Date.now());
19564
+ updateTool(id, { status: "running", startedAt: Date.now() });
19565
+ },
19508
19566
  onToolResult: (r) => {
19509
19567
  pendingToolCallsRef.current.delete(r.tool_call_id);
19510
19568
  setLastActivityAt(Date.now());
@@ -19513,7 +19571,7 @@ ${lines.join("\n")}` }]);
19513
19571
  setCurrentToolName(null);
19514
19572
  }
19515
19573
  updateTool(r.tool_call_id, {
19516
- status: r.ok ? "done" : "error",
19574
+ status: !r.ok && typeof r.content === "string" && r.content.startsWith("Permission denied") ? "rejected" : r.ok ? "done" : "error",
19517
19575
  result: r.content
19518
19576
  });
19519
19577
  },
@@ -19812,16 +19870,6 @@ ${lines.join("\n")}` }]);
19812
19870
  const trimmedDisplay = (display ?? full).trim() || trimmedFull;
19813
19871
  const historyEntry = trimmedDisplay;
19814
19872
  if (busyRef.current) {
19815
- if (activeScopeRef.current && !isAbortingRef.current) {
19816
- isAbortingRef.current = true;
19817
- supervisorRef.current.killTurn();
19818
- activeScopeRef.current.abort("new_message");
19819
- setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "(preempted)" }]);
19820
- setTasks([]);
19821
- setTasksStartedAt(null);
19822
- setTasksStartTokens(0);
19823
- tasksRef.current = [];
19824
- }
19825
19873
  const key = mkKey();
19826
19874
  setEvents((e) => [...e, { kind: "user", key, text: trimmedDisplay, queued: true }]);
19827
19875
  setQueue((q) => [...q, { full: trimmedFull, display: trimmedDisplay, key }]);
@@ -20606,6 +20654,10 @@ async function runPrintMode(opts2) {
20606
20654
  onToolResult: (result) => {
20607
20655
  const snippet = result.content.length > 400 ? result.content.slice(0, 400) + "..." : result.content;
20608
20656
  process.stderr.write(`\x1B[2m[result: ${snippet.replace(/\n/g, " \u23CE ")}]\x1B[0m
20657
+ `);
20658
+ },
20659
+ onWarning: (msg) => {
20660
+ process.stderr.write(`\x1B[33mkimiflare: ${msg}\x1B[0m
20609
20661
  `);
20610
20662
  },
20611
20663
  askPermission: async ({ tool, args }) => {