@ordewell/core 0.5.3 → 0.5.5
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/{ITerminalRunner-Bd-vAJnw.d.ts → ITerminalRunner-BV9Rd2o9.d.ts} +3 -1
- package/dist/{ITerminalRunner-ByeoLF57.d.mts → ITerminalRunner-C77ZNZS9.d.mts} +3 -1
- package/dist/{ModeResolver-DVJ7HV3k.d.mts → ModeResolver-D-SUFRNF.d.mts} +1 -1
- package/dist/{ModeResolver-Dkig8ghQ.d.ts → ModeResolver-D3XO0fT9.d.ts} +1 -1
- package/dist/{Task-BxQkPlXO.d.mts → Task-Vl5Zq_D-.d.mts} +168 -7
- package/dist/{Task-BxQkPlXO.d.ts → Task-Vl5Zq_D-.d.ts} +168 -7
- package/dist/{chunk-JVMDEHRQ.mjs → chunk-HD2FWPRV.mjs} +72 -37
- package/dist/chunk-HD2FWPRV.mjs.map +1 -0
- package/dist/{chunk-GWPIYDQW.mjs → chunk-KLN7ELXO.mjs} +897 -18
- package/dist/chunk-KLN7ELXO.mjs.map +1 -0
- package/dist/{chunk-XWOUIA6A.mjs → chunk-UUBGVCGJ.mjs} +2 -2
- package/dist/index.d.mts +320 -60
- package/dist/index.d.ts +320 -60
- package/dist/index.js +2497 -672
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1605 -659
- package/dist/index.mjs.map +1 -1
- package/dist/order-labels.d.mts +1 -1
- package/dist/order-labels.d.ts +1 -1
- package/dist/{parsing-CF_grC29.d.ts → parsing-BTP4bwkk.d.ts} +11 -3
- package/dist/{parsing-DRp4dPC0.d.mts → parsing-CDtRSxBY.d.mts} +11 -3
- package/dist/parsing.d.mts +3 -3
- package/dist/parsing.d.ts +3 -3
- package/dist/parsing.js.map +1 -1
- package/dist/parsing.mjs +2 -2
- package/dist/plan-utils-BFaPo-IT.d.ts +708 -0
- package/dist/plan-utils-pE4TBwxl.d.mts +708 -0
- package/dist/plan-utils.d.mts +3 -3
- package/dist/plan-utils.d.ts +3 -3
- package/dist/plan-utils.js +668 -7
- package/dist/plan-utils.js.map +1 -1
- package/dist/plan-utils.mjs +38 -4
- package/dist/testing.d.mts +5 -3
- package/dist/testing.d.ts +5 -3
- package/dist/testing.js +3 -0
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +3 -0
- package/dist/testing.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-GWPIYDQW.mjs.map +0 -1
- package/dist/chunk-JVMDEHRQ.mjs.map +0 -1
- package/dist/plan-utils-CkNbqAmS.d.ts +0 -329
- package/dist/plan-utils-CtB3_Ovf.d.mts +0 -329
- /package/dist/{chunk-XWOUIA6A.mjs.map → chunk-UUBGVCGJ.mjs.map} +0 -0
package/dist/plan-utils.js
CHANGED
|
@@ -21,14 +21,31 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var plan_utils_exports = {};
|
|
22
22
|
__export(plan_utils_exports, {
|
|
23
23
|
CHECKPOINT_TRUNCATE_LENGTH: () => CHECKPOINT_TRUNCATE_LENGTH,
|
|
24
|
+
EMPTY_CONVERSATION: () => EMPTY_CONVERSATION,
|
|
25
|
+
EMPTY_HOLD: () => EMPTY_HOLD,
|
|
26
|
+
NO_TURN: () => NO_TURN,
|
|
27
|
+
aheadOfDraft: () => aheadOfDraft,
|
|
24
28
|
canMergeTasks: () => canMergeTasks,
|
|
25
29
|
canSetDependencies: () => canSetDependencies,
|
|
26
30
|
canSplitTask: () => canSplitTask,
|
|
27
31
|
capConflictFiles: () => capConflictFiles,
|
|
28
32
|
dependencyCandidates: () => dependencyCandidates,
|
|
29
33
|
dependentsOf: () => dependentsOf,
|
|
34
|
+
drainNext: () => drainNext,
|
|
35
|
+
followTurn: () => followTurn,
|
|
36
|
+
fromTranscript: () => fromTranscript,
|
|
37
|
+
hasHiddenDetail: () => hasHiddenDetail,
|
|
38
|
+
holdPrompt: () => holdPrompt,
|
|
39
|
+
outputLines: () => outputLines,
|
|
40
|
+
outputPreview: () => outputPreview,
|
|
41
|
+
reduceConversation: () => reduceConversation,
|
|
42
|
+
stopTurn: () => stopTurn,
|
|
30
43
|
summarizeToolCall: () => summarizeToolCall,
|
|
31
|
-
|
|
44
|
+
taskStartedNotice: () => taskStartedNotice,
|
|
45
|
+
toolHeadline: () => toolHeadline,
|
|
46
|
+
truncateCheckpointSummary: () => truncateCheckpointSummary,
|
|
47
|
+
unsendAll: () => unsendAll,
|
|
48
|
+
unsendLatest: () => unsendLatest
|
|
32
49
|
});
|
|
33
50
|
module.exports = __toCommonJS(plan_utils_exports);
|
|
34
51
|
|
|
@@ -105,9 +122,9 @@ function canSplitTask(tasks, taskId) {
|
|
|
105
122
|
}
|
|
106
123
|
|
|
107
124
|
// src/services/researchStepSummary.ts
|
|
108
|
-
function ellipsize(
|
|
109
|
-
const
|
|
110
|
-
return
|
|
125
|
+
function ellipsize(text2, max) {
|
|
126
|
+
const oneLine2 = text2.replace(/\s+/g, " ").trim();
|
|
127
|
+
return oneLine2.length > max ? `${oneLine2.slice(0, max)}\u2026` : oneLine2;
|
|
111
128
|
}
|
|
112
129
|
function summarizeToolCall(tool, argsJson, toolLabel) {
|
|
113
130
|
const display = toolLabel?.trim() || tool;
|
|
@@ -124,8 +141,8 @@ function summarizeToolCall(tool, argsJson, toolLabel) {
|
|
|
124
141
|
try {
|
|
125
142
|
const args = JSON.parse(argsJson);
|
|
126
143
|
const prompt = typeof args.prompt === "string" ? args.prompt : "";
|
|
127
|
-
const
|
|
128
|
-
return `spawn: "${
|
|
144
|
+
const oneLine2 = prompt.replace(/\s+/g, " ").trim();
|
|
145
|
+
return `spawn: "${oneLine2.slice(0, 60)}${oneLine2.length > 60 ? "\u2026" : ""}"`;
|
|
129
146
|
} catch {
|
|
130
147
|
return "spawn_research_agent";
|
|
131
148
|
}
|
|
@@ -177,16 +194,660 @@ function truncateCheckpointSummary(summary) {
|
|
|
177
194
|
function capConflictFiles(files, max = 5) {
|
|
178
195
|
return files.length <= max ? files.join(", ") : `${files.slice(0, max).join(", ")}, +${files.length - max} more`;
|
|
179
196
|
}
|
|
197
|
+
|
|
198
|
+
// src/models/Usage.ts
|
|
199
|
+
function isMeasured(totals) {
|
|
200
|
+
return totals.inputTokens !== void 0 || totals.outputTokens !== void 0 || totals.cachedInputTokens !== void 0 || Object.keys(totals.reportedCost ?? {}).length > 0;
|
|
201
|
+
}
|
|
202
|
+
function usageLine(usage) {
|
|
203
|
+
const contextFill = plannerContextFill(usage);
|
|
204
|
+
return {
|
|
205
|
+
totals: usage.totals,
|
|
206
|
+
...usage.bySubagent ? { bySubagent: usage.bySubagent } : {},
|
|
207
|
+
...contextFill ? { contextFill } : {}
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function plannerContextFill(usage) {
|
|
211
|
+
if (usage.lastPromptTokens === void 0 || usage.contextWindow === void 0 || usage.contextWindow <= 0) return void 0;
|
|
212
|
+
return { usedTokens: usage.lastPromptTokens, windowTokens: usage.contextWindow };
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// src/services/terminalRender.ts
|
|
216
|
+
var ANSI_OR_CTRL_RE = /\x1b\[[0-9;?]*[A-Za-z]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)?|\x1b[()][AB012]|\x1b[=>]|[\x00-\x08\x0b-\x1f\x7f]/g;
|
|
217
|
+
|
|
218
|
+
// src/conversation/format.ts
|
|
219
|
+
var DISPLAY_NAMES = {
|
|
220
|
+
read_file: "Read",
|
|
221
|
+
read_files: "Read",
|
|
222
|
+
list_dir: "List",
|
|
223
|
+
glob: "Glob",
|
|
224
|
+
grep: "Grep",
|
|
225
|
+
find_symbol: "Symbol",
|
|
226
|
+
bash: "Bash",
|
|
227
|
+
fetch: "Fetch",
|
|
228
|
+
web_search: "WebSearch",
|
|
229
|
+
spawn_research_agent: "Agent"
|
|
230
|
+
};
|
|
231
|
+
var HINT_FIELDS = ["file_path", "filePath", "path", "url", "pattern", "query", "command", "description", "prompt"];
|
|
232
|
+
function parseArgs(args) {
|
|
233
|
+
try {
|
|
234
|
+
const parsed = JSON.parse(args);
|
|
235
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
236
|
+
} catch {
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function oneLine(text2) {
|
|
241
|
+
return text2.replace(/\s+/g, " ").trim();
|
|
242
|
+
}
|
|
243
|
+
function firstLineOf(command) {
|
|
244
|
+
const lines = command.trim().split(/\r?\n/);
|
|
245
|
+
const more = lines.length - 1;
|
|
246
|
+
return more > 0 ? `${lines[0]} \u2026 +${more} line${more === 1 ? "" : "s"}` : lines[0];
|
|
247
|
+
}
|
|
248
|
+
function text(value) {
|
|
249
|
+
return typeof value === "string" ? value : "";
|
|
250
|
+
}
|
|
251
|
+
function searchArg(pattern, path, include = "") {
|
|
252
|
+
return `${pattern}${path ? ` in ${path}` : ""}${include ? ` (${include})` : ""}`;
|
|
253
|
+
}
|
|
254
|
+
function hintArg(args) {
|
|
255
|
+
for (const field of HINT_FIELDS) {
|
|
256
|
+
const value = text(args[field]);
|
|
257
|
+
if (value) return field === "command" ? firstLineOf(value) : oneLine(value);
|
|
258
|
+
}
|
|
259
|
+
const firstText = Object.values(args).find((v) => typeof v === "string" && v.trim() !== "");
|
|
260
|
+
return firstText ? oneLine(firstText) : "";
|
|
261
|
+
}
|
|
262
|
+
function keyArgOf(tool, args) {
|
|
263
|
+
switch (tool) {
|
|
264
|
+
case "bash":
|
|
265
|
+
return firstLineOf(text(args.command));
|
|
266
|
+
case "read_file":
|
|
267
|
+
case "list_dir":
|
|
268
|
+
return text(args.path);
|
|
269
|
+
case "read_files":
|
|
270
|
+
return Array.isArray(args.paths) ? args.paths.map(String).join(", ") : "";
|
|
271
|
+
case "glob":
|
|
272
|
+
return searchArg(text(args.pattern), text(args.path));
|
|
273
|
+
case "grep":
|
|
274
|
+
return searchArg(text(args.pattern), text(args.path), text(args.include));
|
|
275
|
+
case "find_symbol":
|
|
276
|
+
return `${text(args.symbol)}${text(args.language) ? ` [${text(args.language)}]` : ""}`;
|
|
277
|
+
case "fetch":
|
|
278
|
+
return text(args.url);
|
|
279
|
+
case "web_search":
|
|
280
|
+
return oneLine(text(args.query));
|
|
281
|
+
case "spawn_research_agent":
|
|
282
|
+
return oneLine(text(args.prompt));
|
|
283
|
+
default:
|
|
284
|
+
return hintArg(args);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function toolHeadline(tool, args, toolLabel) {
|
|
288
|
+
const name = toolLabel?.trim() || DISPLAY_NAMES[tool] || tool;
|
|
289
|
+
const parsed = parseArgs(args);
|
|
290
|
+
return { name, keyArg: parsed ? keyArgOf(tool, parsed) : oneLine(args) };
|
|
291
|
+
}
|
|
292
|
+
function outputLines(output) {
|
|
293
|
+
const lines = output.replace(/\r\n?/g, "\n").replace(ANSI_OR_CTRL_RE, "").split("\n");
|
|
294
|
+
while (lines.length > 0 && lines[lines.length - 1].trim() === "") lines.pop();
|
|
295
|
+
return lines;
|
|
296
|
+
}
|
|
297
|
+
function outputPreview(output, maxLines) {
|
|
298
|
+
const lines = outputLines(output);
|
|
299
|
+
const shown = lines.slice(0, Math.max(0, maxLines));
|
|
300
|
+
return { lines: shown, hiddenLineCount: lines.length - shown.length };
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// src/conversation/records.ts
|
|
304
|
+
function settledMessage(id, role, text2, turnId) {
|
|
305
|
+
return { type: "message", id, role, text: text2, streaming: false, ...turnId ? { turnId } : {} };
|
|
306
|
+
}
|
|
307
|
+
function subagentBlock(id, { toolCallId, model, usage, turnId, ...fields }) {
|
|
308
|
+
return {
|
|
309
|
+
type: "subagent",
|
|
310
|
+
id,
|
|
311
|
+
...fields,
|
|
312
|
+
...toolCallId ? { toolCallId } : {},
|
|
313
|
+
...model ? { model } : {},
|
|
314
|
+
...usage ? { usage } : {},
|
|
315
|
+
...turnId ? { turnId } : {}
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
function usageBlock(id, { totals, bySubagent, contextFill }) {
|
|
319
|
+
return { type: "usage", id, totals, ...bySubagent ? { bySubagent } : {}, ...contextFill ? { contextFill } : {} };
|
|
320
|
+
}
|
|
321
|
+
var STATUS_OF_OUTCOME = {
|
|
322
|
+
success: "ok",
|
|
323
|
+
failure: "error",
|
|
324
|
+
refused: "denied",
|
|
325
|
+
denied: "denied",
|
|
326
|
+
not_executed: "interrupted"
|
|
327
|
+
};
|
|
328
|
+
function settledTool(call, step) {
|
|
329
|
+
return { ...call, status: STATUS_OF_OUTCOME[step.outcome], outcome: step.outcome, output: step.result, outputLineCount: outputLines(step.result).length };
|
|
330
|
+
}
|
|
331
|
+
function pendingTool(id, { tool, toolLabel, args, toolCallId, turnId }) {
|
|
332
|
+
return {
|
|
333
|
+
type: "tool",
|
|
334
|
+
id,
|
|
335
|
+
tool,
|
|
336
|
+
headline: toolHeadline(tool, args, toolLabel),
|
|
337
|
+
args,
|
|
338
|
+
status: "pending",
|
|
339
|
+
output: "",
|
|
340
|
+
outputLineCount: 0,
|
|
341
|
+
...toolCallId ? { toolCallId } : {},
|
|
342
|
+
...toolLabel ? { toolLabel } : {},
|
|
343
|
+
...turnId ? { turnId } : {}
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
function toolFromStep(id, step, turnId) {
|
|
347
|
+
return settledTool(pendingTool(id, { ...step, turnId }), step);
|
|
348
|
+
}
|
|
349
|
+
function planMarker(content) {
|
|
350
|
+
const count = /(\d+) tasks?\b/.exec(content);
|
|
351
|
+
return { status: content.startsWith("Plan updated") ? "updated" : "generated", ...count ? { taskCount: Number(count[1]) } : {} };
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// src/conversation/reduce.ts
|
|
355
|
+
var EMPTY_CONVERSATION = { blocks: [], nextId: 1 };
|
|
356
|
+
function findLastIndex(items, match) {
|
|
357
|
+
for (let i = items.length - 1; i >= 0; i--) if (match(items[i])) return i;
|
|
358
|
+
return -1;
|
|
359
|
+
}
|
|
360
|
+
function replaceAt(items, index, item) {
|
|
361
|
+
const next = items.slice();
|
|
362
|
+
next[index] = item;
|
|
363
|
+
return next;
|
|
364
|
+
}
|
|
365
|
+
function insertTop(blocks, block) {
|
|
366
|
+
const last = blocks[blocks.length - 1];
|
|
367
|
+
return last?.type === "usage" ? [...blocks.slice(0, -1), block, last] : [...blocks, block];
|
|
368
|
+
}
|
|
369
|
+
function append(view, make) {
|
|
370
|
+
return { ...view, blocks: insertTop(view.blocks, make(`b${view.nextId}`)), nextId: view.nextId + 1 };
|
|
371
|
+
}
|
|
372
|
+
function subagentAt(view, lane) {
|
|
373
|
+
const block = view.blocks[lane];
|
|
374
|
+
if (block.type !== "subagent") throw new Error(`block ${lane} is not a subagent`);
|
|
375
|
+
return block;
|
|
376
|
+
}
|
|
377
|
+
function laneBlocks(view, lane) {
|
|
378
|
+
return lane === null ? view.blocks : subagentAt(view, lane).children;
|
|
379
|
+
}
|
|
380
|
+
function setChildren(view, lane, children) {
|
|
381
|
+
return { ...view, blocks: replaceAt(view.blocks, lane, { ...subagentAt(view, lane), children }) };
|
|
382
|
+
}
|
|
383
|
+
function laneReplace(view, lane, index, block) {
|
|
384
|
+
if (lane === null) return { ...view, blocks: replaceAt(view.blocks, index, block) };
|
|
385
|
+
return setChildren(view, lane, replaceAt(subagentAt(view, lane).children, index, block));
|
|
386
|
+
}
|
|
387
|
+
function laneAppend(view, lane, make) {
|
|
388
|
+
if (lane === null) return append(view, make);
|
|
389
|
+
const children = [...subagentAt(view, lane).children, make(`b${view.nextId}`)];
|
|
390
|
+
return { ...setChildren(view, lane, children), nextId: view.nextId + 1 };
|
|
391
|
+
}
|
|
392
|
+
function isStreaming(block) {
|
|
393
|
+
return (block.type === "message" || block.type === "thinking") && block.streaming;
|
|
394
|
+
}
|
|
395
|
+
function sealed(block) {
|
|
396
|
+
return isStreaming(block) ? { ...block, streaming: false } : block;
|
|
397
|
+
}
|
|
398
|
+
function sealLane(view, lane, keep) {
|
|
399
|
+
const blocks = laneBlocks(view, lane);
|
|
400
|
+
if (!blocks.some((b, i) => i !== keep && isStreaming(b))) return view;
|
|
401
|
+
if (lane === null) return { ...view, blocks: view.blocks.map((b, i) => i === keep ? b : sealed(b)) };
|
|
402
|
+
return setChildren(view, lane, subagentAt(view, lane).children.map((b, i) => i === keep ? b : sealed(b)));
|
|
403
|
+
}
|
|
404
|
+
function appendOutput(view, lane, make) {
|
|
405
|
+
const next = laneAppend(view, lane, make);
|
|
406
|
+
return sealLane(next, lane, findLastIndex(laneBlocks(next, lane), (b) => b.type !== "usage"));
|
|
407
|
+
}
|
|
408
|
+
function isUnsettledSegment(block, turnId) {
|
|
409
|
+
return block.type === "message" && block.turnId === turnId && block.segmentId !== void 0;
|
|
410
|
+
}
|
|
411
|
+
function isBuildingPlan(block, turnId) {
|
|
412
|
+
return block.type === "plan" && block.status === "building" && block.turnId === turnId;
|
|
413
|
+
}
|
|
414
|
+
function finalSegmentIndex(blocks, turnId, pastPlan = false) {
|
|
415
|
+
for (let i = blocks.length - 1; i >= 0; i--) {
|
|
416
|
+
const block = blocks[i];
|
|
417
|
+
if (block.type === "usage" || block.type === "thinking" || block.type === "approval" || pastPlan && block.type === "plan") continue;
|
|
418
|
+
if (block.turnId !== turnId) continue;
|
|
419
|
+
return isUnsettledSegment(block, turnId) ? i : -1;
|
|
420
|
+
}
|
|
421
|
+
return -1;
|
|
422
|
+
}
|
|
423
|
+
function openTurn(view, turnId, prompt) {
|
|
424
|
+
const i = findLastIndex(view.blocks, (b) => b.type === "message" && b.role === "user");
|
|
425
|
+
const sent = view.blocks[i];
|
|
426
|
+
if (sent?.type === "message" && sent.turnId === void 0 && sent.text === prompt) {
|
|
427
|
+
return { ...view, blocks: replaceAt(view.blocks, i, { ...sent, turnId }) };
|
|
428
|
+
}
|
|
429
|
+
return append(view, (id) => settledMessage(id, "user", prompt, turnId));
|
|
430
|
+
}
|
|
431
|
+
function streamText(view, { turnId, segmentId, text: text2 }) {
|
|
432
|
+
const i = findLastIndex(view.blocks, (b) => isUnsettledSegment(b, turnId) && b.segmentId === segmentId);
|
|
433
|
+
const segment = view.blocks[i];
|
|
434
|
+
if (segment?.type === "message") {
|
|
435
|
+
return sealLane(laneReplace(view, null, i, { ...segment, text: segment.text + text2, streaming: true }), null, i);
|
|
436
|
+
}
|
|
437
|
+
return appendOutput(view, null, (id) => ({ type: "message", id, role: "planner", text: text2, streaming: true, turnId, segmentId }));
|
|
438
|
+
}
|
|
439
|
+
function dropBuildingPlan(view, turnId, segmentId) {
|
|
440
|
+
const blocks = view.blocks.filter((b) => !(isBuildingPlan(b, turnId) && (segmentId === void 0 || b.segmentId === segmentId)));
|
|
441
|
+
return blocks.length === view.blocks.length ? view : { ...view, blocks };
|
|
442
|
+
}
|
|
443
|
+
function settleReply(view, { content, turnId }) {
|
|
444
|
+
if (turnId !== void 0) {
|
|
445
|
+
const i = finalSegmentIndex(view.blocks, turnId);
|
|
446
|
+
if (i >= 0) {
|
|
447
|
+
return dropBuildingPlan({ ...view, blocks: replaceAt(view.blocks, i, settledMessage(view.blocks[i].id, "planner", content, turnId)) }, turnId);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
return append(dropBuildingPlan(view, turnId), (id) => settledMessage(id, "planner", content, turnId));
|
|
451
|
+
}
|
|
452
|
+
function retractText(view, { turnId, segmentId }) {
|
|
453
|
+
const blocks = view.blocks.filter((b) => !(isUnsettledSegment(b, turnId) && (segmentId === void 0 || b.segmentId === segmentId)));
|
|
454
|
+
return dropBuildingPlan(blocks.length === view.blocks.length ? view : { ...view, blocks }, turnId, segmentId);
|
|
455
|
+
}
|
|
456
|
+
function subagentLane(view, subagentId, turnId) {
|
|
457
|
+
const existing = findLastIndex(view.blocks, (b) => b.type === "subagent" && b.subagentId === subagentId);
|
|
458
|
+
if (existing >= 0) return [view, existing];
|
|
459
|
+
const spawn = findLastIndex(view.blocks, (b) => b.type === "tool" && (b.spawns === subagentId || b.toolCallId === subagentId));
|
|
460
|
+
const call = view.blocks[spawn];
|
|
461
|
+
if (call?.type === "tool") {
|
|
462
|
+
const block = subagentBlock(call.id, {
|
|
463
|
+
subagentId,
|
|
464
|
+
brief: call.headline.keyArg,
|
|
465
|
+
status: "running",
|
|
466
|
+
children: [],
|
|
467
|
+
digest: "",
|
|
468
|
+
toolCallId: call.toolCallId,
|
|
469
|
+
turnId: call.turnId
|
|
470
|
+
});
|
|
471
|
+
return [{ ...view, blocks: replaceAt(view.blocks, spawn, block) }, spawn];
|
|
472
|
+
}
|
|
473
|
+
const next = append(view, (id) => subagentBlock(id, { subagentId, brief: "", status: "running", children: [], digest: "", turnId }));
|
|
474
|
+
return [next, findLastIndex(next.blocks, (b) => b.type === "subagent" && b.subagentId === subagentId)];
|
|
475
|
+
}
|
|
476
|
+
function updateSubagent(view, subagentId, turnId, update) {
|
|
477
|
+
const [next, lane] = subagentLane(view, subagentId, turnId);
|
|
478
|
+
return { ...next, blocks: replaceAt(next.blocks, lane, update(subagentAt(next, lane))) };
|
|
479
|
+
}
|
|
480
|
+
function startSubagent(view, { subagentId, brief, model, turnId }) {
|
|
481
|
+
return updateSubagent(view, subagentId, turnId, (block) => ({ ...block, ...brief ? { brief } : {}, ...model ? { model } : {} }));
|
|
482
|
+
}
|
|
483
|
+
function finishSubagent(view, { subagentId, outcome, digest, usage, turnId }) {
|
|
484
|
+
return updateSubagent(view, subagentId, turnId, (block) => ({
|
|
485
|
+
...block,
|
|
486
|
+
status: outcome,
|
|
487
|
+
digest,
|
|
488
|
+
children: block.children.map(sealed),
|
|
489
|
+
...usage ? { usage } : {}
|
|
490
|
+
}));
|
|
491
|
+
}
|
|
492
|
+
function think(view, text2, turnId, segmentId, subagentId) {
|
|
493
|
+
const [placed, lane] = subagentId ? subagentLane(view, subagentId, turnId) : [view, null];
|
|
494
|
+
const blocks = laneBlocks(placed, lane);
|
|
495
|
+
const lastIndex = findLastIndex(blocks, (b) => b.type !== "usage");
|
|
496
|
+
const last = blocks[lastIndex];
|
|
497
|
+
if (last?.type === "thinking" && last.streaming && last.segmentId === segmentId) {
|
|
498
|
+
return laneReplace(placed, lane, lastIndex, { ...last, text: last.text + text2 });
|
|
499
|
+
}
|
|
500
|
+
return appendOutput(placed, lane, (id) => ({
|
|
501
|
+
type: "thinking",
|
|
502
|
+
id,
|
|
503
|
+
text: text2,
|
|
504
|
+
streaming: true,
|
|
505
|
+
...turnId ? { turnId } : {},
|
|
506
|
+
...segmentId ? { segmentId } : {},
|
|
507
|
+
...subagentId ? { subagentId } : {}
|
|
508
|
+
}));
|
|
509
|
+
}
|
|
510
|
+
function announceTool(view, call) {
|
|
511
|
+
const spawns = call.tool === "spawn_research_agent" ? call.subagentId : void 0;
|
|
512
|
+
const [placed, lane] = call.subagentId && !spawns ? subagentLane(view, call.subagentId, call.turnId) : [view, null];
|
|
513
|
+
return appendOutput(placed, lane, (id) => ({ ...pendingTool(id, call), ...spawns ? { spawns } : {} }));
|
|
514
|
+
}
|
|
515
|
+
function isPendingCallOf(block, step) {
|
|
516
|
+
if (block.type !== "tool" || block.status !== "pending") return false;
|
|
517
|
+
return step.toolCallId ? block.toolCallId === step.toolCallId : block.toolCallId === void 0 && block.tool === step.tool;
|
|
518
|
+
}
|
|
519
|
+
function settleTool(view, { step, turnId }) {
|
|
520
|
+
const [placed, lane] = step.subagentId ? subagentLane(view, step.subagentId, turnId) : [view, null];
|
|
521
|
+
const blocks = laneBlocks(placed, lane);
|
|
522
|
+
const i = findLastIndex(blocks, (b) => isPendingCallOf(b, step));
|
|
523
|
+
const pending = blocks[i];
|
|
524
|
+
if (pending?.type === "tool") return laneReplace(placed, lane, i, settledTool(pending, step));
|
|
525
|
+
if (lane === null && step.toolCallId && blocks.some((b) => b.type === "subagent" && b.toolCallId === step.toolCallId)) return view;
|
|
526
|
+
return laneAppend(placed, lane, (id) => toolFromStep(id, step, turnId));
|
|
527
|
+
}
|
|
528
|
+
function streamPlan(view, { token, turnId, segmentId }) {
|
|
529
|
+
const i = findLastIndex(view.blocks, (b) => isBuildingPlan(b, turnId));
|
|
530
|
+
const building = view.blocks[i];
|
|
531
|
+
if (building?.type === "plan" && building.segmentId === segmentId) {
|
|
532
|
+
return { ...view, blocks: replaceAt(view.blocks, i, { ...building, text: building.text + token }) };
|
|
533
|
+
}
|
|
534
|
+
return append(dropBuildingPlan(view, turnId), (id) => ({
|
|
535
|
+
type: "plan",
|
|
536
|
+
id,
|
|
537
|
+
status: "building",
|
|
538
|
+
text: token,
|
|
539
|
+
...turnId ? { turnId } : {},
|
|
540
|
+
...segmentId ? { segmentId } : {}
|
|
541
|
+
}));
|
|
542
|
+
}
|
|
543
|
+
function markPlan(view, content, turnId) {
|
|
544
|
+
const marker = planMarker(content);
|
|
545
|
+
const i = findLastIndex(view.blocks, (b) => isBuildingPlan(b, turnId));
|
|
546
|
+
const building = view.blocks[i];
|
|
547
|
+
if (building?.type === "plan") {
|
|
548
|
+
const settled = { type: "plan", id: building.id, ...marker, text: "", ...building.turnId ? { turnId: building.turnId } : {} };
|
|
549
|
+
return { ...view, blocks: replaceAt(view.blocks, i, settled) };
|
|
550
|
+
}
|
|
551
|
+
return append(view, (id) => ({ type: "plan", id, text: "", ...marker }));
|
|
552
|
+
}
|
|
553
|
+
function requestApproval(view, { id: approvalId, kind, subject, scope, detail, turnId }) {
|
|
554
|
+
return append(view, (id) => ({
|
|
555
|
+
type: "approval",
|
|
556
|
+
id,
|
|
557
|
+
approvalId,
|
|
558
|
+
kind,
|
|
559
|
+
subject,
|
|
560
|
+
scope,
|
|
561
|
+
status: "pending",
|
|
562
|
+
...detail ? { detail } : {},
|
|
563
|
+
...turnId ? { turnId } : {}
|
|
564
|
+
}));
|
|
565
|
+
}
|
|
566
|
+
function settleApproval(view, { id, granted }) {
|
|
567
|
+
const i = findLastIndex(view.blocks, (b) => b.type === "approval" && b.approvalId === id);
|
|
568
|
+
const request = view.blocks[i];
|
|
569
|
+
if (request?.type !== "approval") return view;
|
|
570
|
+
return { ...view, blocks: replaceAt(view.blocks, i, { ...request, status: granted ? "granted" : "denied", decidedBy: "asked" }) };
|
|
571
|
+
}
|
|
572
|
+
function decideApproval(view, { kind, subject, scope, detail, granted, source }) {
|
|
573
|
+
return append(view, (id) => ({
|
|
574
|
+
type: "approval",
|
|
575
|
+
id,
|
|
576
|
+
kind,
|
|
577
|
+
subject,
|
|
578
|
+
scope,
|
|
579
|
+
status: granted ? "granted" : "denied",
|
|
580
|
+
decidedBy: source,
|
|
581
|
+
...detail ? { detail } : {}
|
|
582
|
+
}));
|
|
583
|
+
}
|
|
584
|
+
function reportUsage(view, message) {
|
|
585
|
+
if (!isMeasured(message.totals)) return view;
|
|
586
|
+
const last = view.blocks[view.blocks.length - 1];
|
|
587
|
+
const line = usageBlock(last?.type === "usage" ? last.id : `b${view.nextId}`, message);
|
|
588
|
+
if (last?.type === "usage") return { ...view, blocks: replaceAt(view.blocks, view.blocks.length - 1, line) };
|
|
589
|
+
return { ...view, blocks: [...view.blocks, line], nextId: view.nextId + 1 };
|
|
590
|
+
}
|
|
591
|
+
function closeBlock(block, interrupted) {
|
|
592
|
+
return interrupted && block.type === "tool" && block.status === "pending" ? { ...block, status: "interrupted" } : sealed(block);
|
|
593
|
+
}
|
|
594
|
+
function closeSubagent(block, cut) {
|
|
595
|
+
const children = block.children.map((c) => closeBlock(c, cut !== null));
|
|
596
|
+
const status = cut && block.status === "running" ? cut : block.status;
|
|
597
|
+
return status === block.status && children.every((c, i) => c === block.children[i]) ? block : { ...block, status, children };
|
|
598
|
+
}
|
|
599
|
+
function endTurn(view, { turnId, outcome }) {
|
|
600
|
+
let next = dropBuildingPlan(view, turnId);
|
|
601
|
+
const planText = outcome === "plan" ? finalSegmentIndex(next.blocks, turnId, true) : -1;
|
|
602
|
+
if (planText >= 0) next = { ...next, blocks: next.blocks.filter((_, i) => i !== planText) };
|
|
603
|
+
const cut = outcome === "stopped" ? "stopped" : outcome === "error" ? "failed" : null;
|
|
604
|
+
const blocks = next.blocks.map((b) => b.type === "subagent" ? closeSubagent(b, cut) : closeBlock(b, cut !== null));
|
|
605
|
+
return blocks.every((b, i) => b === next.blocks[i]) ? next : { ...next, blocks };
|
|
606
|
+
}
|
|
607
|
+
function markCompaction(view, summary) {
|
|
608
|
+
const i = findLastIndex(view.blocks, (b) => b.type === "message" && b.role === "planner" && b.turnId === void 0 && b.text === summary);
|
|
609
|
+
const announced = view.blocks[i];
|
|
610
|
+
if (announced?.type === "message") return { ...view, blocks: replaceAt(view.blocks, i, { ...announced, role: "system" }) };
|
|
611
|
+
return append(view, (id) => settledMessage(id, "system", summary));
|
|
612
|
+
}
|
|
613
|
+
function syncTranscript(view, { plan, turnId }) {
|
|
614
|
+
const history = plan.conversationHistory ?? [];
|
|
615
|
+
const committed = findLastIndex(history, (e) => e.kind === "plan_generated");
|
|
616
|
+
let next = view;
|
|
617
|
+
let latest = view.transcriptAt;
|
|
618
|
+
for (const [i, entry] of history.entries()) {
|
|
619
|
+
const isNew = view.transcriptAt === void 0 || entry.timestamp > view.transcriptAt;
|
|
620
|
+
if (isNew && entry.kind === "plan_generated") next = markPlan(next, entry.content, i === committed ? turnId : void 0);
|
|
621
|
+
if (isNew && entry.kind === "system") next = append(next, (id) => settledMessage(id, "system", entry.content));
|
|
622
|
+
if (isNew && entry.kind === "compaction") next = markCompaction(next, entry.content);
|
|
623
|
+
if (latest === void 0 || entry.timestamp > latest) latest = entry.timestamp;
|
|
624
|
+
}
|
|
625
|
+
return next === view && latest === view.transcriptAt ? view : { ...next, transcriptAt: latest };
|
|
626
|
+
}
|
|
627
|
+
function reduceConversation(view, input) {
|
|
628
|
+
switch (input.type) {
|
|
629
|
+
case "local_entry":
|
|
630
|
+
return append(view, (id) => settledMessage(id, input.role, input.text));
|
|
631
|
+
case "planner_turn_started":
|
|
632
|
+
return input.prompt === void 0 ? view : openTurn(view, input.turnId, input.prompt);
|
|
633
|
+
case "planner_text_delta":
|
|
634
|
+
return streamText(view, input);
|
|
635
|
+
case "planner_message":
|
|
636
|
+
return settleReply(view, input);
|
|
637
|
+
case "planner_text_retracted":
|
|
638
|
+
return retractText(view, input);
|
|
639
|
+
case "planner_thinking_delta":
|
|
640
|
+
return think(view, input.text, input.turnId, input.segmentId, input.subagentId);
|
|
641
|
+
case "research_step":
|
|
642
|
+
return announceTool(view, input);
|
|
643
|
+
case "research_step_done":
|
|
644
|
+
return settleTool(view, input);
|
|
645
|
+
case "subagent_started":
|
|
646
|
+
return startSubagent(view, input);
|
|
647
|
+
case "subagent_finished":
|
|
648
|
+
return finishSubagent(view, input);
|
|
649
|
+
case "plan_token":
|
|
650
|
+
return streamPlan(view, input);
|
|
651
|
+
case "plan_generated":
|
|
652
|
+
return syncTranscript(view, input);
|
|
653
|
+
case "planner_turn_ended":
|
|
654
|
+
return endTurn(view, input);
|
|
655
|
+
case "approval_request":
|
|
656
|
+
return requestApproval(view, input);
|
|
657
|
+
case "approval_settled":
|
|
658
|
+
return settleApproval(view, input);
|
|
659
|
+
case "approval_decided":
|
|
660
|
+
return decideApproval(view, input);
|
|
661
|
+
case "planner_usage":
|
|
662
|
+
return reportUsage(view, input);
|
|
663
|
+
default:
|
|
664
|
+
return view;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// src/conversation/transcript.ts
|
|
669
|
+
var USER = 0;
|
|
670
|
+
var RESEARCH = 1;
|
|
671
|
+
var SETTLED = 2;
|
|
672
|
+
function fromEntry(entry) {
|
|
673
|
+
if (entry.kind === "plan_generated") return (id) => ({ type: "plan", id: id(), text: "", ...planMarker(entry.content) });
|
|
674
|
+
const role = entry.kind === "system" || entry.kind === "compaction" ? "system" : entry.role === "user" ? "user" : "planner";
|
|
675
|
+
return (id) => settledMessage(id(), role, entry.content);
|
|
676
|
+
}
|
|
677
|
+
function spawnBrief(step) {
|
|
678
|
+
try {
|
|
679
|
+
const args = JSON.parse(step.args);
|
|
680
|
+
const prompt = args && typeof args === "object" ? args.prompt : void 0;
|
|
681
|
+
return typeof prompt === "string" ? prompt.trim() : void 0;
|
|
682
|
+
} catch {
|
|
683
|
+
return void 0;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
function spawnedBy(step, unclaimed) {
|
|
687
|
+
const byId = unclaimed.find((e) => e.subagentId === step.toolCallId);
|
|
688
|
+
if (byId) return byId;
|
|
689
|
+
if (step.tool !== "spawn_research_agent") return void 0;
|
|
690
|
+
const brief = spawnBrief(step);
|
|
691
|
+
return brief === void 0 ? void 0 : unclaimed.find((e) => e.brief === brief);
|
|
692
|
+
}
|
|
693
|
+
function research(log) {
|
|
694
|
+
const subagents = log.filter((e) => "type" in e && e.type === "subagent");
|
|
695
|
+
const ownSubagent = new Set(subagents.map((e) => e.subagentId));
|
|
696
|
+
const unclaimed = [...subagents];
|
|
697
|
+
const spawnCall = /* @__PURE__ */ new Map();
|
|
698
|
+
const placed = [];
|
|
699
|
+
for (const entry of log) {
|
|
700
|
+
if ("type" in entry) {
|
|
701
|
+
if (entry.type === "system") placed.push({ at: entry.timestamp, rank: RESEARCH, build: (id) => settledMessage(id(), "system", entry.content) });
|
|
702
|
+
continue;
|
|
703
|
+
}
|
|
704
|
+
if (entry.subagentId && ownSubagent.has(entry.subagentId)) continue;
|
|
705
|
+
const spawned = spawnedBy(entry, unclaimed);
|
|
706
|
+
if (spawned) {
|
|
707
|
+
unclaimed.splice(unclaimed.indexOf(spawned), 1);
|
|
708
|
+
spawnCall.set(spawned.subagentId, entry.toolCallId);
|
|
709
|
+
continue;
|
|
710
|
+
}
|
|
711
|
+
placed.push({ at: entry.timestamp, rank: RESEARCH, build: (id) => toolFromStep(id(), entry) });
|
|
712
|
+
}
|
|
713
|
+
for (const entry of subagents) {
|
|
714
|
+
const toolCallId = spawnCall.get(entry.subagentId);
|
|
715
|
+
const steps = log.filter((e) => !("type" in e) && e.subagentId === entry.subagentId);
|
|
716
|
+
placed.push({
|
|
717
|
+
at: entry.timestamp,
|
|
718
|
+
rank: RESEARCH,
|
|
719
|
+
build: (id) => subagentBlock(id(), {
|
|
720
|
+
subagentId: entry.subagentId,
|
|
721
|
+
brief: entry.brief,
|
|
722
|
+
status: entry.outcome,
|
|
723
|
+
digest: entry.digest,
|
|
724
|
+
children: steps.map((step) => toolFromStep(id(), step)),
|
|
725
|
+
toolCallId,
|
|
726
|
+
model: entry.model,
|
|
727
|
+
usage: entry.usage
|
|
728
|
+
})
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
return placed;
|
|
732
|
+
}
|
|
733
|
+
function fromTranscript(conversationHistory, researchLog, plannerUsage) {
|
|
734
|
+
const history = conversationHistory ?? [];
|
|
735
|
+
const compacted = history[0]?.kind === "compaction" ? history[0] : void 0;
|
|
736
|
+
const kept = compacted ? history.slice(1) : history;
|
|
737
|
+
const cutoff = compacted ? kept[0]?.timestamp ?? compacted.timestamp : "";
|
|
738
|
+
const placed = [
|
|
739
|
+
...kept.map((entry) => ({ at: entry.timestamp, rank: entry.role === "user" && !entry.kind ? USER : SETTLED, build: fromEntry(entry) })),
|
|
740
|
+
...research(researchLog ?? []).filter((item) => item.at >= cutoff)
|
|
741
|
+
];
|
|
742
|
+
placed.sort((a, b) => a.at < b.at ? -1 : a.at > b.at ? 1 : a.rank - b.rank);
|
|
743
|
+
if (compacted) placed.unshift({ at: "", rank: SETTLED, build: fromEntry(compacted) });
|
|
744
|
+
let nextId = 1;
|
|
745
|
+
const id = () => `b${nextId++}`;
|
|
746
|
+
const blocks = placed.map((item) => item.build(id));
|
|
747
|
+
if (plannerUsage && isMeasured(plannerUsage.totals)) blocks.push(usageBlock(id(), usageLine(plannerUsage)));
|
|
748
|
+
const transcriptAt = history.reduce((latest, e) => latest === void 0 || e.timestamp > latest ? e.timestamp : latest, void 0);
|
|
749
|
+
return { blocks, nextId, ...transcriptAt ? { transcriptAt } : {} };
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
// src/conversation/promptHold.ts
|
|
753
|
+
var EMPTY_HOLD = [];
|
|
754
|
+
function holdPrompt(hold, text2) {
|
|
755
|
+
return [...hold, text2];
|
|
756
|
+
}
|
|
757
|
+
function drainNext(hold) {
|
|
758
|
+
const [text2, ...rest] = hold;
|
|
759
|
+
return text2 === void 0 ? void 0 : { text: text2, rest };
|
|
760
|
+
}
|
|
761
|
+
function unsendLatest(hold) {
|
|
762
|
+
if (hold.length === 0) return void 0;
|
|
763
|
+
return { text: hold[hold.length - 1], rest: hold.slice(0, -1) };
|
|
764
|
+
}
|
|
765
|
+
function unsendAll(hold) {
|
|
766
|
+
if (hold.length === 0) return void 0;
|
|
767
|
+
return { text: hold.join("\n"), rest: EMPTY_HOLD };
|
|
768
|
+
}
|
|
769
|
+
function aheadOfDraft(text2, draft) {
|
|
770
|
+
return draft ? `${text2}
|
|
771
|
+
${draft}` : text2;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// src/conversation/turnGate.ts
|
|
775
|
+
var NO_TURN = { open: null, stopped: null };
|
|
776
|
+
var TURN_STREAM = /* @__PURE__ */ new Set([
|
|
777
|
+
"planner_text_delta",
|
|
778
|
+
"planner_thinking_delta",
|
|
779
|
+
"planner_text_retracted",
|
|
780
|
+
"planner_message",
|
|
781
|
+
"plan_token",
|
|
782
|
+
"research_step",
|
|
783
|
+
"research_step_done",
|
|
784
|
+
"subagent_started",
|
|
785
|
+
"subagent_finished",
|
|
786
|
+
"planner_turn_ended"
|
|
787
|
+
]);
|
|
788
|
+
function cutOff(gate, input) {
|
|
789
|
+
if (gate.stopped === null || !TURN_STREAM.has(input.type)) return false;
|
|
790
|
+
const turnId = "turnId" in input ? input.turnId : void 0;
|
|
791
|
+
return turnId === void 0 || turnId === gate.stopped;
|
|
792
|
+
}
|
|
793
|
+
function withGate(live, gate) {
|
|
794
|
+
return gate.open === live.gate.open && gate.stopped === live.gate.stopped ? live : { ...live, gate };
|
|
795
|
+
}
|
|
796
|
+
function followTurn(view, gate, input) {
|
|
797
|
+
const live = { view, gate };
|
|
798
|
+
if (input.type === "planner_turn_started") {
|
|
799
|
+
return withGate({ view: reduceConversation(view, input), gate }, { open: input.turnId, stopped: null });
|
|
800
|
+
}
|
|
801
|
+
if (cutOff(gate, input)) {
|
|
802
|
+
return input.type === "planner_turn_ended" ? withGate(live, { ...gate, stopped: null }) : live;
|
|
803
|
+
}
|
|
804
|
+
const next = { view: reduceConversation(view, input), gate };
|
|
805
|
+
return input.type === "planner_turn_ended" && input.turnId === gate.open ? withGate(next, { ...gate, open: null }) : next;
|
|
806
|
+
}
|
|
807
|
+
function stopTurn(view, gate) {
|
|
808
|
+
if (gate.open === null) return { view, gate };
|
|
809
|
+
return {
|
|
810
|
+
view: reduceConversation(view, { type: "planner_turn_ended", turnId: gate.open, outcome: "stopped" }),
|
|
811
|
+
gate: { open: null, stopped: gate.open }
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
// src/conversation/detail.ts
|
|
816
|
+
function hasHiddenDetail(blocks) {
|
|
817
|
+
return blocks.some((b) => b.type === "thinking" || b.type === "tool" || b.type === "subagent");
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
// src/conversation/notices.ts
|
|
821
|
+
function taskStartedNotice(title, runner) {
|
|
822
|
+
return runner ? `Started "${title}" \xB7 ${runner}` : `Started "${title}"`;
|
|
823
|
+
}
|
|
180
824
|
// Annotate the CommonJS export names for ESM import in node:
|
|
181
825
|
0 && (module.exports = {
|
|
182
826
|
CHECKPOINT_TRUNCATE_LENGTH,
|
|
827
|
+
EMPTY_CONVERSATION,
|
|
828
|
+
EMPTY_HOLD,
|
|
829
|
+
NO_TURN,
|
|
830
|
+
aheadOfDraft,
|
|
183
831
|
canMergeTasks,
|
|
184
832
|
canSetDependencies,
|
|
185
833
|
canSplitTask,
|
|
186
834
|
capConflictFiles,
|
|
187
835
|
dependencyCandidates,
|
|
188
836
|
dependentsOf,
|
|
837
|
+
drainNext,
|
|
838
|
+
followTurn,
|
|
839
|
+
fromTranscript,
|
|
840
|
+
hasHiddenDetail,
|
|
841
|
+
holdPrompt,
|
|
842
|
+
outputLines,
|
|
843
|
+
outputPreview,
|
|
844
|
+
reduceConversation,
|
|
845
|
+
stopTurn,
|
|
189
846
|
summarizeToolCall,
|
|
190
|
-
|
|
847
|
+
taskStartedNotice,
|
|
848
|
+
toolHeadline,
|
|
849
|
+
truncateCheckpointSummary,
|
|
850
|
+
unsendAll,
|
|
851
|
+
unsendLatest
|
|
191
852
|
});
|
|
192
853
|
//# sourceMappingURL=plan-utils.js.map
|