kimiflare 0.65.0 → 0.66.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 +80 -22
- package/dist/index.js.map +1 -1
- package/dist/sdk/index.js +62 -19
- package/dist/sdk/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -401,11 +401,12 @@ var init_logger = __esm({
|
|
|
401
401
|
});
|
|
402
402
|
|
|
403
403
|
// src/util/sse.ts
|
|
404
|
-
async function* readSSE(stream, signal, idleTimeoutMs) {
|
|
404
|
+
async function* readSSE(stream, signal, idleTimeoutMs, postFirstByteIdleTimeoutMs) {
|
|
405
405
|
const reader = stream.getReader();
|
|
406
406
|
const decoder = new TextDecoder("utf-8");
|
|
407
407
|
let buffer = "";
|
|
408
408
|
let lastDataAt = Date.now();
|
|
409
|
+
let gotFirstByte = false;
|
|
409
410
|
const onAbort = () => {
|
|
410
411
|
reader.cancel(new DOMException("aborted", "AbortError")).catch(() => {
|
|
411
412
|
});
|
|
@@ -427,16 +428,18 @@ async function* readSSE(stream, signal, idleTimeoutMs) {
|
|
|
427
428
|
try {
|
|
428
429
|
while (true) {
|
|
429
430
|
if (signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
430
|
-
|
|
431
|
-
|
|
431
|
+
const activeIdleTimeoutMs = gotFirstByte && postFirstByteIdleTimeoutMs !== void 0 ? postFirstByteIdleTimeoutMs : idleTimeoutMs;
|
|
432
|
+
if (activeIdleTimeoutMs !== void 0 && Date.now() - lastDataAt > activeIdleTimeoutMs) {
|
|
433
|
+
logger.warn("sse:idle_timeout", { idleTimeoutMs: activeIdleTimeoutMs, gotFirstByte });
|
|
432
434
|
throw new DOMException(
|
|
433
|
-
`kimiflare: stream idle for ${
|
|
435
|
+
`kimiflare: stream idle for ${activeIdleTimeoutMs}ms \u2014 no data received from API`,
|
|
434
436
|
"TimeoutError"
|
|
435
437
|
);
|
|
436
438
|
}
|
|
437
439
|
const { done, value } = await abortRace(reader.read());
|
|
438
440
|
if (done) break;
|
|
439
441
|
lastDataAt = Date.now();
|
|
442
|
+
gotFirstByte = true;
|
|
440
443
|
buffer += decoder.decode(value, { stream: true });
|
|
441
444
|
buffer = buffer.replace(/\r\n/g, "\n");
|
|
442
445
|
let sep3;
|
|
@@ -717,7 +720,7 @@ async function* runKimi(opts2) {
|
|
|
717
720
|
if (meta) yield { type: "gateway_meta", meta };
|
|
718
721
|
let lastUsage = null;
|
|
719
722
|
logger.debug("runKimi:stream_start", { requestId });
|
|
720
|
-
for await (const ev of parseStream(res.body, opts2.signal, opts2.idleTimeoutMs)) {
|
|
723
|
+
for await (const ev of parseStream(res.body, opts2.signal, opts2.idleTimeoutMs, opts2.postFirstByteIdleTimeoutMs)) {
|
|
721
724
|
if (ev.type === "usage") lastUsage = ev.usage;
|
|
722
725
|
yield ev;
|
|
723
726
|
}
|
|
@@ -799,12 +802,11 @@ function readGatewayMeta(headers) {
|
|
|
799
802
|
if (model) meta.model = model;
|
|
800
803
|
return Object.keys(meta).length > 0 ? meta : null;
|
|
801
804
|
}
|
|
802
|
-
async function* parseStream(body, signal, idleTimeoutMs = DEFAULT_IDLE_TIMEOUT_MS) {
|
|
805
|
+
async function* parseStream(body, signal, idleTimeoutMs = DEFAULT_IDLE_TIMEOUT_MS, postFirstByteIdleTimeoutMs = DEFAULT_POST_FIRST_BYTE_IDLE_TIMEOUT_MS) {
|
|
803
806
|
const toolCalls = /* @__PURE__ */ new Map();
|
|
804
807
|
let lastUsage = null;
|
|
805
808
|
let finishReason = null;
|
|
806
|
-
|
|
807
|
-
for await (const dataStr of readSSE(body, signal, idleTimeoutMs)) {
|
|
809
|
+
for await (const dataStr of readSSE(body, signal, idleTimeoutMs, postFirstByteIdleTimeoutMs)) {
|
|
808
810
|
if (dataStr === "[DONE]") break;
|
|
809
811
|
let chunk = null;
|
|
810
812
|
try {
|
|
@@ -942,7 +944,7 @@ function sleep(ms, signal) {
|
|
|
942
944
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
943
945
|
});
|
|
944
946
|
}
|
|
945
|
-
var RETRYABLE_CODES, MAX_ATTEMPTS, DEFAULT_IDLE_TIMEOUT_MS;
|
|
947
|
+
var RETRYABLE_CODES, MAX_ATTEMPTS, DEFAULT_IDLE_TIMEOUT_MS, DEFAULT_POST_FIRST_BYTE_IDLE_TIMEOUT_MS;
|
|
946
948
|
var init_client = __esm({
|
|
947
949
|
"src/agent/client.ts"() {
|
|
948
950
|
"use strict";
|
|
@@ -954,6 +956,7 @@ var init_client = __esm({
|
|
|
954
956
|
RETRYABLE_CODES = /* @__PURE__ */ new Set([3040]);
|
|
955
957
|
MAX_ATTEMPTS = 5;
|
|
956
958
|
DEFAULT_IDLE_TIMEOUT_MS = 6e4;
|
|
959
|
+
DEFAULT_POST_FIRST_BYTE_IDLE_TIMEOUT_MS = 3e4;
|
|
957
960
|
}
|
|
958
961
|
});
|
|
959
962
|
|
|
@@ -2155,7 +2158,7 @@ var init_session_state = __esm({
|
|
|
2155
2158
|
}
|
|
2156
2159
|
add(a) {
|
|
2157
2160
|
while (this.totalChars() + a.raw.length > this.maxTotalChars && this.artifacts.size > 0) {
|
|
2158
|
-
this.
|
|
2161
|
+
this.evictSizeWeighted();
|
|
2159
2162
|
}
|
|
2160
2163
|
while (this.artifacts.size >= this.maxArtifacts) {
|
|
2161
2164
|
this.evictOldest();
|
|
@@ -2196,6 +2199,21 @@ var init_session_state = __esm({
|
|
|
2196
2199
|
}
|
|
2197
2200
|
if (oldest) this.artifacts.delete(oldest.id);
|
|
2198
2201
|
}
|
|
2202
|
+
/** Evict the largest artifact among the oldest quartile (by timestamp).
|
|
2203
|
+
* Bounded by the oldest quartile so we never evict freshly-added artifacts;
|
|
2204
|
+
* size-weighted within that window so one big artifact gets dropped instead
|
|
2205
|
+
* of many small ones. */
|
|
2206
|
+
evictSizeWeighted() {
|
|
2207
|
+
const sorted = [...this.artifacts.values()].sort((a, b) => a.ts < b.ts ? -1 : 1);
|
|
2208
|
+
if (sorted.length === 0) return;
|
|
2209
|
+
const quartile = Math.max(1, Math.ceil(sorted.length / 4));
|
|
2210
|
+
const candidates = sorted.slice(0, quartile);
|
|
2211
|
+
let pick3 = candidates[0];
|
|
2212
|
+
for (const a of candidates) {
|
|
2213
|
+
if (a.raw.length > pick3.raw.length) pick3 = a;
|
|
2214
|
+
}
|
|
2215
|
+
this.artifacts.delete(pick3.id);
|
|
2216
|
+
}
|
|
2199
2217
|
};
|
|
2200
2218
|
}
|
|
2201
2219
|
});
|
|
@@ -3404,7 +3422,8 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
3404
3422
|
cloudMode: opts2.cloudMode,
|
|
3405
3423
|
cloudToken: opts2.cloudToken,
|
|
3406
3424
|
cloudDeviceId: opts2.cloudDeviceId,
|
|
3407
|
-
idleTimeoutMs: 6e4
|
|
3425
|
+
idleTimeoutMs: opts2.idleTimeoutMs ?? 6e4,
|
|
3426
|
+
postFirstByteIdleTimeoutMs: opts2.postFirstByteIdleTimeoutMs
|
|
3408
3427
|
});
|
|
3409
3428
|
let gotFirstChunk = false;
|
|
3410
3429
|
for await (const ev of events) {
|
|
@@ -3454,7 +3473,7 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
3454
3473
|
if (lastUsage) {
|
|
3455
3474
|
opts2.callbacks.onUsageFinal?.(lastUsage, gatewayMeta);
|
|
3456
3475
|
cumulativePromptTokens += lastUsage.prompt_tokens;
|
|
3457
|
-
if (!budgetExhausted && opts2.maxInputTokens !== void 0 && opts2.maxInputTokens > 0 && cumulativePromptTokens >= opts2.maxInputTokens
|
|
3476
|
+
if (!budgetExhausted && opts2.maxInputTokens !== void 0 && opts2.maxInputTokens > 0 && cumulativePromptTokens >= opts2.maxInputTokens) {
|
|
3458
3477
|
budgetExhausted = true;
|
|
3459
3478
|
}
|
|
3460
3479
|
}
|
|
@@ -3693,7 +3712,22 @@ ${sandboxResult.output}` : sandboxResult.output;
|
|
|
3693
3712
|
}
|
|
3694
3713
|
}
|
|
3695
3714
|
}
|
|
3696
|
-
} catch {
|
|
3715
|
+
} catch (err) {
|
|
3716
|
+
const sid = opts2.sessionId ?? "default";
|
|
3717
|
+
const next = (memoryExtractionErrorCounts.get(sid) ?? 0) + 1;
|
|
3718
|
+
memoryExtractionErrorCounts.set(sid, next);
|
|
3719
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3720
|
+
logger.debug("memory:extract_error", {
|
|
3721
|
+
sessionId: opts2.sessionId,
|
|
3722
|
+
tool: tc.function.name,
|
|
3723
|
+
count: next,
|
|
3724
|
+
error: msg
|
|
3725
|
+
});
|
|
3726
|
+
if (next === 1) {
|
|
3727
|
+
opts2.callbacks.onWarning?.(
|
|
3728
|
+
`[memory] auto-extraction failed (${msg}). Subsequent failures will be counted silently; check /memory health.`
|
|
3729
|
+
);
|
|
3730
|
+
}
|
|
3697
3731
|
}
|
|
3698
3732
|
})();
|
|
3699
3733
|
}
|
|
@@ -3770,7 +3804,7 @@ function validateToolArguments(raw) {
|
|
|
3770
3804
|
return "{}";
|
|
3771
3805
|
}
|
|
3772
3806
|
}
|
|
3773
|
-
var BudgetExhaustedError, AgentLoopError, codeModeApiCache, driftAccumulator, DRIFT_THRESHOLD, MAX_PROMPT_TOKENS, MAX_TOOL_CONTENT_CHARS;
|
|
3807
|
+
var BudgetExhaustedError, AgentLoopError, codeModeApiCache, driftAccumulator, DRIFT_THRESHOLD, memoryExtractionErrorCounts, MAX_PROMPT_TOKENS, MAX_TOOL_CONTENT_CHARS;
|
|
3774
3808
|
var init_loop = __esm({
|
|
3775
3809
|
"src/agent/loop.ts"() {
|
|
3776
3810
|
"use strict";
|
|
@@ -3800,6 +3834,7 @@ var init_loop = __esm({
|
|
|
3800
3834
|
codeModeApiCache = /* @__PURE__ */ new Map();
|
|
3801
3835
|
driftAccumulator = /* @__PURE__ */ new Map();
|
|
3802
3836
|
DRIFT_THRESHOLD = 5;
|
|
3837
|
+
memoryExtractionErrorCounts = /* @__PURE__ */ new Map();
|
|
3803
3838
|
MAX_PROMPT_TOKENS = 24e4;
|
|
3804
3839
|
MAX_TOOL_CONTENT_CHARS = 1e4;
|
|
3805
3840
|
}
|
|
@@ -3867,10 +3902,13 @@ var init_read = __esm({
|
|
|
3867
3902
|
needsPermission: false,
|
|
3868
3903
|
render: ({ path }) => ({ title: `read ${collapsePath(path, process.cwd())}` }),
|
|
3869
3904
|
async run(args, ctx) {
|
|
3905
|
+
if (ctx.signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
3870
3906
|
const abs = resolvePath(ctx.cwd, args.path);
|
|
3871
3907
|
const st = await stat2(abs);
|
|
3872
3908
|
if (st.size > MAX_BYTES) throw new Error(`file too large: ${st.size} bytes (max ${MAX_BYTES})`);
|
|
3873
|
-
|
|
3909
|
+
if (ctx.signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
3910
|
+
const text = await readFile3(abs, { encoding: "utf8", signal: ctx.signal });
|
|
3911
|
+
if (ctx.signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
3874
3912
|
const lines = text.split("\n");
|
|
3875
3913
|
const start = Math.max(0, (args.offset ?? 1) - 1);
|
|
3876
3914
|
const end = args.limit ? Math.min(lines.length, start + args.limit) : lines.length;
|
|
@@ -4162,14 +4200,31 @@ var init_glob = __esm({
|
|
|
4162
4200
|
needsPermission: false,
|
|
4163
4201
|
render: (args) => ({ title: `glob ${args.pattern ?? ""}${args.path ? ` in ${collapsePath(String(args.path), process.cwd())}` : ""}` }),
|
|
4164
4202
|
async run(args, ctx) {
|
|
4203
|
+
if (ctx.signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
4165
4204
|
const root = args.path ? resolvePath(ctx.cwd, args.path) : ctx.cwd;
|
|
4166
|
-
const
|
|
4205
|
+
const stream = fg.stream(args.pattern, {
|
|
4167
4206
|
cwd: root,
|
|
4168
4207
|
absolute: true,
|
|
4169
4208
|
dot: false,
|
|
4170
4209
|
onlyFiles: false,
|
|
4171
4210
|
stats: true
|
|
4172
4211
|
});
|
|
4212
|
+
const entries = [];
|
|
4213
|
+
const onAbort = () => {
|
|
4214
|
+
try {
|
|
4215
|
+
stream.destroy(new DOMException("aborted", "AbortError"));
|
|
4216
|
+
} catch {
|
|
4217
|
+
}
|
|
4218
|
+
};
|
|
4219
|
+
ctx.signal?.addEventListener("abort", onAbort, { once: true });
|
|
4220
|
+
try {
|
|
4221
|
+
for await (const entry of stream) {
|
|
4222
|
+
if (ctx.signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
4223
|
+
entries.push(entry);
|
|
4224
|
+
}
|
|
4225
|
+
} finally {
|
|
4226
|
+
ctx.signal?.removeEventListener("abort", onAbort);
|
|
4227
|
+
}
|
|
4173
4228
|
entries.sort((a, b) => (b.stats?.mtimeMs ?? 0) - (a.stats?.mtimeMs ?? 0));
|
|
4174
4229
|
const paths = entries.slice(0, 200).map((e) => e.path);
|
|
4175
4230
|
return paths.length ? paths.join("\n") : "(no matches)";
|
|
@@ -4193,14 +4248,14 @@ async function hasRipgrep() {
|
|
|
4193
4248
|
}
|
|
4194
4249
|
return cachedHasRg;
|
|
4195
4250
|
}
|
|
4196
|
-
async function runRipgrep(args, root, mode) {
|
|
4251
|
+
async function runRipgrep(args, root, mode, signal) {
|
|
4197
4252
|
const rgArgs = ["--no-heading", "--color=never", "--line-number"];
|
|
4198
4253
|
if (args.case_insensitive) rgArgs.push("-i");
|
|
4199
4254
|
if (args.glob) rgArgs.push("--glob", args.glob);
|
|
4200
4255
|
if (mode === "files") rgArgs.push("-l");
|
|
4201
4256
|
rgArgs.push("--", args.pattern, root);
|
|
4202
4257
|
try {
|
|
4203
|
-
const { stdout } = await pExecFile("rg", rgArgs, { maxBuffer: 10 * 1024 * 1024 });
|
|
4258
|
+
const { stdout } = await pExecFile("rg", rgArgs, { maxBuffer: 10 * 1024 * 1024, signal });
|
|
4204
4259
|
const trimmed = stdout.trim();
|
|
4205
4260
|
if (!trimmed) return { content: "(no matches)", rawBytes: 0, reducedBytes: 0 };
|
|
4206
4261
|
return {
|
|
@@ -4214,7 +4269,7 @@ async function runRipgrep(args, root, mode) {
|
|
|
4214
4269
|
throw new Error(err.stderr || String(e));
|
|
4215
4270
|
}
|
|
4216
4271
|
}
|
|
4217
|
-
async function runJsFallback(args, root, mode) {
|
|
4272
|
+
async function runJsFallback(args, root, mode, signal) {
|
|
4218
4273
|
const re = new RegExp(args.pattern, args.case_insensitive ? "i" : "");
|
|
4219
4274
|
const globPattern = args.glob ? `**/${args.glob}` : "**/*";
|
|
4220
4275
|
const files = await fg2(globPattern, {
|
|
@@ -4225,7 +4280,9 @@ async function runJsFallback(args, root, mode) {
|
|
|
4225
4280
|
ignore: ["**/node_modules/**", "**/.git/**", "**/dist/**"]
|
|
4226
4281
|
});
|
|
4227
4282
|
const out = [];
|
|
4228
|
-
for (
|
|
4283
|
+
for (let fi = 0; fi < Math.min(files.length, 5e3); fi++) {
|
|
4284
|
+
if (signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
4285
|
+
const file = files[fi];
|
|
4229
4286
|
try {
|
|
4230
4287
|
const content = await readFile6(file, "utf8");
|
|
4231
4288
|
if (mode === "files") {
|
|
@@ -4280,10 +4337,11 @@ var init_grep = __esm({
|
|
|
4280
4337
|
needsPermission: false,
|
|
4281
4338
|
render: (args) => ({ title: `grep ${args.pattern ?? ""}${args.glob ? ` (${args.glob})` : ""}` }),
|
|
4282
4339
|
async run(args, ctx) {
|
|
4340
|
+
if (ctx.signal?.aborted) throw new DOMException("aborted", "AbortError");
|
|
4283
4341
|
const root = args.path ? resolvePath(ctx.cwd, args.path) : ctx.cwd;
|
|
4284
4342
|
const mode = args.output_mode ?? "content";
|
|
4285
|
-
if (await hasRipgrep()) return runRipgrep(args, root, mode);
|
|
4286
|
-
return runJsFallback(args, root, mode);
|
|
4343
|
+
if (await hasRipgrep()) return runRipgrep(args, root, mode, ctx.signal);
|
|
4344
|
+
return runJsFallback(args, root, mode, ctx.signal);
|
|
4287
4345
|
}
|
|
4288
4346
|
};
|
|
4289
4347
|
}
|