zidane 5.1.22 → 5.2.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/README.md +2 -2
- package/dist/chat.d.ts +138 -4
- package/dist/chat.d.ts.map +1 -1
- package/dist/chat.js +2 -2
- package/dist/{index-D-cTScN3.d.ts → index-BRTRan3z.d.ts} +29 -8
- package/dist/{index-D-cTScN3.d.ts.map → index-BRTRan3z.d.ts.map} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/{login-BXVt5wuA.js → login-D7Tp-K5f.js} +2 -2
- package/dist/{login-BXVt5wuA.js.map → login-D7Tp-K5f.js.map} +1 -1
- package/dist/{presets-tvD28pCu.js → presets-AgF0RFx1.js} +29 -10
- package/dist/presets-AgF0RFx1.js.map +1 -0
- package/dist/presets.d.ts +1 -1
- package/dist/presets.js +1 -1
- package/dist/{tools-CMVruxF0.js → tools-BRbbfdJh.js} +130 -2
- package/dist/tools-BRbbfdJh.js.map +1 -0
- package/dist/tools.d.ts +1 -1
- package/dist/tools.js +1 -1
- package/dist/{transcript-anchors-MFY4ArMh.d.ts → transcript-anchors-GXkj_ox7.d.ts} +11 -2
- package/dist/transcript-anchors-GXkj_ox7.d.ts.map +1 -0
- package/dist/tui.d.ts +1 -1
- package/dist/tui.js +78 -42
- package/dist/tui.js.map +1 -1
- package/dist/{turn-operations-CSlpiiqJ.js → turn-operations-CQTMxSnC.js} +342 -8
- package/dist/turn-operations-CQTMxSnC.js.map +1 -0
- package/dist/types.d.ts +1 -1
- package/docs/CHAT.md +62 -3
- package/docs/SKILL.md +3 -1
- package/package.json +1 -1
- package/dist/presets-tvD28pCu.js.map +0 -1
- package/dist/tools-CMVruxF0.js.map +0 -1
- package/dist/transcript-anchors-MFY4ArMh.d.ts.map +0 -1
- package/dist/turn-operations-CSlpiiqJ.js.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { a as multiEdit, c as grep, d as resolveOldString, f as styleReplacementForVia, i as readFile$1, l as glob, n as createSpawnTool, o as listFiles, r as shell, t as writeFile$1, u as edit } from "./tools-
|
|
1
|
+
import { a as multiEdit, c as grep, d as resolveOldString, f as styleReplacementForVia, i as readFile$1, l as glob, n as createSpawnTool, o as listFiles, r as shell, t as writeFile$1, u as edit } from "./tools-BRbbfdJh.js";
|
|
2
2
|
import { o as errorMessage } from "./errors-COmsomd5.js";
|
|
3
3
|
import { n as toolResultToText } from "./types-IcokUOyC.js";
|
|
4
4
|
import { r as normalizeMcpServers } from "./mcp-B1psg7jf.js";
|
|
5
5
|
import { a as discoverSkills } from "./interpolate-BhmHKD6x.js";
|
|
6
6
|
import { n as formatTokenUsage } from "./stats-DgOvY7wd.js";
|
|
7
|
-
import { n as definePreset } from "./presets-
|
|
7
|
+
import { n as definePreset, t as composePresets } from "./presets-AgF0RFx1.js";
|
|
8
8
|
import { a as writeFileAtomic, i as anthropic, n as openai, r as cerebras, t as openrouter } from "./providers-v1Rn2rqG.js";
|
|
9
9
|
import { spawn } from "node:child_process";
|
|
10
10
|
import { readdir, stat, writeFile } from "node:fs/promises";
|
|
@@ -253,6 +253,296 @@ function joinPrompt(parts) {
|
|
|
253
253
|
return parts.filter((p) => typeof p === "string" && p.length > 0).join("\n\n");
|
|
254
254
|
}
|
|
255
255
|
//#endregion
|
|
256
|
+
//#region src/chat/todos.ts
|
|
257
|
+
const TODOWRITE_TOOL = "todowrite";
|
|
258
|
+
const TODOREAD_TOOL = "todoread";
|
|
259
|
+
/** True when `name` is one of the todo tool canonical names. */
|
|
260
|
+
function isTodoTool(name) {
|
|
261
|
+
return name === "todowrite" || name === "todoread";
|
|
262
|
+
}
|
|
263
|
+
/** `session.metadata[TODOS_METADATA_KEY]: Record<runId, TodoItem[]>` */
|
|
264
|
+
const TODOS_METADATA_KEY = "todosByRun";
|
|
265
|
+
/** `session.metadata[TODO_WRITE_COUNTS_METADATA_KEY]: Record<runId, number>` */
|
|
266
|
+
const TODO_WRITE_COUNTS_METADATA_KEY = "todoWriteCountsByRun";
|
|
267
|
+
const TODO_STATUS_VALUES = [
|
|
268
|
+
"pending",
|
|
269
|
+
"in_progress",
|
|
270
|
+
"completed",
|
|
271
|
+
"cancelled"
|
|
272
|
+
];
|
|
273
|
+
const WRITE_DESCRIPTION = "Replace the active task list. Pass the **full** list of items every call — there is no partial update. Use the `status` field to track progress: `pending` (queued), `in_progress` (currently working), `completed` (done), `cancelled` (no longer relevant).\n\nOnly checkpoint at significant transitions:\n 1. When the user gives you a multi-step task — write the initial plan with everything `pending`.\n 2. When you transition between steps — mark the previous one `completed` and the next one `in_progress`.\n 3. When the user asks for the current status — re-emit the list unchanged so they can see it.\n\nDo NOT call this on every action. The list is for the user's situational awareness, not for self-narrating.";
|
|
274
|
+
const READ_DESCRIPTION = "Return the current active task list (the one most recently written by `todowrite` in this run). Returns an empty list if nothing has been written yet. Use sparingly — you already see the latest list in your own `todowrite` tool_result above.";
|
|
275
|
+
function defaultReminder(count) {
|
|
276
|
+
return `(You've called todowrite ${count} times in this run. Make sure each checkpoint reflects real progress; avoid re-planning every step.)`;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Read the active list for a given run. Returns a fresh `[]` (not stored
|
|
280
|
+
* in metadata) when no slot exists — the caller can mutate the result
|
|
281
|
+
* without affecting state.
|
|
282
|
+
*/
|
|
283
|
+
function getTodosForRun(session, runId) {
|
|
284
|
+
const items = readTodosBag(session)[runId];
|
|
285
|
+
return Array.isArray(items) ? [...items] : [];
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Replace the active list for a given run. Empty arrays don't create a
|
|
289
|
+
* slot — see the file-level "empty-payload guard" note.
|
|
290
|
+
*/
|
|
291
|
+
function setTodosForRun(session, runId, items) {
|
|
292
|
+
const bag = { ...readTodosBag(session) };
|
|
293
|
+
if (items.length === 0) delete bag[runId];
|
|
294
|
+
else bag[runId] = items.map(normalizeItem);
|
|
295
|
+
session.setMeta(TODOS_METADATA_KEY, bag);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Reconcile `session.metadata.todosByRun` against `session.runs`. Drops
|
|
299
|
+
* keys whose runId isn't in the run list. Useful after `session.setRuns()`
|
|
300
|
+
* (fork / restore) or to GC stale metadata mutated by an external caller.
|
|
301
|
+
*
|
|
302
|
+
* Also prunes the parallel counter bag so it doesn't drift.
|
|
303
|
+
*/
|
|
304
|
+
function pruneTodosByRun(session) {
|
|
305
|
+
const validRunIds = new Set(session.runs.map((r) => r.id));
|
|
306
|
+
const dropped = [];
|
|
307
|
+
const bag = readTodosBag(session);
|
|
308
|
+
const nextBag = {};
|
|
309
|
+
for (const [runId, items] of Object.entries(bag)) if (validRunIds.has(runId)) nextBag[runId] = items;
|
|
310
|
+
else dropped.push(runId);
|
|
311
|
+
if (dropped.length > 0) session.setMeta(TODOS_METADATA_KEY, nextBag);
|
|
312
|
+
const counts = readCountsBag(session);
|
|
313
|
+
const nextCounts = {};
|
|
314
|
+
let countsChanged = false;
|
|
315
|
+
for (const [runId, n] of Object.entries(counts)) if (validRunIds.has(runId)) nextCounts[runId] = n;
|
|
316
|
+
else countsChanged = true;
|
|
317
|
+
if (countsChanged) session.setMeta(TODO_WRITE_COUNTS_METADATA_KEY, nextCounts);
|
|
318
|
+
return { dropped };
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Build a `Preset` carrying the `{ todowrite, todoread }` tool pair plus the
|
|
322
|
+
* dedup hasher and per-run write budget that police the model's usage of
|
|
323
|
+
* them.
|
|
324
|
+
*
|
|
325
|
+
* Returning a `Preset` (not a bare tool map) lets the result flow through
|
|
326
|
+
* {@link composePresets} unchanged — todos compose with any other preset
|
|
327
|
+
* the same way every other preset does. `dedupTools` and `toolBudgets` are
|
|
328
|
+
* tool-name-keyed records that `composePresets` deep-merges, so a caller's
|
|
329
|
+
* custom entries for other tools survive the layering, and a caller's
|
|
330
|
+
* override for `todowrite` itself wins by being placed later in the chain.
|
|
331
|
+
*
|
|
332
|
+
* ```ts
|
|
333
|
+
* import { basic, composePresets } from 'zidane/presets'
|
|
334
|
+
* import { createTodoTools } from 'zidane/chat'
|
|
335
|
+
*
|
|
336
|
+
* createAgent({
|
|
337
|
+
* ...composePresets(basic, createTodoTools({ maxWritesPerRun: 6 })),
|
|
338
|
+
* provider,
|
|
339
|
+
* })
|
|
340
|
+
* ```
|
|
341
|
+
*
|
|
342
|
+
* For the trivial "just add the tools to an existing config" case, plain
|
|
343
|
+
* spread is also fine since the returned `Preset` only sets `tools` +
|
|
344
|
+
* `behavior`:
|
|
345
|
+
*
|
|
346
|
+
* ```ts
|
|
347
|
+
* createAgent({ ...basic, ...createTodoTools(), provider })
|
|
348
|
+
* ```
|
|
349
|
+
*/
|
|
350
|
+
function createTodoTools(options = {}) {
|
|
351
|
+
const maxItems = options.maxItems ?? 100;
|
|
352
|
+
const remindAfter = options.remindAfter ?? 3;
|
|
353
|
+
const reminderText = options.reminderText ?? ((count, _items) => defaultReminder(count));
|
|
354
|
+
const dedupIdentical = options.dedupIdentical ?? true;
|
|
355
|
+
const maxWritesPerRun = options.maxWritesPerRun ?? 6;
|
|
356
|
+
const onMaxWrites = options.onMaxWrites ?? "steer";
|
|
357
|
+
const tools = {
|
|
358
|
+
[TODOWRITE_TOOL]: createTodoWriteTool({
|
|
359
|
+
maxItems,
|
|
360
|
+
remindAfter,
|
|
361
|
+
reminderText,
|
|
362
|
+
description: options.writeDescription ?? WRITE_DESCRIPTION
|
|
363
|
+
}),
|
|
364
|
+
[TODOREAD_TOOL]: createTodoReadTool({ description: options.readDescription ?? READ_DESCRIPTION })
|
|
365
|
+
};
|
|
366
|
+
const behavior = {};
|
|
367
|
+
if (dedupIdentical) behavior.dedupTools = { [TODOWRITE_TOOL]: dedupTodoWriteInput };
|
|
368
|
+
if (maxWritesPerRun > 0) behavior.toolBudgets = { [TODOWRITE_TOOL]: {
|
|
369
|
+
max: maxWritesPerRun,
|
|
370
|
+
onExceed: onMaxWrites
|
|
371
|
+
} };
|
|
372
|
+
return definePreset(Object.keys(behavior).length > 0 ? {
|
|
373
|
+
tools,
|
|
374
|
+
behavior
|
|
375
|
+
} : { tools });
|
|
376
|
+
}
|
|
377
|
+
function createTodoWriteTool(opts) {
|
|
378
|
+
return {
|
|
379
|
+
spec: {
|
|
380
|
+
name: TODOWRITE_TOOL,
|
|
381
|
+
description: opts.description,
|
|
382
|
+
inputSchema: {
|
|
383
|
+
type: "object",
|
|
384
|
+
properties: { todos: {
|
|
385
|
+
type: "array",
|
|
386
|
+
description: "The complete task list. Replaces the prior list in full.",
|
|
387
|
+
maxItems: opts.maxItems,
|
|
388
|
+
items: {
|
|
389
|
+
type: "object",
|
|
390
|
+
properties: {
|
|
391
|
+
id: {
|
|
392
|
+
type: "string",
|
|
393
|
+
description: "Stable identifier (the model picks)."
|
|
394
|
+
},
|
|
395
|
+
content: {
|
|
396
|
+
type: "string",
|
|
397
|
+
description: "One-line task summary."
|
|
398
|
+
},
|
|
399
|
+
status: {
|
|
400
|
+
type: "string",
|
|
401
|
+
enum: [...TODO_STATUS_VALUES],
|
|
402
|
+
description: "`pending`, `in_progress`, `completed`, or `cancelled`."
|
|
403
|
+
}
|
|
404
|
+
},
|
|
405
|
+
required: [
|
|
406
|
+
"id",
|
|
407
|
+
"content",
|
|
408
|
+
"status"
|
|
409
|
+
]
|
|
410
|
+
}
|
|
411
|
+
} },
|
|
412
|
+
required: ["todos"]
|
|
413
|
+
}
|
|
414
|
+
},
|
|
415
|
+
async execute(input, ctx) {
|
|
416
|
+
const { session, runId } = requireSessionAndRun(ctx, TODOWRITE_TOOL);
|
|
417
|
+
const rawItems = Array.isArray(input.todos) ? input.todos : [];
|
|
418
|
+
const items = sanitizeItems(rawItems, opts.maxItems);
|
|
419
|
+
const dropped = rawItems.length - items.length;
|
|
420
|
+
const byId = /* @__PURE__ */ new Map();
|
|
421
|
+
for (const item of items) byId.set(item.id, item);
|
|
422
|
+
const normalized = [...byId.values()];
|
|
423
|
+
setTodosForRun(session, runId, normalized);
|
|
424
|
+
const count = incrementCount(session, runId);
|
|
425
|
+
const lines = [];
|
|
426
|
+
lines.push(`Updated ${normalized.length} todo item${normalized.length === 1 ? "" : "s"}.`);
|
|
427
|
+
const tally = summarizeStatuses(normalized);
|
|
428
|
+
if (tally) lines.push(tally);
|
|
429
|
+
if (dropped > 0) lines.push(`Dropped ${dropped} malformed item${dropped === 1 ? "" : "s"}.`);
|
|
430
|
+
const reminder = opts.remindAfter > 0 && count >= opts.remindAfter ? opts.reminderText(count, normalized) : void 0;
|
|
431
|
+
if (reminder && reminder.length > 0) lines.push(reminder);
|
|
432
|
+
return lines.join("\n");
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
function createTodoReadTool(opts) {
|
|
437
|
+
return {
|
|
438
|
+
spec: {
|
|
439
|
+
name: TODOREAD_TOOL,
|
|
440
|
+
description: opts.description,
|
|
441
|
+
inputSchema: {
|
|
442
|
+
type: "object",
|
|
443
|
+
properties: {}
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
async execute(_input, ctx) {
|
|
447
|
+
const { session, runId } = requireSessionAndRun(ctx, TODOREAD_TOOL);
|
|
448
|
+
const items = getTodosForRun(session, runId);
|
|
449
|
+
if (items.length === 0) return "No todos yet — call todowrite to start tracking tasks.";
|
|
450
|
+
return JSON.stringify({ todos: items });
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Both tool bodies need a `Session` + `runId`. Centralize the guards so the
|
|
456
|
+
* error messages stay symmetric and one fix lands in both places.
|
|
457
|
+
*/
|
|
458
|
+
function requireSessionAndRun(ctx, toolName) {
|
|
459
|
+
if (!ctx.session) throw new Error(`${toolName}: no session on tool context — todos require a session via createSession().`);
|
|
460
|
+
if (!ctx.runId) throw new Error(`${toolName}: no runId on tool context.`);
|
|
461
|
+
return {
|
|
462
|
+
session: ctx.session,
|
|
463
|
+
runId: ctx.runId
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
function readTodosBag(session) {
|
|
467
|
+
const raw = session.metadata[TODOS_METADATA_KEY];
|
|
468
|
+
if (!raw || typeof raw !== "object") return {};
|
|
469
|
+
return raw;
|
|
470
|
+
}
|
|
471
|
+
function readCountsBag(session) {
|
|
472
|
+
const raw = session.metadata[TODO_WRITE_COUNTS_METADATA_KEY];
|
|
473
|
+
if (!raw || typeof raw !== "object") return {};
|
|
474
|
+
return raw;
|
|
475
|
+
}
|
|
476
|
+
function incrementCount(session, runId) {
|
|
477
|
+
const bag = { ...readCountsBag(session) };
|
|
478
|
+
const next = (bag[runId] ?? 0) + 1;
|
|
479
|
+
bag[runId] = next;
|
|
480
|
+
session.setMeta(TODO_WRITE_COUNTS_METADATA_KEY, bag);
|
|
481
|
+
return next;
|
|
482
|
+
}
|
|
483
|
+
function normalizeItem(item) {
|
|
484
|
+
return {
|
|
485
|
+
id: item.id,
|
|
486
|
+
content: item.content,
|
|
487
|
+
status: item.status
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
function sanitizeItems(raw, cap) {
|
|
491
|
+
const out = [];
|
|
492
|
+
for (const item of raw) {
|
|
493
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) continue;
|
|
494
|
+
const obj = item;
|
|
495
|
+
const id = typeof obj.id === "string" ? obj.id : void 0;
|
|
496
|
+
const content = typeof obj.content === "string" ? obj.content : void 0;
|
|
497
|
+
const status = typeof obj.status === "string" && TODO_STATUS_VALUES.includes(obj.status) ? obj.status : void 0;
|
|
498
|
+
if (!id || !content || !status) continue;
|
|
499
|
+
out.push({
|
|
500
|
+
id,
|
|
501
|
+
content,
|
|
502
|
+
status
|
|
503
|
+
});
|
|
504
|
+
if (out.length >= cap) break;
|
|
505
|
+
}
|
|
506
|
+
return out;
|
|
507
|
+
}
|
|
508
|
+
function summarizeStatuses(items) {
|
|
509
|
+
if (items.length === 0) return void 0;
|
|
510
|
+
const counts = {
|
|
511
|
+
pending: 0,
|
|
512
|
+
in_progress: 0,
|
|
513
|
+
completed: 0,
|
|
514
|
+
cancelled: 0
|
|
515
|
+
};
|
|
516
|
+
for (const item of items) counts[item.status] += 1;
|
|
517
|
+
const parts = [];
|
|
518
|
+
if (counts.completed) parts.push(`${counts.completed} completed`);
|
|
519
|
+
if (counts.in_progress) parts.push(`${counts.in_progress} in progress`);
|
|
520
|
+
if (counts.pending) parts.push(`${counts.pending} pending`);
|
|
521
|
+
if (counts.cancelled) parts.push(`${counts.cancelled} cancelled`);
|
|
522
|
+
return parts.length > 0 ? parts.join(" · ") : void 0;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Hasher for {@link import('../types').AgentBehavior.dedupTools}.
|
|
526
|
+
* Returns a stable digest of the items list so identical re-writes hit
|
|
527
|
+
* cache. Order-sensitive on purpose: re-ordering the list is a meaningful
|
|
528
|
+
* state change ("the model reprioritized") and should NOT collapse.
|
|
529
|
+
*
|
|
530
|
+
* Returns `undefined` (the documented opt-out) when the input doesn't
|
|
531
|
+
* look like a todowrite payload, so a malformed call always re-runs.
|
|
532
|
+
*/
|
|
533
|
+
function dedupTodoWriteInput(input) {
|
|
534
|
+
const todos = input.todos;
|
|
535
|
+
if (!Array.isArray(todos)) return void 0;
|
|
536
|
+
const parts = [];
|
|
537
|
+
for (const item of todos) {
|
|
538
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return void 0;
|
|
539
|
+
const obj = item;
|
|
540
|
+
if (typeof obj.id !== "string" || typeof obj.content !== "string" || typeof obj.status !== "string") return void 0;
|
|
541
|
+
parts.push(`${obj.id}\u0000${obj.status}\u0000${obj.content}`);
|
|
542
|
+
}
|
|
543
|
+
return parts.join("");
|
|
544
|
+
}
|
|
545
|
+
//#endregion
|
|
256
546
|
//#region src/chat/agents.ts
|
|
257
547
|
/**
|
|
258
548
|
* Resolve a profile's `accent` token to a concrete hex color via the
|
|
@@ -314,7 +604,9 @@ const DEFAULT_PERSIST_EXCLUDE_TOOLS = [
|
|
|
314
604
|
"skills_read",
|
|
315
605
|
"present_plan",
|
|
316
606
|
"ask_user",
|
|
317
|
-
"spawn"
|
|
607
|
+
"spawn",
|
|
608
|
+
"todowrite",
|
|
609
|
+
"todoread"
|
|
318
610
|
];
|
|
319
611
|
/**
|
|
320
612
|
* Token-saving `AgentBehavior` defaults shared by the built-in profiles.
|
|
@@ -370,7 +662,7 @@ const BUILD_AGENT = {
|
|
|
370
662
|
label: "Build",
|
|
371
663
|
description: "full tool access — read, write, edit, shell, and spawn subagents",
|
|
372
664
|
accent: "accent",
|
|
373
|
-
preset: definePreset({
|
|
665
|
+
preset: composePresets(definePreset({
|
|
374
666
|
name: "build",
|
|
375
667
|
system: buildBuildSystem(),
|
|
376
668
|
behavior: { ...SHARED_BEHAVIOR },
|
|
@@ -378,7 +670,7 @@ const BUILD_AGENT = {
|
|
|
378
670
|
...BUILD_TOOLS,
|
|
379
671
|
spawn: createSpawnTool({ persist: true })
|
|
380
672
|
}
|
|
381
|
-
})
|
|
673
|
+
}), createTodoTools())
|
|
382
674
|
};
|
|
383
675
|
/**
|
|
384
676
|
* Plan agent — read-only exploration mode. Locked down to file reading and
|
|
@@ -2926,6 +3218,15 @@ function selectableTurnIds(events, settings) {
|
|
|
2926
3218
|
* after a session ends mid-spawn would be misleading. The next prompt
|
|
2927
3219
|
* feeds the parent, so the parent's last view is what matters.
|
|
2928
3220
|
*
|
|
3221
|
+
* Zero-context placeholder turns are also skipped. `executeTurn`
|
|
3222
|
+
* synthesizes an assistant turn with `usage: { input: 0, output: 0 }`
|
|
3223
|
+
* when the provider stream throws / aborts before any usage is reported
|
|
3224
|
+
* (see `src/loop.ts`'s catch path) — that turn is purely a shape
|
|
3225
|
+
* contract for resume, not a real context-window measurement. Without
|
|
3226
|
+
* the skip, an abort mid-stream shadows the prior real turn and the
|
|
3227
|
+
* footer reads `ctx 0` on the next session load even though earlier
|
|
3228
|
+
* turns accumulated meaningful context (and `run.cost`).
|
|
3229
|
+
*
|
|
2929
3230
|
* `runs` is optional for backwards compatibility (older call sites and
|
|
2930
3231
|
* tests that don't have ancestry info). Without it, this falls back to the
|
|
2931
3232
|
* pre-fix behavior — depth is unknown so every assistant turn qualifies.
|
|
@@ -2937,7 +3238,9 @@ function lastContextSizeFromTurns(turns, runs = []) {
|
|
|
2937
3238
|
const turn = turns[i];
|
|
2938
3239
|
if (turn.role !== "assistant" || !turn.usage) continue;
|
|
2939
3240
|
if (turn.runId && childRunIds.has(turn.runId)) continue;
|
|
2940
|
-
|
|
3241
|
+
const size = (turn.usage.input ?? 0) + (turn.usage.cacheRead ?? 0) + (turn.usage.cacheCreation ?? 0);
|
|
3242
|
+
if (size === 0) continue;
|
|
3243
|
+
return size;
|
|
2941
3244
|
}
|
|
2942
3245
|
return 0;
|
|
2943
3246
|
}
|
|
@@ -7033,6 +7336,37 @@ const TOOL_DISPLAY = {
|
|
|
7033
7336
|
};
|
|
7034
7337
|
}
|
|
7035
7338
|
},
|
|
7339
|
+
todowrite: {
|
|
7340
|
+
displayName: "Todos",
|
|
7341
|
+
format: (input) => {
|
|
7342
|
+
const todos = Array.isArray(input.todos) ? input.todos : null;
|
|
7343
|
+
if (!todos) return null;
|
|
7344
|
+
const counts = {
|
|
7345
|
+
pending: 0,
|
|
7346
|
+
in_progress: 0,
|
|
7347
|
+
completed: 0,
|
|
7348
|
+
cancelled: 0
|
|
7349
|
+
};
|
|
7350
|
+
for (const t of todos) {
|
|
7351
|
+
if (!t || typeof t !== "object") continue;
|
|
7352
|
+
const status = t.status;
|
|
7353
|
+
if (typeof status === "string" && status in counts) counts[status] += 1;
|
|
7354
|
+
}
|
|
7355
|
+
const meta = [];
|
|
7356
|
+
if (counts.completed) meta.push(`${counts.completed} done`);
|
|
7357
|
+
if (counts.in_progress) meta.push(`${counts.in_progress} in progress`);
|
|
7358
|
+
if (counts.pending) meta.push(`${counts.pending} pending`);
|
|
7359
|
+
if (counts.cancelled) meta.push(`${counts.cancelled} cancelled`);
|
|
7360
|
+
return {
|
|
7361
|
+
target: `${todos.length} item${todos.length === 1 ? "" : "s"}`,
|
|
7362
|
+
meta
|
|
7363
|
+
};
|
|
7364
|
+
}
|
|
7365
|
+
},
|
|
7366
|
+
todoread: {
|
|
7367
|
+
displayName: "Todos",
|
|
7368
|
+
format: () => ({ target: "read" })
|
|
7369
|
+
},
|
|
7036
7370
|
ask_user: {
|
|
7037
7371
|
displayName: "Ask user",
|
|
7038
7372
|
format: (input) => {
|
|
@@ -7277,6 +7611,6 @@ function countNeighbors(turnIds, turnId) {
|
|
|
7277
7611
|
};
|
|
7278
7612
|
}
|
|
7279
7613
|
//#endregion
|
|
7280
|
-
export { useMcpAuthDispatch as $, bootTick as $n, isVisible as $t, getSafelist as A, KEYBINDING_DEF_BY_ACTION as An,
|
|
7614
|
+
export { useMcpAuthDispatch as $, bootTick as $n, isVisible as $t, getSafelist as A, KEYBINDING_DEF_BY_ACTION as An, TODOREAD_TOOL as Ar, clampFps as At, supportsOAuth as B, uniqueSkillNamesFromReferences as Bn, COMMUNICATION_DOCTRINE as Br, CATPPUCCIN_MOCHA as Bt, resolveSessionExportTarget as C, maskToOutcomeKinds as Cn, BUILTIN_AGENTS as Cr, shortId as Ct, useSafeModeQueue as D, findGitRoot$1 as Dn, accentColor as Dr, SETTINGS_CHOICES as Dt, useSafeModeActions as E, summarizeOutcomes as En, PLAN_AGENT as Er, DEFAULT_SETTINGS as Et, suggestSafelistEntry as F, parseBindingSpec as Fn, getTodosForRun as Fr, resolveTheme as Ft, defaultMcpsConfigPaths as G, collectReferences as Gn, PLAN_MODE_DOCTRINE as Gr, ConfigProvider as Gt, filterModelCatalog as H, createFilesCompletionProvider as Hn, IDENTITY_PREFIX as Hr, DiscoveryProvider as Ht, writeProjects as I, readKeybindings as In, isTodoTool as Ir, VAPORWAVE_THEME as It, projectUserPaths as J, useCompletion as Jn, TOKEN_DISCIPLINE_DOCTRINE as Jr, createStateStore as Jt, discoverProjectMcps as K, findActiveTrigger as Kn, PLAN_MODE_DOCTRINE_NO_PROMPTS as Kr, useConfig as Kt, splitPromptSegments as L, stripJsonComments as Ln, pruneTodosByRun as Lr, CATPPUCCIN_FRAPPE as Lt, matchesSafelistEntry as M, keybindingsPath as Mn, TODOWRITE_TOOL as Mr, BUILTIN_THEMES as Mt, projectsFilePath as N, matchesBinding as Nn, TODO_WRITE_COUNTS_METADATA_KEY as Nr, DEFAULT_THEME as Nt, IMPLICITLY_SAFE_TOOLS as O, DEFAULT_KEYBINDINGS as On, resolveAgentId as Or, SETTINGS_TOGGLES as Ot, readProjects as P, mergeKeybindings as Pn, createTodoTools as Pr, resolveChipColor as Pt, McpAuthProvider as Q, bootProfileEnabled as Qn, isTurnHighlighted as Qt, formatPathForCwd as R, SKILLS_TRIGGER as Rn, setTodosForRun as Rr, CATPPUCCIN_LATTE as Rt, renderSession as S, buildEditOutcomesAnnotation as Sn, BUILD_AGENT as Sr, fmtTokens as St, SafeModeProvider as T, resolveApprovalForPayload as Tn, DEFAULT_PERSIST_EXCLUDE_TOOLS as Tr, useEnabledToggleSet as Tt, indexOfEntry as U, uniqueFilesFromReferences as Un, INTERACTION_GUIDANCE as Ur, useDiscovery as Ut, buildModelCatalog as V, FILES_TRIGGER as Vn, DOING_TASKS_DOCTRINE as Vr, createDiscoverySlot as Vt, buildMcpServers as W, applyInsert as Wn, INTERACTION_GUIDANCE_NO_PROMPTS as Wr, useDiscoveryOptional as Wt, mcpCredentialsPath as X, buildLinearRamp as Xn, buildPlanSystem as Xr, eventsFromTurns as Xt, createFileMcpCredentialStore as Y, blendHsl as Yn, buildBuildSystem as Yr, deriveSessionTitle as Yt, patchMcpCredential as Z, tryOpenBrowser as Zn, envSection as Zr, isEditErrorResult as Zt, turnContextSize as _, extractEditPayload as _n, modelSupportsReasoning as _r, truncateTrailing as _t, computeTurnAnchors as a, selectableTurnIds as an, readProviderCredential as ar, InteractionsProvider as at, defaultSkillScanPaths as b, splitLines as bn, openrouterDescriptor as br, ageString as bt, formatToolCall as c, titleFromTurns as cn, writeCredentials as cr, createInteractionTools as ct, useSelectStyle as d, turnSelectionOwnership as dn, anthropicDescriptor as dr, pendingInteractionsFromTurns as dt, lastContextSizeFromTurns as en, shouldAutoCompact as er, useMcpAuthState as et, useSurfaces as f, applyEditPayload as fn, cerebrasDescriptor as fr, serializeInteractionResponse as ft, finalizeStreamingMarkdownForOwner as g, computeLineDiff as gn, getModelInfo as gr, hintsLength as gt, finalizeStreamingMarkdown as h, computeInlineDiff as hn, getContextWindow as hr, clipHintsToWidth as ht, turnAsText as i, saveState as in, readCredentials as ir, ASK_USER_TOOL as it, isOnSafelist as j, ensureKeybindingsFile as jn, TODOS_METADATA_KEY as jr, useSettings as jt, addToSafelist as k, KEYBINDING_DEFS as kn, singleAgentRegistry as kr, SettingsProvider as kt, ThemeProvider as l, toolCallPreview as ln, BUILTIN_PROVIDERS as lr, isInteractionTool as lt, useTheme as m, buildUnifiedDiff as mn, effectiveContextWindow as mr, useInteractionsQueue as mt, deleteTurnSafely as n, loadState as nn, applyApiKeyEnv as nr, reduceMcpAuth as nt, TOOL_DISPLAY as o, stripSpawnTokensLine as on, removeProviderCredential as or, PRESENT_PLAN_TOOL as ot, useSyntaxStyles as p, buildContextualDiff as pn, credKeyOf as pr, useInteractionsActions as pt, parseMcpsFile as q, mergeReferences as qn, SUBAGENT_GUIDANCE as qr, resolveConfig as qt, truncateTurnsAt as r, marginTopFor as rn, credentialsPath as rr, splitMarkdownCodeBlocks as rt, displayNameFor as s, sumRunCosts as sn, setProviderCredential as sr, buildResumedToolResultsTurn as st, countNeighbors as t, listSessionMeta as tn, detectAuth as tr, getMcpAuthStatus as tt, useColors as u, toolResultText as un, OUTPUT_RESERVE_TOKENS as ur, makeRequestInteraction as ut, useStreamBuffer as v, filetypeFromPath as vn, modelsForDescriptor as vr, cleanTitle as vt, writeSessionExport as w, parseEditOutcomesFromResult as wn, DEFAULT_AGENT_ID as wr, listProjectFiles as wt, discoverProjectSkills as x, tokenize as xn, piIdOf as xr, compactPath as xt, buildSkillsConfig as y, previewEditPayload as yn, openaiDescriptor as yr, generateSessionTitle as yt, runOAuthLogin as z, createSkillsCompletionProvider as zn, ACTIONS_WITH_CARE_DOCTRINE as zr, CATPPUCCIN_MACCHIATO as zt };
|
|
7281
7615
|
|
|
7282
|
-
//# sourceMappingURL=turn-operations-
|
|
7616
|
+
//# sourceMappingURL=turn-operations-CQTMxSnC.js.map
|