kimiflare 0.13.0 → 0.13.1
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 +147 -46
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -230,57 +230,87 @@ async function* parseStream(body, signal) {
|
|
|
230
230
|
const toolCalls = /* @__PURE__ */ new Map();
|
|
231
231
|
let lastUsage = null;
|
|
232
232
|
let finishReason = null;
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (d) {
|
|
250
|
-
if (typeof d.reasoning_content === "string" && d.reasoning_content.length) {
|
|
251
|
-
yield { type: "reasoning", delta: d.reasoning_content };
|
|
233
|
+
let timeoutId = null;
|
|
234
|
+
let timedOut = false;
|
|
235
|
+
const resetTimeout = () => {
|
|
236
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
237
|
+
timeoutId = setTimeout(() => {
|
|
238
|
+
timedOut = true;
|
|
239
|
+
}, STREAM_TIMEOUT_MS);
|
|
240
|
+
};
|
|
241
|
+
try {
|
|
242
|
+
for await (const dataStr of readSSE(body, signal)) {
|
|
243
|
+
if (timedOut) {
|
|
244
|
+
throw new KimiApiError(
|
|
245
|
+
`kimiflare: stream timed out (no data for ${STREAM_TIMEOUT_MS / 1e3}s)`,
|
|
246
|
+
void 0,
|
|
247
|
+
void 0
|
|
248
|
+
);
|
|
252
249
|
}
|
|
253
|
-
|
|
254
|
-
|
|
250
|
+
resetTimeout();
|
|
251
|
+
if (dataStr === "[DONE]") break;
|
|
252
|
+
let chunk = null;
|
|
253
|
+
try {
|
|
254
|
+
chunk = JSON.parse(dataStr);
|
|
255
|
+
} catch {
|
|
256
|
+
continue;
|
|
255
257
|
}
|
|
256
|
-
if (
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
258
|
+
if (!chunk) continue;
|
|
259
|
+
if (chunk.usage) {
|
|
260
|
+
lastUsage = chunk.usage;
|
|
261
|
+
yield { type: "usage", usage: chunk.usage };
|
|
262
|
+
}
|
|
263
|
+
const choice = chunk.choices?.[0];
|
|
264
|
+
if (!choice) continue;
|
|
265
|
+
const d = choice.delta;
|
|
266
|
+
if (d) {
|
|
267
|
+
if (typeof d.reasoning_content === "string" && d.reasoning_content.length) {
|
|
268
|
+
yield { type: "reasoning", delta: d.reasoning_content };
|
|
269
|
+
}
|
|
270
|
+
if (typeof d.content === "string" && d.content.length) {
|
|
271
|
+
yield { type: "text", delta: d.content };
|
|
272
|
+
}
|
|
273
|
+
if (Array.isArray(d.tool_calls)) {
|
|
274
|
+
for (const tc of d.tool_calls) {
|
|
275
|
+
const idx = typeof tc.index === "number" ? tc.index : 0;
|
|
276
|
+
let buf = toolCalls.get(idx);
|
|
277
|
+
const incomingName = tc.function?.name ?? null;
|
|
278
|
+
const incomingId = tc.id ?? null;
|
|
279
|
+
if (!buf) {
|
|
280
|
+
buf = { id: incomingId ?? `tc_${idx}`, name: incomingName ?? "", args: "" };
|
|
281
|
+
toolCalls.set(idx, buf);
|
|
282
|
+
if (buf.name) {
|
|
283
|
+
yield { type: "tool_call_start", index: idx, id: buf.id, name: buf.name };
|
|
284
|
+
}
|
|
285
|
+
} else {
|
|
286
|
+
if (!buf.name && incomingName) {
|
|
287
|
+
buf.name = incomingName;
|
|
288
|
+
yield { type: "tool_call_start", index: idx, id: buf.id, name: buf.name };
|
|
289
|
+
}
|
|
290
|
+
if (buf.id.startsWith("tc_") && incomingId) buf.id = incomingId;
|
|
267
291
|
}
|
|
268
|
-
|
|
269
|
-
if (
|
|
270
|
-
buf.
|
|
271
|
-
yield { type: "
|
|
292
|
+
const argDelta = tc.function?.arguments;
|
|
293
|
+
if (typeof argDelta === "string" && argDelta.length) {
|
|
294
|
+
buf.args += argDelta;
|
|
295
|
+
yield { type: "tool_call_args", index: idx, argsDelta: argDelta };
|
|
272
296
|
}
|
|
273
|
-
if (buf.id.startsWith("tc_") && incomingId) buf.id = incomingId;
|
|
274
|
-
}
|
|
275
|
-
const argDelta = tc.function?.arguments;
|
|
276
|
-
if (typeof argDelta === "string" && argDelta.length) {
|
|
277
|
-
buf.args += argDelta;
|
|
278
|
-
yield { type: "tool_call_args", index: idx, argsDelta: argDelta };
|
|
279
297
|
}
|
|
280
298
|
}
|
|
281
299
|
}
|
|
300
|
+
if (choice.finish_reason) finishReason = choice.finish_reason;
|
|
282
301
|
}
|
|
283
|
-
|
|
302
|
+
for (const [idx, buf] of [...toolCalls.entries()].sort((a, b) => a[0] - b[0])) {
|
|
303
|
+
if (!buf.name) continue;
|
|
304
|
+
yield {
|
|
305
|
+
type: "tool_call_complete",
|
|
306
|
+
index: idx,
|
|
307
|
+
id: buf.id,
|
|
308
|
+
name: buf.name,
|
|
309
|
+
arguments: buf.args
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
} finally {
|
|
313
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
284
314
|
}
|
|
285
315
|
for (const [idx, buf] of [...toolCalls.entries()].sort((a, b) => a[0] - b[0])) {
|
|
286
316
|
if (!buf.name) continue;
|
|
@@ -354,7 +384,7 @@ function sleep(ms, signal) {
|
|
|
354
384
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
355
385
|
});
|
|
356
386
|
}
|
|
357
|
-
var RETRYABLE_CODES, MAX_ATTEMPTS;
|
|
387
|
+
var RETRYABLE_CODES, MAX_ATTEMPTS, STREAM_TIMEOUT_MS;
|
|
358
388
|
var init_client = __esm({
|
|
359
389
|
"src/agent/client.ts"() {
|
|
360
390
|
"use strict";
|
|
@@ -363,6 +393,7 @@ var init_client = __esm({
|
|
|
363
393
|
init_messages();
|
|
364
394
|
RETRYABLE_CODES = /* @__PURE__ */ new Set([3040]);
|
|
365
395
|
MAX_ATTEMPTS = 5;
|
|
396
|
+
STREAM_TIMEOUT_MS = 6e4;
|
|
366
397
|
}
|
|
367
398
|
});
|
|
368
399
|
|
|
@@ -3575,6 +3606,60 @@ function findImagePaths(text) {
|
|
|
3575
3606
|
}
|
|
3576
3607
|
return [...new Set(paths)];
|
|
3577
3608
|
}
|
|
3609
|
+
function stripImagesFromHistory(messages) {
|
|
3610
|
+
for (const m of messages) {
|
|
3611
|
+
if (!Array.isArray(m.content)) continue;
|
|
3612
|
+
let changed = false;
|
|
3613
|
+
const next = [];
|
|
3614
|
+
for (const part of m.content) {
|
|
3615
|
+
if (part.type === "image_url") {
|
|
3616
|
+
changed = true;
|
|
3617
|
+
next.push({ type: "text", text: "[image]" });
|
|
3618
|
+
} else {
|
|
3619
|
+
next.push(part);
|
|
3620
|
+
}
|
|
3621
|
+
}
|
|
3622
|
+
if (changed) {
|
|
3623
|
+
m.content = next;
|
|
3624
|
+
}
|
|
3625
|
+
}
|
|
3626
|
+
}
|
|
3627
|
+
function truncateOldToolResults(messages, keepRecent) {
|
|
3628
|
+
const toolIndices = [];
|
|
3629
|
+
for (let i = 0; i < messages.length; i++) {
|
|
3630
|
+
if (messages[i].role === "tool") toolIndices.push(i);
|
|
3631
|
+
}
|
|
3632
|
+
const cutoff = toolIndices.length - keepRecent;
|
|
3633
|
+
for (let i = 0; i < cutoff; i++) {
|
|
3634
|
+
const idx = toolIndices[i];
|
|
3635
|
+
const m = messages[idx];
|
|
3636
|
+
const text = typeof m.content === "string" ? m.content : "";
|
|
3637
|
+
if (text.length > 500) {
|
|
3638
|
+
m.content = text.slice(0, 500) + "\n\u2026 [truncated]";
|
|
3639
|
+
}
|
|
3640
|
+
}
|
|
3641
|
+
}
|
|
3642
|
+
async function maybeAutoCompact(messages, cfg, onInfo) {
|
|
3643
|
+
const heapUsed = process.memoryUsage().heapUsed;
|
|
3644
|
+
if (heapUsed < HEAP_AUTO_COMPACT_THRESHOLD || messages.length <= MSG_AUTO_COMPACT_THRESHOLD) {
|
|
3645
|
+
return false;
|
|
3646
|
+
}
|
|
3647
|
+
onInfo("auto-compacting to reduce memory usage");
|
|
3648
|
+
const result = await compactMessages({
|
|
3649
|
+
accountId: cfg.accountId,
|
|
3650
|
+
apiToken: cfg.apiToken,
|
|
3651
|
+
model: cfg.model,
|
|
3652
|
+
messages,
|
|
3653
|
+
keepLastTurns: 2
|
|
3654
|
+
});
|
|
3655
|
+
if (result.replacedCount > 0) {
|
|
3656
|
+
messages.length = 0;
|
|
3657
|
+
messages.push(...result.newMessages);
|
|
3658
|
+
onInfo(`compacted ${result.replacedCount} messages into a summary`);
|
|
3659
|
+
return true;
|
|
3660
|
+
}
|
|
3661
|
+
return false;
|
|
3662
|
+
}
|
|
3578
3663
|
function App({ initialCfg, initialUpdateResult }) {
|
|
3579
3664
|
const { exit } = useApp();
|
|
3580
3665
|
const [cfg, setCfg] = useState6(initialCfg);
|
|
@@ -4002,6 +4087,13 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
4002
4087
|
})
|
|
4003
4088
|
}
|
|
4004
4089
|
});
|
|
4090
|
+
stripImagesFromHistory(messagesRef.current);
|
|
4091
|
+
truncateOldToolResults(messagesRef.current, 8);
|
|
4092
|
+
await maybeAutoCompact(
|
|
4093
|
+
messagesRef.current,
|
|
4094
|
+
cfg,
|
|
4095
|
+
(text) => setEvents((es) => [...es, { kind: "info", key: mkKey(), text }])
|
|
4096
|
+
);
|
|
4005
4097
|
if (existsSync(join5(cwd, "KIMI.md"))) {
|
|
4006
4098
|
messagesRef.current[0] = {
|
|
4007
4099
|
role: "system",
|
|
@@ -4456,7 +4548,14 @@ use: /thinking low | medium | high`
|
|
|
4456
4548
|
})
|
|
4457
4549
|
}
|
|
4458
4550
|
});
|
|
4459
|
-
|
|
4551
|
+
stripImagesFromHistory(messagesRef.current);
|
|
4552
|
+
truncateOldToolResults(messagesRef.current, 8);
|
|
4553
|
+
await maybeAutoCompact(
|
|
4554
|
+
messagesRef.current,
|
|
4555
|
+
cfg,
|
|
4556
|
+
(text2) => setEvents((es) => [...es, { kind: "info", key: mkKey(), text: text2 }])
|
|
4557
|
+
);
|
|
4558
|
+
void saveSessionSafe();
|
|
4460
4559
|
} catch (e) {
|
|
4461
4560
|
if (e.name === "AbortError") {
|
|
4462
4561
|
setEvents((es) => [...es, { kind: "info", key: mkKey(), text: "(interrupted)" }]);
|
|
@@ -4652,7 +4751,7 @@ async function renderApp(cfg, updateResult) {
|
|
|
4652
4751
|
const instance = render(/* @__PURE__ */ jsx13(App, { initialCfg: cfg, initialUpdateResult: updateResult }));
|
|
4653
4752
|
await instance.waitUntilExit();
|
|
4654
4753
|
}
|
|
4655
|
-
var CONTEXT_LIMIT, AUTO_COMPACT_SUGGEST_PCT, MAX_EVENTS, nextAssistantId, nextKey, mkKey, MAX_IMAGES_PER_MESSAGE, EFFORT_DESCRIPTIONS;
|
|
4754
|
+
var CONTEXT_LIMIT, AUTO_COMPACT_SUGGEST_PCT, MAX_EVENTS, nextAssistantId, nextKey, mkKey, MAX_IMAGES_PER_MESSAGE, EFFORT_DESCRIPTIONS, HEAP_AUTO_COMPACT_THRESHOLD, MSG_AUTO_COMPACT_THRESHOLD;
|
|
4656
4755
|
var init_app = __esm({
|
|
4657
4756
|
"src/app.tsx"() {
|
|
4658
4757
|
"use strict";
|
|
@@ -4689,6 +4788,8 @@ var init_app = __esm({
|
|
|
4689
4788
|
medium: "medium \u2014 balanced (default). Solid quality on most edits, fast on trivial prompts.",
|
|
4690
4789
|
high: "high \u2014 deepest reasoning; slowest. Best for complex debugging, architecture, multi-file refactors."
|
|
4691
4790
|
};
|
|
4791
|
+
HEAP_AUTO_COMPACT_THRESHOLD = 2e9;
|
|
4792
|
+
MSG_AUTO_COMPACT_THRESHOLD = 50;
|
|
4692
4793
|
}
|
|
4693
4794
|
});
|
|
4694
4795
|
|