kimiflare 0.68.1 → 0.69.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 +752 -517
- package/dist/index.js.map +1 -1
- package/dist/sdk/index.js +165 -85
- package/dist/sdk/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1244,7 +1244,10 @@ async function logTurnDebug(ctx) {
|
|
|
1244
1244
|
durationMs: ctx.durationMs,
|
|
1245
1245
|
intentClassification: ctx.intentClassification,
|
|
1246
1246
|
codeMode: ctx.codeMode,
|
|
1247
|
-
selectedSkills: ctx.selectedSkills?.map((s) => s.name)
|
|
1247
|
+
selectedSkills: ctx.selectedSkills?.map((s) => s.name),
|
|
1248
|
+
userPromptPreview: ctx.userPromptPreview,
|
|
1249
|
+
preTurnMs: ctx.preTurnMs,
|
|
1250
|
+
memoryRecalled: ctx.memoryRecalled
|
|
1248
1251
|
});
|
|
1249
1252
|
}
|
|
1250
1253
|
var LOG_VERSION;
|
|
@@ -2703,6 +2706,10 @@ function deleteOrphanedSkills(db, existingPaths) {
|
|
|
2703
2706
|
const result = db.prepare(`DELETE FROM skill_index WHERE file_path NOT IN (${placeholders})`).run(...existingPaths);
|
|
2704
2707
|
return Number(result.changes);
|
|
2705
2708
|
}
|
|
2709
|
+
function hasAnySections(db) {
|
|
2710
|
+
const row = db.prepare("SELECT 1 FROM skill_sections LIMIT 1").get();
|
|
2711
|
+
return row !== void 0;
|
|
2712
|
+
}
|
|
2706
2713
|
function listAllSectionRows(db) {
|
|
2707
2714
|
return db.prepare(
|
|
2708
2715
|
`SELECT s.id, s.heading, s.body, s.embedding, i.name, i.description, i.file_path
|
|
@@ -2728,6 +2735,7 @@ var init_db = __esm({
|
|
|
2728
2735
|
|
|
2729
2736
|
// src/skills/search.ts
|
|
2730
2737
|
async function searchSections(query, db, opts2) {
|
|
2738
|
+
if (!hasAnySections(db)) return [];
|
|
2731
2739
|
const embeddings = await fetchEmbeddings({
|
|
2732
2740
|
accountId: opts2.accountId,
|
|
2733
2741
|
apiToken: opts2.apiToken,
|
|
@@ -3162,6 +3170,15 @@ function getSessionWebFetchHistory(sessionId) {
|
|
|
3162
3170
|
function isHighSignalMemory(memory) {
|
|
3163
3171
|
return memory.topicKey === "project_dependencies" || memory.topicKey === "project_tsconfig" || memory.topicKey === "project_entry_point" || memory.category === "instruction" || memory.category === "preference" || memory.category === "event" && memory.importance >= 3;
|
|
3164
3172
|
}
|
|
3173
|
+
function extractLastUserText(messages) {
|
|
3174
|
+
const lastUser = [...messages].reverse().find((m) => m.role === "user");
|
|
3175
|
+
if (!lastUser) return "";
|
|
3176
|
+
if (typeof lastUser.content === "string") return lastUser.content;
|
|
3177
|
+
if (Array.isArray(lastUser.content)) {
|
|
3178
|
+
return lastUser.content.filter((p) => p.type === "text").map((p) => p.text).join(" ");
|
|
3179
|
+
}
|
|
3180
|
+
return "";
|
|
3181
|
+
}
|
|
3165
3182
|
function raceWithSignal(promise, signal) {
|
|
3166
3183
|
return Promise.race([
|
|
3167
3184
|
promise,
|
|
@@ -3179,87 +3196,84 @@ async function runAgentTurn(opts2) {
|
|
|
3179
3196
|
logger.info("turn:start", { sessionId: opts2.sessionId, codeMode: opts2.codeMode ?? false });
|
|
3180
3197
|
const max = opts2.maxToolIterations ?? 50;
|
|
3181
3198
|
const codeMode = opts2.codeMode ?? false;
|
|
3199
|
+
const preTurnStart = performance.now();
|
|
3182
3200
|
let memoryRecalledCount = 0;
|
|
3183
3201
|
let skillResult;
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
}
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
};
|
|
3254
|
-
}
|
|
3255
|
-
}
|
|
3256
|
-
} catch (err) {
|
|
3257
|
-
if (err instanceof DOMException && err.name === "AbortError") throw err;
|
|
3202
|
+
const lastUserPrompt = extractLastUserText(opts2.messages);
|
|
3203
|
+
const userPromptPreview = lastUserPrompt.slice(0, 200);
|
|
3204
|
+
const skipSkillRouting = opts2.intentClassification?.tier === "light" && lastUserPrompt.length < 40;
|
|
3205
|
+
const recallPromise = opts2.sessionStartRecall && opts2.memoryManager ? (async () => {
|
|
3206
|
+
const results = await opts2.sessionStartRecall;
|
|
3207
|
+
if (results.length === 0 || !opts2.memoryManager) return null;
|
|
3208
|
+
const text = await opts2.memoryManager.synthesizeRecalled(results, opts2.signal);
|
|
3209
|
+
return { text, count: results.length };
|
|
3210
|
+
})() : Promise.resolve(null);
|
|
3211
|
+
const skillsPromise = opts2.skillsDb && opts2.skillRoutingConfig && opts2.intentClassification && lastUserPrompt && !skipSkillRouting ? selectSkills(
|
|
3212
|
+
{
|
|
3213
|
+
prompt: lastUserPrompt,
|
|
3214
|
+
tier: opts2.intentClassification.tier,
|
|
3215
|
+
maxSkillTokens: opts2.skillRoutingConfig.maxSkillTokens ?? 25e4 - 1e4
|
|
3216
|
+
},
|
|
3217
|
+
{
|
|
3218
|
+
db: opts2.skillsDb,
|
|
3219
|
+
accountId: opts2.skillRoutingConfig.accountId,
|
|
3220
|
+
apiToken: opts2.skillRoutingConfig.apiToken,
|
|
3221
|
+
embeddingModel: opts2.skillRoutingConfig.embeddingModel,
|
|
3222
|
+
gateway: opts2.skillRoutingConfig.gateway,
|
|
3223
|
+
cloudMode: opts2.skillRoutingConfig.cloudMode,
|
|
3224
|
+
cloudToken: opts2.skillRoutingConfig.cloudToken,
|
|
3225
|
+
cloudDeviceId: opts2.skillRoutingConfig.cloudDeviceId
|
|
3226
|
+
}
|
|
3227
|
+
) : Promise.resolve(void 0);
|
|
3228
|
+
const [recallSettled, skillsSettled] = await Promise.allSettled([
|
|
3229
|
+
raceWithSignal(recallPromise, opts2.signal),
|
|
3230
|
+
raceWithSignal(skillsPromise, opts2.signal)
|
|
3231
|
+
]);
|
|
3232
|
+
for (const settled of [recallSettled, skillsSettled]) {
|
|
3233
|
+
if (settled.status === "rejected" && settled.reason instanceof DOMException && settled.reason.name === "AbortError") {
|
|
3234
|
+
throw settled.reason;
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
if (recallSettled.status === "fulfilled" && recallSettled.value) {
|
|
3238
|
+
const { text, count } = recallSettled.value;
|
|
3239
|
+
const lastSystemIdx = opts2.messages.findLastIndex((m) => m.role === "system");
|
|
3240
|
+
const insertIdx = lastSystemIdx >= 0 ? lastSystemIdx + 1 : opts2.messages.length;
|
|
3241
|
+
opts2.messages.splice(insertIdx, 0, { role: "system", content: text });
|
|
3242
|
+
memoryRecalledCount = count;
|
|
3243
|
+
opts2.callbacks.onMemoryRecalled?.(count);
|
|
3244
|
+
}
|
|
3245
|
+
if (skillsSettled.status === "fulfilled" && skillsSettled.value) {
|
|
3246
|
+
skillResult = skillsSettled.value;
|
|
3247
|
+
opts2.callbacks.onSkillsSelected?.(skillResult);
|
|
3248
|
+
const allTools = opts2.tools;
|
|
3249
|
+
if (opts2.cacheStable) {
|
|
3250
|
+
opts2.messages[1] = {
|
|
3251
|
+
role: "system",
|
|
3252
|
+
content: buildSessionPrefix({
|
|
3253
|
+
cwd: opts2.cwd,
|
|
3254
|
+
tools: allTools,
|
|
3255
|
+
model: opts2.model,
|
|
3256
|
+
mode: opts2.mode,
|
|
3257
|
+
skillContext: skillResult.skillContext
|
|
3258
|
+
})
|
|
3259
|
+
};
|
|
3260
|
+
} else {
|
|
3261
|
+
opts2.messages[0] = {
|
|
3262
|
+
role: "system",
|
|
3263
|
+
content: buildSystemPrompt({
|
|
3264
|
+
cwd: opts2.cwd,
|
|
3265
|
+
tools: allTools,
|
|
3266
|
+
model: opts2.model,
|
|
3267
|
+
mode: opts2.mode,
|
|
3268
|
+
skillContext: skillResult.skillContext
|
|
3269
|
+
})
|
|
3270
|
+
};
|
|
3258
3271
|
}
|
|
3259
3272
|
}
|
|
3260
3273
|
if (opts2.signal.aborted) {
|
|
3261
3274
|
throw new DOMException("aborted", "AbortError");
|
|
3262
3275
|
}
|
|
3276
|
+
const preTurnMs = Math.round(performance.now() - preTurnStart);
|
|
3263
3277
|
opts2.callbacks.onMetaBanner?.({
|
|
3264
3278
|
intentTier: opts2.intentClassification?.tier ?? "medium",
|
|
3265
3279
|
skillsActive: skillResult?.sectionCount ?? 0,
|
|
@@ -3414,7 +3428,9 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
3414
3428
|
...opts2.gateway.metadata ?? {},
|
|
3415
3429
|
feature: "chat",
|
|
3416
3430
|
...opts2.sessionId ? { sessionId: opts2.sessionId } : {},
|
|
3417
|
-
|
|
3431
|
+
tier: opts2.intentClassification?.tier ?? "medium",
|
|
3432
|
+
cm: codeMode ? "1" : "0",
|
|
3433
|
+
skl: String(skillResult?.sectionCount ?? 0)
|
|
3418
3434
|
}
|
|
3419
3435
|
} : void 0;
|
|
3420
3436
|
const events = runKimi({
|
|
@@ -3512,7 +3528,14 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
3512
3528
|
previousMessages,
|
|
3513
3529
|
toolResults,
|
|
3514
3530
|
usage: lastUsage,
|
|
3515
|
-
shadowStrip: shadowStripMetrics
|
|
3531
|
+
shadowStrip: shadowStripMetrics,
|
|
3532
|
+
durationMs: Math.round(performance.now() - turnStart),
|
|
3533
|
+
intentClassification: opts2.intentClassification,
|
|
3534
|
+
codeMode: opts2.codeMode,
|
|
3535
|
+
selectedSkills: opts2.selectedSkills,
|
|
3536
|
+
userPromptPreview,
|
|
3537
|
+
preTurnMs,
|
|
3538
|
+
memoryRecalled: memoryRecalledCount > 0
|
|
3516
3539
|
});
|
|
3517
3540
|
}
|
|
3518
3541
|
if (budgetExhausted) {
|
|
@@ -3821,7 +3844,10 @@ ${sandboxResult.output}` : sandboxResult.output;
|
|
|
3821
3844
|
durationMs: Math.round(performance.now() - turnStart),
|
|
3822
3845
|
intentClassification: opts2.intentClassification,
|
|
3823
3846
|
codeMode: opts2.codeMode,
|
|
3824
|
-
selectedSkills: opts2.selectedSkills
|
|
3847
|
+
selectedSkills: opts2.selectedSkills,
|
|
3848
|
+
userPromptPreview,
|
|
3849
|
+
preTurnMs,
|
|
3850
|
+
memoryRecalled: memoryRecalledCount > 0
|
|
3825
3851
|
});
|
|
3826
3852
|
}
|
|
3827
3853
|
if (budgetExhausted) {
|
|
@@ -3942,15 +3968,61 @@ var init_paths = __esm({
|
|
|
3942
3968
|
|
|
3943
3969
|
// src/tools/read.ts
|
|
3944
3970
|
import { readFile as readFile3, stat as stat2 } from "fs/promises";
|
|
3945
|
-
|
|
3971
|
+
import { createReadStream } from "fs";
|
|
3972
|
+
import { createInterface } from "readline";
|
|
3973
|
+
function aborted(signal) {
|
|
3974
|
+
return signal?.aborted === true;
|
|
3975
|
+
}
|
|
3976
|
+
function abortError() {
|
|
3977
|
+
return new DOMException("aborted", "AbortError");
|
|
3978
|
+
}
|
|
3979
|
+
async function readSliceStreaming(abs, offset, limit, signal) {
|
|
3980
|
+
if (aborted(signal)) throw abortError();
|
|
3981
|
+
const rs = createReadStream(abs, { encoding: "utf8" });
|
|
3982
|
+
const onAbort = () => rs.destroy(abortError());
|
|
3983
|
+
signal?.addEventListener("abort", onAbort);
|
|
3984
|
+
try {
|
|
3985
|
+
const rl = createInterface({ input: rs, crlfDelay: Infinity });
|
|
3986
|
+
const startLine = Math.max(1, offset);
|
|
3987
|
+
const endLine = startLine + Math.max(0, limit) - 1;
|
|
3988
|
+
const collected = [];
|
|
3989
|
+
let lineNum = 0;
|
|
3990
|
+
let bytesScanned = 0;
|
|
3991
|
+
for await (const line of rl) {
|
|
3992
|
+
if (aborted(signal)) throw abortError();
|
|
3993
|
+
lineNum += 1;
|
|
3994
|
+
bytesScanned += Buffer.byteLength(line, "utf8") + 1;
|
|
3995
|
+
if (bytesScanned > MAX_STREAM_BYTES) {
|
|
3996
|
+
throw new Error(
|
|
3997
|
+
`file too large to stream: exceeded ${MAX_STREAM_BYTES} bytes while seeking slice at line ${startLine}`
|
|
3998
|
+
);
|
|
3999
|
+
}
|
|
4000
|
+
if (lineNum >= startLine && lineNum <= endLine) {
|
|
4001
|
+
collected.push(line);
|
|
4002
|
+
}
|
|
4003
|
+
if (lineNum >= endLine) break;
|
|
4004
|
+
}
|
|
4005
|
+
return collected;
|
|
4006
|
+
} finally {
|
|
4007
|
+
signal?.removeEventListener("abort", onAbort);
|
|
4008
|
+
rs.destroy();
|
|
4009
|
+
}
|
|
4010
|
+
}
|
|
4011
|
+
function formatLines(lines, startLine) {
|
|
4012
|
+
const endLine = startLine + lines.length - 1;
|
|
4013
|
+
const width = String(endLine).length;
|
|
4014
|
+
return lines.map((l, i) => `${String(startLine + i).padStart(width, " ")} ${l}`).join("\n");
|
|
4015
|
+
}
|
|
4016
|
+
var MAX_BYTES, MAX_STREAM_BYTES, readTool;
|
|
3946
4017
|
var init_read = __esm({
|
|
3947
4018
|
"src/tools/read.ts"() {
|
|
3948
4019
|
"use strict";
|
|
3949
4020
|
init_paths();
|
|
3950
4021
|
MAX_BYTES = 2 * 1024 * 1024;
|
|
4022
|
+
MAX_STREAM_BYTES = 50 * 1024 * 1024;
|
|
3951
4023
|
readTool = {
|
|
3952
4024
|
name: "read",
|
|
3953
|
-
description: "Read a text file from the local filesystem. Supports optional line offset/limit.
|
|
4025
|
+
description: "Read a text file from the local filesystem. Supports optional line offset/limit. Files up to 2MB are read in a single pass; larger files require an explicit offset+limit slice and are streamed line by line (cancellable mid-stream). Returns contents with 1-indexed line numbers prefixed, cat -n style. When reading a full file without offset/limit, the output is reduced to a compact outline (imports, exports, signatures, preview) by default; use expand_artifact to retrieve the full content or specify offset/limit for a targeted slice.",
|
|
3954
4026
|
parameters: {
|
|
3955
4027
|
type: "object",
|
|
3956
4028
|
properties: {
|
|
@@ -3964,13 +4036,21 @@ var init_read = __esm({
|
|
|
3964
4036
|
needsPermission: false,
|
|
3965
4037
|
render: ({ path }) => ({ title: `read ${collapsePath(path, process.cwd())}` }),
|
|
3966
4038
|
async run(args, ctx) {
|
|
3967
|
-
if (ctx.signal
|
|
4039
|
+
if (aborted(ctx.signal)) throw abortError();
|
|
3968
4040
|
const abs = resolvePath(ctx.cwd, args.path);
|
|
3969
4041
|
const st = await stat2(abs);
|
|
3970
|
-
if (
|
|
3971
|
-
if (
|
|
4042
|
+
if (aborted(ctx.signal)) throw abortError();
|
|
4043
|
+
if (st.size > MAX_BYTES) {
|
|
4044
|
+
if (args.offset === void 0 || args.limit === void 0) {
|
|
4045
|
+
throw new Error(
|
|
4046
|
+
`file too large: ${st.size} bytes (max ${MAX_BYTES} for full read; supply offset+limit to stream a slice)`
|
|
4047
|
+
);
|
|
4048
|
+
}
|
|
4049
|
+
const lines2 = await readSliceStreaming(abs, args.offset, args.limit, ctx.signal);
|
|
4050
|
+
return formatLines(lines2, args.offset);
|
|
4051
|
+
}
|
|
3972
4052
|
const text = await readFile3(abs, { encoding: "utf8", signal: ctx.signal });
|
|
3973
|
-
if (ctx.signal
|
|
4053
|
+
if (aborted(ctx.signal)) throw abortError();
|
|
3974
4054
|
const lines = text.split("\n");
|
|
3975
4055
|
const start = Math.max(0, (args.offset ?? 1) - 1);
|
|
3976
4056
|
const end = args.limit ? Math.min(lines.length, start + args.limit) : lines.length;
|
|
@@ -10164,7 +10244,7 @@ var rpc_exports = {};
|
|
|
10164
10244
|
__export(rpc_exports, {
|
|
10165
10245
|
startRpcServer: () => startRpcServer
|
|
10166
10246
|
});
|
|
10167
|
-
import { createInterface } from "readline";
|
|
10247
|
+
import { createInterface as createInterface2 } from "readline";
|
|
10168
10248
|
async function startRpcServer(input = process.stdin, output = process.stdout) {
|
|
10169
10249
|
let session = null;
|
|
10170
10250
|
let unsubscribe = null;
|
|
@@ -10174,7 +10254,7 @@ async function startRpcServer(input = process.stdin, output = process.stdout) {
|
|
|
10174
10254
|
function sendEvent(event) {
|
|
10175
10255
|
send({ ...event });
|
|
10176
10256
|
}
|
|
10177
|
-
const rl =
|
|
10257
|
+
const rl = createInterface2({
|
|
10178
10258
|
input,
|
|
10179
10259
|
crlfDelay: Infinity
|
|
10180
10260
|
});
|
|
@@ -10318,69 +10398,6 @@ var init_rpc = __esm({
|
|
|
10318
10398
|
}
|
|
10319
10399
|
});
|
|
10320
10400
|
|
|
10321
|
-
// src/agent/supervisor.ts
|
|
10322
|
-
var TurnSupervisor;
|
|
10323
|
-
var init_supervisor = __esm({
|
|
10324
|
-
"src/agent/supervisor.ts"() {
|
|
10325
|
-
"use strict";
|
|
10326
|
-
init_loop();
|
|
10327
|
-
init_logger();
|
|
10328
|
-
TurnSupervisor = class {
|
|
10329
|
-
currentTurn = null;
|
|
10330
|
-
_phase = "idle";
|
|
10331
|
-
_killRequested = false;
|
|
10332
|
-
get phase() {
|
|
10333
|
-
return this._phase;
|
|
10334
|
-
}
|
|
10335
|
-
get isRunning() {
|
|
10336
|
-
return this._phase !== "idle";
|
|
10337
|
-
}
|
|
10338
|
-
get killRequested() {
|
|
10339
|
-
return this._killRequested;
|
|
10340
|
-
}
|
|
10341
|
-
startTurn(opts2, callbacks) {
|
|
10342
|
-
if (this.isRunning) {
|
|
10343
|
-
logger.warn("supervisor:start_rejected", { reason: "turn_already_running", phase: this._phase });
|
|
10344
|
-
throw new Error("TurnSupervisor: turn already in progress");
|
|
10345
|
-
}
|
|
10346
|
-
this._phase = "preparing";
|
|
10347
|
-
this._killRequested = false;
|
|
10348
|
-
logger.debug("supervisor:turn_start", { sessionId: opts2.sessionId });
|
|
10349
|
-
this.currentTurn = runAgentTurn(opts2).then(async () => {
|
|
10350
|
-
this._phase = "idle";
|
|
10351
|
-
if (this._killRequested) {
|
|
10352
|
-
logger.debug("supervisor:turn_killed", { sessionId: opts2.sessionId });
|
|
10353
|
-
} else {
|
|
10354
|
-
logger.debug("supervisor:turn_done", { sessionId: opts2.sessionId });
|
|
10355
|
-
}
|
|
10356
|
-
await callbacks?.onDone?.();
|
|
10357
|
-
}).catch(async (error) => {
|
|
10358
|
-
this._phase = "idle";
|
|
10359
|
-
const err = error;
|
|
10360
|
-
logger.warn("supervisor:turn_error", {
|
|
10361
|
-
sessionId: opts2.sessionId,
|
|
10362
|
-
error: err.message ?? String(err),
|
|
10363
|
-
name: err.name
|
|
10364
|
-
});
|
|
10365
|
-
await callbacks?.onError?.(err);
|
|
10366
|
-
}).finally(() => {
|
|
10367
|
-
this.currentTurn = null;
|
|
10368
|
-
this._killRequested = false;
|
|
10369
|
-
});
|
|
10370
|
-
}
|
|
10371
|
-
/** Request that the current turn be killed. This does NOT directly abort
|
|
10372
|
-
* the turn — the caller must abort the AbortScope that was passed to
|
|
10373
|
-
* `startTurn`. This method only records the intent so the supervisor
|
|
10374
|
-
* knows the turn was intentionally killed rather than failing. */
|
|
10375
|
-
killTurn() {
|
|
10376
|
-
if (!this.isRunning) return;
|
|
10377
|
-
this._killRequested = true;
|
|
10378
|
-
logger.debug("supervisor:kill_requested", { phase: this._phase });
|
|
10379
|
-
}
|
|
10380
|
-
};
|
|
10381
|
-
}
|
|
10382
|
-
});
|
|
10383
|
-
|
|
10384
10401
|
// src/agent/llm-summarize.ts
|
|
10385
10402
|
function indexOfNthUserFromEnd(messages, n) {
|
|
10386
10403
|
let seen = 0;
|
|
@@ -18537,6 +18554,401 @@ var init_modal_host = __esm({
|
|
|
18537
18554
|
}
|
|
18538
18555
|
});
|
|
18539
18556
|
|
|
18557
|
+
// src/ui/use-session-manager.ts
|
|
18558
|
+
import { useCallback as useCallback6, useRef as useRef5, useState as useState16 } from "react";
|
|
18559
|
+
function extractFirstUserText(messages) {
|
|
18560
|
+
const firstUser = messages.find((m) => m.role === "user");
|
|
18561
|
+
if (!firstUser) return "session";
|
|
18562
|
+
if (typeof firstUser.content === "string") {
|
|
18563
|
+
return firstUser.content || "session";
|
|
18564
|
+
}
|
|
18565
|
+
if (Array.isArray(firstUser.content)) {
|
|
18566
|
+
const textPart = firstUser.content.find((p) => p.type === "text");
|
|
18567
|
+
if (textPart?.text) return textPart.text;
|
|
18568
|
+
}
|
|
18569
|
+
return "session";
|
|
18570
|
+
}
|
|
18571
|
+
function useSessionManager(deps) {
|
|
18572
|
+
const sessionIdRef = useRef5(null);
|
|
18573
|
+
const sessionCreatedAtRef = useRef5(null);
|
|
18574
|
+
const sessionTitleRef = useRef5(null);
|
|
18575
|
+
const [resumeSessions, setResumeSessions] = useState16(null);
|
|
18576
|
+
const [checkpointSession, setCheckpointSession] = useState16(null);
|
|
18577
|
+
const [checkpointList, setCheckpointList] = useState16([]);
|
|
18578
|
+
const depsRef = useRef5(deps);
|
|
18579
|
+
depsRef.current = deps;
|
|
18580
|
+
const ensureSessionId = useCallback6(() => {
|
|
18581
|
+
if (sessionIdRef.current) return sessionIdRef.current;
|
|
18582
|
+
const text = extractFirstUserText(depsRef.current.messagesRef.current);
|
|
18583
|
+
sessionIdRef.current = makeSessionId(text);
|
|
18584
|
+
return sessionIdRef.current;
|
|
18585
|
+
}, []);
|
|
18586
|
+
const saveSessionSafe = useCallback6(async () => {
|
|
18587
|
+
const d = depsRef.current;
|
|
18588
|
+
if (!d.cfg) return;
|
|
18589
|
+
ensureSessionId();
|
|
18590
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
18591
|
+
if (!sessionCreatedAtRef.current) {
|
|
18592
|
+
sessionCreatedAtRef.current = now2;
|
|
18593
|
+
}
|
|
18594
|
+
try {
|
|
18595
|
+
await saveSession({
|
|
18596
|
+
id: sessionIdRef.current,
|
|
18597
|
+
cwd: process.cwd(),
|
|
18598
|
+
model: d.cfg.model,
|
|
18599
|
+
createdAt: sessionCreatedAtRef.current,
|
|
18600
|
+
updatedAt: now2,
|
|
18601
|
+
title: sessionTitleRef.current ?? void 0,
|
|
18602
|
+
messages: d.messagesRef.current,
|
|
18603
|
+
sessionState: d.compiledContextRef.current ? d.sessionStateRef.current : void 0,
|
|
18604
|
+
artifactStore: serializeArtifactStore(d.artifactStoreRef.current)
|
|
18605
|
+
});
|
|
18606
|
+
} catch (e) {
|
|
18607
|
+
d.setEvents((es) => [
|
|
18608
|
+
...es,
|
|
18609
|
+
{ kind: "error", key: d.mkKey(), text: `session save failed: ${e.message}` }
|
|
18610
|
+
]);
|
|
18611
|
+
}
|
|
18612
|
+
}, [ensureSessionId]);
|
|
18613
|
+
const openResumePicker = useCallback6(async () => {
|
|
18614
|
+
const sessions = await listSessions(200, process.cwd());
|
|
18615
|
+
setResumeSessions(sessions);
|
|
18616
|
+
}, []);
|
|
18617
|
+
const doResumeSession = useCallback6(
|
|
18618
|
+
async (filePath, checkpointId) => {
|
|
18619
|
+
const d = depsRef.current;
|
|
18620
|
+
try {
|
|
18621
|
+
const file = checkpointId ? (await loadSessionFromCheckpoint(filePath, checkpointId)).file : await loadSession(filePath);
|
|
18622
|
+
d.messagesRef.current = file.messages;
|
|
18623
|
+
sessionIdRef.current = file.id;
|
|
18624
|
+
sessionCreatedAtRef.current = file.createdAt;
|
|
18625
|
+
if (file.sessionState && d.compiledContextRef.current) {
|
|
18626
|
+
d.sessionStateRef.current = file.sessionState;
|
|
18627
|
+
}
|
|
18628
|
+
if (file.artifactStore) {
|
|
18629
|
+
d.artifactStoreRef.current = deserializeArtifactStore(file.artifactStore);
|
|
18630
|
+
} else {
|
|
18631
|
+
d.artifactStoreRef.current = new ArtifactStore();
|
|
18632
|
+
}
|
|
18633
|
+
const manager = d.memoryManagerRef.current;
|
|
18634
|
+
if (manager) {
|
|
18635
|
+
try {
|
|
18636
|
+
const cwd = process.cwd();
|
|
18637
|
+
const results = await manager.recall({ text: cwd, repoPath: cwd, limit: 5 });
|
|
18638
|
+
if (results.length > 0) {
|
|
18639
|
+
const text = await manager.synthesizeRecalled(results);
|
|
18640
|
+
const lastSystemIdx = d.messagesRef.current.findLastIndex((m) => m.role === "system");
|
|
18641
|
+
const insertIdx = lastSystemIdx >= 0 ? lastSystemIdx + 1 : d.messagesRef.current.length;
|
|
18642
|
+
d.messagesRef.current.splice(insertIdx, 0, { role: "system", content: text });
|
|
18643
|
+
}
|
|
18644
|
+
} catch {
|
|
18645
|
+
}
|
|
18646
|
+
}
|
|
18647
|
+
const msg = checkpointId ? `resumed session ${file.id} from checkpoint` : `resumed session ${file.id} (${file.messages.filter((m) => m.role !== "system").length} msgs)`;
|
|
18648
|
+
d.setEvents([{ kind: "info", key: d.mkKey(), text: msg }]);
|
|
18649
|
+
const userMsgs = file.messages.filter((m) => m.role === "user" && m.content).map((m) => {
|
|
18650
|
+
if (!m.content) return "";
|
|
18651
|
+
if (typeof m.content === "string") return m.content;
|
|
18652
|
+
const textPart = m.content.find((p) => p.type === "text");
|
|
18653
|
+
return textPart?.text ?? "";
|
|
18654
|
+
}).filter((text) => text.length > 0);
|
|
18655
|
+
if (userMsgs.length > 0) d.setHistory(userMsgs);
|
|
18656
|
+
d.setUsage(null);
|
|
18657
|
+
d.setSessionUsage(null);
|
|
18658
|
+
d.gatewayMetaRef.current = null;
|
|
18659
|
+
d.setGatewayMeta(null);
|
|
18660
|
+
void getCostReport(file.id).then((report) => d.setSessionUsage(report.session));
|
|
18661
|
+
} catch (e) {
|
|
18662
|
+
d.setEvents((es) => [
|
|
18663
|
+
...es,
|
|
18664
|
+
{ kind: "error", key: d.mkKey(), text: `failed to load session: ${e.message}` }
|
|
18665
|
+
]);
|
|
18666
|
+
}
|
|
18667
|
+
},
|
|
18668
|
+
[]
|
|
18669
|
+
);
|
|
18670
|
+
const handleResumePick = useCallback6(
|
|
18671
|
+
async (picked) => {
|
|
18672
|
+
setResumeSessions(null);
|
|
18673
|
+
if (!picked) return;
|
|
18674
|
+
if (picked.checkpointCount > 0) {
|
|
18675
|
+
try {
|
|
18676
|
+
const file = await loadSession(picked.filePath);
|
|
18677
|
+
setCheckpointList(file.checkpoints ?? []);
|
|
18678
|
+
setCheckpointSession(picked);
|
|
18679
|
+
} catch (e) {
|
|
18680
|
+
depsRef.current.setEvents((es) => [
|
|
18681
|
+
...es,
|
|
18682
|
+
{ kind: "error", key: depsRef.current.mkKey(), text: `failed to load checkpoints: ${e.message}` }
|
|
18683
|
+
]);
|
|
18684
|
+
await doResumeSession(picked.filePath);
|
|
18685
|
+
}
|
|
18686
|
+
return;
|
|
18687
|
+
}
|
|
18688
|
+
await doResumeSession(picked.filePath);
|
|
18689
|
+
},
|
|
18690
|
+
[doResumeSession]
|
|
18691
|
+
);
|
|
18692
|
+
const handleCheckpointPick = useCallback6(
|
|
18693
|
+
async (checkpointId) => {
|
|
18694
|
+
const session = checkpointSession;
|
|
18695
|
+
setCheckpointSession(null);
|
|
18696
|
+
setCheckpointList([]);
|
|
18697
|
+
if (!session || !checkpointId) {
|
|
18698
|
+
if (session) {
|
|
18699
|
+
setResumeSessions(await listSessions(200, process.cwd()));
|
|
18700
|
+
}
|
|
18701
|
+
return;
|
|
18702
|
+
}
|
|
18703
|
+
if (checkpointId === "__start__") {
|
|
18704
|
+
await doResumeSession(session.filePath);
|
|
18705
|
+
return;
|
|
18706
|
+
}
|
|
18707
|
+
await doResumeSession(session.filePath, checkpointId);
|
|
18708
|
+
},
|
|
18709
|
+
[checkpointSession, doResumeSession]
|
|
18710
|
+
);
|
|
18711
|
+
const resetSession = useCallback6(() => {
|
|
18712
|
+
sessionIdRef.current = null;
|
|
18713
|
+
sessionCreatedAtRef.current = null;
|
|
18714
|
+
sessionTitleRef.current = null;
|
|
18715
|
+
const d = depsRef.current;
|
|
18716
|
+
d.sessionStateRef.current = emptySessionState();
|
|
18717
|
+
d.artifactStoreRef.current = new ArtifactStore();
|
|
18718
|
+
}, []);
|
|
18719
|
+
return {
|
|
18720
|
+
sessionIdRef,
|
|
18721
|
+
sessionCreatedAtRef,
|
|
18722
|
+
sessionTitleRef,
|
|
18723
|
+
resumeSessions,
|
|
18724
|
+
setResumeSessions,
|
|
18725
|
+
checkpointSession,
|
|
18726
|
+
setCheckpointSession,
|
|
18727
|
+
checkpointList,
|
|
18728
|
+
setCheckpointList,
|
|
18729
|
+
hasPickerOpen: resumeSessions !== null || checkpointSession !== null,
|
|
18730
|
+
ensureSessionId,
|
|
18731
|
+
saveSessionSafe,
|
|
18732
|
+
openResumePicker,
|
|
18733
|
+
doResumeSession,
|
|
18734
|
+
handleResumePick,
|
|
18735
|
+
handleCheckpointPick,
|
|
18736
|
+
resetSession
|
|
18737
|
+
};
|
|
18738
|
+
}
|
|
18739
|
+
var init_use_session_manager = __esm({
|
|
18740
|
+
"src/ui/use-session-manager.ts"() {
|
|
18741
|
+
"use strict";
|
|
18742
|
+
init_sessions();
|
|
18743
|
+
init_session_state();
|
|
18744
|
+
init_usage_tracker();
|
|
18745
|
+
}
|
|
18746
|
+
});
|
|
18747
|
+
|
|
18748
|
+
// src/agent/supervisor.ts
|
|
18749
|
+
var TurnSupervisor;
|
|
18750
|
+
var init_supervisor = __esm({
|
|
18751
|
+
"src/agent/supervisor.ts"() {
|
|
18752
|
+
"use strict";
|
|
18753
|
+
init_loop();
|
|
18754
|
+
init_logger();
|
|
18755
|
+
TurnSupervisor = class {
|
|
18756
|
+
currentTurn = null;
|
|
18757
|
+
_phase = "idle";
|
|
18758
|
+
_killRequested = false;
|
|
18759
|
+
get phase() {
|
|
18760
|
+
return this._phase;
|
|
18761
|
+
}
|
|
18762
|
+
get isRunning() {
|
|
18763
|
+
return this._phase !== "idle";
|
|
18764
|
+
}
|
|
18765
|
+
get killRequested() {
|
|
18766
|
+
return this._killRequested;
|
|
18767
|
+
}
|
|
18768
|
+
startTurn(opts2, callbacks) {
|
|
18769
|
+
if (this.isRunning) {
|
|
18770
|
+
logger.warn("supervisor:start_rejected", { reason: "turn_already_running", phase: this._phase });
|
|
18771
|
+
throw new Error("TurnSupervisor: turn already in progress");
|
|
18772
|
+
}
|
|
18773
|
+
this._phase = "preparing";
|
|
18774
|
+
this._killRequested = false;
|
|
18775
|
+
logger.debug("supervisor:turn_start", { sessionId: opts2.sessionId });
|
|
18776
|
+
this.currentTurn = runAgentTurn(opts2).then(async () => {
|
|
18777
|
+
this._phase = "idle";
|
|
18778
|
+
if (this._killRequested) {
|
|
18779
|
+
logger.debug("supervisor:turn_killed", { sessionId: opts2.sessionId });
|
|
18780
|
+
} else {
|
|
18781
|
+
logger.debug("supervisor:turn_done", { sessionId: opts2.sessionId });
|
|
18782
|
+
}
|
|
18783
|
+
await callbacks?.onDone?.();
|
|
18784
|
+
}).catch(async (error) => {
|
|
18785
|
+
this._phase = "idle";
|
|
18786
|
+
const err = error;
|
|
18787
|
+
logger.warn("supervisor:turn_error", {
|
|
18788
|
+
sessionId: opts2.sessionId,
|
|
18789
|
+
error: err.message ?? String(err),
|
|
18790
|
+
name: err.name
|
|
18791
|
+
});
|
|
18792
|
+
await callbacks?.onError?.(err);
|
|
18793
|
+
}).finally(() => {
|
|
18794
|
+
this.currentTurn = null;
|
|
18795
|
+
this._killRequested = false;
|
|
18796
|
+
});
|
|
18797
|
+
}
|
|
18798
|
+
/** Request that the current turn be killed. This does NOT directly abort
|
|
18799
|
+
* the turn — the caller must abort the AbortScope that was passed to
|
|
18800
|
+
* `startTurn`. This method only records the intent so the supervisor
|
|
18801
|
+
* knows the turn was intentionally killed rather than failing. */
|
|
18802
|
+
killTurn() {
|
|
18803
|
+
if (!this.isRunning) return;
|
|
18804
|
+
this._killRequested = true;
|
|
18805
|
+
logger.debug("supervisor:kill_requested", { phase: this._phase });
|
|
18806
|
+
}
|
|
18807
|
+
};
|
|
18808
|
+
}
|
|
18809
|
+
});
|
|
18810
|
+
|
|
18811
|
+
// src/ui/use-turn-controller.ts
|
|
18812
|
+
import { useCallback as useCallback7, useRef as useRef6, useState as useState17 } from "react";
|
|
18813
|
+
function useTurnController() {
|
|
18814
|
+
const [busy, setBusy] = useState17(false);
|
|
18815
|
+
const busyRef = useRef6(false);
|
|
18816
|
+
const isAbortingRef = useRef6(false);
|
|
18817
|
+
const lastEscapeAtRef = useRef6(0);
|
|
18818
|
+
const supervisorRef = useRef6(new TurnSupervisor());
|
|
18819
|
+
const [turnPhase, setTurnPhase] = useState17("waiting");
|
|
18820
|
+
const [turnStartedAt, setTurnStartedAt] = useState17(null);
|
|
18821
|
+
const [currentToolName, setCurrentToolName] = useState17(null);
|
|
18822
|
+
const [lastActivityAt, setLastActivityAt] = useState17(null);
|
|
18823
|
+
const turnCounterRef = useRef6(0);
|
|
18824
|
+
const [showReasoning, setShowReasoning] = useState17(false);
|
|
18825
|
+
const toggleReasoning = useCallback7(() => {
|
|
18826
|
+
setShowReasoning((s) => !s);
|
|
18827
|
+
}, []);
|
|
18828
|
+
const [tasks, setTasks] = useState17([]);
|
|
18829
|
+
const tasksRef = useRef6([]);
|
|
18830
|
+
const [tasksStartedAt, setTasksStartedAt] = useState17(null);
|
|
18831
|
+
const [tasksStartTokens, setTasksStartTokens] = useState17(0);
|
|
18832
|
+
const beginTurn = useCallback7(() => {
|
|
18833
|
+
setBusy(true);
|
|
18834
|
+
busyRef.current = true;
|
|
18835
|
+
setTurnStartedAt(Date.now());
|
|
18836
|
+
}, []);
|
|
18837
|
+
const endTurn = useCallback7(() => {
|
|
18838
|
+
setBusy(false);
|
|
18839
|
+
busyRef.current = false;
|
|
18840
|
+
setTurnStartedAt(null);
|
|
18841
|
+
setTurnPhase("waiting");
|
|
18842
|
+
setCurrentToolName(null);
|
|
18843
|
+
setLastActivityAt(null);
|
|
18844
|
+
isAbortingRef.current = false;
|
|
18845
|
+
}, []);
|
|
18846
|
+
const clearTaskTracking = useCallback7(() => {
|
|
18847
|
+
setTasks([]);
|
|
18848
|
+
setTasksStartedAt(null);
|
|
18849
|
+
setTasksStartTokens(0);
|
|
18850
|
+
tasksRef.current = [];
|
|
18851
|
+
}, []);
|
|
18852
|
+
const markAborting = useCallback7(() => {
|
|
18853
|
+
if (isAbortingRef.current) return false;
|
|
18854
|
+
isAbortingRef.current = true;
|
|
18855
|
+
supervisorRef.current.killTurn();
|
|
18856
|
+
return true;
|
|
18857
|
+
}, []);
|
|
18858
|
+
return {
|
|
18859
|
+
busy,
|
|
18860
|
+
setBusy,
|
|
18861
|
+
busyRef,
|
|
18862
|
+
isAbortingRef,
|
|
18863
|
+
lastEscapeAtRef,
|
|
18864
|
+
supervisorRef,
|
|
18865
|
+
turnPhase,
|
|
18866
|
+
setTurnPhase,
|
|
18867
|
+
turnStartedAt,
|
|
18868
|
+
setTurnStartedAt,
|
|
18869
|
+
currentToolName,
|
|
18870
|
+
setCurrentToolName,
|
|
18871
|
+
lastActivityAt,
|
|
18872
|
+
setLastActivityAt,
|
|
18873
|
+
turnCounterRef,
|
|
18874
|
+
showReasoning,
|
|
18875
|
+
setShowReasoning,
|
|
18876
|
+
toggleReasoning,
|
|
18877
|
+
tasks,
|
|
18878
|
+
setTasks,
|
|
18879
|
+
tasksRef,
|
|
18880
|
+
tasksStartedAt,
|
|
18881
|
+
setTasksStartedAt,
|
|
18882
|
+
tasksStartTokens,
|
|
18883
|
+
setTasksStartTokens,
|
|
18884
|
+
beginTurn,
|
|
18885
|
+
endTurn,
|
|
18886
|
+
clearTaskTracking,
|
|
18887
|
+
markAborting
|
|
18888
|
+
};
|
|
18889
|
+
}
|
|
18890
|
+
var init_use_turn_controller = __esm({
|
|
18891
|
+
"src/ui/use-turn-controller.ts"() {
|
|
18892
|
+
"use strict";
|
|
18893
|
+
init_supervisor();
|
|
18894
|
+
}
|
|
18895
|
+
});
|
|
18896
|
+
|
|
18897
|
+
// src/ui/input-handlers.ts
|
|
18898
|
+
function clearLimitLoopResolvers(deps) {
|
|
18899
|
+
const hadLimit = deps.limitResolveRef.current !== null;
|
|
18900
|
+
const hadLoop = deps.loopResolveRef.current !== null;
|
|
18901
|
+
if (hadLimit) {
|
|
18902
|
+
deps.limitResolveRef.current("stop");
|
|
18903
|
+
deps.limitResolveRef.current = null;
|
|
18904
|
+
deps.setLimitModal(null);
|
|
18905
|
+
}
|
|
18906
|
+
if (hadLoop) {
|
|
18907
|
+
deps.loopResolveRef.current("stop");
|
|
18908
|
+
deps.loopResolveRef.current = null;
|
|
18909
|
+
deps.setLoopModal(null);
|
|
18910
|
+
}
|
|
18911
|
+
return { hadLimit, hadLoop };
|
|
18912
|
+
}
|
|
18913
|
+
function interruptTurn(deps) {
|
|
18914
|
+
const hadPermission = deps.denyPendingPermission();
|
|
18915
|
+
const { hadLimit, hadLoop } = clearLimitLoopResolvers(deps);
|
|
18916
|
+
if (deps.busyRef.current && deps.activeScopeRef.current && !deps.isAbortingRef.current) {
|
|
18917
|
+
deps.isAbortingRef.current = true;
|
|
18918
|
+
deps.supervisorRef.current.killTurn();
|
|
18919
|
+
deps.activeScopeRef.current.abort("user_stopped");
|
|
18920
|
+
deps.setEvents((e) => [
|
|
18921
|
+
...e,
|
|
18922
|
+
{ kind: "info", key: deps.mkKey(), text: "(interrupted)" }
|
|
18923
|
+
]);
|
|
18924
|
+
if (!deps.skipPendingToolCleanup) {
|
|
18925
|
+
for (const [toolId] of deps.pendingToolCallsRef.current) {
|
|
18926
|
+
deps.updateTool(toolId, { status: "cancelled" });
|
|
18927
|
+
}
|
|
18928
|
+
deps.pendingToolCallsRef.current.clear();
|
|
18929
|
+
}
|
|
18930
|
+
void deps.saveSessionSafe();
|
|
18931
|
+
deps.clearTaskTracking();
|
|
18932
|
+
return { hadPermission, hadLimit, hadLoop, didInterruptTurn: true };
|
|
18933
|
+
}
|
|
18934
|
+
return { hadPermission, hadLimit, hadLoop, didInterruptTurn: false };
|
|
18935
|
+
}
|
|
18936
|
+
function exitApp(deps) {
|
|
18937
|
+
void deps.lspManagerRef.current.stopAll().finally(() => deps.exit());
|
|
18938
|
+
}
|
|
18939
|
+
function interruptOrExit(deps) {
|
|
18940
|
+
const outcome = interruptTurn(deps);
|
|
18941
|
+
if (!outcome.didInterruptTurn && !outcome.hadPermission && !outcome.hadLimit && !outcome.hadLoop) {
|
|
18942
|
+
exitApp(deps);
|
|
18943
|
+
}
|
|
18944
|
+
return outcome;
|
|
18945
|
+
}
|
|
18946
|
+
var init_input_handlers = __esm({
|
|
18947
|
+
"src/ui/input-handlers.ts"() {
|
|
18948
|
+
"use strict";
|
|
18949
|
+
}
|
|
18950
|
+
});
|
|
18951
|
+
|
|
18540
18952
|
// src/cost-attribution/tui-report.ts
|
|
18541
18953
|
var tui_report_exports = {};
|
|
18542
18954
|
__export(tui_report_exports, {
|
|
@@ -18624,7 +19036,7 @@ __export(app_exports, {
|
|
|
18624
19036
|
buildFilePickerIgnoreList: () => buildFilePickerIgnoreList,
|
|
18625
19037
|
renderApp: () => renderApp
|
|
18626
19038
|
});
|
|
18627
|
-
import
|
|
19039
|
+
import React17, { useState as useState18, useRef as useRef7, useEffect as useEffect8, useCallback as useCallback8 } from "react";
|
|
18628
19040
|
import { Box as Box26, Text as Text27, useApp, useInput as useInput10, render } from "ink";
|
|
18629
19041
|
import { existsSync as existsSync4, statSync as statSync4 } from "fs";
|
|
18630
19042
|
import { join as join28 } from "path";
|
|
@@ -18863,13 +19275,13 @@ function App({
|
|
|
18863
19275
|
initialCloudDeviceId
|
|
18864
19276
|
}) {
|
|
18865
19277
|
const { exit } = useApp();
|
|
18866
|
-
const [cfg, setCfg] =
|
|
18867
|
-
const [lspScope, setLspScope] =
|
|
18868
|
-
const [lspProjectPath, setLspProjectPath] =
|
|
18869
|
-
const [cloudToken, setCloudToken] =
|
|
18870
|
-
const [cloudDeviceId, setCloudDeviceId] =
|
|
18871
|
-
const [events, setRawEvents] =
|
|
18872
|
-
const setEvents =
|
|
19278
|
+
const [cfg, setCfg] = useState18(initialCfg);
|
|
19279
|
+
const [lspScope, setLspScope] = useState18(initialLspScope);
|
|
19280
|
+
const [lspProjectPath, setLspProjectPath] = useState18(initialLspProjectPath);
|
|
19281
|
+
const [cloudToken, setCloudToken] = useState18(initialCloudToken);
|
|
19282
|
+
const [cloudDeviceId, setCloudDeviceId] = useState18(initialCloudDeviceId);
|
|
19283
|
+
const [events, setRawEvents] = useState18([]);
|
|
19284
|
+
const setEvents = useCallback8(
|
|
18873
19285
|
(updater) => {
|
|
18874
19286
|
setRawEvents((prev) => {
|
|
18875
19287
|
const next = typeof updater === "function" ? updater(prev) : updater;
|
|
@@ -18878,10 +19290,9 @@ function App({
|
|
|
18878
19290
|
},
|
|
18879
19291
|
[]
|
|
18880
19292
|
);
|
|
18881
|
-
const [input, setInput] =
|
|
18882
|
-
const [
|
|
18883
|
-
const [
|
|
18884
|
-
const [sessionUsage, setSessionUsage] = useState16(null);
|
|
19293
|
+
const [input, setInput] = useState18("");
|
|
19294
|
+
const [usage, setUsage] = useState18(null);
|
|
19295
|
+
const [sessionUsage, setSessionUsage] = useState18(null);
|
|
18885
19296
|
useEffect8(() => {
|
|
18886
19297
|
const handler = (sid) => {
|
|
18887
19298
|
if (sessionIdRef.current && sid === sessionIdRef.current) {
|
|
@@ -18893,9 +19304,35 @@ function App({
|
|
|
18893
19304
|
usageEvents.off("update", handler);
|
|
18894
19305
|
};
|
|
18895
19306
|
}, []);
|
|
18896
|
-
const [gatewayMeta, setGatewayMeta] =
|
|
18897
|
-
const [cloudBudget, setCloudBudget] =
|
|
18898
|
-
const
|
|
19307
|
+
const [gatewayMeta, setGatewayMeta] = useState18(null);
|
|
19308
|
+
const [cloudBudget, setCloudBudget] = useState18(null);
|
|
19309
|
+
const turn = useTurnController();
|
|
19310
|
+
const {
|
|
19311
|
+
busy,
|
|
19312
|
+
busyRef,
|
|
19313
|
+
isAbortingRef,
|
|
19314
|
+
lastEscapeAtRef,
|
|
19315
|
+
supervisorRef,
|
|
19316
|
+
turnPhase,
|
|
19317
|
+
setTurnPhase,
|
|
19318
|
+
turnStartedAt,
|
|
19319
|
+
currentToolName,
|
|
19320
|
+
setCurrentToolName,
|
|
19321
|
+
lastActivityAt,
|
|
19322
|
+
setLastActivityAt,
|
|
19323
|
+
turnCounterRef,
|
|
19324
|
+
showReasoning,
|
|
19325
|
+
tasks,
|
|
19326
|
+
setTasks,
|
|
19327
|
+
tasksRef,
|
|
19328
|
+
tasksStartedAt,
|
|
19329
|
+
setTasksStartedAt,
|
|
19330
|
+
tasksStartTokens,
|
|
19331
|
+
setTasksStartTokens,
|
|
19332
|
+
beginTurn,
|
|
19333
|
+
endTurn,
|
|
19334
|
+
clearTaskTracking
|
|
19335
|
+
} = turn;
|
|
18899
19336
|
const {
|
|
18900
19337
|
pending: perm,
|
|
18901
19338
|
askPermission: askForPermission,
|
|
@@ -18941,38 +19378,28 @@ function App({
|
|
|
18941
19378
|
hasFullscreenModal,
|
|
18942
19379
|
hasAnyModal
|
|
18943
19380
|
} = modals;
|
|
18944
|
-
const [queue, setQueue] =
|
|
18945
|
-
const [history, setHistory] =
|
|
18946
|
-
const [historyIndex, setHistoryIndex] =
|
|
18947
|
-
const [draftInput, setDraftInput] =
|
|
18948
|
-
const [mode, setMode] =
|
|
18949
|
-
const [codeMode, setCodeMode] =
|
|
19381
|
+
const [queue, setQueue] = useState18([]);
|
|
19382
|
+
const [history, setHistory] = useState18([]);
|
|
19383
|
+
const [historyIndex, setHistoryIndex] = useState18(-1);
|
|
19384
|
+
const [draftInput, setDraftInput] = useState18("");
|
|
19385
|
+
const [mode, setMode] = useState18("edit");
|
|
19386
|
+
const [codeMode, setCodeMode] = useState18(false);
|
|
18950
19387
|
const filePickerEnabled = initialCfg?.filePicker ?? true;
|
|
18951
|
-
const [effort, setEffort] =
|
|
19388
|
+
const [effort, setEffort] = useState18(
|
|
18952
19389
|
initialCfg?.reasoningEffort ?? DEFAULT_REASONING_EFFORT
|
|
18953
19390
|
);
|
|
18954
|
-
const [
|
|
18955
|
-
const [
|
|
18956
|
-
const [
|
|
18957
|
-
const [
|
|
18958
|
-
const [
|
|
18959
|
-
const [
|
|
18960
|
-
const [
|
|
18961
|
-
const [
|
|
18962
|
-
const [
|
|
18963
|
-
const [
|
|
18964
|
-
const [
|
|
18965
|
-
const [
|
|
18966
|
-
const [hasUpdate, setHasUpdate] = useState16(initialUpdateResult?.hasUpdate ?? false);
|
|
18967
|
-
const [latestVersion, setLatestVersion] = useState16(initialUpdateResult?.latestVersion ?? null);
|
|
18968
|
-
const [theme, setTheme] = useState16(resolveTheme(initialCfg?.theme));
|
|
18969
|
-
const [originalTheme, setOriginalTheme] = useState16(null);
|
|
18970
|
-
const [skillsActive, setSkillsActive] = useState16(0);
|
|
18971
|
-
const [memoryRecalled, setMemoryRecalled] = useState16(false);
|
|
18972
|
-
const [intentTier, setIntentTier] = useState16(null);
|
|
18973
|
-
const [kimiMdStale, setKimiMdStale] = useState16(false);
|
|
18974
|
-
const [gitBranch, setGitBranch] = useState16(null);
|
|
18975
|
-
const [lastSessionTopic, setLastSessionTopic] = useState16(null);
|
|
19391
|
+
const [selectedRemoteSession, setSelectedRemoteSession] = useState18(null);
|
|
19392
|
+
const [verbose, setVerbose] = useState18(false);
|
|
19393
|
+
const [hasUpdate, setHasUpdate] = useState18(initialUpdateResult?.hasUpdate ?? false);
|
|
19394
|
+
const [latestVersion, setLatestVersion] = useState18(initialUpdateResult?.latestVersion ?? null);
|
|
19395
|
+
const [theme, setTheme] = useState18(resolveTheme(initialCfg?.theme));
|
|
19396
|
+
const [originalTheme, setOriginalTheme] = useState18(null);
|
|
19397
|
+
const [skillsActive, setSkillsActive] = useState18(0);
|
|
19398
|
+
const [memoryRecalled, setMemoryRecalled] = useState18(false);
|
|
19399
|
+
const [intentTier, setIntentTier] = useState18(null);
|
|
19400
|
+
const [kimiMdStale, setKimiMdStale] = useState18(false);
|
|
19401
|
+
const [gitBranch, setGitBranch] = useState18(null);
|
|
19402
|
+
const [lastSessionTopic, setLastSessionTopic] = useState18(null);
|
|
18976
19403
|
useEffect8(() => {
|
|
18977
19404
|
setGitBranch(detectGitBranch());
|
|
18978
19405
|
}, []);
|
|
@@ -19048,57 +19475,80 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19048
19475
|
cancelled = true;
|
|
19049
19476
|
};
|
|
19050
19477
|
}, [cfg?.cloudMode, initialCloudToken]);
|
|
19051
|
-
const [cursorOffset, setCursorOffset] =
|
|
19052
|
-
const [customCommandsVersion, setCustomCommandsVersion] =
|
|
19053
|
-
const cacheStableRef =
|
|
19054
|
-
const messagesRef =
|
|
19478
|
+
const [cursorOffset, setCursorOffset] = useState18(0);
|
|
19479
|
+
const [customCommandsVersion, setCustomCommandsVersion] = useState18(0);
|
|
19480
|
+
const cacheStableRef = useRef7(initialCfg?.cacheStablePrompts !== false);
|
|
19481
|
+
const messagesRef = useRef7(
|
|
19055
19482
|
makePrefixMessages(cacheStableRef.current, cfg?.model ?? DEFAULT_MODEL, "edit", ALL_TOOLS)
|
|
19056
19483
|
);
|
|
19057
|
-
const executorRef =
|
|
19058
|
-
const activeAsstIdRef =
|
|
19059
|
-
const sessionScopeRef =
|
|
19060
|
-
const activeScopeRef =
|
|
19061
|
-
const
|
|
19062
|
-
const
|
|
19063
|
-
const
|
|
19064
|
-
const
|
|
19065
|
-
const
|
|
19066
|
-
const
|
|
19067
|
-
const
|
|
19068
|
-
const
|
|
19069
|
-
const
|
|
19070
|
-
const
|
|
19071
|
-
const
|
|
19072
|
-
const
|
|
19073
|
-
const
|
|
19074
|
-
const
|
|
19075
|
-
const
|
|
19076
|
-
const
|
|
19077
|
-
const
|
|
19078
|
-
const
|
|
19079
|
-
const
|
|
19080
|
-
const compiledContextRef = useRef5(initialCfg?.compiledContext === true);
|
|
19081
|
-
const updateNudgedRef = useRef5(false);
|
|
19082
|
-
const compactSuggestedRef = useRef5(false);
|
|
19083
|
-
const mcpManagerRef = useRef5(new McpManager());
|
|
19084
|
-
const mcpToolsRef = useRef5([]);
|
|
19085
|
-
const mcpInitRef = useRef5(false);
|
|
19086
|
-
const submitRef = useRef5(() => {
|
|
19484
|
+
const executorRef = useRef7(new ToolExecutor(ALL_TOOLS));
|
|
19485
|
+
const activeAsstIdRef = useRef7(null);
|
|
19486
|
+
const sessionScopeRef = useRef7(new AbortScope());
|
|
19487
|
+
const activeScopeRef = useRef7(null);
|
|
19488
|
+
const sigintHandlerRef = useRef7(null);
|
|
19489
|
+
const limitResolveRef = useRef7(null);
|
|
19490
|
+
const loopResolveRef = useRef7(null);
|
|
19491
|
+
const pendingToolCallsRef = useRef7(/* @__PURE__ */ new Map());
|
|
19492
|
+
const modeRef = useRef7(mode);
|
|
19493
|
+
const effortRef = useRef7(effort);
|
|
19494
|
+
const usageRef = useRef7(null);
|
|
19495
|
+
const gatewayMetaRef = useRef7(null);
|
|
19496
|
+
const lastApiErrorRef = useRef7(null);
|
|
19497
|
+
const updateCheckedRef = useRef7(false);
|
|
19498
|
+
const sessionStateRef = useRef7(emptySessionState());
|
|
19499
|
+
const artifactStoreRef = useRef7(new ArtifactStore());
|
|
19500
|
+
const compiledContextRef = useRef7(initialCfg?.compiledContext === true);
|
|
19501
|
+
const updateNudgedRef = useRef7(false);
|
|
19502
|
+
const compactSuggestedRef = useRef7(false);
|
|
19503
|
+
const mcpManagerRef = useRef7(new McpManager());
|
|
19504
|
+
const mcpToolsRef = useRef7([]);
|
|
19505
|
+
const mcpInitRef = useRef7(false);
|
|
19506
|
+
const submitRef = useRef7(() => {
|
|
19087
19507
|
});
|
|
19088
|
-
const lspManagerRef =
|
|
19089
|
-
const lspToolsRef =
|
|
19090
|
-
const lspInitRef =
|
|
19091
|
-
const
|
|
19092
|
-
const
|
|
19093
|
-
const
|
|
19094
|
-
const
|
|
19095
|
-
|
|
19096
|
-
|
|
19097
|
-
|
|
19098
|
-
|
|
19099
|
-
|
|
19508
|
+
const lspManagerRef = useRef7(new LspManager());
|
|
19509
|
+
const lspToolsRef = useRef7([]);
|
|
19510
|
+
const lspInitRef = useRef7(false);
|
|
19511
|
+
const memoryManagerRef = useRef7(null);
|
|
19512
|
+
const sessionStartRecallRef = useRef7(null);
|
|
19513
|
+
const kimiMdStaleNudgedRef = useRef7(false);
|
|
19514
|
+
const sessionMgr = useSessionManager({
|
|
19515
|
+
cfg,
|
|
19516
|
+
messagesRef,
|
|
19517
|
+
sessionStateRef,
|
|
19518
|
+
artifactStoreRef,
|
|
19519
|
+
compiledContextRef,
|
|
19520
|
+
gatewayMetaRef,
|
|
19521
|
+
memoryManagerRef,
|
|
19522
|
+
setEvents,
|
|
19523
|
+
setHistory,
|
|
19524
|
+
setUsage,
|
|
19525
|
+
setSessionUsage,
|
|
19526
|
+
setGatewayMeta,
|
|
19527
|
+
mkKey
|
|
19528
|
+
});
|
|
19529
|
+
const {
|
|
19530
|
+
sessionIdRef,
|
|
19531
|
+
sessionCreatedAtRef,
|
|
19532
|
+
sessionTitleRef,
|
|
19533
|
+
resumeSessions,
|
|
19534
|
+
setResumeSessions,
|
|
19535
|
+
checkpointSession,
|
|
19536
|
+
setCheckpointSession,
|
|
19537
|
+
checkpointList,
|
|
19538
|
+
ensureSessionId,
|
|
19539
|
+
saveSessionSafe,
|
|
19540
|
+
openResumePicker,
|
|
19541
|
+
doResumeSession,
|
|
19542
|
+
handleResumePick,
|
|
19543
|
+
handleCheckpointPick,
|
|
19544
|
+
resetSession
|
|
19545
|
+
} = sessionMgr;
|
|
19546
|
+
const pendingTextRef = useRef7(/* @__PURE__ */ new Map());
|
|
19547
|
+
const flushTimeoutRef = useRef7(null);
|
|
19548
|
+
const customCommandsRef = useRef7([]);
|
|
19549
|
+
const recentFilesRef = useRef7(/* @__PURE__ */ new Map());
|
|
19100
19550
|
const MAX_RECENT_FILES = 10;
|
|
19101
|
-
const allSlashCommands =
|
|
19551
|
+
const allSlashCommands = React17.useMemo(() => {
|
|
19102
19552
|
const customs = customCommandsRef.current.filter((c) => !BUILTIN_COMMAND_NAMES.has(c.name.toLowerCase())).map((c) => ({
|
|
19103
19553
|
name: c.name,
|
|
19104
19554
|
description: c.description ?? "",
|
|
@@ -19107,7 +19557,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19107
19557
|
return [...BUILTIN_COMMANDS, ...customs];
|
|
19108
19558
|
}, [customCommandsVersion]);
|
|
19109
19559
|
const modalActive = commandWizard !== null || commandPicker !== null || commandToDelete !== null || showCommandList || showLspWizard || resumeSessions !== null || checkpointSession !== null || perm !== null || limitModal !== null || loopModal !== null || showInboxModal;
|
|
19110
|
-
const loadFilePickerItems =
|
|
19560
|
+
const loadFilePickerItems = useCallback8(async () => {
|
|
19111
19561
|
const cwd = process.cwd();
|
|
19112
19562
|
const entries = await fg4("**/*", {
|
|
19113
19563
|
cwd,
|
|
@@ -19264,7 +19714,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19264
19714
|
}, 3e5);
|
|
19265
19715
|
return () => clearInterval(id);
|
|
19266
19716
|
}, []);
|
|
19267
|
-
const reloadCustomCommands =
|
|
19717
|
+
const reloadCustomCommands = useCallback8(async () => {
|
|
19268
19718
|
const { commands, warnings } = await loadCustomCommands(process.cwd());
|
|
19269
19719
|
customCommandsRef.current = commands;
|
|
19270
19720
|
setCustomCommandsVersion((v) => v + 1);
|
|
@@ -19391,7 +19841,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19391
19841
|
}, 30 * 60 * 1e3);
|
|
19392
19842
|
return () => clearInterval(id);
|
|
19393
19843
|
}, [cfg]);
|
|
19394
|
-
const initMcp =
|
|
19844
|
+
const initMcp = useCallback8(async () => {
|
|
19395
19845
|
if (!cfg?.mcpServers || mcpInitRef.current) return;
|
|
19396
19846
|
mcpInitRef.current = true;
|
|
19397
19847
|
const manager = mcpManagerRef.current;
|
|
@@ -19456,7 +19906,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19456
19906
|
]);
|
|
19457
19907
|
}
|
|
19458
19908
|
}, [cfg]);
|
|
19459
|
-
const initLsp =
|
|
19909
|
+
const initLsp = useCallback8(async () => {
|
|
19460
19910
|
if (!cfg?.lspEnabled || !cfg?.lspServers || lspInitRef.current) {
|
|
19461
19911
|
if (lspInitRef.current) return;
|
|
19462
19912
|
if (!cfg?.lspEnabled) {
|
|
@@ -19527,46 +19977,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19527
19977
|
void initLsp();
|
|
19528
19978
|
}
|
|
19529
19979
|
}, [cfg, initMcp, initLsp]);
|
|
19530
|
-
const
|
|
19531
|
-
if (sessionIdRef.current) return sessionIdRef.current;
|
|
19532
|
-
const firstUser = messagesRef.current.find((m) => m.role === "user");
|
|
19533
|
-
let firstText = "session";
|
|
19534
|
-
if (typeof firstUser?.content === "string") {
|
|
19535
|
-
firstText = firstUser.content;
|
|
19536
|
-
} else if (Array.isArray(firstUser?.content)) {
|
|
19537
|
-
const textPart = firstUser.content.find((p) => p.type === "text");
|
|
19538
|
-
if (textPart?.text) firstText = textPart.text;
|
|
19539
|
-
}
|
|
19540
|
-
sessionIdRef.current = makeSessionId(firstText);
|
|
19541
|
-
return sessionIdRef.current;
|
|
19542
|
-
}, []);
|
|
19543
|
-
const saveSessionSafe = useCallback6(async () => {
|
|
19544
|
-
if (!cfg) return;
|
|
19545
|
-
ensureSessionId();
|
|
19546
|
-
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
19547
|
-
if (!sessionCreatedAtRef.current) {
|
|
19548
|
-
sessionCreatedAtRef.current = now2;
|
|
19549
|
-
}
|
|
19550
|
-
try {
|
|
19551
|
-
await saveSession({
|
|
19552
|
-
id: sessionIdRef.current,
|
|
19553
|
-
cwd: process.cwd(),
|
|
19554
|
-
model: cfg.model,
|
|
19555
|
-
createdAt: sessionCreatedAtRef.current,
|
|
19556
|
-
updatedAt: now2,
|
|
19557
|
-
title: sessionTitleRef.current ?? void 0,
|
|
19558
|
-
messages: messagesRef.current,
|
|
19559
|
-
sessionState: compiledContextRef.current ? sessionStateRef.current : void 0,
|
|
19560
|
-
artifactStore: serializeArtifactStore(artifactStoreRef.current)
|
|
19561
|
-
});
|
|
19562
|
-
} catch (e) {
|
|
19563
|
-
setEvents((es) => [
|
|
19564
|
-
...es,
|
|
19565
|
-
{ kind: "error", key: mkKey(), text: `session save failed: ${e.message}` }
|
|
19566
|
-
]);
|
|
19567
|
-
}
|
|
19568
|
-
}, [cfg, ensureSessionId]);
|
|
19569
|
-
const onIterationEnd = useCallback6(
|
|
19980
|
+
const onIterationEnd = useCallback8(
|
|
19570
19981
|
async (messages, signal) => {
|
|
19571
19982
|
if (signal.aborted) return messages;
|
|
19572
19983
|
if (!shouldCompact({ messages })) return messages;
|
|
@@ -19644,6 +20055,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19644
20055
|
},
|
|
19645
20056
|
[cfg]
|
|
19646
20057
|
);
|
|
20058
|
+
const interruptDepsRef = useRef7(null);
|
|
19647
20059
|
useInput10((inputChar, key) => {
|
|
19648
20060
|
if (key.ctrl && inputChar === "c") {
|
|
19649
20061
|
logger.info("input:ctrl+c", {
|
|
@@ -19653,36 +20065,9 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19653
20065
|
hasPerm: hasPendingPermission(),
|
|
19654
20066
|
hasLimit: limitResolveRef.current !== null
|
|
19655
20067
|
});
|
|
19656
|
-
const
|
|
19657
|
-
|
|
19658
|
-
const hadLoop = loopResolveRef.current !== null;
|
|
19659
|
-
if (hadLimit) {
|
|
19660
|
-
limitResolveRef.current("stop");
|
|
19661
|
-
limitResolveRef.current = null;
|
|
19662
|
-
setLimitModal(null);
|
|
19663
|
-
}
|
|
19664
|
-
if (hadLoop) {
|
|
19665
|
-
loopResolveRef.current("stop");
|
|
19666
|
-
loopResolveRef.current = null;
|
|
19667
|
-
setLoopModal(null);
|
|
19668
|
-
}
|
|
19669
|
-
if (busyRef.current && activeScopeRef.current && !isAbortingRef.current) {
|
|
19670
|
-
isAbortingRef.current = true;
|
|
19671
|
-
supervisorRef.current.killTurn();
|
|
19672
|
-
activeScopeRef.current.abort("user_stopped");
|
|
19673
|
-
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "(interrupted)" }]);
|
|
19674
|
-
for (const [toolId] of pendingToolCallsRef.current) {
|
|
19675
|
-
updateTool(toolId, { status: "cancelled" });
|
|
19676
|
-
}
|
|
19677
|
-
pendingToolCallsRef.current.clear();
|
|
19678
|
-
void saveSessionSafe();
|
|
19679
|
-
setTasks([]);
|
|
19680
|
-
setTasksStartedAt(null);
|
|
19681
|
-
setTasksStartTokens(0);
|
|
19682
|
-
tasksRef.current = [];
|
|
19683
|
-
} else if (!hadPerm && !hadLimit && !hadLoop) {
|
|
20068
|
+
const outcome = interruptOrExit(interruptDepsRef.current);
|
|
20069
|
+
if (!outcome.didInterruptTurn && !outcome.hadPermission && !outcome.hadLimit && !outcome.hadLoop) {
|
|
19684
20070
|
logger.info("input:ctrl+c:exiting");
|
|
19685
|
-
void lspManagerRef.current.stopAll().finally(() => exit());
|
|
19686
20071
|
}
|
|
19687
20072
|
return;
|
|
19688
20073
|
}
|
|
@@ -19691,34 +20076,12 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19691
20076
|
const modalOpen = perm !== null || limitModal !== null || loopModal !== null || showLspWizard || showCommandList || commandWizard !== null || commandToDelete !== null || resumeSessions !== null || checkpointSession !== null || showThemePicker;
|
|
19692
20077
|
if (!modalOpen && busyRef.current && activeScopeRef.current && !isAbortingRef.current && now2 - lastEscapeAtRef.current > 500) {
|
|
19693
20078
|
lastEscapeAtRef.current = now2;
|
|
19694
|
-
|
|
19695
|
-
supervisorRef.current.killTurn();
|
|
19696
|
-
denyPendingPermission();
|
|
19697
|
-
if (limitResolveRef.current) {
|
|
19698
|
-
limitResolveRef.current("stop");
|
|
19699
|
-
limitResolveRef.current = null;
|
|
19700
|
-
setLimitModal(null);
|
|
19701
|
-
}
|
|
19702
|
-
if (loopResolveRef.current) {
|
|
19703
|
-
loopResolveRef.current("stop");
|
|
19704
|
-
loopResolveRef.current = null;
|
|
19705
|
-
setLoopModal(null);
|
|
19706
|
-
}
|
|
19707
|
-
activeScopeRef.current.abort("user_stopped");
|
|
19708
|
-
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "(interrupted)" }]);
|
|
19709
|
-
for (const [toolId] of pendingToolCallsRef.current) {
|
|
19710
|
-
updateTool(toolId, { status: "cancelled" });
|
|
19711
|
-
}
|
|
19712
|
-
pendingToolCallsRef.current.clear();
|
|
19713
|
-
setTasks([]);
|
|
19714
|
-
setTasksStartedAt(null);
|
|
19715
|
-
setTasksStartTokens(0);
|
|
19716
|
-
tasksRef.current = [];
|
|
20079
|
+
interruptTurn(interruptDepsRef.current);
|
|
19717
20080
|
return;
|
|
19718
20081
|
}
|
|
19719
20082
|
}
|
|
19720
20083
|
if (key.ctrl && inputChar === "r") {
|
|
19721
|
-
|
|
20084
|
+
turn.toggleReasoning();
|
|
19722
20085
|
return;
|
|
19723
20086
|
}
|
|
19724
20087
|
if (key.shift && key.tab) {
|
|
@@ -19739,35 +20102,15 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19739
20102
|
hasLimit: limitResolveRef.current !== null,
|
|
19740
20103
|
hasLoop: loopResolveRef.current !== null
|
|
19741
20104
|
});
|
|
19742
|
-
const
|
|
19743
|
-
|
|
19744
|
-
|
|
19745
|
-
|
|
19746
|
-
|
|
19747
|
-
limitResolveRef.current = null;
|
|
19748
|
-
setLimitModal(null);
|
|
19749
|
-
}
|
|
19750
|
-
if (hadLoop) {
|
|
19751
|
-
loopResolveRef.current("stop");
|
|
19752
|
-
loopResolveRef.current = null;
|
|
19753
|
-
setLoopModal(null);
|
|
19754
|
-
}
|
|
19755
|
-
if (busyRef.current && activeScopeRef.current && !isAbortingRef.current) {
|
|
19756
|
-
isAbortingRef.current = true;
|
|
19757
|
-
supervisorRef.current.killTurn();
|
|
19758
|
-
activeScopeRef.current.abort("user_stopped");
|
|
19759
|
-
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "(interrupted)" }]);
|
|
19760
|
-
void saveSessionSafe();
|
|
19761
|
-
setTasks([]);
|
|
19762
|
-
setTasksStartedAt(null);
|
|
19763
|
-
setTasksStartTokens(0);
|
|
19764
|
-
tasksRef.current = [];
|
|
19765
|
-
} else if (!hadPerm && !hadLimit) {
|
|
20105
|
+
const outcome = interruptOrExit({
|
|
20106
|
+
...interruptDepsRef.current,
|
|
20107
|
+
skipPendingToolCleanup: true
|
|
20108
|
+
});
|
|
20109
|
+
if (!outcome.didInterruptTurn && !outcome.hadPermission && !outcome.hadLimit && !outcome.hadLoop) {
|
|
19766
20110
|
logger.info("sigint:handler:exiting");
|
|
19767
|
-
void lspManagerRef.current.stopAll().finally(() => exit());
|
|
19768
20111
|
}
|
|
19769
20112
|
};
|
|
19770
|
-
const flushAssistantUpdates =
|
|
20113
|
+
const flushAssistantUpdates = useCallback8(() => {
|
|
19771
20114
|
flushTimeoutRef.current = null;
|
|
19772
20115
|
const pending = pendingTextRef.current;
|
|
19773
20116
|
if (pending.size === 0) return;
|
|
@@ -19785,7 +20128,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19785
20128
|
})
|
|
19786
20129
|
);
|
|
19787
20130
|
}, []);
|
|
19788
|
-
const updateAssistant =
|
|
20131
|
+
const updateAssistant = useCallback8(
|
|
19789
20132
|
(id, patch) => {
|
|
19790
20133
|
const result = patch({ text: "", reasoning: "" });
|
|
19791
20134
|
const assistantResult = result;
|
|
@@ -19814,7 +20157,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19814
20157
|
},
|
|
19815
20158
|
[flushAssistantUpdates]
|
|
19816
20159
|
);
|
|
19817
|
-
const updateTool =
|
|
20160
|
+
const updateTool = useCallback8(
|
|
19818
20161
|
(id, patch) => {
|
|
19819
20162
|
setEvents(
|
|
19820
20163
|
(evts) => evts.map(
|
|
@@ -19824,19 +20167,37 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19824
20167
|
},
|
|
19825
20168
|
[]
|
|
19826
20169
|
);
|
|
19827
|
-
const updateGatewayMeta =
|
|
20170
|
+
const updateGatewayMeta = useCallback8((meta) => {
|
|
19828
20171
|
gatewayMetaRef.current = meta;
|
|
19829
20172
|
setGatewayMeta(meta);
|
|
19830
20173
|
}, []);
|
|
19831
|
-
|
|
20174
|
+
interruptDepsRef.current = {
|
|
20175
|
+
busyRef,
|
|
20176
|
+
activeScopeRef,
|
|
20177
|
+
isAbortingRef,
|
|
20178
|
+
supervisorRef,
|
|
20179
|
+
limitResolveRef,
|
|
20180
|
+
loopResolveRef,
|
|
20181
|
+
setLimitModal,
|
|
20182
|
+
setLoopModal,
|
|
20183
|
+
hasPendingPermission,
|
|
20184
|
+
denyPendingPermission,
|
|
20185
|
+
pendingToolCallsRef,
|
|
20186
|
+
updateTool,
|
|
20187
|
+
setEvents,
|
|
20188
|
+
mkKey,
|
|
20189
|
+
saveSessionSafe,
|
|
20190
|
+
clearTaskTracking,
|
|
20191
|
+
lspManagerRef,
|
|
20192
|
+
exit
|
|
20193
|
+
};
|
|
20194
|
+
const runCompact = useCallback8(async () => {
|
|
19832
20195
|
if (!cfg) return;
|
|
19833
20196
|
if (busy) {
|
|
19834
20197
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "can't compact while model is running" }]);
|
|
19835
20198
|
return;
|
|
19836
20199
|
}
|
|
19837
|
-
|
|
19838
|
-
busyRef.current = true;
|
|
19839
|
-
setTurnStartedAt(Date.now());
|
|
20200
|
+
beginTurn();
|
|
19840
20201
|
const turnScope = sessionScopeRef.current.createChild();
|
|
19841
20202
|
activeScopeRef.current = turnScope;
|
|
19842
20203
|
try {
|
|
@@ -19911,24 +20272,14 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19911
20272
|
}
|
|
19912
20273
|
} finally {
|
|
19913
20274
|
logger.info("runCompact:finally");
|
|
19914
|
-
|
|
19915
|
-
busyRef.current = false;
|
|
19916
|
-
setTurnStartedAt(null);
|
|
19917
|
-
setTurnPhase("waiting");
|
|
19918
|
-
setCurrentToolName(null);
|
|
19919
|
-
setLastActivityAt(null);
|
|
20275
|
+
endTurn();
|
|
19920
20276
|
activeScopeRef.current = null;
|
|
19921
|
-
isAbortingRef.current = false;
|
|
19922
20277
|
clearPermissionResolveRef();
|
|
19923
20278
|
limitResolveRef.current = null;
|
|
19924
20279
|
pendingToolCallsRef.current.clear();
|
|
19925
20280
|
}
|
|
19926
20281
|
}, [cfg, busy, saveSessionSafe]);
|
|
19927
|
-
const
|
|
19928
|
-
const sessions = await listSessions(200, process.cwd());
|
|
19929
|
-
setResumeSessions(sessions);
|
|
19930
|
-
}, []);
|
|
19931
|
-
const runInit = useCallback6(async () => {
|
|
20282
|
+
const runInit = useCallback8(async () => {
|
|
19932
20283
|
if (!cfg) return;
|
|
19933
20284
|
if (busy) {
|
|
19934
20285
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "can't /init while model is running" }]);
|
|
@@ -19938,9 +20289,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
19938
20289
|
const { prompt, targetFilename, isRefresh } = buildInitPrompt(cwd);
|
|
19939
20290
|
setEvents((e) => [...e, { kind: "user", key: mkKey(), text: isRefresh ? `/init (refreshing ${targetFilename})` : "/init" }]);
|
|
19940
20291
|
messagesRef.current.push({ role: "user", content: sanitizeString(prompt) });
|
|
19941
|
-
|
|
19942
|
-
busyRef.current = true;
|
|
19943
|
-
setTurnStartedAt(Date.now());
|
|
20292
|
+
beginTurn();
|
|
19944
20293
|
const turnScope = sessionScopeRef.current.createChild();
|
|
19945
20294
|
activeScopeRef.current = turnScope;
|
|
19946
20295
|
const initClassification = classifyIntent(prompt);
|
|
@@ -20207,15 +20556,9 @@ ${wcagWarnings.join("\n")}` }
|
|
|
20207
20556
|
setCodeMode(false);
|
|
20208
20557
|
const asstId = activeAsstIdRef.current;
|
|
20209
20558
|
if (asstId !== null) updateAssistant(asstId, () => ({ streaming: false }));
|
|
20210
|
-
|
|
20211
|
-
busyRef.current = false;
|
|
20212
|
-
setTurnStartedAt(null);
|
|
20213
|
-
setTurnPhase("waiting");
|
|
20214
|
-
setCurrentToolName(null);
|
|
20215
|
-
setLastActivityAt(null);
|
|
20559
|
+
endTurn();
|
|
20216
20560
|
activeAsstIdRef.current = null;
|
|
20217
20561
|
activeScopeRef.current = null;
|
|
20218
|
-
isAbortingRef.current = false;
|
|
20219
20562
|
clearPermissionResolveRef();
|
|
20220
20563
|
limitResolveRef.current = null;
|
|
20221
20564
|
loopResolveRef.current = null;
|
|
@@ -20223,7 +20566,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
20223
20566
|
pendingToolCallsRef.current.clear();
|
|
20224
20567
|
}
|
|
20225
20568
|
}, [cfg, busy, updateAssistant, updateTool, updateGatewayMeta]);
|
|
20226
|
-
const handleThemePick =
|
|
20569
|
+
const handleThemePick = useCallback8(
|
|
20227
20570
|
(picked) => {
|
|
20228
20571
|
setShowThemePicker(false);
|
|
20229
20572
|
if (!picked) return;
|
|
@@ -20241,100 +20584,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
20241
20584
|
},
|
|
20242
20585
|
[]
|
|
20243
20586
|
);
|
|
20244
|
-
const
|
|
20245
|
-
async (filePath, checkpointId) => {
|
|
20246
|
-
try {
|
|
20247
|
-
const file = checkpointId ? (await loadSessionFromCheckpoint(filePath, checkpointId)).file : await loadSession(filePath);
|
|
20248
|
-
messagesRef.current = file.messages;
|
|
20249
|
-
sessionIdRef.current = file.id;
|
|
20250
|
-
sessionCreatedAtRef.current = file.createdAt;
|
|
20251
|
-
if (file.sessionState && compiledContextRef.current) {
|
|
20252
|
-
sessionStateRef.current = file.sessionState;
|
|
20253
|
-
}
|
|
20254
|
-
if (file.artifactStore) {
|
|
20255
|
-
artifactStoreRef.current = deserializeArtifactStore(file.artifactStore);
|
|
20256
|
-
} else {
|
|
20257
|
-
artifactStoreRef.current = new ArtifactStore();
|
|
20258
|
-
}
|
|
20259
|
-
const manager = memoryManagerRef.current;
|
|
20260
|
-
if (manager) {
|
|
20261
|
-
try {
|
|
20262
|
-
const cwd = process.cwd();
|
|
20263
|
-
const results = await manager.recall({ text: cwd, repoPath: cwd, limit: 5 });
|
|
20264
|
-
if (results.length > 0) {
|
|
20265
|
-
const text = await manager.synthesizeRecalled(results);
|
|
20266
|
-
const lastSystemIdx = messagesRef.current.findLastIndex((m) => m.role === "system");
|
|
20267
|
-
const insertIdx = lastSystemIdx >= 0 ? lastSystemIdx + 1 : messagesRef.current.length;
|
|
20268
|
-
messagesRef.current.splice(insertIdx, 0, { role: "system", content: text });
|
|
20269
|
-
}
|
|
20270
|
-
} catch {
|
|
20271
|
-
}
|
|
20272
|
-
}
|
|
20273
|
-
const msg = checkpointId ? `resumed session ${file.id} from checkpoint` : `resumed session ${file.id} (${file.messages.filter((m) => m.role !== "system").length} msgs)`;
|
|
20274
|
-
setEvents([{ kind: "info", key: mkKey(), text: msg }]);
|
|
20275
|
-
const userMsgs = file.messages.filter((m) => m.role === "user" && m.content).map((m) => {
|
|
20276
|
-
if (!m.content) return "";
|
|
20277
|
-
if (typeof m.content === "string") return m.content;
|
|
20278
|
-
const textPart = m.content.find((p) => p.type === "text");
|
|
20279
|
-
return textPart?.text ?? "";
|
|
20280
|
-
}).filter((text) => text.length > 0);
|
|
20281
|
-
if (userMsgs.length > 0) setHistory(userMsgs);
|
|
20282
|
-
setUsage(null);
|
|
20283
|
-
setSessionUsage(null);
|
|
20284
|
-
gatewayMetaRef.current = null;
|
|
20285
|
-
setGatewayMeta(null);
|
|
20286
|
-
void getCostReport(file.id).then((report) => setSessionUsage(report.session));
|
|
20287
|
-
} catch (e) {
|
|
20288
|
-
setEvents((es) => [
|
|
20289
|
-
...es,
|
|
20290
|
-
{ kind: "error", key: mkKey(), text: `failed to load session: ${e.message}` }
|
|
20291
|
-
]);
|
|
20292
|
-
}
|
|
20293
|
-
},
|
|
20294
|
-
[]
|
|
20295
|
-
);
|
|
20296
|
-
const handleResumePick = useCallback6(
|
|
20297
|
-
async (picked) => {
|
|
20298
|
-
setResumeSessions(null);
|
|
20299
|
-
if (!picked) return;
|
|
20300
|
-
if (picked.checkpointCount > 0) {
|
|
20301
|
-
try {
|
|
20302
|
-
const file = await loadSession(picked.filePath);
|
|
20303
|
-
setCheckpointList(file.checkpoints ?? []);
|
|
20304
|
-
setCheckpointSession(picked);
|
|
20305
|
-
} catch (e) {
|
|
20306
|
-
setEvents((es) => [
|
|
20307
|
-
...es,
|
|
20308
|
-
{ kind: "error", key: mkKey(), text: `failed to load checkpoints: ${e.message}` }
|
|
20309
|
-
]);
|
|
20310
|
-
await doResumeSession(picked.filePath);
|
|
20311
|
-
}
|
|
20312
|
-
return;
|
|
20313
|
-
}
|
|
20314
|
-
await doResumeSession(picked.filePath);
|
|
20315
|
-
},
|
|
20316
|
-
[doResumeSession]
|
|
20317
|
-
);
|
|
20318
|
-
const handleCheckpointPick = useCallback6(
|
|
20319
|
-
async (checkpointId) => {
|
|
20320
|
-
const session = checkpointSession;
|
|
20321
|
-
setCheckpointSession(null);
|
|
20322
|
-
setCheckpointList([]);
|
|
20323
|
-
if (!session || !checkpointId) {
|
|
20324
|
-
if (session) {
|
|
20325
|
-
setResumeSessions(await listSessions(200, process.cwd()));
|
|
20326
|
-
}
|
|
20327
|
-
return;
|
|
20328
|
-
}
|
|
20329
|
-
if (checkpointId === "__start__") {
|
|
20330
|
-
await doResumeSession(session.filePath);
|
|
20331
|
-
return;
|
|
20332
|
-
}
|
|
20333
|
-
await doResumeSession(session.filePath, checkpointId);
|
|
20334
|
-
},
|
|
20335
|
-
[checkpointSession, doResumeSession]
|
|
20336
|
-
);
|
|
20337
|
-
const handleSlash = useCallback6(
|
|
20587
|
+
const handleSlash = useCallback8(
|
|
20338
20588
|
(cmd) => {
|
|
20339
20589
|
const raw = cmd.trim();
|
|
20340
20590
|
const [head, ...rest] = raw.split(/\s+/);
|
|
@@ -20354,11 +20604,7 @@ ${wcagWarnings.join("\n")}` }
|
|
|
20354
20604
|
} else {
|
|
20355
20605
|
messagesRef.current = [messagesRef.current[0]];
|
|
20356
20606
|
}
|
|
20357
|
-
|
|
20358
|
-
sessionCreatedAtRef.current = null;
|
|
20359
|
-
sessionTitleRef.current = null;
|
|
20360
|
-
sessionStateRef.current = emptySessionState();
|
|
20361
|
-
artifactStoreRef.current = new ArtifactStore();
|
|
20607
|
+
resetSession();
|
|
20362
20608
|
executorRef.current.clearArtifacts();
|
|
20363
20609
|
if (flushTimeoutRef.current) {
|
|
20364
20610
|
clearTimeout(flushTimeoutRef.current);
|
|
@@ -20374,15 +20620,13 @@ ${wcagWarnings.join("\n")}` }
|
|
|
20374
20620
|
setSessionUsage(null);
|
|
20375
20621
|
gatewayMetaRef.current = null;
|
|
20376
20622
|
setGatewayMeta(null);
|
|
20377
|
-
|
|
20378
|
-
setTasksStartedAt(null);
|
|
20379
|
-
setTasksStartTokens(0);
|
|
20623
|
+
clearTaskTracking();
|
|
20380
20624
|
compactSuggestedRef.current = false;
|
|
20381
20625
|
updateNudgedRef.current = false;
|
|
20382
20626
|
return true;
|
|
20383
20627
|
}
|
|
20384
20628
|
if (c === "/reasoning") {
|
|
20385
|
-
setShowReasoning((s) => {
|
|
20629
|
+
turn.setShowReasoning((s) => {
|
|
20386
20630
|
const next = !s;
|
|
20387
20631
|
setEvents((e) => [
|
|
20388
20632
|
...e,
|
|
@@ -21341,7 +21585,7 @@ ${lines.join("\n")}` }]);
|
|
|
21341
21585
|
},
|
|
21342
21586
|
[cfg, exit, usage, theme, mode, openResumePicker, runCompact, runInit, initMcp, setCfg, setShowRemoteDashboard, setSelectedRemoteSession]
|
|
21343
21587
|
);
|
|
21344
|
-
const handleCommandSave =
|
|
21588
|
+
const handleCommandSave = useCallback8(
|
|
21345
21589
|
async (opts2) => {
|
|
21346
21590
|
setCommandWizard(null);
|
|
21347
21591
|
try {
|
|
@@ -21363,7 +21607,7 @@ ${lines.join("\n")}` }]);
|
|
|
21363
21607
|
},
|
|
21364
21608
|
[commandWizard, reloadCustomCommands, setEvents]
|
|
21365
21609
|
);
|
|
21366
|
-
const handleCommandDelete =
|
|
21610
|
+
const handleCommandDelete = useCallback8(
|
|
21367
21611
|
async (cmd) => {
|
|
21368
21612
|
setCommandToDelete(null);
|
|
21369
21613
|
try {
|
|
@@ -21382,7 +21626,7 @@ ${lines.join("\n")}` }]);
|
|
|
21382
21626
|
},
|
|
21383
21627
|
[reloadCustomCommands, setEvents, setCommandToDelete]
|
|
21384
21628
|
);
|
|
21385
|
-
const handleLspSave =
|
|
21629
|
+
const handleLspSave = useCallback8(
|
|
21386
21630
|
(servers, enabled, scope) => {
|
|
21387
21631
|
setCfg((c) => c ? { ...c, lspEnabled: enabled, lspServers: servers } : c);
|
|
21388
21632
|
setLspScope(scope);
|
|
@@ -21411,7 +21655,7 @@ ${lines.join("\n")}` }]);
|
|
|
21411
21655
|
},
|
|
21412
21656
|
[cfg, setCfg, setEvents, setShowLspWizard]
|
|
21413
21657
|
);
|
|
21414
|
-
const handleRemoteCancel =
|
|
21658
|
+
const handleRemoteCancel = useCallback8(
|
|
21415
21659
|
async (session) => {
|
|
21416
21660
|
try {
|
|
21417
21661
|
const { cancelRemoteSession: cancelRemoteSession2 } = await Promise.resolve().then(() => (init_worker_client(), worker_client_exports));
|
|
@@ -21431,7 +21675,7 @@ ${lines.join("\n")}` }]);
|
|
|
21431
21675
|
},
|
|
21432
21676
|
[setEvents, setShowRemoteDashboard]
|
|
21433
21677
|
);
|
|
21434
|
-
const processMessage =
|
|
21678
|
+
const processMessage = useCallback8(
|
|
21435
21679
|
async (text, displayText, opts2) => {
|
|
21436
21680
|
if (!cfg) return;
|
|
21437
21681
|
let trimmed = text.trim();
|
|
@@ -21534,11 +21778,9 @@ ${lines.join("\n")}` }]);
|
|
|
21534
21778
|
{ kind: "info", key: mkKey(), text: "Tip: Rerunning /init occasionally helps KimiFlare stay accurate as your project evolves." }
|
|
21535
21779
|
]);
|
|
21536
21780
|
}
|
|
21537
|
-
|
|
21538
|
-
busyRef.current = true;
|
|
21781
|
+
beginTurn();
|
|
21539
21782
|
gatewayMetaRef.current = null;
|
|
21540
21783
|
setGatewayMeta(null);
|
|
21541
|
-
setTurnStartedAt(Date.now());
|
|
21542
21784
|
const classification = classifyIntent(trimmed);
|
|
21543
21785
|
setIntentTier(classification.tier);
|
|
21544
21786
|
if (!sessionTitleRef.current) {
|
|
@@ -21716,24 +21958,15 @@ ${lines.join("\n")}` }]);
|
|
|
21716
21958
|
setCodeMode(false);
|
|
21717
21959
|
const asstId = activeAsstIdRef.current;
|
|
21718
21960
|
if (asstId !== null) updateAssistant(asstId, () => ({ streaming: false }));
|
|
21719
|
-
|
|
21720
|
-
busyRef.current = false;
|
|
21721
|
-
setTurnStartedAt(null);
|
|
21722
|
-
setTurnPhase("waiting");
|
|
21723
|
-
setCurrentToolName(null);
|
|
21724
|
-
setLastActivityAt(null);
|
|
21961
|
+
endTurn();
|
|
21725
21962
|
activeAsstIdRef.current = null;
|
|
21726
21963
|
activeScopeRef.current = null;
|
|
21727
|
-
isAbortingRef.current = false;
|
|
21728
21964
|
clearPermissionResolveRef();
|
|
21729
21965
|
limitResolveRef.current = null;
|
|
21730
21966
|
loopResolveRef.current = null;
|
|
21731
21967
|
setLoopModal(null);
|
|
21732
21968
|
pendingToolCallsRef.current.clear();
|
|
21733
|
-
|
|
21734
|
-
setTasksStartedAt(null);
|
|
21735
|
-
setTasksStartTokens(0);
|
|
21736
|
-
tasksRef.current = [];
|
|
21969
|
+
clearTaskTracking();
|
|
21737
21970
|
setEvents(
|
|
21738
21971
|
(evts) => evts.map((e) => e.kind === "tool" && e.status === "running" ? { ...e, status: "error", result: "(stopped)" } : e)
|
|
21739
21972
|
);
|
|
@@ -21955,7 +22188,7 @@ ${lines.join("\n")}` }]);
|
|
|
21955
22188
|
processMessage(next.full, next.display, { queuedKey: next.key });
|
|
21956
22189
|
}
|
|
21957
22190
|
}, [busy, queue, processMessage]);
|
|
21958
|
-
const submit =
|
|
22191
|
+
const submit = useCallback8(
|
|
21959
22192
|
(full, display) => {
|
|
21960
22193
|
const trimmedFull = full.trim();
|
|
21961
22194
|
if (!trimmedFull) return;
|
|
@@ -22210,7 +22443,6 @@ var init_app = __esm({
|
|
|
22210
22443
|
"src/app.tsx"() {
|
|
22211
22444
|
"use strict";
|
|
22212
22445
|
init_loop();
|
|
22213
|
-
init_supervisor();
|
|
22214
22446
|
init_system_prompt();
|
|
22215
22447
|
init_llm_summarize();
|
|
22216
22448
|
init_artifact_compaction();
|
|
@@ -22268,6 +22500,9 @@ var init_app = __esm({
|
|
|
22268
22500
|
init_use_picker_controller();
|
|
22269
22501
|
init_use_modal_host();
|
|
22270
22502
|
init_modal_host();
|
|
22503
|
+
init_use_session_manager();
|
|
22504
|
+
init_use_turn_controller();
|
|
22505
|
+
init_input_handlers();
|
|
22271
22506
|
MAX_GITIGNORE_SIZE = 1 * 1024 * 1024;
|
|
22272
22507
|
FEEDBACK_WORKER_URL2 = "https://hello.kimiflare.com";
|
|
22273
22508
|
CONTEXT_LIMIT = 262e3;
|