mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-08-15 19:55:36 +00:00
feat(agent-core-v2): add spine_trim and spine_spawn experimental tools
spine_trim: model-driven tool-response trimming as a pure derivation over the message stream. Tool results over 10 KiB (non-spine, text-only) carry a byte-stable TRIM_ID tag; the model can snip or slice (head/tail/anchor) the immediately preceding tool-result batch. Host validation shares the single eligibility derivation with rendering; consumed, out-of-window, or unknown ids reject with do-not-retry. Gated on KIMI_CODE_SPINE + KIMI_CODE_SPINE_TRIM. spine_spawn: fission the current node into >=2 concurrent forked branches (lifecycle.fork plus trailing tool-call batch trim) and join their terminal memories as closed child nodes synthesized from the structured spine.spawn.result.v1 receipt in the message stream. All-or-nothing capacity admission (default 4 threads including main, override via KIMI_CODE_SPINE_SPAWN_MAX_THREADS), whole-batch abort on start failure, guaranteed branch release. Gated on KIMI_CODE_SPINE + KIMI_CODE_SPINE_SPAWN. Also adds legacyReplay regression coverage: five sanitized real old-session wire logs restore with zero unknown-op skips, pinning op-replay vs pure-derivation equivalence and the documented historical divergences (receipt anchors, assembled memory bodies, undo witness erasure).
This commit is contained in:
parent
e065fed7e2
commit
52dfd155d8
27 changed files with 6514 additions and 56 deletions
|
|
@ -28,14 +28,19 @@ const DEFAULT_APPROVE_TOOLS = new Set([
|
|||
'UpdateGoal',
|
||||
// Spine task-tree control tools are receipt-only transitions of the model's
|
||||
// own task state (the real tree move is committed by the spine service on
|
||||
// observed evidence) and fire once per node boundary. They register only
|
||||
// when `KIMI_CODE_SPINE` is set (`registerTool(..., { when })`), so these
|
||||
// names are inert with the experiment off; asking per call would make the
|
||||
// spine workflow unusable.
|
||||
// observed evidence) and fire once per node boundary; spine_trim is likewise
|
||||
// receipt-only (the accepted receipt IS the trim, validated by the host
|
||||
// against the derived eligibility window). spine_spawn is receipt-only too:
|
||||
// the structured receipt IS the join, and the host validates capacity before
|
||||
// forking any child agents. They register only when the relevant flags are set
|
||||
// (`registerTool(..., { when })`), so these names are inert with the
|
||||
// experiment off; asking per call would make the spine workflow unusable.
|
||||
'spine_open',
|
||||
'spine_close',
|
||||
'spine_next',
|
||||
'spine_tree',
|
||||
'spine_trim',
|
||||
'spine_spawn',
|
||||
'select_tools',
|
||||
]);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,3 +31,49 @@ export const spineFlag: FlagDefinitionInput = {
|
|||
};
|
||||
|
||||
registerFlagDefinition(spineFlag);
|
||||
|
||||
export const SPINE_TRIM_FLAG_ID = 'spine_trim';
|
||||
export const SPINE_TRIM_FLAG_ENV = 'KIMI_CODE_SPINE_TRIM';
|
||||
|
||||
/**
|
||||
* Gates the tool-response trim projection: oversized tool results carry a
|
||||
* stable `TRIM_ID` tag and the model can conservatively snip / slice them out
|
||||
* of the projected context via `spine_trim`. The stored history is never
|
||||
* rewritten. Requires the spine flag (the fold is integrated into the spine
|
||||
* projector fold), and keeps `ignoreMaster: true` for the same reason.
|
||||
*/
|
||||
export const spineTrimFlag: FlagDefinitionInput = {
|
||||
id: SPINE_TRIM_FLAG_ID,
|
||||
title: 'Spine trim (tool-response trimming)',
|
||||
description:
|
||||
'Tag oversized tool results with a stable TRIM_ID and let the model conservatively trim them from the projected context (spine_trim); the stored history is never rewritten. Requires the spine flag.',
|
||||
env: SPINE_TRIM_FLAG_ENV,
|
||||
default: false,
|
||||
surface: 'core',
|
||||
ignoreMaster: true,
|
||||
};
|
||||
|
||||
registerFlagDefinition(spineTrimFlag);
|
||||
|
||||
export const SPINE_SPAWN_FLAG_ID = 'spine_spawn';
|
||||
export const SPINE_SPAWN_FLAG_ENV = 'KIMI_CODE_SPINE_SPAWN';
|
||||
|
||||
/**
|
||||
* Gates the `spine_spawn` parallel branch fission experiment: the model can
|
||||
* split the current continuation into N independent child agents, each running
|
||||
* its own prompt and returning terminal memory. Requires the spine flag (the
|
||||
* spawn fold is integrated into the spine projector fold) and keeps
|
||||
* `ignoreMaster: true` for the same reason as the other spine flags.
|
||||
*/
|
||||
export const spineSpawnFlag: FlagDefinitionInput = {
|
||||
id: SPINE_SPAWN_FLAG_ID,
|
||||
title: 'Spine spawn (parallel branch fission)',
|
||||
description:
|
||||
'Experimental parallel branch fission via spine_spawn: split the current continuation into independent child agents, each returning terminal memory. Requires the spine flag.',
|
||||
env: SPINE_SPAWN_FLAG_ENV,
|
||||
default: false,
|
||||
surface: 'core',
|
||||
ignoreMaster: true,
|
||||
};
|
||||
|
||||
registerFlagDefinition(spineSpawnFlag);
|
||||
|
|
|
|||
|
|
@ -13,9 +13,13 @@ export * from './spineDerive';
|
|||
export * from './spineOps';
|
||||
export * from './spineService';
|
||||
export * from './spineTree';
|
||||
export * from './spineTrimDerive';
|
||||
export * from './spineTrimFold';
|
||||
export * from './tools/controlResult';
|
||||
export * from './tools/descriptions';
|
||||
export * from './tools/spine-close';
|
||||
export * from './tools/spine-next';
|
||||
export * from './tools/spine-open';
|
||||
export * from './tools/spine-spawn';
|
||||
export * from './tools/spine-tree';
|
||||
export * from './tools/spine-trim';
|
||||
|
|
|
|||
|
|
@ -17,23 +17,30 @@ import type { ContextMessage } from '#/agent/contextMemory/types';
|
|||
|
||||
import type { SpineEpochArchiveInput } from './spineArchive';
|
||||
import type { SpineState } from './spineOps';
|
||||
import type { SpineTrimOp } from './spineTrimDerive';
|
||||
|
||||
export const SPINE_TOOL_OPEN = 'spine_open';
|
||||
export const SPINE_TOOL_CLOSE = 'spine_close';
|
||||
export const SPINE_TOOL_NEXT = 'spine_next';
|
||||
export const SPINE_TOOL_TREE = 'spine_tree';
|
||||
export const SPINE_TOOL_TRIM = 'spine_trim';
|
||||
export const SPINE_TOOL_SPAWN = 'spine_spawn';
|
||||
|
||||
/**
|
||||
* All four spine control tool names. Profiles whitelist these so the main
|
||||
* agent's active-tool filter lets the registered tools through; surfaces that
|
||||
* merely display a profile's tool list (e.g. the `Agent` tool description)
|
||||
* filter them out instead, since the tools register only for the main agent.
|
||||
* All six spine tool names. Profiles whitelist these so the main agent's
|
||||
* active-tool filter lets the registered tools through; surfaces that merely
|
||||
* display a profile's tool list (e.g. the `Agent` tool description) filter
|
||||
* them out instead, since the tools register only for the main agent.
|
||||
* `spine_trim` and `spine_spawn` are NOT control tools: they carry no tree
|
||||
* transition and are gated on separate flags.
|
||||
*/
|
||||
export const SPINE_TOOL_NAMES = [
|
||||
SPINE_TOOL_OPEN,
|
||||
SPINE_TOOL_CLOSE,
|
||||
SPINE_TOOL_NEXT,
|
||||
SPINE_TOOL_TREE,
|
||||
SPINE_TOOL_TRIM,
|
||||
SPINE_TOOL_SPAWN,
|
||||
] as const;
|
||||
|
||||
export type SpineControlToolName =
|
||||
|
|
@ -41,6 +48,11 @@ export type SpineControlToolName =
|
|||
| typeof SPINE_TOOL_CLOSE
|
||||
| typeof SPINE_TOOL_NEXT;
|
||||
|
||||
export interface SpineSpawnTaskInput {
|
||||
readonly summary: string;
|
||||
readonly prompt: string;
|
||||
}
|
||||
|
||||
export interface SpineTransitionAccepted {
|
||||
readonly accepted: true;
|
||||
}
|
||||
|
|
@ -61,6 +73,26 @@ export interface IAgentSpineService {
|
|||
acceptClose(memory: string): SpineTransitionResult;
|
||||
acceptNext(summary: string, memory: string): SpineTransitionResult;
|
||||
|
||||
/**
|
||||
* Validates a `spine_trim` call against the derived trim projection (the
|
||||
* single eligibility source): unknown, consumed, out-of-window, or
|
||||
* anchor-missing ids reject with a do-not-retry reason. Not a transition —
|
||||
* no per-step budget; the accepted receipt in history IS the trim.
|
||||
*/
|
||||
acceptTrim(trimId: string, op: SpineTrimOp): SpineTransitionResult;
|
||||
|
||||
/**
|
||||
* Executes a `spine_spawn` fission: forks one child agent per task, runs them
|
||||
* in parallel, and returns a structured JSON receipt. The receipt landing in
|
||||
* history IS the join; derive synthesizes the closed child nodes from it.
|
||||
* Rejected results surface capacity/validation reasons as errors so the model
|
||||
* can retry.
|
||||
*/
|
||||
executeSpawn(
|
||||
tasks: readonly SpineSpawnTaskInput[],
|
||||
signal: AbortSignal,
|
||||
): Promise<SpineTransitionResult & { readonly receipt?: string }>;
|
||||
|
||||
archiveEpochRoot(input: SpineEpochArchiveInput): Promise<string | undefined>;
|
||||
|
||||
renderTree(): string;
|
||||
|
|
|
|||
|
|
@ -12,15 +12,20 @@
|
|||
* sessions; persisted metadata can degrade, so the match is textual and a
|
||||
* near-miss does not count — and replays the transitions under the same
|
||||
* guards the legacy ops enforced (cursor position, non-empty bodies, root
|
||||
* epochs never close). Root-epoch boundaries come from the compaction summary
|
||||
* message itself (`origin.kind === 'compaction_summary'`, with the summary
|
||||
* prefix text as the fallback carrier when the origin metadata is absent). A
|
||||
* closing node's memory is the model-written body verbatim: the projection
|
||||
* fold re-materializes the span's surviving user requests and each closed
|
||||
* child's own `<spine_memory node_id="...">` slot from the surviving stream,
|
||||
* so an undo that rewrites the span rewrites the folded view with it — the
|
||||
* memory itself never needs patching. Consumed by `spineService`; the fold
|
||||
* projection and archive rendering read this state.
|
||||
* epochs never close). A `spine_spawn` call whose structured JSON receipt lands
|
||||
* in history synthesizes N closed sibling nodes under the current cursor in
|
||||
* input order; every sibling shares the receipt message as a point span
|
||||
* (`openedAt === closedAt === receipt index`), so the first sibling's span
|
||||
* absorbs the receipt tool message and the carrier stays visible in the parent
|
||||
* context. Root-epoch boundaries come from the compaction summary message
|
||||
* itself (`origin.kind === 'compaction_summary'`, with the summary prefix text
|
||||
* as the fallback carrier when the origin metadata is absent). A closing node's
|
||||
* memory is the model-written body verbatim: the projection fold re-materializes
|
||||
* the span's surviving user requests and each closed child's own
|
||||
* `<spine_memory node_id="...">` slot from the surviving stream, so an undo
|
||||
* that rewrites the span rewrites the folded view with it — the memory itself
|
||||
* never needs patching. Consumed by `spineService`; the fold projection and
|
||||
* archive rendering read this state.
|
||||
*
|
||||
* Silence is the design, not an oversight: a call whose accepted receipt never
|
||||
* landed, a receipt whose call is missing, or a transition the guards reject
|
||||
|
|
@ -28,7 +33,9 @@
|
|||
* no lost-commit audit and no repair op. The stream is the whole truth, so a
|
||||
* transition the stream does not fully witness is not a transition — the
|
||||
* legacy op world needed `reportLostCommits` precisely because it kept a
|
||||
* second record that could disagree with the receipts.
|
||||
* second record that could disagree with the receipts. `spine_spawn` receipts
|
||||
* are all-or-nothing in the same spirit: a malformed or partially-invalid
|
||||
* receipt is ignored entirely, synthesizing zero nodes.
|
||||
*/
|
||||
|
||||
import {
|
||||
|
|
@ -38,7 +45,7 @@ import {
|
|||
import type { ContextMessage } from '#/agent/contextMemory/types';
|
||||
|
||||
import { SPINE_TOOL_CLOSE, SPINE_TOOL_NEXT, SPINE_TOOL_OPEN } from './spine';
|
||||
import type { SpineNode, SpineState } from './spineOps';
|
||||
import type { SpineNode, SpineSpawnEvidence, SpineState } from './spineOps';
|
||||
import {
|
||||
childNodeId,
|
||||
epochStartupNodeId,
|
||||
|
|
@ -52,8 +59,12 @@ import { ACCEPTED_OUTPUT } from './tools/controlResult';
|
|||
/** Receipt left by sessions predating the delayed-commit receipt wording. */
|
||||
const LEGACY_ACCEPTED_RECEIPT = 'accepted';
|
||||
|
||||
/** Tool name for the parallel-branch spawn control call. */
|
||||
const SPINE_TOOL_SPAWN = 'spine_spawn';
|
||||
|
||||
export function deriveSpineState(messages: readonly ContextMessage[]): SpineState {
|
||||
const accepted = collectAcceptedCallIds(messages);
|
||||
const spawnReceipts = collectSpawnReceipts(messages);
|
||||
const nodes: Record<string, SpineNode> = {};
|
||||
let openStack: readonly string[] = [];
|
||||
let rootEpoch = 0;
|
||||
|
|
@ -137,6 +148,38 @@ export function deriveSpineState(messages: readonly ContextMessage[]): SpineStat
|
|||
openStack = [...openStack.slice(0, -1), openedId];
|
||||
}
|
||||
|
||||
function spawnNodes(parentId: string, spawn: SpawnReceiptInfo): void {
|
||||
const parent = nodes[parentId];
|
||||
if (parent === undefined || parent.closedAt !== undefined) return;
|
||||
const receiptAt = spawn.receiptAt;
|
||||
let childIndex = nextChildIndex(parent.children);
|
||||
const newChildren: string[] = [];
|
||||
const newNodes: Record<string, SpineNode> = {};
|
||||
for (const result of spawn.results) {
|
||||
const id = childNodeId(parentId, childIndex);
|
||||
const spawnEvidence: SpineSpawnEvidence = {
|
||||
summary: result.summary,
|
||||
outcome: result.outcome,
|
||||
};
|
||||
newNodes[id] = {
|
||||
id,
|
||||
summary: result.summary,
|
||||
openedAt: receiptAt,
|
||||
closedAt: receiptAt,
|
||||
memory: result.memoryBody,
|
||||
spawn:
|
||||
result.diagnostic === undefined
|
||||
? spawnEvidence
|
||||
: { ...spawnEvidence, diagnostic: result.diagnostic },
|
||||
children: [],
|
||||
};
|
||||
newChildren.push(id);
|
||||
childIndex += 1;
|
||||
}
|
||||
nodes[parentId] = { ...parent, children: [...parent.children, ...newChildren] };
|
||||
Object.assign(nodes, newNodes);
|
||||
}
|
||||
|
||||
openEpoch(1, 0);
|
||||
for (let i = 0; i < messages.length; i++) {
|
||||
const message = messages[i];
|
||||
|
|
@ -149,6 +192,14 @@ export function deriveSpineState(messages: readonly ContextMessage[]): SpineStat
|
|||
}
|
||||
if (message.role !== 'assistant') continue;
|
||||
for (const call of message.toolCalls) {
|
||||
if (call.name === SPINE_TOOL_SPAWN) {
|
||||
const spawn = spawnReceipts.get(call.id);
|
||||
if (spawn !== undefined) {
|
||||
const parentId = openStack.at(-1);
|
||||
if (parentId !== undefined) spawnNodes(parentId, spawn);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!accepted.has(call.id)) continue;
|
||||
const args = parseTransitionArgs(call.arguments);
|
||||
if (args === undefined) continue;
|
||||
|
|
@ -212,6 +263,129 @@ function isSpineTransitionTool(name: string): boolean {
|
|||
return name === SPINE_TOOL_OPEN || name === SPINE_TOOL_CLOSE || name === SPINE_TOOL_NEXT;
|
||||
}
|
||||
|
||||
interface SpawnTask {
|
||||
readonly summary: string;
|
||||
readonly prompt: string;
|
||||
}
|
||||
|
||||
interface SpawnCallInfo {
|
||||
readonly carrierAt: number;
|
||||
readonly tasks: readonly SpawnTask[];
|
||||
}
|
||||
|
||||
interface SpawnResult {
|
||||
readonly summary: string;
|
||||
readonly outcome: 'completed' | 'errored' | 'aborted';
|
||||
readonly memoryBody: string;
|
||||
readonly diagnostic?: string;
|
||||
}
|
||||
|
||||
interface SpawnReceiptInfo {
|
||||
readonly receiptAt: number;
|
||||
readonly results: readonly SpawnResult[];
|
||||
}
|
||||
|
||||
function parseSpawnArgs(raw: string | null | undefined): readonly SpawnTask[] | undefined {
|
||||
if (raw === undefined || raw === null) return undefined;
|
||||
let parsed: unknown;
|
||||
try {
|
||||
parsed = JSON.parse(raw);
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof parsed !== 'object' || parsed === null) return undefined;
|
||||
const record = parsed as Record<string, unknown>;
|
||||
const tasksRaw = record['tasks'];
|
||||
if (!Array.isArray(tasksRaw) || tasksRaw.length < 2) return undefined;
|
||||
const tasks: SpawnTask[] = [];
|
||||
for (const item of tasksRaw) {
|
||||
if (typeof item !== 'object' || item === null) return undefined;
|
||||
const itemRecord = item as Record<string, unknown>;
|
||||
const summary = itemRecord['summary'];
|
||||
const prompt = itemRecord['prompt'];
|
||||
if (typeof summary !== 'string' || typeof prompt !== 'string') return undefined;
|
||||
tasks.push({ summary, prompt });
|
||||
}
|
||||
return tasks;
|
||||
}
|
||||
|
||||
function collectSpawnReceipts(
|
||||
messages: readonly ContextMessage[],
|
||||
): ReadonlyMap<string, SpawnReceiptInfo> {
|
||||
const calls = new Map<string, SpawnCallInfo>();
|
||||
for (let i = 0; i < messages.length; i++) {
|
||||
const message = messages[i];
|
||||
if (message === undefined || message.role !== 'assistant') continue;
|
||||
for (const call of message.toolCalls) {
|
||||
if (call.name !== SPINE_TOOL_SPAWN) continue;
|
||||
const tasks = parseSpawnArgs(call.arguments);
|
||||
if (tasks !== undefined) calls.set(call.id, { carrierAt: i, tasks });
|
||||
}
|
||||
}
|
||||
const receipts = new Map<string, SpawnReceiptInfo>();
|
||||
for (let i = 0; i < messages.length; i++) {
|
||||
const message = messages[i];
|
||||
if (message === undefined || message.role !== 'tool') continue;
|
||||
const callId = message.toolCallId;
|
||||
if (callId === undefined) continue;
|
||||
const call = calls.get(callId);
|
||||
if (call === undefined) continue;
|
||||
if (message.isError === true) continue;
|
||||
const validated = validateSpawnReceipt(call.tasks, messageText(message), i);
|
||||
if (validated !== undefined) receipts.set(callId, validated);
|
||||
}
|
||||
return receipts;
|
||||
}
|
||||
|
||||
function validateSpawnReceipt(
|
||||
tasks: readonly SpawnTask[],
|
||||
receiptText: string,
|
||||
receiptAt: number,
|
||||
): SpawnReceiptInfo | undefined {
|
||||
let parsed: unknown;
|
||||
try {
|
||||
parsed = JSON.parse(receiptText);
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof parsed !== 'object' || parsed === null) return undefined;
|
||||
const record = parsed as Record<string, unknown>;
|
||||
if (record['schema'] !== 'spine.spawn.result.v1') return undefined;
|
||||
const resultsRaw = record['results'];
|
||||
if (!Array.isArray(resultsRaw) || resultsRaw.length < 2 || resultsRaw.length !== tasks.length) {
|
||||
return undefined;
|
||||
}
|
||||
const results: SpawnResult[] = [];
|
||||
const seenOrdinals = new Set<number>();
|
||||
for (const item of resultsRaw) {
|
||||
if (typeof item !== 'object' || item === null) return undefined;
|
||||
const itemRecord = item as Record<string, unknown>;
|
||||
const ordinal = itemRecord['ordinal'];
|
||||
if (typeof ordinal !== 'number' || !Number.isInteger(ordinal)) return undefined;
|
||||
if (ordinal < 0 || ordinal >= tasks.length || seenOrdinals.has(ordinal)) return undefined;
|
||||
seenOrdinals.add(ordinal);
|
||||
const outcome = itemRecord['outcome'];
|
||||
if (outcome !== 'completed' && outcome !== 'errored' && outcome !== 'aborted') return undefined;
|
||||
const memoryBody = itemRecord['memory_body'];
|
||||
if (typeof memoryBody !== 'string' || memoryBody.length === 0) return undefined;
|
||||
const diagnostic = itemRecord['diagnostic'];
|
||||
if (diagnostic !== undefined && (typeof diagnostic !== 'string' || diagnostic.length === 0)) {
|
||||
return undefined;
|
||||
}
|
||||
if (outcome !== 'completed' && diagnostic === undefined) return undefined;
|
||||
const task = tasks[ordinal];
|
||||
if (task === undefined || task.summary.trim().length === 0) return undefined;
|
||||
results[ordinal] = {
|
||||
summary: task.summary,
|
||||
outcome,
|
||||
memoryBody,
|
||||
diagnostic,
|
||||
};
|
||||
}
|
||||
if (seenOrdinals.size !== tasks.length) return undefined;
|
||||
return { receiptAt, results };
|
||||
}
|
||||
|
||||
function isEpochBoundary(message: ContextMessage): boolean {
|
||||
if (message.role !== 'user') return false;
|
||||
if (isCompactionSummaryMessage(message)) return true;
|
||||
|
|
|
|||
|
|
@ -14,31 +14,42 @@
|
|||
* inside its span survive in place with their original message identity
|
||||
* (text AND media parts preserved), each nested closed node contributes its
|
||||
* own `<spine_memory node_id="...">` slot, and the node's own memory lands
|
||||
* last — the same slot layout the upstream `assemble_memory` produces.
|
||||
* last — the same slot layout the upstream `assemble_memory` produces. Nodes
|
||||
* synthesized from a `spine_spawn` receipt additionally render an evidence
|
||||
* line `<spine_spawn_evidence node_id="..." summary="..." outcome="..." />`
|
||||
* before their memory slot; the receipt tool message is absorbed by the
|
||||
* point span and never reaches the projection.
|
||||
*
|
||||
* Real user requests carry stable `[U#]` anchors: every request in the stored
|
||||
* history consumes its ordinal even when an epoch boundary folds it away, so a
|
||||
* surviving request keeps the same anchor across projections and across the
|
||||
* close that folds its span. A synthetic `<spine_status>` orientation line
|
||||
* closes the view. The stored history is never mutated; token numbers for the
|
||||
* status line are precomputed by the `spine` service and passed in. Consumed
|
||||
* by `spineService.fold`.
|
||||
* close that folds its span. Tool messages in live ranges additionally pass
|
||||
* the trim projection (when given): oversized results keep their full body
|
||||
* behind a byte-stable `[TRIM_ID: trim_N]` label, and accepted trims render
|
||||
* as the cleared placeholder or a kept slice. A synthetic `<spine_status>`
|
||||
* orientation line closes the view. The stored history is never mutated;
|
||||
* token numbers for the status line are precomputed by the `spine` service
|
||||
* and passed in. Consumed by `spineService.fold`.
|
||||
*
|
||||
* Span invariants (mirroring the upstream reducer): a closed span ends BEFORE
|
||||
* the assistant message carrying the close/next call, so the carrier, its
|
||||
* receipt, and any slower batched tool results stay visible and paired in the
|
||||
* parent context; a `spine.next` sibling opens at the carrier's index, so
|
||||
* next-chain spans are disjoint and contiguous. A span closed entirely before
|
||||
* the current epoch is owned by the epoch summary and skipped silently — left
|
||||
* queued, it would pin the level walk and keep every post-epoch span raw
|
||||
* forever. The synthetic root-epoch node and truncation-voided nodes
|
||||
* (`openedAt < 0`) never produce landmarks or spans.
|
||||
* next-chain spans are disjoint and contiguous. `spine_spawn` siblings share a
|
||||
* point span at the receipt message, so the first sibling absorbs the receipt
|
||||
* into its closed range and the carrier stays visible in the parent context.
|
||||
* A span closed entirely before the current epoch is owned by the epoch
|
||||
* summary and skipped silently — left queued, it would pin the level walk and
|
||||
* keep every post-epoch span raw forever. The synthetic root-epoch node and
|
||||
* truncation-voided nodes (`openedAt < 0`) never produce landmarks or spans.
|
||||
*/
|
||||
|
||||
import type { ContextMessage } from '#/agent/contextMemory/types';
|
||||
import type { ContentPart } from '#/kosong/contract/message';
|
||||
|
||||
import type { SpineNode, SpineState } from './spineOps';
|
||||
import type { SpineNode, SpineSpawnEvidence, SpineState } from './spineOps';
|
||||
import type { SpineTrimProjection } from './spineTrimDerive';
|
||||
import { applySpineTrim } from './spineTrimFold';
|
||||
|
||||
export interface SpineFoldStatus {
|
||||
readonly cursorId: string;
|
||||
|
|
@ -62,6 +73,8 @@ export interface SpineFoldInput {
|
|||
readonly state: SpineState;
|
||||
readonly epochSummaryMessage?: ContextMessage;
|
||||
readonly status?: SpineFoldStatus;
|
||||
/** Derived trim projection applied to tool messages in live ranges. */
|
||||
readonly trim?: SpineTrimProjection;
|
||||
}
|
||||
|
||||
export function foldSpine(
|
||||
|
|
@ -74,6 +87,7 @@ export function foldSpine(
|
|||
state,
|
||||
anchors: userRequestAnchors(messages),
|
||||
epochStartAt: state.epochStartAt,
|
||||
trim: input.trim,
|
||||
};
|
||||
const out: ContextMessage[] = [];
|
||||
|
||||
|
|
@ -104,6 +118,7 @@ interface FoldContext {
|
|||
/** `[U#]` ordinal per message index (0 = not a real user request). */
|
||||
readonly anchors: readonly number[];
|
||||
readonly epochStartAt: number;
|
||||
readonly trim: SpineTrimProjection | undefined;
|
||||
}
|
||||
|
||||
type SpanSink = (ctx: FoldContext, index: number, out: ContextMessage[]) => void;
|
||||
|
|
@ -154,7 +169,11 @@ function renderNode(
|
|||
}
|
||||
// A closed node folds: real user requests inside the span survive in place
|
||||
// (media included), nested closed nodes render their own slots, and the
|
||||
// node's own memory lands last.
|
||||
// node's own memory lands last. Spawned nodes prefix their memory with an
|
||||
// evidence line.
|
||||
if (node.spawn !== undefined) {
|
||||
out.push(spineSpawnEvidenceMessage(node, node.spawn));
|
||||
}
|
||||
walkChildren(ctx, node.children, lo, hi, out, pushSurvivingUserRequest);
|
||||
const memoryMessage = spineMemoryMessage(node);
|
||||
if (memoryMessage !== undefined) out.push(memoryMessage);
|
||||
|
|
@ -165,7 +184,8 @@ function pushRaw(ctx: FoldContext, index: number, out: ContextMessage[]): void {
|
|||
const message = ctx.messages[index];
|
||||
if (message === undefined) return;
|
||||
const anchor = ctx.anchors[index] ?? 0;
|
||||
out.push(anchor > 0 ? annotateUserRequest(message, anchor) : message);
|
||||
const surviving = anchor > 0 ? annotateUserRequest(message, anchor) : message;
|
||||
out.push(ctx.trim === undefined ? surviving : applySpineTrim(ctx.trim, index, surviving));
|
||||
}
|
||||
|
||||
/** Folded-range sink: only real user requests survive, tagged and original. */
|
||||
|
|
@ -181,7 +201,7 @@ export function isUserRequest(message: ContextMessage): boolean {
|
|||
}
|
||||
|
||||
function userRequestAnchors(messages: readonly ContextMessage[]): readonly number[] {
|
||||
const anchors: number[] = new Array<number>(messages.length).fill(0);
|
||||
const anchors: number[] = Array.from({ length: messages.length }, () => 0);
|
||||
let anchor = 0;
|
||||
for (let i = 0; i < messages.length; i++) {
|
||||
const message = messages[i];
|
||||
|
|
@ -220,6 +240,23 @@ function spineMemoryMessage(node: SpineNode): ContextMessage | undefined {
|
|||
};
|
||||
}
|
||||
|
||||
function spineSpawnEvidenceMessage(
|
||||
node: SpineNode,
|
||||
spawn: SpineSpawnEvidence,
|
||||
): ContextMessage {
|
||||
const diagnostic =
|
||||
spawn.diagnostic === undefined ? '' : ` diagnostic="${escapeAttr(spawn.diagnostic)}"`;
|
||||
const text = `<spine_spawn_evidence node_id="${node.id}" summary="${escapeAttr(
|
||||
spawn.summary,
|
||||
)}" outcome="${spawn.outcome}"${diagnostic} />`;
|
||||
return {
|
||||
role: 'user',
|
||||
content: [{ type: 'text', text }],
|
||||
toolCalls: [],
|
||||
origin: { kind: 'injection', variant: 'spine_spawn_evidence' },
|
||||
};
|
||||
}
|
||||
|
||||
function annotateUserRequest(message: ContextMessage, anchorNumber: number): ContextMessage {
|
||||
const anchor = `[U${String(anchorNumber)}] `;
|
||||
const content = prefixFirstText(message.content, anchor);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@
|
|||
* open-node stack (its top is the cursor), and the current root-epoch
|
||||
* boundary, with `openedAt`/`closedAt` indexing the stored history. Consumed
|
||||
* by the Agent-scope `spineService` and the `spineFold` projection.
|
||||
*
|
||||
* `SpineNode.spawn` is an optional evidence field produced only by the
|
||||
* derivation for nodes synthesized from a `spine_spawn` receipt. The legacy
|
||||
* op reducers below never create it and always leave it undefined.
|
||||
*/
|
||||
|
||||
import { z } from 'zod';
|
||||
|
|
@ -25,6 +29,12 @@ import {
|
|||
SPINE_VOID_OPENED_AT,
|
||||
} from './spineTree';
|
||||
|
||||
export interface SpineSpawnEvidence {
|
||||
readonly summary: string;
|
||||
readonly outcome: 'completed' | 'errored' | 'aborted';
|
||||
readonly diagnostic?: string;
|
||||
}
|
||||
|
||||
export interface SpineNode {
|
||||
readonly id: string;
|
||||
readonly summary: string;
|
||||
|
|
@ -34,6 +44,7 @@ export interface SpineNode {
|
|||
readonly archivePath?: string;
|
||||
readonly baselineTokens?: number;
|
||||
readonly finalTokens?: number;
|
||||
readonly spawn?: SpineSpawnEvidence;
|
||||
readonly children: readonly string[];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,13 @@
|
|||
* so a restore re-derives them and the first post-restore sweep rewrites any
|
||||
* archive a crash lost. Persistence failures are never swallowed: a failed
|
||||
* archive write is reported through `onUnexpectedError`, and the node's memory
|
||||
* carries the failure note in the projection from then on. Renders the
|
||||
* read-only `spine_tree` view across every root epoch (current first by
|
||||
* carries the failure note in the projection from then on. It also owns the
|
||||
* tool-response trim projection (gated on `KIMI_CODE_SPINE_TRIM`): the same
|
||||
* stream derives the oversized-result tags and replays the accepted
|
||||
* `spine_trim` receipts (`deriveSpineTrimProjection`), the fold renders them,
|
||||
* and `acceptTrim` validates calls against that same derivation — one
|
||||
* eligibility source for rendering and validation. Renders the read-only
|
||||
* `spine_tree` view across every root epoch (current first by
|
||||
* numeric order), so a superseded epoch's closed-node archives stay
|
||||
* discoverable after a root compaction. Registers its history fold into
|
||||
* `contextProjector` and its `<spine_view>` prompt block into `llmRequester`
|
||||
|
|
@ -63,14 +68,17 @@ import { IEventBus } from '#/app/event/eventBus';
|
|||
import { IFlagService } from '#/app/flag/flag';
|
||||
import { IHostEnvironment } from '#/os/interface/hostEnvironment';
|
||||
import { IHostFileSystem } from '#/os/interface/hostFileSystem';
|
||||
import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle';
|
||||
import { ISessionContext } from '#/session/sessionContext/sessionContext';
|
||||
import { ISessionSubagentService } from '#/session/subagent/subagent';
|
||||
import { IWireService } from '#/wire/wire';
|
||||
|
||||
import { SPINE_FLAG_ID } from './flag';
|
||||
import { SPINE_FLAG_ID, SPINE_SPAWN_FLAG_ID, SPINE_TRIM_FLAG_ID } from './flag';
|
||||
import { appendSpineView, loadSpineViewOverride } from './instructions';
|
||||
import {
|
||||
IAgentSpineService,
|
||||
SPINE_TOOL_OPEN,
|
||||
type SpineSpawnTaskInput,
|
||||
type SpineTransitionResult,
|
||||
} from './spine';
|
||||
import {
|
||||
|
|
@ -81,6 +89,11 @@ import {
|
|||
type SpineEpochArchiveInput,
|
||||
} from './spineArchive';
|
||||
import { deriveSpineState } from './spineDerive';
|
||||
import {
|
||||
deriveSpineTrimProjection,
|
||||
type SpineTrimOp,
|
||||
type SpineTrimProjection,
|
||||
} from './spineTrimDerive';
|
||||
import { foldSpine, type SpineFoldStatus } from './spineFold';
|
||||
import { type SpineNode, type SpineState } from './spineOps';
|
||||
import {
|
||||
|
|
@ -93,6 +106,13 @@ import {
|
|||
spineNodeViewFromState,
|
||||
type SpineTreeViewInput,
|
||||
} from './spineTree';
|
||||
import {
|
||||
executeSpawnBranches,
|
||||
maxSpawnBranchCount,
|
||||
resolveMaxThreads,
|
||||
SPINE_SPAWN_MAX_THREADS_ENV,
|
||||
type SpawnBranchResult,
|
||||
} from './spineSpawn';
|
||||
|
||||
const REJECT_DISABLED: SpineTransitionResult = {
|
||||
accepted: false,
|
||||
|
|
@ -111,6 +131,16 @@ const REJECT_ROOT_EPOCH: SpineTransitionResult = {
|
|||
'Root-epoch nodes cannot be closed. Use open to start a child node under the current scope.',
|
||||
};
|
||||
|
||||
const REJECT_TRIM_DISABLED: SpineTransitionResult = {
|
||||
accepted: false,
|
||||
reason: 'Spine trim is disabled. Set KIMI_CODE_SPINE_TRIM=1 to enable it.',
|
||||
};
|
||||
|
||||
const REJECT_SPAWN_DISABLED: SpineTransitionResult = {
|
||||
accepted: false,
|
||||
reason: 'Spine spawn is disabled. Set KIMI_CODE_SPINE_SPAWN=1 to enable it.',
|
||||
};
|
||||
|
||||
const ARCHIVE_FAILURE_NOTE =
|
||||
'[spine: the trajectory archive for this node could not be written; its detailed history was not persisted.]';
|
||||
|
||||
|
|
@ -121,6 +151,8 @@ export class AgentSpineService extends Disposable implements IAgentSpineService
|
|||
private transitionThisStep = false;
|
||||
private cachedMessages: readonly ContextMessage[] | undefined;
|
||||
private cachedState: SpineState | undefined;
|
||||
private cachedTrimMessages: readonly ContextMessage[] | undefined;
|
||||
private cachedTrimProjection: SpineTrimProjection | undefined;
|
||||
/**
|
||||
* Ephemeral per-node token gauges, recorded at accept time. Token baselines
|
||||
* are not in the message stream, so pure derivation cannot recover them —
|
||||
|
|
@ -147,6 +179,11 @@ export class AgentSpineService extends Disposable implements IAgentSpineService
|
|||
private readonly failedArchiveIds = new Set<string>();
|
||||
private spineViewOverride: string | undefined;
|
||||
private spineViewReady: Promise<void> = Promise.resolve();
|
||||
/**
|
||||
* Number of child agents currently running as part of an in-flight
|
||||
* `spine_spawn` fission. Ephemeral: reset at step bounds and on restore.
|
||||
*/
|
||||
private activeSpawnBranches = 0;
|
||||
|
||||
constructor(
|
||||
@IAgentContextMemoryService private readonly context: IAgentContextMemoryService,
|
||||
|
|
@ -160,6 +197,8 @@ export class AgentSpineService extends Disposable implements IAgentSpineService
|
|||
@IAgentScopeContext private readonly agentScope: IAgentScopeContext,
|
||||
@IWireService private readonly wire: IWireService,
|
||||
@IEventBus private readonly eventBus: IEventBus,
|
||||
@IAgentLifecycleService private readonly lifecycle: IAgentLifecycleService,
|
||||
@ISessionSubagentService private readonly subagentService: ISessionSubagentService,
|
||||
@IAgentLoopService loop: IAgentLoopService,
|
||||
@IAgentContextProjectorService projector: IAgentContextProjectorService,
|
||||
@IAgentLLMRequesterService llmRequester: IAgentLLMRequesterService,
|
||||
|
|
@ -213,10 +252,13 @@ export class AgentSpineService extends Disposable implements IAgentSpineService
|
|||
// close and its sweep self-heals.
|
||||
this.cachedMessages = undefined;
|
||||
this.cachedState = undefined;
|
||||
this.cachedTrimMessages = undefined;
|
||||
this.cachedTrimProjection = undefined;
|
||||
this.baselines.clear();
|
||||
this.finals.clear();
|
||||
this.archivedIds.clear();
|
||||
this.failedArchiveIds.clear();
|
||||
this.activeSpawnBranches = 0;
|
||||
await next();
|
||||
}),
|
||||
);
|
||||
|
|
@ -242,6 +284,75 @@ export class AgentSpineService extends Disposable implements IAgentSpineService
|
|||
return this.flags.enabled(SPINE_FLAG_ID);
|
||||
}
|
||||
|
||||
get trimEnabled(): boolean {
|
||||
return this.flags.enabled(SPINE_TRIM_FLAG_ID);
|
||||
}
|
||||
|
||||
get spawnEnabled(): boolean {
|
||||
return this.flags.enabled(SPINE_SPAWN_FLAG_ID);
|
||||
}
|
||||
|
||||
executeSpawn(
|
||||
tasks: readonly SpineSpawnTaskInput[],
|
||||
signal: AbortSignal,
|
||||
): Promise<SpineTransitionResult & { readonly receipt?: string }> {
|
||||
return this.doExecuteSpawn(tasks, signal);
|
||||
}
|
||||
|
||||
private async doExecuteSpawn(
|
||||
tasks: readonly SpineSpawnTaskInput[],
|
||||
signal: AbortSignal,
|
||||
): Promise<SpineTransitionResult & { readonly receipt?: string }> {
|
||||
if (!this.enabled) return REJECT_DISABLED;
|
||||
if (!this.spawnEnabled) return REJECT_SPAWN_DISABLED;
|
||||
|
||||
const maxThreads = resolveMaxThreads(process.env[SPINE_SPAWN_MAX_THREADS_ENV]);
|
||||
const maxBranches = maxSpawnBranchCount(maxThreads);
|
||||
|
||||
if (tasks.length < 2) {
|
||||
return reject('spine_spawn requires at least 2 tasks.');
|
||||
}
|
||||
if (tasks.length > maxBranches) {
|
||||
return reject(
|
||||
`spine_spawn accepts at most ${String(maxBranches)} tasks under the configured limit of ${String(maxThreads)} threads.`,
|
||||
);
|
||||
}
|
||||
|
||||
// Aggregate capacity admission is checked before the per-step gate so that
|
||||
// an overlapping fission that cannot fit is rejected with the all-or-nothing
|
||||
// reason even while another transition is still in flight.
|
||||
if (this.activeSpawnBranches + tasks.length > maxBranches) {
|
||||
return {
|
||||
accepted: false,
|
||||
reason:
|
||||
`aggregate admission requested ${String(tasks.length)} child agents, but shared capacity was unavailable under the configured limit of ${String(maxBranches)} concurrent child agents. ` +
|
||||
`Admission is all-or-nothing. Retry spine_spawn with fewer tasks after capacity is available, or increase ${SPINE_SPAWN_MAX_THREADS_ENV}.`,
|
||||
};
|
||||
}
|
||||
|
||||
if (this.transitionThisStep) return REJECT_CONFLICT;
|
||||
|
||||
for (const task of tasks) {
|
||||
if (task.summary.trim().length === 0 || task.prompt.trim().length === 0) {
|
||||
return reject('spine_spawn task summary and prompt must not be empty.');
|
||||
}
|
||||
}
|
||||
|
||||
this.transitionThisStep = true;
|
||||
this.activeSpawnBranches += tasks.length;
|
||||
try {
|
||||
const branches = await executeSpawnBranches(
|
||||
{ lifecycle: this.lifecycle, subagentService: this.subagentService },
|
||||
tasks,
|
||||
signal,
|
||||
);
|
||||
const receipt = buildSpawnReceipt(branches);
|
||||
return { accepted: true, receipt };
|
||||
} finally {
|
||||
this.activeSpawnBranches -= tasks.length;
|
||||
}
|
||||
}
|
||||
|
||||
acceptOpen(summary: string): SpineTransitionResult {
|
||||
const guard = this.guard();
|
||||
if (guard !== null) return guard;
|
||||
|
|
@ -293,6 +404,31 @@ export class AgentSpineService extends Disposable implements IAgentSpineService
|
|||
return { accepted: true };
|
||||
}
|
||||
|
||||
acceptTrim(trimId: string, op: SpineTrimOp): SpineTransitionResult {
|
||||
if (!this.enabled) return REJECT_DISABLED;
|
||||
if (!this.trimEnabled) return REJECT_TRIM_DISABLED;
|
||||
const projection = this.trimProjection();
|
||||
const index = projection.tagIndex.get(trimId);
|
||||
if (index === undefined) {
|
||||
return reject(`Unknown TRIM_ID "${trimId}"; it is not attached to a tool result. Do not retry it.`);
|
||||
}
|
||||
if (projection.consumed.has(trimId)) {
|
||||
return reject(`TRIM_ID "${trimId}" was already trimmed. Do not retry it.`);
|
||||
}
|
||||
if (!projection.eligible.has(trimId)) {
|
||||
return reject(
|
||||
`TRIM_ID "${trimId}" is outside the immediately preceding tool-result batch. Do not retry it.`,
|
||||
);
|
||||
}
|
||||
if (op.kind === 'slice' && op.shape.type === 'anchor') {
|
||||
const target = this.context.get()[index];
|
||||
if (target === undefined || !messageText(target).includes(op.shape.anchor)) {
|
||||
return reject(`Anchor text not found in "${trimId}". Do not retry it.`);
|
||||
}
|
||||
}
|
||||
return { accepted: true };
|
||||
}
|
||||
|
||||
renderTree(): string {
|
||||
const state = this.state();
|
||||
const input = this.treeViewInput();
|
||||
|
|
@ -308,7 +444,8 @@ export class AgentSpineService extends Disposable implements IAgentSpineService
|
|||
const state = this.state();
|
||||
const epochSummaryMessage =
|
||||
state.epochMemoryAt === undefined ? undefined : messages[state.epochMemoryAt];
|
||||
return foldSpine(messages, { state, status: this.buildStatus(), epochSummaryMessage });
|
||||
const trim = this.trimEnabled ? this.trimProjection() : undefined;
|
||||
return foldSpine(messages, { state, status: this.buildStatus(), epochSummaryMessage, trim });
|
||||
}
|
||||
|
||||
currentState(): SpineState {
|
||||
|
|
@ -382,6 +519,22 @@ export class AgentSpineService extends Disposable implements IAgentSpineService
|
|||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* The trim projection over the same stream, cached with the same
|
||||
* reference-equality guard. This is the single eligibility source: the fold
|
||||
* renders it and `acceptTrim` validates against it.
|
||||
*/
|
||||
private trimProjection(): SpineTrimProjection {
|
||||
const messages = this.context.get();
|
||||
if (this.cachedTrimProjection !== undefined && this.cachedTrimMessages === messages) {
|
||||
return this.cachedTrimProjection;
|
||||
}
|
||||
const projection = deriveSpineTrimProjection(messages);
|
||||
this.cachedTrimMessages = messages;
|
||||
this.cachedTrimProjection = projection;
|
||||
return projection;
|
||||
}
|
||||
|
||||
private cursorId(): string {
|
||||
return topOf(this.derivedState());
|
||||
}
|
||||
|
|
@ -532,6 +685,29 @@ function reject(reason: string): SpineTransitionResult {
|
|||
return { accepted: false, reason };
|
||||
}
|
||||
|
||||
interface SpawnReceiptJson {
|
||||
readonly schema: 'spine.spawn.result.v1';
|
||||
readonly results: readonly SpawnReceiptResultJson[];
|
||||
}
|
||||
|
||||
interface SpawnReceiptResultJson {
|
||||
readonly ordinal: number;
|
||||
readonly outcome: 'completed' | 'errored' | 'aborted';
|
||||
readonly memory_body: string;
|
||||
readonly diagnostic?: string;
|
||||
}
|
||||
|
||||
function buildSpawnReceipt(branches: readonly SpawnBranchResult[]): string {
|
||||
const results: SpawnReceiptResultJson[] = branches.map((branch, ordinal) => ({
|
||||
ordinal,
|
||||
outcome: branch.outcome,
|
||||
memory_body: branch.memoryBody,
|
||||
diagnostic: branch.diagnostic,
|
||||
}));
|
||||
const receipt: SpawnReceiptJson = { schema: 'spine.spawn.result.v1', results };
|
||||
return JSON.stringify(receipt);
|
||||
}
|
||||
|
||||
registerScopedService(
|
||||
LifecycleScope.Agent,
|
||||
IAgentSpineService,
|
||||
|
|
|
|||
250
packages/agent-core-v2/src/agent/spine/spineSpawn.ts
Normal file
250
packages/agent-core-v2/src/agent/spine/spineSpawn.ts
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
/**
|
||||
* `spine` domain (L4) — `spine_spawn` fission executor.
|
||||
*
|
||||
* Pure module (not a DI service). `executeSpawnBranches` forks one child agent
|
||||
* per task via `IAgentLifecycleService.fork('main', { trimTrailingToolCallBatch: true })`,
|
||||
* runs each branch with `ISessionSubagentService.run`, and waits for all
|
||||
* completions. Single-branch failures do not propagate: each branch records its
|
||||
* own outcome. The caller (`AgentSpineService`) owns capacity admission and
|
||||
* constructs the `spine.spawn.result.v1` receipt.
|
||||
*
|
||||
* Cache affinity: each forked agent shares the parent's session id through the
|
||||
* Agent-scope `IAgentProfileService.resolveRequestParams`, which uses
|
||||
* `ISessionContext.sessionId` as the prompt-cache key. That is the existing v2
|
||||
* seam; no extra wiring is required here. (If a future provider needs a
|
||||
* different cache key shape, extend `RunAgentOptions` or `ForkAgentOptions`.)
|
||||
*/
|
||||
|
||||
import type { IAgentScopeHandle } from '#/_base/di/scope';
|
||||
import { onUnexpectedError } from '#/_base/errors/unexpectedError';
|
||||
import type { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle';
|
||||
import type {
|
||||
AgentRunHandle,
|
||||
ISessionSubagentService,
|
||||
RunAgentOptions,
|
||||
} from '#/session/subagent/subagent';
|
||||
|
||||
import type { SpineSpawnTaskInput } from './spine';
|
||||
|
||||
export type SpawnBranchOutcome = 'completed' | 'errored' | 'aborted';
|
||||
|
||||
export interface SpawnBranchResult {
|
||||
readonly summary: string;
|
||||
readonly outcome: SpawnBranchOutcome;
|
||||
readonly memoryBody: string;
|
||||
readonly diagnostic?: string;
|
||||
}
|
||||
|
||||
export interface SpawnExecutorDependencies {
|
||||
readonly lifecycle: IAgentLifecycleService;
|
||||
readonly subagentService: ISessionSubagentService;
|
||||
}
|
||||
|
||||
const EMPTY_MEMORY_DIAGNOSTIC = 'child completed without a non-empty final memory';
|
||||
|
||||
export function taskEnvelope(task: SpineSpawnTaskInput): string {
|
||||
return (
|
||||
'You are one branch of a spine_spawn fission. The original continuation is suspended during this fission; no supervisory model is active.\n' +
|
||||
`Branch label and outcome: ${task.summary}\n` +
|
||||
`Assignment:\n${task.prompt}\n` +
|
||||
'When you finish, return only the terminal memory for this branch.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default aggregate thread limit for spine_spawn fissions. The main agent plus
|
||||
* up to `DEFAULT_MAX_THREADS - 1` concurrent child agents may run; the number of
|
||||
* tasks in one spawn call therefore cannot exceed `DEFAULT_MAX_THREADS - 1`.
|
||||
*/
|
||||
export const DEFAULT_MAX_THREADS = 4;
|
||||
|
||||
/**
|
||||
* Environment variable that overrides the default max thread count.
|
||||
*/
|
||||
export const SPINE_SPAWN_MAX_THREADS_ENV = 'KIMI_CODE_SPINE_SPAWN_MAX_THREADS';
|
||||
|
||||
/**
|
||||
* Parses the configured max thread count, falling back to the default when the
|
||||
* env value is missing, non-numeric, or not a positive integer.
|
||||
*/
|
||||
export function resolveMaxThreads(raw: string | undefined): number {
|
||||
if (raw === undefined || raw.length === 0) return DEFAULT_MAX_THREADS;
|
||||
const parsed = Number(raw);
|
||||
if (!Number.isInteger(parsed) || parsed < 2) return DEFAULT_MAX_THREADS;
|
||||
return parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the largest number of tasks a single spawn call may admit. The main
|
||||
* agent occupies one thread, leaving `maxThreads - 1` for children.
|
||||
*/
|
||||
export function maxSpawnBranchCount(maxThreads: number): number {
|
||||
return Math.max(1, maxThreads - 1);
|
||||
}
|
||||
|
||||
export async function executeSpawnBranches(
|
||||
deps: SpawnExecutorDependencies,
|
||||
tasks: readonly SpineSpawnTaskInput[],
|
||||
signal: AbortSignal,
|
||||
): Promise<readonly SpawnBranchResult[]> {
|
||||
const starts = await Promise.all(
|
||||
tasks.map((task) =>
|
||||
startBranch(deps, task, signal).then(
|
||||
(branch): BranchStart => ({ ok: true, branch }),
|
||||
(error: unknown): BranchStart => ({ ok: false, error }),
|
||||
),
|
||||
),
|
||||
);
|
||||
const started = starts.flatMap((start) => (start.ok ? [start.branch] : []));
|
||||
try {
|
||||
// A start failure aborts the whole batch: live siblings are cancelled and
|
||||
// reported aborted (the same all-or-nothing shape upstream uses), and every
|
||||
// started agent is still released in the finally below.
|
||||
const batchAborted = starts.some((start) => !start.ok);
|
||||
if (batchAborted) {
|
||||
for (const branch of started) {
|
||||
branch.run.turn.cancel('a sibling branch failed to start');
|
||||
}
|
||||
}
|
||||
const completions = await Promise.allSettled(
|
||||
starts.map((start) =>
|
||||
start.ok ? awaitBranch(start.branch, signal) : Promise.reject(start.error),
|
||||
),
|
||||
);
|
||||
return completions.map((completion, index) =>
|
||||
finalizeBranch(tasks[index]!, starts[index]!, completion, batchAborted),
|
||||
);
|
||||
} finally {
|
||||
await Promise.all(started.map((branch) => releaseBranch(deps, branch)));
|
||||
}
|
||||
}
|
||||
|
||||
type BranchStart =
|
||||
| { readonly ok: true; readonly branch: SpawnBranch }
|
||||
| { readonly ok: false; readonly error: unknown };
|
||||
|
||||
interface SpawnBranch {
|
||||
readonly task: SpineSpawnTaskInput;
|
||||
readonly handle: IAgentScopeHandle;
|
||||
readonly run: AgentRunHandle;
|
||||
}
|
||||
|
||||
async function startBranch(
|
||||
deps: SpawnExecutorDependencies,
|
||||
task: SpineSpawnTaskInput,
|
||||
signal: AbortSignal,
|
||||
): Promise<SpawnBranch> {
|
||||
const handle = await deps.lifecycle.fork('main', {
|
||||
trimTrailingToolCallBatch: true,
|
||||
});
|
||||
const run = await deps.subagentService.run(
|
||||
handle.id,
|
||||
{ kind: 'prompt', prompt: taskEnvelope(task) },
|
||||
{ signal } satisfies RunAgentOptions,
|
||||
);
|
||||
return { task, handle, run };
|
||||
}
|
||||
|
||||
async function awaitBranch(
|
||||
branch: SpawnBranch,
|
||||
signal: AbortSignal,
|
||||
): Promise<{ readonly summary: string }> {
|
||||
if (signal.aborted) {
|
||||
branch.run.turn.cancel(signal.reason);
|
||||
throw new AbortError(signal.reason);
|
||||
}
|
||||
return branch.run.completion;
|
||||
}
|
||||
|
||||
function finalizeBranch(
|
||||
task: SpineSpawnTaskInput,
|
||||
start: BranchStart,
|
||||
completion: PromiseSettledResult<{ readonly summary: string }>,
|
||||
batchAborted: boolean,
|
||||
): SpawnBranchResult {
|
||||
if (!start.ok) {
|
||||
const message = start.error instanceof Error ? start.error.message : String(start.error);
|
||||
return {
|
||||
summary: task.summary,
|
||||
outcome: 'errored',
|
||||
memoryBody: message,
|
||||
diagnostic: message,
|
||||
};
|
||||
}
|
||||
if (completion.status === 'rejected') {
|
||||
if (batchAborted) {
|
||||
const message = 'branch aborted: a sibling branch failed to start';
|
||||
return {
|
||||
summary: task.summary,
|
||||
outcome: 'aborted',
|
||||
memoryBody: message,
|
||||
diagnostic: message,
|
||||
};
|
||||
}
|
||||
const reason = extractReason(completion.reason);
|
||||
return {
|
||||
summary: task.summary,
|
||||
outcome: reason.kind === 'abort' ? 'aborted' : 'errored',
|
||||
memoryBody: reason.message,
|
||||
diagnostic: reason.message,
|
||||
};
|
||||
}
|
||||
const summary = completion.value.summary.trim();
|
||||
if (summary.length === 0) {
|
||||
return {
|
||||
summary: task.summary,
|
||||
outcome: 'errored',
|
||||
memoryBody: EMPTY_MEMORY_DIAGNOSTIC,
|
||||
diagnostic: EMPTY_MEMORY_DIAGNOSTIC,
|
||||
};
|
||||
}
|
||||
return {
|
||||
summary: task.summary,
|
||||
outcome: 'completed',
|
||||
memoryBody: summary,
|
||||
};
|
||||
}
|
||||
|
||||
async function releaseBranch(
|
||||
deps: SpawnExecutorDependencies,
|
||||
branch: SpawnBranch,
|
||||
): Promise<void> {
|
||||
try {
|
||||
await deps.lifecycle.remove(branch.handle.id);
|
||||
} catch (error) {
|
||||
// A release failure must not mask the batch's results; the receipt is the
|
||||
// join's only record, so report and move on.
|
||||
onUnexpectedError(error);
|
||||
}
|
||||
}
|
||||
|
||||
interface RejectionReason {
|
||||
readonly kind: 'abort' | 'error';
|
||||
readonly message: string;
|
||||
}
|
||||
|
||||
function extractReason(reason: unknown): RejectionReason {
|
||||
const message = reason instanceof Error ? reason.message : String(reason);
|
||||
if (isAbortReason(reason)) return { kind: 'abort', message };
|
||||
return { kind: 'error', message };
|
||||
}
|
||||
|
||||
function isAbortReason(reason: unknown): boolean {
|
||||
if (reason instanceof Error && reason.name === 'AbortError') return true;
|
||||
if (
|
||||
typeof reason === 'object' &&
|
||||
reason !== null &&
|
||||
'name' in reason &&
|
||||
reason.name === 'AbortError'
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class AbortError extends Error {
|
||||
constructor(reason: unknown) {
|
||||
super(reason instanceof Error ? reason.message : String(reason));
|
||||
this.name = 'AbortError';
|
||||
}
|
||||
}
|
||||
218
packages/agent-core-v2/src/agent/spine/spineTrimDerive.ts
Normal file
218
packages/agent-core-v2/src/agent/spine/spineTrimDerive.ts
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
/**
|
||||
* `spine` domain (L4) — derives the tool-response trim projection purely from
|
||||
* the stored `contextMemory` message stream.
|
||||
*
|
||||
* The trim projection is a second, independent read of the same stream the
|
||||
* tree derivation reads: no persisted ops, no commit protocol — a `spine_trim`
|
||||
* call whose accepted receipt landed in history IS the trim, and an undo that
|
||||
* removes the call or the receipt removes the trim with it. Tagging is
|
||||
* automatic: every tool result larger than `SPINE_TRIM_THRESHOLD_BYTES` that
|
||||
* does not answer a `spine_*` control tool and carries text-only content gets
|
||||
* the next `trim_N` id in stream order, so the id a message carries stays
|
||||
* stable across projections for as long as the history before it does.
|
||||
* Trimming itself is model-driven and one-shot: the host validates a call
|
||||
* against the derived eligibility window, and the accepted receipt consumes
|
||||
* the id forever.
|
||||
*
|
||||
* Eligibility is deliberately NOT the projection. The `[TRIM_ID: trim_N]`
|
||||
* label renders byte-stable for as long as the result survives the tree fold
|
||||
* — an id that has left the window stays visible but loses its trimmability —
|
||||
* while the window is derived separately here: the tags of the most recent
|
||||
* COMPLETED tool-call batch (every call answered; an aborted batch never
|
||||
* shifts the window, and interleaved assistant text never expires it either).
|
||||
* Host validation (`AgentSpineService.acceptTrim`) reads this same
|
||||
* derivation, so rendering and validation share exactly one eligibility
|
||||
* source. Consumed by `spineTrimFold` (rendering) and `spineService`
|
||||
* (validation).
|
||||
*/
|
||||
|
||||
import type { ContextMessage } from '#/agent/contextMemory/types';
|
||||
|
||||
import { SPINE_TOOL_TRIM } from './spine';
|
||||
import { TRIM_ACCEPTED_OUTPUT } from './tools/controlResult';
|
||||
|
||||
/**
|
||||
* Tool results larger than this (UTF-8 bytes of joined text) get a trim tag.
|
||||
* Matches the upstream `TOOL_RESPONSE_TRIM_THRESHOLD_BYTES`.
|
||||
*/
|
||||
export const SPINE_TRIM_THRESHOLD_BYTES = 10 * 1024;
|
||||
|
||||
export type SpineTrimSliceShape =
|
||||
| { readonly type: 'head'; readonly chars: number }
|
||||
| { readonly type: 'tail'; readonly chars: number }
|
||||
| {
|
||||
readonly type: 'anchor';
|
||||
readonly anchor: string;
|
||||
readonly preceding: number;
|
||||
readonly following: number;
|
||||
};
|
||||
|
||||
export type SpineTrimOp =
|
||||
| { readonly kind: 'snip' }
|
||||
| { readonly kind: 'slice'; readonly shape: SpineTrimSliceShape };
|
||||
|
||||
export interface SpineTrimProjection {
|
||||
/** Tool-message index → trim id, while the message survives the tree fold. */
|
||||
readonly labels: ReadonlyMap<number, string>;
|
||||
/** Trim id → tool-message index. */
|
||||
readonly tagIndex: ReadonlyMap<string, number>;
|
||||
/** Tool-message index → accepted trim (a mask wins over the label). */
|
||||
readonly masks: ReadonlyMap<number, SpineTrimOp>;
|
||||
/** Ids trimmable right now: the last completed batch's unconsumed tags. */
|
||||
readonly eligible: ReadonlySet<string>;
|
||||
/** Ids consumed by an accepted trim, however long ago. */
|
||||
readonly consumed: ReadonlySet<string>;
|
||||
}
|
||||
|
||||
export function deriveSpineTrimProjection(
|
||||
messages: readonly ContextMessage[],
|
||||
): SpineTrimProjection {
|
||||
const callNames = new Map<string, string>();
|
||||
const trimCalls = new Map<string, SpineTrimCallArgs>();
|
||||
const labels = new Map<number, string>();
|
||||
const tagIndex = new Map<string, number>();
|
||||
const masks = new Map<number, SpineTrimOp>();
|
||||
const consumed = new Set<string>();
|
||||
let eligible = new Set<string>();
|
||||
let pendingCalls = new Set<string>();
|
||||
let batchTags: string[] = [];
|
||||
let tagCounter = 0;
|
||||
|
||||
for (let i = 0; i < messages.length; i++) {
|
||||
const message = messages[i];
|
||||
if (message === undefined) continue;
|
||||
if (message.role === 'assistant' && message.toolCalls.length > 0) {
|
||||
// A new batch starts: the previous one can no longer gain receipts, so
|
||||
// it shifts the eligibility window only if it completed. An aborted
|
||||
// batch (calls left unanswered) leaves the window where it was.
|
||||
if (pendingCalls.size === 0) eligible = new Set(batchTags);
|
||||
pendingCalls = new Set<string>();
|
||||
batchTags = [];
|
||||
for (const call of message.toolCalls) {
|
||||
callNames.set(call.id, call.name);
|
||||
pendingCalls.add(call.id);
|
||||
if (call.name === SPINE_TOOL_TRIM) {
|
||||
const args = parseTrimCallArgs(call.arguments);
|
||||
if (args !== undefined) trimCalls.set(call.id, args);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (message.role !== 'tool') continue;
|
||||
const callId = message.toolCallId;
|
||||
if (callId === undefined) continue;
|
||||
pendingCalls.delete(callId);
|
||||
const name = callNames.get(callId);
|
||||
if (name === SPINE_TOOL_TRIM) {
|
||||
if (message.isError === true) continue;
|
||||
if (messageText(message) !== TRIM_ACCEPTED_OUTPUT) continue;
|
||||
const args = trimCalls.get(callId);
|
||||
const target = args === undefined ? undefined : tagIndex.get(args.trimId);
|
||||
if (args === undefined || target === undefined || consumed.has(args.trimId)) continue;
|
||||
masks.set(target, args.op);
|
||||
consumed.add(args.trimId);
|
||||
continue;
|
||||
}
|
||||
if (name === undefined || name.startsWith('spine_')) continue;
|
||||
if (!message.content.every((part) => part.type === 'text')) continue;
|
||||
const text = messageText(message);
|
||||
if (utf8Length(text) <= SPINE_TRIM_THRESHOLD_BYTES) continue;
|
||||
tagCounter += 1;
|
||||
const tag = `trim_${String(tagCounter)}`;
|
||||
labels.set(i, tag);
|
||||
tagIndex.set(tag, i);
|
||||
batchTags.push(tag);
|
||||
}
|
||||
// A tail batch still waiting for receipts never shifts the window, so a
|
||||
// trim call validates against the batch that precedes its own.
|
||||
if (pendingCalls.size === 0) eligible = new Set(batchTags);
|
||||
|
||||
return { labels, tagIndex, masks, eligible, consumed };
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the flat tool arguments into a trim op; returns undefined for a
|
||||
* malformed shape (a `slice` must name exactly one of head / tail / anchor).
|
||||
* Shared by the derivation (parsing stored calls) and the `spine_trim` tool
|
||||
* (validating fresh input), so a call the tool rejects can never parse here.
|
||||
*/
|
||||
export function normalizeTrimOp(
|
||||
op: string,
|
||||
shape: {
|
||||
readonly head?: number | undefined;
|
||||
readonly tail?: number | undefined;
|
||||
readonly anchor?: string | undefined;
|
||||
readonly preceding?: number | undefined;
|
||||
readonly following?: number | undefined;
|
||||
},
|
||||
): SpineTrimOp | undefined {
|
||||
if (op === 'snip') return { kind: 'snip' };
|
||||
if (op !== 'slice') return undefined;
|
||||
const slices: SpineTrimSliceShape[] = [];
|
||||
if (shape.head !== undefined) slices.push({ type: 'head', chars: shape.head });
|
||||
if (shape.tail !== undefined) slices.push({ type: 'tail', chars: shape.tail });
|
||||
if (shape.anchor !== undefined) {
|
||||
slices.push({
|
||||
type: 'anchor',
|
||||
anchor: shape.anchor,
|
||||
preceding: shape.preceding ?? 0,
|
||||
following: shape.following ?? 0,
|
||||
});
|
||||
}
|
||||
if (slices.length !== 1) return undefined;
|
||||
const slice = slices[0];
|
||||
if (slice === undefined) return undefined;
|
||||
return { kind: 'slice', shape: slice };
|
||||
}
|
||||
|
||||
interface SpineTrimCallArgs {
|
||||
readonly trimId: string;
|
||||
readonly op: SpineTrimOp;
|
||||
}
|
||||
|
||||
function parseTrimCallArgs(raw: string | null): SpineTrimCallArgs | undefined {
|
||||
if (raw === null) return undefined;
|
||||
let parsed: unknown;
|
||||
try {
|
||||
parsed = JSON.parse(raw);
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof parsed !== 'object' || parsed === null) return undefined;
|
||||
const record = parsed as Record<string, unknown>;
|
||||
const trimId = record['TRIM_ID'];
|
||||
if (typeof trimId !== 'string' || trimId.length === 0) return undefined;
|
||||
const op = record['op'];
|
||||
if (typeof op !== 'string') return undefined;
|
||||
const normalized = normalizeTrimOp(op, {
|
||||
head: positiveInt(record['head']),
|
||||
tail: positiveInt(record['tail']),
|
||||
anchor: nonEmptyString(record['anchor']),
|
||||
preceding: nonNegativeInt(record['preceding']),
|
||||
following: nonNegativeInt(record['following']),
|
||||
});
|
||||
if (normalized === undefined) return undefined;
|
||||
return { trimId, op: normalized };
|
||||
}
|
||||
|
||||
function positiveInt(value: unknown): number | undefined {
|
||||
return typeof value === 'number' && Number.isInteger(value) && value > 0 ? value : undefined;
|
||||
}
|
||||
|
||||
function nonNegativeInt(value: unknown): number | undefined {
|
||||
return typeof value === 'number' && Number.isInteger(value) && value >= 0 ? value : undefined;
|
||||
}
|
||||
|
||||
function nonEmptyString(value: unknown): string | undefined {
|
||||
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
||||
}
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
function utf8Length(text: string): number {
|
||||
return encoder.encode(text).length;
|
||||
}
|
||||
|
||||
function messageText(message: ContextMessage): string {
|
||||
return message.content.map((part) => (part.type === 'text' ? part.text : '')).join('');
|
||||
}
|
||||
99
packages/agent-core-v2/src/agent/spine/spineTrimFold.ts
Normal file
99
packages/agent-core-v2/src/agent/spine/spineTrimFold.ts
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/**
|
||||
* `spine` domain (L4) — renders the derived trim projection onto the messages
|
||||
* that survive the tree fold.
|
||||
*
|
||||
* Three renderings, each byte-stable until a mask lands: an untrimmed
|
||||
* oversized result keeps its full body behind a `[TRIM_ID: trim_N]` label —
|
||||
* the label stays visible after the id leaves the eligibility window, because
|
||||
* visibility is the projection and trimmability is not; a snipped result
|
||||
* collapses to the upstream cleared placeholder; a sliced result renders only
|
||||
* the kept head / tail / anchor window with the label gone, so a trimmed
|
||||
* result can never be trimmed again. Pure mapping over stored messages — the
|
||||
* stored history is never mutated. Consumed by `spineFold`'s live-range sink.
|
||||
*/
|
||||
|
||||
import type { ContextMessage } from '#/agent/contextMemory/types';
|
||||
import type { ContentPart } from '#/kosong/contract/message';
|
||||
|
||||
import type { SpineTrimOp, SpineTrimProjection, SpineTrimSliceShape } from './spineTrimDerive';
|
||||
|
||||
/** Placeholder body of a snipped result — verbatim upstream wording. */
|
||||
export const SPINE_TRIM_SNIPPED_PLACEHOLDER = '[Old tool result content cleared]';
|
||||
|
||||
export function applySpineTrim(
|
||||
projection: SpineTrimProjection,
|
||||
index: number,
|
||||
message: ContextMessage,
|
||||
): ContextMessage {
|
||||
const mask = projection.masks.get(index);
|
||||
if (mask !== undefined) return maskMessage(message, mask);
|
||||
const tag = projection.labels.get(index);
|
||||
if (tag === undefined) return message;
|
||||
return { ...message, content: prefixFirstText(message.content, `[TRIM_ID: ${tag}]\n`) };
|
||||
}
|
||||
|
||||
function maskMessage(message: ContextMessage, op: SpineTrimOp): ContextMessage {
|
||||
const text =
|
||||
op.kind === 'snip' ? SPINE_TRIM_SNIPPED_PLACEHOLDER : sliceText(messageText(message), op.shape);
|
||||
return { ...message, content: [{ type: 'text', text }] };
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a slice shape to a body. head / tail count CHARACTERS (code points,
|
||||
* so a surrogate pair is never split); an anchor window keeps complete LINES:
|
||||
* the line the anchor starts on plus `preceding` / `following` full lines
|
||||
* around it. An anchor the body does not contain renders the body unchanged —
|
||||
* host validation rejects such calls before their receipt can land, so this
|
||||
* branch is only a degraded-history fallback.
|
||||
*/
|
||||
function sliceText(text: string, shape: SpineTrimSliceShape): string {
|
||||
switch (shape.type) {
|
||||
case 'head':
|
||||
return Array.from(text).slice(0, shape.chars).join('');
|
||||
case 'tail': {
|
||||
const chars = Array.from(text);
|
||||
return chars.slice(Math.max(0, chars.length - shape.chars)).join('');
|
||||
}
|
||||
case 'anchor': {
|
||||
const window = anchorWindow(text, shape.anchor, shape.preceding, shape.following);
|
||||
return window ?? text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function anchorWindow(
|
||||
text: string,
|
||||
anchor: string,
|
||||
preceding: number,
|
||||
following: number,
|
||||
): string | undefined {
|
||||
const at = text.indexOf(anchor);
|
||||
if (at < 0) return undefined;
|
||||
// The anchor line spans the newline boundaries around the anchor's start.
|
||||
let start = text.slice(0, at).lastIndexOf('\n') + 1;
|
||||
for (let i = 0; i < preceding && start > 0; i++) {
|
||||
const newline = text.lastIndexOf('\n', start - 2);
|
||||
const nextStart = newline + 1;
|
||||
if (nextStart >= start) break;
|
||||
start = nextStart;
|
||||
}
|
||||
let end = text.indexOf('\n', at);
|
||||
if (end < 0) end = text.length;
|
||||
for (let i = 0; i < following && end < text.length; i++) {
|
||||
const newline = text.indexOf('\n', end + 1);
|
||||
end = newline < 0 ? text.length : newline;
|
||||
}
|
||||
return text.slice(start, end);
|
||||
}
|
||||
|
||||
function prefixFirstText(content: readonly ContentPart[], prefix: string): ContentPart[] {
|
||||
const index = content.findIndex((part) => part.type === 'text');
|
||||
if (index < 0) return [{ type: 'text', text: prefix.trimEnd() }, ...content];
|
||||
return content.map((part, position) =>
|
||||
position === index && part.type === 'text' ? { type: 'text', text: prefix + part.text } : part,
|
||||
);
|
||||
}
|
||||
|
||||
function messageText(message: ContextMessage): string {
|
||||
return message.content.map((part) => (part.type === 'text' ? part.text : '')).join('');
|
||||
}
|
||||
|
|
@ -20,3 +20,30 @@ export function toControlResult(result: SpineTransitionResult): ExecutableToolRe
|
|||
if (result.accepted) return { isError: false, output: ACCEPTED_OUTPUT };
|
||||
return { isError: true, output: result.reason };
|
||||
}
|
||||
|
||||
/**
|
||||
* Receipt of an accepted `spine_trim` call. Unlike a transition receipt the
|
||||
* trim takes effect immediately — the receipt landing in history IS the trim
|
||||
* — and the trim derivation matches this text verbatim.
|
||||
*/
|
||||
export const TRIM_ACCEPTED_OUTPUT = 'trim accepted';
|
||||
|
||||
export function toTrimResult(result: SpineTransitionResult): ExecutableToolResult {
|
||||
if (result.accepted) return { isError: false, output: TRIM_ACCEPTED_OUTPUT };
|
||||
return { isError: true, output: result.reason };
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the result of `IAgentSpineService.executeSpawn` to an executable tool
|
||||
* result: accepted fissions return the structured JSON receipt verbatim so it
|
||||
* can be matched by `deriveSpineState`; rejected fissions surface the reason as
|
||||
* an error so the model can self-correct.
|
||||
*/
|
||||
export function toSpawnResult(
|
||||
result: SpineTransitionResult & { readonly receipt?: string },
|
||||
): ExecutableToolResult {
|
||||
if (result.accepted) {
|
||||
return { isError: false, output: result.receipt ?? '' };
|
||||
}
|
||||
return { isError: true, output: result.reason };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,3 +24,39 @@ export const SPINE_NEXT_SUMMARY_DESCRIPTION =
|
|||
|
||||
export const SPINE_NODE_MEMORY_DESCRIPTION =
|
||||
'Continuation memory for the node being closed. Optimize for compact recoverability: preserve the smallest sufficient state that lets future work continue correctly without replaying this node. Treat inherited context and assembled child memory as already available; write only compact deltas and current state needed for continuation. Include objective/status, decisions, artifacts/evidence, validation, constraints or risks, next action when work remains, and [U#] request status. Use precise paths, ids, commit hashes, and test names when they matter.';
|
||||
|
||||
export const SPINE_TRIM_DESCRIPTION =
|
||||
'Conservatively trim one tagged tool-result projection without changing the Spine tree or creating memory. A TRIM_ID is valid only for the immediately preceding tool-result batch and expires after the next assistant tool request; after a miss, do not retry it. Use slice to retain needed evidence, use snip only after useful facts are preserved, and otherwise leave the result unchanged.';
|
||||
|
||||
export const SPINE_TRIM_ID_DESCRIPTION =
|
||||
'Trim id attached to a tool response in the immediately previous tool-result batch; it expires after your next assistant tool request.';
|
||||
|
||||
export const SPINE_TRIM_OP_DESCRIPTION =
|
||||
'Use snip only when useful facts are preserved elsewhere; use slice to keep the needed head, tail, or anchor window.';
|
||||
|
||||
export const SPINE_TRIM_HEAD_DESCRIPTION =
|
||||
'For op="slice", keep this many characters from the start of the current visible body. Mutually exclusive with tail and anchor.';
|
||||
|
||||
export const SPINE_TRIM_TAIL_DESCRIPTION =
|
||||
'For op="slice", keep this many characters from the end of the current visible body. Mutually exclusive with head and anchor.';
|
||||
|
||||
export const SPINE_TRIM_ANCHOR_DESCRIPTION =
|
||||
'For op="slice", locate this non-empty text in the current visible body and keep an anchor window. Mutually exclusive with head and tail.';
|
||||
|
||||
export const SPINE_TRIM_PRECEDING_DESCRIPTION =
|
||||
'For anchor slice, keep this many complete lines before the anchor line.';
|
||||
|
||||
export const SPINE_TRIM_FOLLOWING_DESCRIPTION =
|
||||
'For anchor slice, keep this many complete lines after the anchor line.';
|
||||
|
||||
export const SPINE_SPAWN_DESCRIPTION =
|
||||
'Fission the current continuation into parallel, independent branches. Each branch runs in its own child agent with no supervisory model active; the original continuation is suspended until all branches complete. The branches complete their assignments in parallel, and the host atomically records their outcomes in input order as a structured receipt. Use only when the branches are genuinely independent and can proceed without coordination; do not use spine_spawn for work that requires cross-branch synchronization or a shared plan.';
|
||||
|
||||
export const SPINE_SPAWN_TASKS_DESCRIPTION =
|
||||
'Array of branch assignments. Must contain at least 2 entries and no more than the current capacity.';
|
||||
|
||||
export const SPINE_SPAWN_SUMMARY_DESCRIPTION =
|
||||
'Concise branch label, distinct within this spawn call, and its independently owned outcome.';
|
||||
|
||||
export const SPINE_SPAWN_PROMPT_DESCRIPTION =
|
||||
'Complete branch assignment, including the task, any constraints, and coordination conventions the branch should follow. The branch will be run in isolation with only this prompt and the inherited context.';
|
||||
|
|
|
|||
78
packages/agent-core-v2/src/agent/spine/tools/spine-spawn.ts
Normal file
78
packages/agent-core-v2/src/agent/spine/tools/spine-spawn.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* `spine` domain (L4) — `spine_spawn` control tool.
|
||||
*
|
||||
* Receipt-only, but NOT a transition in the ordinary sense: the accepted
|
||||
* structured receipt landing in history IS the join, from which the projection
|
||||
* synthesizes N closed child nodes. The service owns capacity admission and
|
||||
* per-step mutual exclusion with the other spine control tools. Self-registers
|
||||
* via `registerTool` gated on BOTH the `KIMI_CODE_SPINE` and
|
||||
* `KIMI_CODE_SPINE_SPAWN` flags and `agentId === 'main'` (main-agent-only,
|
||||
* like the other spine tools), and only when the configured capacity admits at
|
||||
* least two concurrent child agents. Bound at Agent scope.
|
||||
*/
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
import { toInputJsonSchema } from '#/tool/input-schema';
|
||||
import type { BuiltinTool, ToolExecution } from '#/tool/toolContract';
|
||||
import { registerTool } from '#/agent/toolRegistry/toolContribution';
|
||||
|
||||
import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext';
|
||||
import { SPINE_FLAG_ID, SPINE_SPAWN_FLAG_ID } from '#/agent/spine/flag';
|
||||
import { IAgentSpineService, SPINE_TOOL_SPAWN } from '#/agent/spine/spine';
|
||||
import {
|
||||
maxSpawnBranchCount,
|
||||
resolveMaxThreads,
|
||||
SPINE_SPAWN_MAX_THREADS_ENV,
|
||||
} from '#/agent/spine/spineSpawn';
|
||||
import { IFlagService } from '#/app/flag/flag';
|
||||
import { toSpawnResult } from './controlResult';
|
||||
import {
|
||||
SPINE_SPAWN_DESCRIPTION,
|
||||
SPINE_SPAWN_PROMPT_DESCRIPTION,
|
||||
SPINE_SPAWN_SUMMARY_DESCRIPTION,
|
||||
SPINE_SPAWN_TASKS_DESCRIPTION,
|
||||
} from './descriptions';
|
||||
|
||||
const SpineSpawnInputSchema = z.object({
|
||||
tasks: z
|
||||
.array(
|
||||
z.object({
|
||||
summary: z.string().min(1).describe(SPINE_SPAWN_SUMMARY_DESCRIPTION),
|
||||
prompt: z.string().min(1).describe(SPINE_SPAWN_PROMPT_DESCRIPTION),
|
||||
}),
|
||||
)
|
||||
.min(2)
|
||||
.describe(SPINE_SPAWN_TASKS_DESCRIPTION),
|
||||
});
|
||||
|
||||
export type SpineSpawnInput = z.infer<typeof SpineSpawnInputSchema>;
|
||||
|
||||
export class SpineSpawnTool implements BuiltinTool<SpineSpawnInput> {
|
||||
readonly name = SPINE_TOOL_SPAWN;
|
||||
readonly description = SPINE_SPAWN_DESCRIPTION;
|
||||
readonly parameters: Record<string, unknown> = toInputJsonSchema(SpineSpawnInputSchema);
|
||||
|
||||
constructor(@IAgentSpineService private readonly spine: IAgentSpineService) {}
|
||||
|
||||
resolveExecution(input: SpineSpawnInput): ToolExecution {
|
||||
return {
|
||||
approvalRule: this.name,
|
||||
description: 'Spawn parallel Spine branches',
|
||||
execute: async (ctx) => toSpawnResult(await this.spine.executeSpawn(input.tasks, ctx.signal)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function spawnCapacityAtLeastTwo(): boolean {
|
||||
const maxThreads = resolveMaxThreads(process.env[SPINE_SPAWN_MAX_THREADS_ENV]);
|
||||
return maxSpawnBranchCount(maxThreads) >= 2;
|
||||
}
|
||||
|
||||
registerTool(SpineSpawnTool, {
|
||||
when: (accessor) =>
|
||||
accessor.get(IFlagService).enabled(SPINE_FLAG_ID) &&
|
||||
accessor.get(IFlagService).enabled(SPINE_SPAWN_FLAG_ID) &&
|
||||
accessor.get(IAgentScopeContext).agentId === 'main' &&
|
||||
spawnCapacityAtLeastTwo(),
|
||||
});
|
||||
79
packages/agent-core-v2/src/agent/spine/tools/spine-trim.ts
Normal file
79
packages/agent-core-v2/src/agent/spine/tools/spine-trim.ts
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
* `spine` domain (L4) — `spine_trim` tool.
|
||||
*
|
||||
* Receipt-only, but NOT a transition: no per-step budget and no pending
|
||||
* registration — the host validates the call against the derived eligibility
|
||||
* window (unknown / consumed / out-of-window / anchor-missing ids reject with
|
||||
* a do-not-retry reason), and the accepted receipt landing in history IS the
|
||||
* trim, re-derived by the projection on every read. A malformed slice shape
|
||||
* (not exactly one of head / tail / anchor) rejects here with a retryable
|
||||
* reason, before any receipt exists. Self-registers via `registerTool` gated
|
||||
* on BOTH the `KIMI_CODE_SPINE` and `KIMI_CODE_SPINE_TRIM` flags and
|
||||
* `agentId === 'main'` (main-agent-only, like the other spine tools). Bound
|
||||
* at Agent scope.
|
||||
*/
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
import { toInputJsonSchema } from '#/tool/input-schema';
|
||||
import type { BuiltinTool, ToolExecution } from '#/tool/toolContract';
|
||||
import { registerTool } from '#/agent/toolRegistry/toolContribution';
|
||||
|
||||
import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext';
|
||||
import { SPINE_FLAG_ID, SPINE_TRIM_FLAG_ID } from '#/agent/spine/flag';
|
||||
import { IAgentSpineService, SPINE_TOOL_TRIM } from '#/agent/spine/spine';
|
||||
import { normalizeTrimOp } from '#/agent/spine/spineTrimDerive';
|
||||
import { IFlagService } from '#/app/flag/flag';
|
||||
import { toTrimResult } from './controlResult';
|
||||
import {
|
||||
SPINE_TRIM_ANCHOR_DESCRIPTION,
|
||||
SPINE_TRIM_DESCRIPTION,
|
||||
SPINE_TRIM_FOLLOWING_DESCRIPTION,
|
||||
SPINE_TRIM_HEAD_DESCRIPTION,
|
||||
SPINE_TRIM_ID_DESCRIPTION,
|
||||
SPINE_TRIM_OP_DESCRIPTION,
|
||||
SPINE_TRIM_PRECEDING_DESCRIPTION,
|
||||
SPINE_TRIM_TAIL_DESCRIPTION,
|
||||
} from './descriptions';
|
||||
|
||||
const SpineTrimInputSchema = z.object({
|
||||
TRIM_ID: z.string().min(1).describe(SPINE_TRIM_ID_DESCRIPTION),
|
||||
op: z.enum(['snip', 'slice']).describe(SPINE_TRIM_OP_DESCRIPTION),
|
||||
head: z.number().int().positive().optional().describe(SPINE_TRIM_HEAD_DESCRIPTION),
|
||||
tail: z.number().int().positive().optional().describe(SPINE_TRIM_TAIL_DESCRIPTION),
|
||||
anchor: z.string().min(1).optional().describe(SPINE_TRIM_ANCHOR_DESCRIPTION),
|
||||
preceding: z.number().int().nonnegative().optional().describe(SPINE_TRIM_PRECEDING_DESCRIPTION),
|
||||
following: z.number().int().nonnegative().optional().describe(SPINE_TRIM_FOLLOWING_DESCRIPTION),
|
||||
});
|
||||
|
||||
export type SpineTrimInput = z.infer<typeof SpineTrimInputSchema>;
|
||||
|
||||
const REJECT_SLICE_SHAPE =
|
||||
'op="slice" requires exactly one of head, tail, or anchor; correct the arguments and retry.';
|
||||
|
||||
export class SpineTrimTool implements BuiltinTool<SpineTrimInput> {
|
||||
readonly name = SPINE_TOOL_TRIM;
|
||||
readonly description = SPINE_TRIM_DESCRIPTION;
|
||||
readonly parameters: Record<string, unknown> = toInputJsonSchema(SpineTrimInputSchema);
|
||||
|
||||
constructor(@IAgentSpineService private readonly spine: IAgentSpineService) {}
|
||||
|
||||
resolveExecution(input: SpineTrimInput): ToolExecution {
|
||||
return {
|
||||
approvalRule: this.name,
|
||||
description: 'Trim a tagged tool result',
|
||||
execute: async () => {
|
||||
const op = normalizeTrimOp(input.op, input);
|
||||
if (op === undefined) return { isError: true, output: REJECT_SLICE_SHAPE };
|
||||
return toTrimResult(this.spine.acceptTrim(input.TRIM_ID, op));
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
registerTool(SpineTrimTool, {
|
||||
when: (accessor) =>
|
||||
accessor.get(IFlagService).enabled(SPINE_FLAG_ID) &&
|
||||
accessor.get(IFlagService).enabled(SPINE_TRIM_FLAG_ID) &&
|
||||
accessor.get(IAgentScopeContext).agentId === 'main',
|
||||
});
|
||||
|
|
@ -44,6 +44,15 @@ export interface CreateAgentOptions {
|
|||
export interface ForkAgentOptions {
|
||||
readonly agentId?: string;
|
||||
readonly binding?: Partial<BindAgentInput>;
|
||||
/**
|
||||
* When true, trim the trailing assistant message that carries tool calls from
|
||||
* the copied context history before appending it to the forked agent. This
|
||||
* removes the in-flight tool-call carrier (e.g. `spine_spawn`) so the child
|
||||
* agent does not inherit an unfinished parent action as part of its context.
|
||||
* Only the last message is considered; if it has no tool calls it is left in
|
||||
* place. Default behavior (undefined/false) copies the history verbatim.
|
||||
*/
|
||||
readonly trimTrailingToolCallBatch?: boolean;
|
||||
}
|
||||
|
||||
export interface AgentListFilter {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ import { IAgentToolSelectAnnouncementsService } from '#/agent/toolSelect/toolSel
|
|||
import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode';
|
||||
import { IAgentPermissionGate } from '#/agent/permissionGate/permissionGate';
|
||||
import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory';
|
||||
import type { ContextMessage } from '#/agent/contextMemory/types';
|
||||
import { IAgentContextInjectorService } from '#/agent/contextInjector/contextInjector';
|
||||
import { IAgentFullCompactionService } from '#/agent/fullCompaction/fullCompaction';
|
||||
import { IAgentGoalService } from '#/agent/goal/goal';
|
||||
|
|
@ -309,7 +310,11 @@ export class AgentLifecycleService extends Disposable implements IAgentLifecycle
|
|||
|
||||
const sourceMessages = source.accessor.get(IAgentContextMemoryService)?.get();
|
||||
if (sourceMessages !== undefined && sourceMessages.length > 0) {
|
||||
child.accessor.get(IAgentContextMemoryService)?.append(...sourceMessages);
|
||||
const messagesToCopy =
|
||||
opts?.trimTrailingToolCallBatch === true
|
||||
? trimTrailingToolCallBatch(sourceMessages)
|
||||
: sourceMessages;
|
||||
child.accessor.get(IAgentContextMemoryService)?.append(...messagesToCopy);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
|
@ -353,6 +358,20 @@ export class AgentLifecycleService extends Disposable implements IAgentLifecycle
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a shallow copy of `messages` with the last assistant message that
|
||||
* carries tool calls removed, if such a message is the final message in the
|
||||
* array. If the last message is not an assistant message or has no tool calls,
|
||||
* the array is returned unchanged (the caller already has a fresh reference to
|
||||
* the source messages, so a shallow copy is defensive enough).
|
||||
*/
|
||||
function trimTrailingToolCallBatch(messages: readonly ContextMessage[]): readonly ContextMessage[] {
|
||||
const last = messages.at(-1);
|
||||
if (last === undefined || last.role !== 'assistant') return messages;
|
||||
if (last.toolCalls.length === 0) return messages;
|
||||
return messages.slice(0, -1);
|
||||
}
|
||||
|
||||
registerScopedService(
|
||||
LifecycleScope.Session,
|
||||
IAgentLifecycleService,
|
||||
|
|
|
|||
|
|
@ -55,16 +55,18 @@ const AGENT_TOOLS = [
|
|||
// agent's active-tool whitelist lets the spine tools through when the
|
||||
// `spine` experimental flag is enabled — the tools register only on the
|
||||
// main agent (see `registerTool(..., { when })` gating on
|
||||
// `IFlagService.enabled(SPINE_FLAG_ID)` and `agentId === 'main'`), so for
|
||||
// every other agent a name listed here contributes nothing, same as an
|
||||
// unmatched `mcp__*` pattern. The `Agent` tool description filters these
|
||||
// names out when rendering profile tool lists (see
|
||||
// `session/subagent/tools/agent.ts`), so they never reach an LLM-facing
|
||||
// schema as text either.
|
||||
// `IFlagService.enabled(SPINE_FLAG_ID)` and `agentId === 'main'`; the trim
|
||||
// tool additionally requires `SPINE_TRIM_FLAG_ID`), so for every other
|
||||
// agent a name listed here contributes nothing, same as an unmatched
|
||||
// `mcp__*` pattern. The `Agent` tool description filters these names out
|
||||
// when rendering profile tool lists (see `session/subagent/tools/agent.ts`),
|
||||
// so they never reach an LLM-facing schema as text either.
|
||||
'spine_open',
|
||||
'spine_close',
|
||||
'spine_next',
|
||||
'spine_tree',
|
||||
'spine_trim',
|
||||
'spine_spawn',
|
||||
] as const;
|
||||
|
||||
const CODER_TOOLS = [
|
||||
|
|
|
|||
152
packages/agent-core-v2/test/spine/fixtures/legacy-next.jsonl
Normal file
152
packages/agent-core-v2/test/spine/fixtures/legacy-next.jsonl
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
{"type":"metadata","protocol_version":"1.4","created_at":1783999150312}
|
||||
{"type":"mcp.tools_discovered","serverName":"server_1","hash":"hash_1","tools":[{"name":"tool_1","description":"text_1","inputSchema":{}},{"name":"tool_2","description":"text_2","inputSchema":{}}],"enabledNames":["tool_1","tool_2"],"time":1783999150312}
|
||||
{"type":"permission.set_mode","mode":"yolo","time":1783999150312}
|
||||
{"type":"config.update","profileName":"name_1","systemPrompt":"prompt_3","time":1783999150316}
|
||||
{"type":"tools.set_active_tools","names":["Read","Write","Edit","Grep","Glob","Bash","TaskList","TaskOutput","TaskStop","CronCreate","CronList","CronDelete","ReadMediaFile","TodoList","Skill","WebSearch","Agent","AgentSwarm","FetchURL","AskUserQuestion","EnterPlanMode","ExitPlanMode","CreateGoal","GetGoal","SetGoalBudget","UpdateGoal","mcp__*","spine_open","spine_close","spine_next","spine_tree"],"time":1783999150316}
|
||||
{"type":"config.update","modelAlias":"model_3","thinkingEffort":"max","time":1783999150316}
|
||||
{"type":"config.update","thinkingEffort":"max","time":1783999150316}
|
||||
{"type":"permission.set_mode","mode":"yolo","time":1783999150317}
|
||||
{"type":"permission.set_mode","mode":"yolo","time":1783999150330}
|
||||
{"type":"config.update","modelAlias":"model_4","thinkingEffort":"max","time":1783999160422}
|
||||
{"type":"config.update","thinkingEffort":"on","time":1783999160423}
|
||||
{"type":"turn.prompt","input":[{"type":"text","text":"text_77"}],"origin":{"kind":"user"},"time":1783999162407}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_77"}],"toolCalls":[],"id":"msgid_5"},"time":1783999162407}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_71","turnId":"0","step":1},"time":1783999162407}
|
||||
{"type":"llm.tools_snapshot","hash":"hash_4","tools":[{"name":"Agent","description":"text_4","parameters":{}},{"name":"AgentSwarm","description":"text_5","parameters":{}},{"name":"AskUserQuestion","description":"text_78","parameters":{}},{"name":"Bash","description":"text_79","parameters":{}},{"name":"CreateGoal","description":"text_8","parameters":{}},{"name":"CronCreate","description":"text_9","parameters":{}},{"name":"CronDelete","description":"text_10","parameters":{}},{"name":"CronList","description":"text_11","parameters":{}},{"name":"Edit","description":"text_12","parameters":{}},{"name":"EnterPlanMode","description":"text_13","parameters":{}},{"name":"ExitPlanMode","description":"text_14","parameters":{}},{"name":"FetchURL","description":"text_15","parameters":{}},{"name":"GetGoal","description":"text_16","parameters":{}},{"name":"Glob","description":"text_17","parameters":{}},{"name":"Grep","description":"text_18","parameters":{}},{"name":"mcp__plugin-kimi-datasource_data__call_data_source_tool","description":"text_1","parameters":{}},{"name":"mcp__plugin-kimi-datasource_data__get_data_source_desc","description":"text_2","parameters":{}},{"name":"Read","description":"text_19","parameters":{}},{"name":"ReadMediaFile","description":"text_80","parameters":{}},{"name":"SetGoalBudget","description":"text_21","parameters":{}},{"name":"Skill","description":"text_22","parameters":{}},{"name":"spine_close","description":"text_23","parameters":{}},{"name":"spine_next","description":"text_24","parameters":{}},{"name":"spine_open","description":"text_25","parameters":{}},{"name":"spine_tree","description":"text_26","parameters":{}},{"name":"TaskList","description":"text_27","parameters":{}},{"name":"TaskOutput","description":"text_81","parameters":{}},{"name":"TaskStop","description":"text_29","parameters":{}},{"name":"UpdateGoal","description":"text_30","parameters":{}},{"name":"WebSearch","description":"text_31","parameters":{}},{"name":"Write","description":"text_32","parameters":{}}],"time":1783999162408}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":262044,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":2,"turnStep":"0.1","time":1783999162409}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":25761,"output":171,"inputCacheRead":512,"inputCacheCreation":0},"usageScope":"turn","time":1783999172043}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_72","turnId":"0","step":1,"stepUuid":"uuid_71","part":{"type":"think","think":"text_82"}},"time":1783999172044}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_73","turnId":"0","step":1,"stepUuid":"uuid_71","toolCallId":"tool_kUFbxDvgvmx5Fdg0LzShRg3G","name":"spine_open","args":{"summary":"summary_4"}},"time":1783999172045}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_73","toolCallId":"tool_kUFbxDvgvmx5Fdg0LzShRg3G","result":{"output":"accepted — commits after this step completes"}},"time":1783999172047}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_71","turnId":"0","step":1,"finishReason":"tool_use","usage":{"inputOther":25761,"output":171,"inputCacheRead":512,"inputCacheCreation":0},"llmFirstTokenLatencyMs":5853,"llmStreamDurationMs":3781,"llmRequestBuildMs":0,"llmServerFirstTokenMs":5853,"llmServerDecodeMs":3779,"llmClientConsumeMs":2,"messageId":"uuid_74","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999172047}
|
||||
{"type":"spine.open","id":"1.1.1","summary":"summary_4","parentId":"1.1","openedAt":1,"baselineTokens":26457,"time":1783999172047}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_75","turnId":"0","step":2},"time":1783999172047}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":235684,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":4,"turnStep":"0.2","time":1783999172048}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":262,"output":110,"inputCacheRead":27204,"inputCacheCreation":0},"usageScope":"turn","time":1783999177303}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_76","turnId":"0","step":2,"stepUuid":"uuid_75","part":{"type":"think","think":"text_83"}},"time":1783999177303}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_77","turnId":"0","step":2,"stepUuid":"uuid_75","toolCallId":"tool_wlJWxGoJl07piyztnjADuFL3","name":"Glob","args":{}},"time":1783999177306}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_78","turnId":"0","step":2,"stepUuid":"uuid_75","toolCallId":"tool_hTby4xZX4FcDuD42O1eK02Tc","name":"Glob","args":{}},"time":1783999177307}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_79","turnId":"0","step":2,"stepUuid":"uuid_75","toolCallId":"tool_lMqBgw2vQkwfM55riDBcHEqt","name":"Grep","args":{}},"time":1783999177307}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_77","toolCallId":"tool_wlJWxGoJl07piyztnjADuFL3","result":{"output":"text_84"}},"time":1783999177519}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_78","toolCallId":"tool_hTby4xZX4FcDuD42O1eK02Tc","result":{"output":"text_84"}},"time":1783999177520}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_79","toolCallId":"tool_lMqBgw2vQkwfM55riDBcHEqt","result":{"output":"text_85"}},"time":1783999177649}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_75","turnId":"0","step":2,"finishReason":"tool_use","usage":{"inputOther":262,"output":110,"inputCacheRead":27204,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2799,"llmStreamDurationMs":2455,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2799,"llmServerDecodeMs":2454,"llmClientConsumeMs":1,"messageId":"uuid_80","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999177650}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_81","turnId":"0","step":3},"time":1783999177650}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":234289,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":8,"turnStep":"0.3","time":1783999177653}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":451,"output":96,"inputCacheRead":27399,"inputCacheCreation":0},"usageScope":"turn","time":1783999181793}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_82","turnId":"0","step":3,"stepUuid":"uuid_81","part":{"type":"think","think":"text_86"}},"time":1783999181794}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_83","turnId":"0","step":3,"stepUuid":"uuid_81","toolCallId":"tool_yl2Tw1GX0PTBTsjbM3K2hJK4","name":"Read","args":{}},"time":1783999181796}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_83","toolCallId":"tool_yl2Tw1GX0PTBTsjbM3K2hJK4","result":{"output":"text_87","note":"text_88"}},"time":1783999181799}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_81","turnId":"0","step":3,"finishReason":"tool_use","usage":{"inputOther":451,"output":96,"inputCacheRead":27399,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2030,"llmStreamDurationMs":2109,"llmRequestBuildMs":1,"llmServerFirstTokenMs":2029,"llmServerDecodeMs":2108,"llmClientConsumeMs":1,"messageId":"uuid_84","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999181800}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_85","turnId":"0","step":4},"time":1783999181800}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":233871,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":10,"turnStep":"0.4","time":1783999181801}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":577,"output":210,"inputCacheRead":27783,"inputCacheCreation":0},"usageScope":"turn","time":1783999188918}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_86","turnId":"0","step":4,"stepUuid":"uuid_85","part":{"type":"think","think":"text_89"}},"time":1783999188918}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_87","turnId":"0","step":4,"stepUuid":"uuid_85","toolCallId":"tool_7mUyqSIE4Fh462U9oTeJAQQ6","name":"Bash","args":{}},"time":1783999188919}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_87","toolCallId":"tool_7mUyqSIE4Fh462U9oTeJAQQ6","result":{"output":"text_90"}},"time":1783999188942}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_85","turnId":"0","step":4,"finishReason":"tool_use","usage":{"inputOther":577,"output":210,"inputCacheRead":27783,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1846,"llmStreamDurationMs":5271,"llmRequestBuildMs":1,"llmServerFirstTokenMs":1845,"llmServerDecodeMs":5269,"llmClientConsumeMs":2,"messageId":"uuid_88","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999188943}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_89","turnId":"0","step":5},"time":1783999188943}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":232638,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":12,"turnStep":"0.5","time":1783999188944}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":1756,"output":101,"inputCacheRead":28287,"inputCacheCreation":0},"usageScope":"turn","time":1783999192551}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_90","turnId":"0","step":5,"stepUuid":"uuid_89","part":{"type":"think","think":"text_91"}},"time":1783999192551}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_91","turnId":"0","step":5,"stepUuid":"uuid_89","toolCallId":"tool_nwmDS011zJqemqyx0NDxcXFX","name":"Bash","args":{}},"time":1783999192552}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_91","toolCallId":"tool_nwmDS011zJqemqyx0NDxcXFX","result":{"output":"text_92"}},"time":1783999192565}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_89","turnId":"0","step":5,"finishReason":"tool_use","usage":{"inputOther":1756,"output":101,"inputCacheRead":28287,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2033,"llmStreamDurationMs":1574,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2033,"llmServerDecodeMs":1573,"llmClientConsumeMs":1,"messageId":"uuid_92","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999192565}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_93","turnId":"0","step":6},"time":1783999192565}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":231862,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":14,"turnStep":"0.6","time":1783999192566}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":404,"output":161,"inputCacheRead":29970,"inputCacheCreation":0},"usageScope":"turn","time":1783999196321}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_94","turnId":"0","step":6,"stepUuid":"uuid_93","part":{"type":"think","think":"text_93"}},"time":1783999196321}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_95","turnId":"0","step":6,"stepUuid":"uuid_93","toolCallId":"tool_oirTDHDaicmsVaQApKqwDDr9","name":"Bash","args":{}},"time":1783999196322}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_95","toolCallId":"tool_oirTDHDaicmsVaQApKqwDDr9","result":{"output":"text_94"}},"time":1783999196344}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_93","turnId":"0","step":6,"finishReason":"tool_use","usage":{"inputOther":404,"output":161,"inputCacheRead":29970,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1810,"llmStreamDurationMs":1944,"llmRequestBuildMs":0,"llmServerFirstTokenMs":1810,"llmServerDecodeMs":1942,"llmClientConsumeMs":2,"messageId":"uuid_96","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999196345}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_97","turnId":"0","step":7},"time":1783999196345}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":230983,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":16,"turnStep":"0.7","time":1783999196346}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":1072,"output":263,"inputCacheRead":30301,"inputCacheCreation":0},"usageScope":"turn","time":1783999201452}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_98","turnId":"0","step":7,"stepUuid":"uuid_97","part":{"type":"think","think":"text_95"}},"time":1783999201453}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_99","turnId":"0","step":7,"stepUuid":"uuid_97","toolCallId":"tool_2RLxKEyR5pbH3LF4XU9c1Kge","name":"Bash","args":{}},"time":1783999201454}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_99","toolCallId":"tool_2RLxKEyR5pbH3LF4XU9c1Kge","result":{"output":"text_96"}},"time":1783999201481}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_97","turnId":"0","step":7,"finishReason":"tool_use","usage":{"inputOther":1072,"output":263,"inputCacheRead":30301,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1630,"llmStreamDurationMs":3476,"llmRequestBuildMs":0,"llmServerFirstTokenMs":1630,"llmServerDecodeMs":3473,"llmClientConsumeMs":3,"messageId":"uuid_100","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999201481}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_101","turnId":"0","step":8},"time":1783999201482}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":229724,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":18,"turnStep":"0.8","time":1783999201483}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":1261,"output":213,"inputCacheRead":31300,"inputCacheCreation":0},"usageScope":"turn","time":1783999209067}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_102","turnId":"0","step":8,"stepUuid":"uuid_101","part":{"type":"think","think":"text_97"}},"time":1783999209068}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_103","turnId":"0","step":8,"stepUuid":"uuid_101","toolCallId":"tool_YqkYsXJiC4ni8Bk0kZ95duQ4","name":"Read","args":{}},"time":1783999209068}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_104","turnId":"0","step":8,"stepUuid":"uuid_101","toolCallId":"tool_m1pnjO1um9E7UHPjpQ88PJzv","name":"Read","args":{}},"time":1783999209069}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_104","toolCallId":"tool_m1pnjO1um9E7UHPjpQ88PJzv","result":{"output":"text_98","note":"text_99"}},"time":1783999209070}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_103","toolCallId":"tool_YqkYsXJiC4ni8Bk0kZ95duQ4","result":{"output":"text_100","note":"text_101"}},"time":1783999209078}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_101","turnId":"0","step":8,"finishReason":"tool_use","usage":{"inputOther":1261,"output":213,"inputCacheRead":31300,"inputCacheCreation":0},"llmFirstTokenLatencyMs":3875,"llmStreamDurationMs":3709,"llmRequestBuildMs":0,"llmServerFirstTokenMs":3875,"llmServerDecodeMs":3708,"llmClientConsumeMs":1,"messageId":"uuid_105","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999209078}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_106","turnId":"0","step":9},"time":1783999209079}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":226741,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":21,"turnStep":"0.9","time":1783999209080}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":3015,"output":338,"inputCacheRead":32488,"inputCacheCreation":0},"usageScope":"turn","time":1783999219490}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_107","turnId":"0","step":9,"stepUuid":"uuid_106","part":{"type":"think","think":"text_102"}},"time":1783999219491}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_108","turnId":"0","step":9,"stepUuid":"uuid_106","toolCallId":"tool_27Vb4ML92jZDpTfHPuLI8gzG","name":"Bash","args":{}},"time":1783999219492}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_108","toolCallId":"tool_27Vb4ML92jZDpTfHPuLI8gzG","result":{"output":"text_103"}},"time":1783999219540}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_106","turnId":"0","step":9,"finishReason":"tool_use","usage":{"inputOther":3015,"output":338,"inputCacheRead":32488,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2995,"llmStreamDurationMs":7414,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2995,"llmServerDecodeMs":7408,"llmClientConsumeMs":6,"messageId":"uuid_109","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999219540}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_110","turnId":"0","step":10},"time":1783999219541}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":226209,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":23,"turnStep":"0.10","time":1783999219542}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":509,"output":198,"inputCacheRead":35430,"inputCacheCreation":0},"usageScope":"turn","time":1783999229376}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_111","turnId":"0","step":10,"stepUuid":"uuid_110","part":{"type":"think","think":"text_104"}},"time":1783999229377}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_112","turnId":"0","step":10,"stepUuid":"uuid_110","toolCallId":"tool_7dxDBcpW5St5CeM9A6M6Tyfe","name":"spine_next","args":{"memory":"memory_4","summary":"summary_5"}},"time":1783999229380}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_112","toolCallId":"tool_7dxDBcpW5St5CeM9A6M6Tyfe","result":{"output":"accepted — commits after this step completes"}},"time":1783999229382}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_110","turnId":"0","step":10,"finishReason":"tool_use","usage":{"inputOther":509,"output":198,"inputCacheRead":35430,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2346,"llmStreamDurationMs":7473,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2346,"llmServerDecodeMs":7468,"llmClientConsumeMs":5,"messageId":"uuid_113","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999229382}
|
||||
{"type":"spine.next","closedId":"1.1.1","closedAt":21,"memory":"memory_4","archivePath":"path_4","openedId":"1.1.2","summary":"summary_5","baselineTokens":36150,"time":1783999229385}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_114","turnId":"0","step":11},"time":1783999229385}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":225991,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":5,"turnStep":"0.11","time":1783999229387}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":381,"output":388,"inputCacheRead":27210,"inputCacheCreation":0},"usageScope":"turn","time":1783999237668}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_115","turnId":"0","step":11,"stepUuid":"uuid_114","part":{"type":"think","think":"text_105"}},"time":1783999237669}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_116","turnId":"0","step":11,"stepUuid":"uuid_114","toolCallId":"tool_Vkoh7tPKxTdxnVSKlbBAzeaK","name":"Bash","args":{}},"time":1783999237669}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_116","toolCallId":"tool_Vkoh7tPKxTdxnVSKlbBAzeaK","result":{"output":"text_106","isError":true}},"time":1783999237752}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_114","turnId":"0","step":11,"finishReason":"tool_use","usage":{"inputOther":381,"output":388,"inputCacheRead":27210,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1816,"llmStreamDurationMs":6464,"llmRequestBuildMs":0,"llmServerFirstTokenMs":1816,"llmServerDecodeMs":6450,"llmClientConsumeMs":14,"messageId":"uuid_117","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999237752}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_118","turnId":"0","step":12},"time":1783999237752}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":234032,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":7,"turnStep":"0.12","time":1783999237753}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":627,"output":382,"inputCacheRead":27524,"inputCacheCreation":0},"usageScope":"turn","time":1783999246105}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_119","turnId":"0","step":12,"stepUuid":"uuid_118","part":{"type":"think","think":"text_107"}},"time":1783999246106}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_120","turnId":"0","step":12,"stepUuid":"uuid_118","toolCallId":"tool_gZECrzZR8s8Vd7hz8GzLX0HV","name":"Bash","args":{}},"time":1783999246107}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_120","toolCallId":"tool_gZECrzZR8s8Vd7hz8GzLX0HV","result":{"output":"text_108"}},"time":1783999246170}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_118","turnId":"0","step":12,"finishReason":"tool_use","usage":{"inputOther":627,"output":382,"inputCacheRead":27524,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2170,"llmStreamDurationMs":6182,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2170,"llmServerDecodeMs":6172,"llmClientConsumeMs":10,"messageId":"uuid_121","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999246170}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_122","turnId":"0","step":13},"time":1783999246170}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":233500,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":9,"turnStep":"0.13","time":1783999246171}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":599,"output":262,"inputCacheRead":28084,"inputCacheCreation":0},"usageScope":"turn","time":1783999255345}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_123","turnId":"0","step":13,"stepUuid":"uuid_122","part":{"type":"think","think":"text_109"}},"time":1783999255346}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_124","turnId":"0","step":13,"stepUuid":"uuid_122","toolCallId":"tool_c6t4r4Sbnv0rzyTnfTZndEr5","name":"spine_next","args":{"memory":"memory_5","summary":"summary_6"}},"time":1783999255347}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_124","toolCallId":"tool_c6t4r4Sbnv0rzyTnfTZndEr5","result":{"output":"accepted — commits after this step completes"}},"time":1783999255349}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_122","turnId":"0","step":13,"finishReason":"tool_use","usage":{"inputOther":599,"output":262,"inputCacheRead":28084,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1961,"llmStreamDurationMs":7213,"llmRequestBuildMs":1,"llmServerFirstTokenMs":1960,"llmServerDecodeMs":7209,"llmClientConsumeMs":4,"messageId":"uuid_125","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999255350}
|
||||
{"type":"spine.next","closedId":"1.1.2","closedAt":27,"memory":"memory_5","archivePath":"path_5","openedId":"1.1.3","summary":"summary_6","baselineTokens":28958,"time":1783999255355}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_126","turnId":"0","step":14},"time":1783999255356}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":233183,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":6,"turnStep":"0.14","time":1783999255359}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":470,"output":164,"inputCacheRead":27301,"inputCacheCreation":0},"usageScope":"turn","time":1783999261946}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_127","turnId":"0","step":14,"stepUuid":"uuid_126","part":{"type":"think","think":"text_110"}},"time":1783999261946}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_128","turnId":"0","step":14,"stepUuid":"uuid_126","toolCallId":"tool_SYug73WfPPCdo0aPWcarrYJc","name":"Glob","args":{}},"time":1783999261947}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_129","turnId":"0","step":14,"stepUuid":"uuid_126","toolCallId":"tool_AVvRXTCGJL8tEBe5QOnldiqY","name":"Bash","args":{}},"time":1783999261947}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_128","toolCallId":"tool_SYug73WfPPCdo0aPWcarrYJc","result":{"output":"text_111"}},"time":1783999262080}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_129","toolCallId":"tool_AVvRXTCGJL8tEBe5QOnldiqY","result":{"output":"text_112"}},"time":1783999262093}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_126","turnId":"0","step":14,"finishReason":"tool_use","usage":{"inputOther":470,"output":164,"inputCacheRead":27301,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2064,"llmStreamDurationMs":4523,"llmRequestBuildMs":1,"llmServerFirstTokenMs":2063,"llmServerDecodeMs":4521,"llmClientConsumeMs":2,"messageId":"uuid_130","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999262094}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_131","turnId":"0","step":15},"time":1783999262095}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":233922,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":9,"turnStep":"0.15","time":1783999262096}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":633,"output":52,"inputCacheRead":27705,"inputCacheCreation":0},"usageScope":"turn","time":1783999266389}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_132","turnId":"0","step":15,"stepUuid":"uuid_131","part":{"type":"think","think":"text_113"}},"time":1783999266390}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_133","turnId":"0","step":15,"stepUuid":"uuid_131","toolCallId":"tool_pfJXJuiwftBA2ccRRu8ObhiH","name":"Read","args":{}},"time":1783999266392}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_133","toolCallId":"tool_pfJXJuiwftBA2ccRRu8ObhiH","result":{"output":"text_87","note":"text_88"}},"time":1783999266395}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_131","turnId":"0","step":15,"finishReason":"tool_use","usage":{"inputOther":633,"output":52,"inputCacheRead":27705,"inputCacheCreation":0},"llmFirstTokenLatencyMs":3095,"llmStreamDurationMs":1197,"llmRequestBuildMs":0,"llmServerFirstTokenMs":3095,"llmServerDecodeMs":1196,"llmClientConsumeMs":1,"messageId":"uuid_134","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999266395}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_135","turnId":"0","step":16},"time":1783999266396}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":233427,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":11,"turnStep":"0.16","time":1783999266397}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":528,"output":282,"inputCacheRead":28272,"inputCacheCreation":0},"usageScope":"turn","time":1783999279151}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_136","turnId":"0","step":16,"stepUuid":"uuid_135","part":{"type":"think","think":"text_114"}},"time":1783999279152}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_137","turnId":"0","step":16,"stepUuid":"uuid_135","toolCallId":"tool_U4hzMeIUMaMX2De0nv5jDJJI","name":"Bash","args":{}},"time":1783999279153}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_137","toolCallId":"tool_U4hzMeIUMaMX2De0nv5jDJJI","result":{"output":"text_115"}},"time":1783999279511}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_135","turnId":"0","step":16,"finishReason":"tool_use","usage":{"inputOther":528,"output":282,"inputCacheRead":28272,"inputCacheCreation":0},"llmFirstTokenLatencyMs":5724,"llmStreamDurationMs":7030,"llmRequestBuildMs":1,"llmServerFirstTokenMs":5723,"llmServerDecodeMs":7025,"llmClientConsumeMs":5,"messageId":"uuid_138","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999279511}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_139","turnId":"0","step":17},"time":1783999279512}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":232479,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":13,"turnStep":"0.17","time":1783999279513}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":888,"output":278,"inputCacheRead":28733,"inputCacheCreation":0},"usageScope":"turn","time":1783999291911}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_140","turnId":"0","step":17,"stepUuid":"uuid_139","part":{"type":"think","think":"text_116"}},"time":1783999291912}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_141","turnId":"0","step":17,"stepUuid":"uuid_139","toolCallId":"tool_ntUMlV5WbuSvkwIjDABHTOXC","name":"Bash","args":{}},"time":1783999291912}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_142","turnId":"0","step":17,"stepUuid":"uuid_139","toolCallId":"tool_wEROuM4YAVeFIn5QvH7Ijj7X","name":"Bash","args":{}},"time":1783999291912}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_141","toolCallId":"tool_ntUMlV5WbuSvkwIjDABHTOXC","result":{"output":"text_117"}},"time":1783999291915}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_142","toolCallId":"tool_wEROuM4YAVeFIn5QvH7Ijj7X","result":{"output":"text_118"}},"time":1783999291915}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_139","turnId":"0","step":17,"finishReason":"tool_use","usage":{"inputOther":888,"output":278,"inputCacheRead":28733,"inputCacheCreation":0},"llmFirstTokenLatencyMs":3974,"llmStreamDurationMs":8424,"llmRequestBuildMs":1,"llmServerFirstTokenMs":3973,"llmServerDecodeMs":8421,"llmClientConsumeMs":3,"messageId":"uuid_143","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1783999291916}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_144","turnId":"0","step":18},"time":1783999291916}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_5","modelAlias":"model_4","thinkingEffort":"on","thinkingKeep":"all","maxTokens":232028,"toolSelect":false,"systemPromptHash":"hash_5","systemPrompt":"prompt_4","toolsHash":"hash_4","messageCount":16,"turnStep":"0.18","time":1783999291918}
|
||||
{"type":"usage.record","model":"model_4","usage":{"inputOther":575,"output":390,"inputCacheRead":29554,"inputCacheCreation":0},"usageScope":"turn","time":1783999301177}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_145","turnId":"0","step":18,"stepUuid":"uuid_144","part":{"type":"think","think":"text_119"}},"time":1783999301178}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_146","turnId":"0","step":18,"stepUuid":"uuid_144","part":{"type":"text","text":"text_120"}},"time":1783999301178}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_144","turnId":"0","step":18,"finishReason":"end_turn","usage":{"inputOther":575,"output":390,"inputCacheRead":29554,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1810,"llmStreamDurationMs":7449,"llmRequestBuildMs":0,"llmServerFirstTokenMs":1810,"llmServerDecodeMs":7446,"llmClientConsumeMs":3,"messageId":"uuid_147","providerFinishReason":"completed","rawFinishReason":"stop"},"time":1783999301178}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
{"type":"metadata","protocol_version":"1.4","created_at":1784009295445}
|
||||
{"type":"mcp.tools_discovered","serverName":"server_1","hash":"hash_1","tools":[{"name":"tool_1","description":"text_1","inputSchema":{}},{"name":"tool_2","description":"text_2","inputSchema":{}}],"enabledNames":["tool_1","tool_2"],"time":1784009295445}
|
||||
{"type":"permission.set_mode","mode":"yolo","time":1784009295445}
|
||||
{"type":"config.update","profileName":"name_1","systemPrompt":"prompt_1","time":1784009295450}
|
||||
{"type":"tools.set_active_tools","names":["Read","Write","Edit","Grep","Glob","Bash","TaskList","TaskOutput","TaskStop","CronCreate","CronList","CronDelete","ReadMediaFile","TodoList","Skill","WebSearch","Agent","AgentSwarm","FetchURL","AskUserQuestion","EnterPlanMode","ExitPlanMode","CreateGoal","GetGoal","SetGoalBudget","UpdateGoal","mcp__*","spine_open","spine_close","spine_next","spine_tree"],"time":1784009295450}
|
||||
{"type":"config.update","modelAlias":"model_1","thinkingEffort":"max","time":1784009295450}
|
||||
{"type":"config.update","thinkingEffort":"max","time":1784009295450}
|
||||
{"type":"permission.set_mode","mode":"yolo","time":1784009295450}
|
||||
{"type":"permission.set_mode","mode":"yolo","time":1784009295451}
|
||||
{"type":"turn.prompt","input":[{"type":"text","text":"text_3"}],"origin":{"kind":"user"},"time":1784009295633}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_3"}],"toolCalls":[],"id":"msgid_1"},"time":1784009295633}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1","turnId":"0","step":1},"time":1784009295635}
|
||||
{"type":"llm.tools_snapshot","hash":"hash_2","tools":[{"name":"Agent","description":"text_4","parameters":{}},{"name":"AgentSwarm","description":"text_5","parameters":{}},{"name":"AskUserQuestion","description":"text_6","parameters":{}},{"name":"Bash","description":"text_7","parameters":{}},{"name":"CreateGoal","description":"text_8","parameters":{}},{"name":"CronCreate","description":"text_9","parameters":{}},{"name":"CronDelete","description":"text_10","parameters":{}},{"name":"CronList","description":"text_11","parameters":{}},{"name":"Edit","description":"text_12","parameters":{}},{"name":"EnterPlanMode","description":"text_13","parameters":{}},{"name":"ExitPlanMode","description":"text_14","parameters":{}},{"name":"FetchURL","description":"text_15","parameters":{}},{"name":"GetGoal","description":"text_16","parameters":{}},{"name":"Glob","description":"text_17","parameters":{}},{"name":"Grep","description":"text_18","parameters":{}},{"name":"mcp__plugin-kimi-datasource_data__call_data_source_tool","description":"text_1","parameters":{}},{"name":"mcp__plugin-kimi-datasource_data__get_data_source_desc","description":"text_2","parameters":{}},{"name":"Read","description":"text_19","parameters":{}},{"name":"ReadMediaFile","description":"text_20","parameters":{}},{"name":"SetGoalBudget","description":"text_21","parameters":{}},{"name":"Skill","description":"text_22","parameters":{}},{"name":"spine_close","description":"text_23","parameters":{}},{"name":"spine_next","description":"text_24","parameters":{}},{"name":"spine_open","description":"text_25","parameters":{}},{"name":"spine_tree","description":"text_26","parameters":{}},{"name":"TaskList","description":"text_27","parameters":{}},{"name":"TaskOutput","description":"text_28","parameters":{}},{"name":"TaskStop","description":"text_29","parameters":{}},{"name":"UpdateGoal","description":"text_30","parameters":{}},{"name":"WebSearch","description":"text_31","parameters":{}},{"name":"Write","description":"text_32","parameters":{}}],"time":1784009295637}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_2","modelAlias":"model_1","thinkingEffort":"max","thinkingKeep":"all","maxTokens":1048510,"toolSelect":false,"systemPromptHash":"hash_3","systemPrompt":"prompt_2","toolsHash":"hash_2","messageCount":2,"turnStep":"0.1","time":1784009295638}
|
||||
{"type":"usage.record","model":"model_1","usage":{"inputOther":26308,"output":191,"inputCacheRead":2048,"inputCacheCreation":0},"usageScope":"turn","time":1784009299686}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_2","turnId":"0","step":1,"stepUuid":"uuid_1","part":{"type":"think","think":"text_33"}},"time":1784009299686}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_3","turnId":"0","step":1,"stepUuid":"uuid_1","part":{"type":"text","text":"text_34"}},"time":1784009299687}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_4","turnId":"0","step":1,"stepUuid":"uuid_1","toolCallId":"spine_open_0","name":"spine_open","args":{"summary":"summary_1"}},"time":1784009299696}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_4","toolCallId":"spine_open_0","result":{"output":"accepted — commits after this step completes"}},"time":1784009299698}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1","turnId":"0","step":1,"finishReason":"tool_use","usage":{"inputOther":26308,"output":191,"inputCacheRead":2048,"inputCacheCreation":0},"llmFirstTokenLatencyMs":3214,"llmStreamDurationMs":834,"llmRequestBuildMs":1,"llmServerFirstTokenMs":3213,"llmServerDecodeMs":832,"llmClientConsumeMs":2,"messageId":"uuid_5","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1784009299698}
|
||||
{"type":"spine.open","id":"1.1.1","summary":"summary_1","parentId":"1.1","openedAt":1,"baselineTokens":28560,"time":1784009299699}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_6","turnId":"0","step":2},"time":1784009299699}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_2","modelAlias":"model_1","thinkingEffort":"max","thinkingKeep":"all","maxTokens":1020013,"toolSelect":false,"systemPromptHash":"hash_3","systemPrompt":"prompt_2","toolsHash":"hash_2","messageCount":4,"turnStep":"0.2","time":1784009299700}
|
||||
{"type":"usage.record","model":"model_1","usage":{"inputOther":439,"output":83,"inputCacheRead":28160,"inputCacheCreation":0},"usageScope":"turn","time":1784009301785}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_7","turnId":"0","step":2,"stepUuid":"uuid_6","part":{"type":"think","think":"text_35"}},"time":1784009301785}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_8","turnId":"0","step":2,"stepUuid":"uuid_6","toolCallId":"FetchURL_1","name":"FetchURL","args":{}},"time":1784009301786}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_8","toolCallId":"FetchURL_1","result":{"output":"text_36"}},"time":1784009308035}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_6","turnId":"0","step":2,"finishReason":"tool_use","usage":{"inputOther":439,"output":83,"inputCacheRead":28160,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1820,"llmStreamDurationMs":265,"llmRequestBuildMs":1,"llmServerFirstTokenMs":1819,"llmServerDecodeMs":265,"llmClientConsumeMs":0,"messageId":"uuid_9","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1784009308035}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_10","turnId":"0","step":3},"time":1784009308036}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_2","modelAlias":"model_1","thinkingEffort":"max","thinkingKeep":"all","maxTokens":1019530,"toolSelect":false,"systemPromptHash":"hash_3","systemPrompt":"prompt_2","toolsHash":"hash_2","messageCount":6,"turnStep":"0.3","time":1784009308037}
|
||||
{"type":"usage.record","model":"model_1","usage":{"inputOther":602,"output":171,"inputCacheRead":28416,"inputCacheCreation":0},"usageScope":"turn","time":1784009310484}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_11","turnId":"0","step":3,"stepUuid":"uuid_10","part":{"type":"think","think":"text_37"}},"time":1784009310485}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_12","turnId":"0","step":3,"stepUuid":"uuid_10","part":{"type":"text","text":"text_38"}},"time":1784009310485}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_13","turnId":"0","step":3,"stepUuid":"uuid_10","toolCallId":"FetchURL_2","name":"FetchURL","args":{}},"time":1784009310485}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_13","toolCallId":"FetchURL_2","result":{"output":"text_39"}},"time":1784009323505}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_10","turnId":"0","step":3,"finishReason":"tool_use","usage":{"inputOther":602,"output":171,"inputCacheRead":28416,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1730,"llmStreamDurationMs":717,"llmRequestBuildMs":1,"llmServerFirstTokenMs":1729,"llmServerDecodeMs":717,"llmClientConsumeMs":0,"messageId":"uuid_14","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1784009323506}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_15","turnId":"0","step":4},"time":1784009323507}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_2","modelAlias":"model_1","thinkingEffort":"max","thinkingKeep":"all","maxTokens":1005908,"toolSelect":false,"systemPromptHash":"hash_3","systemPrompt":"prompt_2","toolsHash":"hash_2","messageCount":8,"turnStep":"0.4","time":1784009323509}
|
||||
{"type":"usage.record","model":"model_1","usage":{"inputOther":13911,"output":1778,"inputCacheRead":28928,"inputCacheCreation":0},"usageScope":"turn","time":1784009336882}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_16","turnId":"0","step":4,"stepUuid":"uuid_15","part":{"type":"think","think":"text_40"}},"time":1784009336883}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_17","turnId":"0","step":4,"stepUuid":"uuid_15","part":{"type":"text","text":"text_41"}},"time":1784009336883}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_18","turnId":"0","step":4,"stepUuid":"uuid_15","toolCallId":"spine_close_3","name":"spine_close","args":{"memory":"memory_1"}},"time":1784009336885}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_18","toolCallId":"spine_close_3","result":{"output":"accepted — commits after this step completes"}},"time":1784009336886}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_15","turnId":"0","step":4,"finishReason":"tool_use","usage":{"inputOther":13911,"output":1778,"inputCacheRead":28928,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2795,"llmStreamDurationMs":10578,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2795,"llmServerDecodeMs":10555,"llmClientConsumeMs":23,"messageId":"uuid_19","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1784009336887}
|
||||
{"type":"spine.close","id":"1.1.1","closedAt":6,"memory":"memory_1","archivePath":"path_1","finalTokens":44630,"time":1784009336889}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_20","turnId":"0","step":5},"time":1784009336889}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_2","modelAlias":"model_1","thinkingEffort":"max","thinkingKeep":"all","maxTokens":1003943,"toolSelect":false,"systemPromptHash":"hash_3","systemPrompt":"prompt_2","toolsHash":"hash_2","messageCount":5,"turnStep":"0.5","time":1784009336890}
|
||||
{"type":"usage.record","model":"model_1","usage":{"inputOther":2250,"output":202,"inputCacheRead":28160,"inputCacheCreation":0},"usageScope":"turn","time":1784009339938}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_21","turnId":"0","step":5,"stepUuid":"uuid_20","part":{"type":"think","think":"text_42"}},"time":1784009339938}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_22","turnId":"0","step":5,"stepUuid":"uuid_20","part":{"type":"text","text":"text_43"}},"time":1784009339938}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_20","turnId":"0","step":5,"finishReason":"end_turn","usage":{"inputOther":2250,"output":202,"inputCacheRead":28160,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1841,"llmStreamDurationMs":1207,"llmRequestBuildMs":1,"llmServerFirstTokenMs":1840,"llmServerDecodeMs":1202,"llmClientConsumeMs":5,"messageId":"uuid_23","providerFinishReason":"completed","rawFinishReason":"stop"},"time":1784009339938}
|
||||
{"type":"turn.prompt","input":[{"type":"text","text":"text_44"}],"origin":{"kind":"user"},"time":1784009362225}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_44"}],"toolCalls":[],"id":"msgid_2"},"time":1784009362225}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_24","turnId":"1","step":1},"time":1784009362226}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_2","modelAlias":"model_1","thinkingEffort":"max","thinkingKeep":"all","maxTokens":1017948,"toolSelect":false,"systemPromptHash":"hash_3","systemPrompt":"prompt_2","toolsHash":"hash_2","messageCount":7,"turnStep":"1.1","time":1784009362228}
|
||||
{"type":"usage.record","model":"model_1","usage":{"inputOther":428,"output":1538,"inputCacheRead":30208,"inputCacheCreation":0},"usageScope":"turn","time":1784009374137}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_25","turnId":"1","step":1,"stepUuid":"uuid_24","part":{"type":"think","think":"text_45"}},"time":1784009374138}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_26","turnId":"1","step":1,"stepUuid":"uuid_24","part":{"type":"text","text":"text_46"}},"time":1784009374138}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_27","turnId":"1","step":1,"stepUuid":"uuid_24","toolCallId":"spine_open_1","name":"spine_open","args":{"summary":"summary_2"}},"time":1784009374141}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_28","turnId":"1","step":1,"stepUuid":"uuid_24","toolCallId":"Grep_2","name":"Grep","args":{}},"time":1784009374142}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_29","turnId":"1","step":1,"stepUuid":"uuid_24","toolCallId":"Grep_3","name":"Grep","args":{}},"time":1784009374143}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_30","turnId":"1","step":1,"stepUuid":"uuid_24","toolCallId":"Grep_4","name":"Grep","args":{}},"time":1784009374143}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_27","toolCallId":"spine_open_1","result":{"output":"accepted — commits after this step completes"}},"time":1784009374145}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_29","toolCallId":"Grep_3","result":{"output":"text_47"}},"time":1784009374188}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_28","toolCallId":"Grep_2","result":{"output":"text_48"}},"time":1784009374204}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_30","toolCallId":"Grep_4","result":{"output":"text_49"}},"time":1784009374211}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_24","turnId":"1","step":1,"finishReason":"tool_use","usage":{"inputOther":428,"output":1538,"inputCacheRead":30208,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1878,"llmStreamDurationMs":10031,"llmRequestBuildMs":1,"llmServerFirstTokenMs":1877,"llmServerDecodeMs":10010,"llmClientConsumeMs":21,"messageId":"uuid_31","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1784009374211}
|
||||
{"type":"spine.open","id":"1.1.2","summary":"summary_2","parentId":"1.1","openedAt":11,"baselineTokens":34236,"time":1784009374212}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_32","turnId":"1","step":2},"time":1784009374213}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_2","modelAlias":"model_1","thinkingEffort":"max","thinkingKeep":"all","maxTokens":1014337,"toolSelect":false,"systemPromptHash":"hash_3","systemPrompt":"prompt_2","toolsHash":"hash_2","messageCount":12,"turnStep":"1.2","time":1784009374215}
|
||||
{"type":"usage.record","model":"model_1","usage":{"inputOther":3444,"output":315,"inputCacheRead":30464,"inputCacheCreation":0},"usageScope":"turn","time":1784009377132}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_33","turnId":"1","step":2,"stepUuid":"uuid_32","part":{"type":"think","think":"text_50"}},"time":1784009377132}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_34","turnId":"1","step":2,"stepUuid":"uuid_32","part":{"type":"text","text":"text_51"}},"time":1784009377133}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_35","turnId":"1","step":2,"stepUuid":"uuid_32","toolCallId":"Read_5","name":"Read","args":{}},"time":1784009377135}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_36","turnId":"1","step":2,"stepUuid":"uuid_32","toolCallId":"Read_6","name":"Read","args":{}},"time":1784009377136}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_37","turnId":"1","step":2,"stepUuid":"uuid_32","toolCallId":"Read_7","name":"Read","args":{}},"time":1784009377136}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_35","toolCallId":"Read_5","result":{"output":"text_52","note":"text_53"}},"time":1784009377139}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_36","toolCallId":"Read_6","result":{"output":"text_54","note":"text_55"}},"time":1784009377140}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_37","toolCallId":"Read_7","result":{"output":"text_56","note":"text_57"}},"time":1784009377143}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_32","turnId":"1","step":2,"finishReason":"tool_use","usage":{"inputOther":3444,"output":315,"inputCacheRead":30464,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1704,"llmStreamDurationMs":1213,"llmRequestBuildMs":0,"llmServerFirstTokenMs":1704,"llmServerDecodeMs":1209,"llmClientConsumeMs":4,"messageId":"uuid_38","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1784009377144}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_39","turnId":"1","step":3},"time":1784009377144}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_2","modelAlias":"model_1","thinkingEffort":"max","thinkingKeep":"all","maxTokens":1010440,"toolSelect":false,"systemPromptHash":"hash_3","systemPrompt":"prompt_2","toolsHash":"hash_2","messageCount":16,"turnStep":"1.3","time":1784009377146}
|
||||
{"type":"usage.record","model":"model_1","usage":{"inputOther":4163,"output":1375,"inputCacheRead":33792,"inputCacheCreation":0},"usageScope":"turn","time":1784009390176}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_40","turnId":"1","step":3,"stepUuid":"uuid_39","part":{"type":"think","think":"text_58"}},"time":1784009390177}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_41","turnId":"1","step":3,"stepUuid":"uuid_39","part":{"type":"text","text":"text_59"}},"time":1784009390178}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_42","turnId":"1","step":3,"stepUuid":"uuid_39","toolCallId":"Read_8","name":"Read","args":{}},"time":1784009390178}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_43","turnId":"1","step":3,"stepUuid":"uuid_39","toolCallId":"Read_9","name":"Read","args":{}},"time":1784009390179}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_43","toolCallId":"Read_9","result":{"output":"text_60","note":"text_61"}},"time":1784009390182}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_42","toolCallId":"Read_8","result":{"output":"text_62","note":"text_63"}},"time":1784009390183}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_39","turnId":"1","step":3,"finishReason":"tool_use","usage":{"inputOther":4163,"output":1375,"inputCacheRead":33792,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2053,"llmStreamDurationMs":10977,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2053,"llmServerDecodeMs":10961,"llmClientConsumeMs":16,"messageId":"uuid_44","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1784009390184}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_45","turnId":"1","step":4},"time":1784009390185}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_2","modelAlias":"model_1","thinkingEffort":"max","thinkingKeep":"all","maxTokens":1003608,"toolSelect":false,"systemPromptHash":"hash_3","systemPrompt":"prompt_2","toolsHash":"hash_2","messageCount":19,"turnStep":"1.4","time":1784009390186}
|
||||
{"type":"usage.record","model":"model_1","usage":{"inputOther":10860,"output":2589,"inputCacheRead":33792,"inputCacheCreation":0},"usageScope":"turn","time":1784009410411}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_46","turnId":"1","step":4,"stepUuid":"uuid_45","part":{"type":"think","think":"text_64"}},"time":1784009410413}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_47","turnId":"1","step":4,"stepUuid":"uuid_45","part":{"type":"text","text":"text_65"}},"time":1784009410413}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_48","turnId":"1","step":4,"stepUuid":"uuid_45","toolCallId":"spine_close_10","name":"spine_close","args":{"memory":"memory_2"}},"time":1784009410414}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_48","toolCallId":"spine_close_10","result":{"output":"accepted — commits after this step completes"}},"time":1784009410415}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_45","turnId":"1","step":4,"finishReason":"tool_use","usage":{"inputOther":10860,"output":2589,"inputCacheRead":33792,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2567,"llmStreamDurationMs":17658,"llmRequestBuildMs":1,"llmServerFirstTokenMs":2566,"llmServerDecodeMs":17626,"llmClientConsumeMs":32,"messageId":"uuid_49","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1784009410416}
|
||||
{"type":"spine.close","id":"1.1.2","closedAt":22,"memory":"memory_2","archivePath":"path_2","finalTokens":47254,"time":1784009410418}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_50","turnId":"1","step":5},"time":1784009410419}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_2","modelAlias":"model_1","thinkingEffort":"max","thinkingKeep":"all","maxTokens":1001319,"toolSelect":false,"systemPromptHash":"hash_3","systemPrompt":"prompt_2","toolsHash":"hash_2","messageCount":10,"turnStep":"1.5","time":1784009410420}
|
||||
{"type":"usage.record","model":"model_1","usage":{"inputOther":31557,"output":375,"inputCacheRead":2048,"inputCacheCreation":0},"usageScope":"turn","time":1784009416478}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_51","turnId":"1","step":5,"stepUuid":"uuid_50","part":{"type":"think","think":"text_66"}},"time":1784009416478}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_52","turnId":"1","step":5,"stepUuid":"uuid_50","part":{"type":"text","text":"text_67"}},"time":1784009416479}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_50","turnId":"1","step":5,"finishReason":"end_turn","usage":{"inputOther":31557,"output":375,"inputCacheRead":2048,"inputCacheCreation":0},"llmFirstTokenLatencyMs":3579,"llmStreamDurationMs":2479,"llmRequestBuildMs":0,"llmServerFirstTokenMs":3579,"llmServerDecodeMs":2473,"llmClientConsumeMs":6,"messageId":"uuid_53","providerFinishReason":"completed","rawFinishReason":"stop"},"time":1784009416479}
|
||||
{"type":"turn.prompt","input":[{"type":"text","text":"text_68"}],"origin":{"kind":"user"},"time":1784009489598}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_68"}],"toolCalls":[],"id":"msgid_3"},"time":1784009489598}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_54","turnId":"2","step":1},"time":1784009489599}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_2","modelAlias":"model_1","thinkingEffort":"max","thinkingKeep":"all","maxTokens":1014583,"toolSelect":false,"systemPromptHash":"hash_3","systemPrompt":"prompt_2","toolsHash":"hash_2","messageCount":12,"turnStep":"2.1","time":1784009489601}
|
||||
{"type":"usage.record","model":"model_1","usage":{"inputOther":466,"output":1792,"inputCacheRead":33536,"inputCacheCreation":0},"usageScope":"turn","time":1784009502792}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_55","turnId":"2","step":1,"stepUuid":"uuid_54","part":{"type":"think","think":"text_69"}},"time":1784009502792}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_56","turnId":"2","step":1,"stepUuid":"uuid_54","part":{"type":"text","text":"text_70"}},"time":1784009502793}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_57","turnId":"2","step":1,"stepUuid":"uuid_54","toolCallId":"spine_open_2","name":"spine_open","args":{"summary":"summary_3"}},"time":1784009502793}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_57","toolCallId":"spine_open_2","result":{"output":"accepted — commits after this step completes"}},"time":1784009502794}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_54","turnId":"2","step":1,"finishReason":"tool_use","usage":{"inputOther":466,"output":1792,"inputCacheRead":33536,"inputCacheCreation":0},"llmFirstTokenLatencyMs":3490,"llmStreamDurationMs":9701,"llmRequestBuildMs":1,"llmServerFirstTokenMs":3489,"llmServerDecodeMs":9685,"llmClientConsumeMs":16,"messageId":"uuid_58","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1784009502794}
|
||||
{"type":"spine.open","id":"1.1.3","summary":"summary_3","parentId":"1.1","openedAt":27,"baselineTokens":35807,"time":1784009502795}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_59","turnId":"2","step":2},"time":1784009502795}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_2","modelAlias":"model_1","thinkingEffort":"max","thinkingKeep":"all","maxTokens":1012766,"toolSelect":false,"systemPromptHash":"hash_3","systemPrompt":"prompt_2","toolsHash":"hash_2","messageCount":14,"turnStep":"2.2","time":1784009502796}
|
||||
{"type":"usage.record","model":"model_1","usage":{"inputOther":2050,"output":269,"inputCacheRead":33792,"inputCacheCreation":0},"usageScope":"turn","time":1784009506486}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_60","turnId":"2","step":2,"stepUuid":"uuid_59","part":{"type":"think","think":"text_71"}},"time":1784009506486}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_61","turnId":"2","step":2,"stepUuid":"uuid_59","toolCallId":"spine_close_3","name":"spine_close","args":{"memory":"memory_3"}},"time":1784009506487}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_61","toolCallId":"spine_close_3","result":{"output":"accepted — commits after this step completes"}},"time":1784009506488}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_59","turnId":"2","step":2,"finishReason":"tool_use","usage":{"inputOther":2050,"output":269,"inputCacheRead":33792,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2489,"llmStreamDurationMs":1201,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2489,"llmServerDecodeMs":1201,"llmClientConsumeMs":0,"messageId":"uuid_62","providerFinishReason":"tool_calls","rawFinishReason":"tool_calls"},"time":1784009506488}
|
||||
{"type":"spine.close","id":"1.1.3","closedAt":28,"memory":"memory_3","archivePath":"path_3","finalTokens":36124,"time":1784009506489}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_63","turnId":"2","step":3},"time":1784009506490}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_2","modelAlias":"model_1","thinkingEffort":"max","thinkingKeep":"all","maxTokens":1012449,"toolSelect":false,"systemPromptHash":"hash_3","systemPrompt":"prompt_2","toolsHash":"hash_2","messageCount":15,"turnStep":"2.3","time":1784009506491}
|
||||
{"type":"usage.record","model":"model_1","usage":{"inputOther":723,"output":434,"inputCacheRead":33792,"inputCacheCreation":0},"usageScope":"turn","time":1784009511166}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_64","turnId":"2","step":3,"stepUuid":"uuid_63","part":{"type":"think","think":"text_72"}},"time":1784009511166}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_65","turnId":"2","step":3,"stepUuid":"uuid_63","part":{"type":"text","text":"text_73"}},"time":1784009511167}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_63","turnId":"2","step":3,"finishReason":"end_turn","usage":{"inputOther":723,"output":434,"inputCacheRead":33792,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2288,"llmStreamDurationMs":2387,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2288,"llmServerDecodeMs":2378,"llmClientConsumeMs":9,"messageId":"uuid_66","providerFinishReason":"completed","rawFinishReason":"stop"},"time":1784009511167}
|
||||
{"type":"turn.prompt","input":[{"type":"text","text":"text_74"}],"origin":{"kind":"skill_activation","activationId":"origin_1","skillName":"origin_2","trigger":"user-slash","skillPath":"origin_3","skillSource":"origin_4","skillArgs":"origin_5"},"time":1784009949568}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_74"}],"toolCalls":[],"origin":{"kind":"skill_activation","activationId":"origin_1","skillName":"origin_2","trigger":"user-slash","skillPath":"origin_3","skillSource":"origin_4","skillArgs":"origin_5"},"id":"msgid_4"},"time":1784009949568}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_67","turnId":"3","step":1},"time":1784009949569}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_2","modelAlias":"model_1","thinkingEffort":"max","thinkingKeep":"all","maxTokens":1012584,"toolSelect":false,"systemPromptHash":"hash_3","systemPrompt":"prompt_2","toolsHash":"hash_2","messageCount":17,"turnStep":"3.1","time":1784009949571}
|
||||
{"type":"usage.record","model":"model_1","usage":{"inputOther":1339,"output":1296,"inputCacheRead":34304,"inputCacheCreation":0},"usageScope":"turn","time":1784009960793}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_68","turnId":"3","step":1,"stepUuid":"uuid_67","part":{"type":"think","think":"text_75"}},"time":1784009960795}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_69","turnId":"3","step":1,"stepUuid":"uuid_67","part":{"type":"text","text":"text_76"}},"time":1784009960795}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_67","turnId":"3","step":1,"finishReason":"end_turn","usage":{"inputOther":1339,"output":1296,"inputCacheRead":34304,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2236,"llmStreamDurationMs":8986,"llmRequestBuildMs":1,"llmServerFirstTokenMs":2235,"llmServerDecodeMs":8967,"llmClientConsumeMs":19,"messageId":"uuid_70","providerFinishReason":"completed","rawFinishReason":"stop"},"time":1784009960795}
|
||||
|
|
@ -0,0 +1,628 @@
|
|||
{"type":"metadata","protocol_version":"1.4","created_at":1783493436957}
|
||||
{"type":"config.update","modelAlias":"model_6","profileName":"name_1","systemPrompt":"prompt_5"}
|
||||
{"type":"tools.set_active_tools","names":["Read","Write","Edit","Grep","Glob","Bash","TaskList","TaskOutput","TaskStop","CronCreate","CronList","CronDelete","ReadMediaFile","TodoList","Skill","WebSearch","Agent","AgentSwarm","FetchURL","AskUserQuestion","EnterPlanMode","ExitPlanMode","CreateGoal","GetGoal","SetGoalBudget","UpdateGoal","mcp__*","spine_open","spine_close","spine_next","spine_tree"]}
|
||||
{"type":"config.update","thinkingLevel":"on"}
|
||||
{"type":"permission.set_mode","mode":"manual"}
|
||||
{"type":"context.append_message","message":{"id":"msgid_6","role":"user","content":[{"type":"text","text":"text_121"}],"toolCalls":[],"origin":{"kind":"user"}}}
|
||||
{"type":"turn.prompt","turnId":0}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":21686,"output":175,"inputCacheRead":0,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":1}}
|
||||
{"type":"context_size.measured","length":2,"tokens":21861}
|
||||
{"type":"context.append_message","message":{"id":"msgid_7","role":"assistant","content":[{"type":"think","think":"text_122"},{"type":"text","text":"text_123"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_7\"}"}],"providerMessageId":"msgid_8"}}
|
||||
{"type":"permission.set_mode","mode":"yolo"}
|
||||
{"type":"permission.record_approval_result","turnId":0,"toolCallId":"spine_open_0","toolName":"spine_open","action":"text_124","sessionApprovalRule":"spine_open","result":{"decision":"approved","scope":"session"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_9"}}
|
||||
{"type":"spine.open","id":"1.1.1","summary":"summary_7","parentId":"1.1","openedAt":1,"baselineTokens":21864}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":412,"output":174,"inputCacheRead":21504,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":2}}
|
||||
{"type":"context_size.measured","length":4,"tokens":22090}
|
||||
{"type":"context.append_message","message":{"id":"msgid_10","role":"assistant","content":[{"type":"think","think":"text_125"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_11"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_126"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_12"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":406,"output":194,"inputCacheRead":21760,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":3}}
|
||||
{"type":"context_size.measured","length":6,"tokens":22360}
|
||||
{"type":"context.append_message","message":{"id":"msgid_13","role":"assistant","content":[{"type":"think","think":"text_127"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_6\"}"}],"providerMessageId":"msgid_14"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_15"}}
|
||||
{"type":"spine.close","id":"1.1.1","closedAt":6,"memory":"memory_6","archivePath":"path_6"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":260,"output":137,"inputCacheRead":21504,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":4}}
|
||||
{"type":"context_size.measured","length":8,"tokens":21901}
|
||||
{"type":"context.append_message","message":{"id":"msgid_16","role":"assistant","content":[{"type":"think","think":"text_128"},{"type":"text","text":"text_129"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_8\"}"}],"providerMessageId":"msgid_17"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_18"}}
|
||||
{"type":"spine.open","id":"1.1.2","summary":"summary_8","parentId":"1.1","openedAt":7,"baselineTokens":21904}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":449,"output":74,"inputCacheRead":21504,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":5}}
|
||||
{"type":"context_size.measured","length":10,"tokens":22027}
|
||||
{"type":"context.append_message","message":{"id":"msgid_19","role":"assistant","content":[{"type":"think","think":"text_130"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_20"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_131"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_21"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":392,"output":218,"inputCacheRead":21760,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":6}}
|
||||
{"type":"context_size.measured","length":12,"tokens":22370}
|
||||
{"type":"context.append_message","message":{"id":"msgid_22","role":"assistant","content":[{"type":"think","think":"text_132"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_7\"}"}],"providerMessageId":"msgid_23"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_24"}}
|
||||
{"type":"spine.close","id":"1.1.2","closedAt":12,"memory":"memory_7","archivePath":"path_7"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":382,"output":313,"inputCacheRead":21504,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":7}}
|
||||
{"type":"context_size.measured","length":14,"tokens":22199}
|
||||
{"type":"context.append_message","message":{"id":"msgid_25","role":"assistant","content":[{"type":"think","think":"text_133"},{"type":"text","text":"text_134"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_9\"}"}],"providerMessageId":"msgid_26"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_27"}}
|
||||
{"type":"spine.open","id":"1.1.3","summary":"summary_9","parentId":"1.1","openedAt":13,"baselineTokens":22202}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":498,"output":314,"inputCacheRead":21760,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":8}}
|
||||
{"type":"context_size.measured","length":16,"tokens":22572}
|
||||
{"type":"context.append_message","message":{"id":"msgid_28","role":"assistant","content":[{"type":"think","think":"text_135"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"},{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_8\"}"}],"providerMessageId":"msgid_29"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_136"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_30"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_31"}}
|
||||
{"type":"spine.close","id":"1.1.3","closedAt":17,"memory":"memory_8","archivePath":"path_8"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":246,"output":458,"inputCacheRead":21760,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":9}}
|
||||
{"type":"context_size.measured","length":19,"tokens":22464}
|
||||
{"type":"context.append_message","message":{"id":"msgid_32","role":"assistant","content":[{"type":"think","think":"text_137"},{"type":"text","text":"text_138"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_10\"}"}],"providerMessageId":"msgid_33"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_34"}}
|
||||
{"type":"spine.open","id":"1.1.4","summary":"summary_10","parentId":"1.1","openedAt":18,"baselineTokens":22467}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":762,"output":92,"inputCacheRead":21760,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":10}}
|
||||
{"type":"context_size.measured","length":21,"tokens":22614}
|
||||
{"type":"context.append_message","message":{"id":"msgid_35","role":"assistant","content":[{"type":"think","think":"text_139"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_36"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_140"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_37"}}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_141"}],"toolCalls":[],"origin":{"kind":"injection","variant":"todo_list_reminder"},"id":"msgid_38"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":668,"output":230,"inputCacheRead":22272,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":11}}
|
||||
{"type":"context_size.measured","length":24,"tokens":23170}
|
||||
{"type":"context.append_message","message":{"id":"msgid_39","role":"assistant","content":[{"type":"think","think":"text_142"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_9\"}"}],"providerMessageId":"msgid_40"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_41"}}
|
||||
{"type":"spine.close","id":"1.1.4","closedAt":24,"memory":"memory_9","archivePath":"path_9"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":365,"output":232,"inputCacheRead":21760,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":12}}
|
||||
{"type":"context_size.measured","length":26,"tokens":22357}
|
||||
{"type":"context.append_message","message":{"id":"msgid_42","role":"assistant","content":[{"type":"think","think":"text_143"},{"type":"text","text":"text_144"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_11\"}"}],"providerMessageId":"msgid_43"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_44"}}
|
||||
{"type":"spine.open","id":"1.1.5","summary":"summary_11","parentId":"1.1","openedAt":25,"baselineTokens":22360}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":405,"output":87,"inputCacheRead":22016,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":13}}
|
||||
{"type":"context_size.measured","length":28,"tokens":22508}
|
||||
{"type":"context.append_message","message":{"id":"msgid_45","role":"assistant","content":[{"type":"think","think":"text_145"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_46"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_146"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_47"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":531,"output":253,"inputCacheRead":22272,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":14}}
|
||||
{"type":"context_size.measured","length":30,"tokens":23056}
|
||||
{"type":"context.append_message","message":{"id":"msgid_48","role":"assistant","content":[{"type":"think","think":"text_147"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_10\"}"}],"providerMessageId":"msgid_49"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_50"}}
|
||||
{"type":"spine.close","id":"1.1.5","closedAt":30,"memory":"memory_10","archivePath":"path_10"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":246,"output":337,"inputCacheRead":22016,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":15}}
|
||||
{"type":"context_size.measured","length":32,"tokens":22599}
|
||||
{"type":"context.append_message","message":{"id":"msgid_51","role":"assistant","content":[{"type":"think","think":"text_148"},{"type":"text","text":"text_149"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_12\"}"},{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_52"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_53"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_150"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_54"}}
|
||||
{"type":"spine.open","id":"1.1.6","summary":"summary_12","parentId":"1.1","openedAt":31,"baselineTokens":22837}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":955,"output":249,"inputCacheRead":22016,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":16}}
|
||||
{"type":"context_size.measured","length":35,"tokens":23220}
|
||||
{"type":"context.append_message","message":{"id":"msgid_55","role":"assistant","content":[{"type":"think","think":"text_151"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_11\"}"}],"providerMessageId":"msgid_56"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_57"}}
|
||||
{"type":"spine.close","id":"1.1.6","closedAt":35,"memory":"memory_11","archivePath":"path_11"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":389,"output":330,"inputCacheRead":22016,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":17}}
|
||||
{"type":"context_size.measured","length":37,"tokens":22735}
|
||||
{"type":"context.append_message","message":{"id":"msgid_58","role":"assistant","content":[{"type":"think","think":"text_152"},{"type":"text","text":"text_153"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_13\"}"}],"providerMessageId":"msgid_59"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_60"}}
|
||||
{"type":"spine.open","id":"1.1.7","summary":"summary_13","parentId":"1.1","openedAt":36,"baselineTokens":22738}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":524,"output":141,"inputCacheRead":22272,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":18}}
|
||||
{"type":"context_size.measured","length":39,"tokens":22937}
|
||||
{"type":"context.append_message","message":{"id":"msgid_61","role":"assistant","content":[{"type":"think","think":"text_154"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_62"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_155"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_63"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1070,"output":253,"inputCacheRead":22272,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":19}}
|
||||
{"type":"context_size.measured","length":41,"tokens":23595}
|
||||
{"type":"context.append_message","message":{"id":"msgid_64","role":"assistant","content":[{"type":"think","think":"text_156"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_12\"}"}],"providerMessageId":"msgid_65"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_66"}}
|
||||
{"type":"spine.close","id":"1.1.7","closedAt":41,"memory":"memory_12","archivePath":"path_12"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":282,"output":308,"inputCacheRead":22272,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":20}}
|
||||
{"type":"context_size.measured","length":43,"tokens":22862}
|
||||
{"type":"context.append_message","message":{"id":"msgid_67","role":"assistant","content":[{"type":"think","think":"text_157"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_14\"}"},{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_68"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_69"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_158"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_70"}}
|
||||
{"type":"spine.open","id":"1.1.8","summary":"summary_14","parentId":"1.1","openedAt":42,"baselineTokens":23180}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_141"}],"toolCalls":[],"origin":{"kind":"injection","variant":"todo_list_reminder"},"id":"msgid_71"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1166,"output":283,"inputCacheRead":22272,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":21}}
|
||||
{"type":"context_size.measured","length":47,"tokens":23721}
|
||||
{"type":"context.append_message","message":{"id":"msgid_72","role":"assistant","content":[{"type":"think","think":"text_159"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_13\"}"}],"providerMessageId":"msgid_73"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_74"}}
|
||||
{"type":"spine.close","id":"1.1.8","closedAt":47,"memory":"memory_13","archivePath":"path_13"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":437,"output":207,"inputCacheRead":22272,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":22}}
|
||||
{"type":"context_size.measured","length":49,"tokens":22916}
|
||||
{"type":"context.append_message","message":{"id":"msgid_75","role":"assistant","content":[{"type":"think","think":"text_160"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_15\"}"},{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_76"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_77"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_161"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_78"}}
|
||||
{"type":"spine.open","id":"1.1.9","summary":"summary_15","parentId":"1.1","openedAt":48,"baselineTokens":23275}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":925,"output":195,"inputCacheRead":22528,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":23}}
|
||||
{"type":"context_size.measured","length":52,"tokens":23648}
|
||||
{"type":"context.append_message","message":{"id":"msgid_79","role":"assistant","content":[{"type":"think","think":"text_162"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_14\"}"}],"providerMessageId":"msgid_80"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_81"}}
|
||||
{"type":"spine.close","id":"1.1.9","closedAt":52,"memory":"memory_14","archivePath":"path_14"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":818,"output":131,"inputCacheRead":22016,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":24}}
|
||||
{"type":"context_size.measured","length":54,"tokens":22965}
|
||||
{"type":"context.append_message","message":{"id":"msgid_82","role":"assistant","content":[{"type":"think","think":"text_163"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_16\"}"}],"providerMessageId":"msgid_83"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_84"}}
|
||||
{"type":"spine.open","id":"1.1.10","summary":"summary_16","parentId":"1.1","openedAt":53,"baselineTokens":22968}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":238,"output":173,"inputCacheRead":22784,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":25}}
|
||||
{"type":"context_size.measured","length":56,"tokens":23195}
|
||||
{"type":"context.append_message","message":{"id":"msgid_85","role":"assistant","content":[{"type":"think","think":"text_164"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_86"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_165"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_87"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":978,"output":191,"inputCacheRead":22784,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":26}}
|
||||
{"type":"context_size.measured","length":58,"tokens":23953}
|
||||
{"type":"context.append_message","message":{"id":"msgid_88","role":"assistant","content":[{"type":"think","think":"text_166"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_15\"}"}],"providerMessageId":"msgid_89"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_90"}}
|
||||
{"type":"spine.close","id":"1.1.10","closedAt":58,"memory":"memory_15","archivePath":"path_15"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":175,"output":456,"inputCacheRead":22784,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":27}}
|
||||
{"type":"context_size.measured","length":60,"tokens":23415}
|
||||
{"type":"context.append_message","message":{"id":"msgid_91","role":"assistant","content":[{"type":"think","think":"text_167"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_17\"}"},{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_92"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_93"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_168"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_94"}}
|
||||
{"type":"spine.open","id":"1.1.11","summary":"summary_17","parentId":"1.1","openedAt":59,"baselineTokens":23854}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1282,"output":236,"inputCacheRead":22784,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":28}}
|
||||
{"type":"context_size.measured","length":63,"tokens":24302}
|
||||
{"type":"context.append_message","message":{"id":"msgid_95","role":"assistant","content":[{"type":"think","think":"text_169"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_16\"}"}],"providerMessageId":"msgid_96"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_97"}}
|
||||
{"type":"spine.close","id":"1.1.11","closedAt":63,"memory":"memory_16","archivePath":"path_16"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":303,"output":194,"inputCacheRead":22784,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":29}}
|
||||
{"type":"context_size.measured","length":65,"tokens":23281}
|
||||
{"type":"context.append_message","message":{"id":"msgid_98","role":"assistant","content":[{"type":"think","think":"text_170"},{"type":"text","text":"text_171"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_18\"}"}],"providerMessageId":"msgid_99"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_100"}}
|
||||
{"type":"spine.open","id":"1.1.12","summary":"summary_18","parentId":"1.1","openedAt":64,"baselineTokens":23284}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":295,"output":179,"inputCacheRead":23040,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":30}}
|
||||
{"type":"context_size.measured","length":67,"tokens":23514}
|
||||
{"type":"context.append_message","message":{"id":"msgid_101","role":"assistant","content":[{"type":"think","think":"text_172"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_102"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_173"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_103"}}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_141"}],"toolCalls":[],"origin":{"kind":"injection","variant":"todo_list_reminder"},"id":"msgid_104"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1242,"output":233,"inputCacheRead":23040,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":31}}
|
||||
{"type":"context_size.measured","length":70,"tokens":24515}
|
||||
{"type":"context.append_message","message":{"id":"msgid_105","role":"assistant","content":[{"type":"think","think":"text_174"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_17\"}"}],"providerMessageId":"msgid_106"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_107"}}
|
||||
{"type":"spine.close","id":"1.1.12","closedAt":70,"memory":"memory_17","archivePath":"path_17"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":175,"output":116,"inputCacheRead":23040,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":32}}
|
||||
{"type":"context_size.measured","length":72,"tokens":23331}
|
||||
{"type":"context.append_message","message":{"id":"msgid_108","role":"assistant","content":[{"type":"think","think":"text_175"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_19\"}"},{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_109"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_110"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_176"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_111"}}
|
||||
{"type":"spine.open","id":"1.1.13","summary":"summary_19","parentId":"1.1","openedAt":71,"baselineTokens":23854}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1043,"output":220,"inputCacheRead":23040,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":33}}
|
||||
{"type":"context_size.measured","length":75,"tokens":24303}
|
||||
{"type":"context.append_message","message":{"id":"msgid_112","role":"assistant","content":[{"type":"think","think":"text_177"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_18\"}"}],"providerMessageId":"msgid_113"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_114"}}
|
||||
{"type":"spine.close","id":"1.1.13","closedAt":75,"memory":"memory_18","archivePath":"path_18"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":300,"output":131,"inputCacheRead":23040,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":34}}
|
||||
{"type":"context_size.measured","length":77,"tokens":23471}
|
||||
{"type":"context.append_message","message":{"id":"msgid_115","role":"assistant","content":[{"type":"think","think":"text_178"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_20\"}"},{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_116"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_117"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_179"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_118"}}
|
||||
{"type":"spine.open","id":"1.1.14","summary":"summary_20","parentId":"1.1","openedAt":76,"baselineTokens":24034}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1244,"output":218,"inputCacheRead":23040,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":35}}
|
||||
{"type":"context_size.measured","length":80,"tokens":24502}
|
||||
{"type":"context.append_message","message":{"id":"msgid_119","role":"assistant","content":[{"type":"think","think":"text_180"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_19\"}"}],"providerMessageId":"msgid_120"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_121"}}
|
||||
{"type":"spine.close","id":"1.1.14","closedAt":80,"memory":"memory_19","archivePath":"path_19"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":169,"output":210,"inputCacheRead":23296,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":36}}
|
||||
{"type":"context_size.measured","length":82,"tokens":23675}
|
||||
{"type":"context.append_message","message":{"id":"msgid_122","role":"assistant","content":[{"type":"think","think":"text_181"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_21\"}"}],"providerMessageId":"msgid_123"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_124"}}
|
||||
{"type":"spine.open","id":"1.1.15","summary":"summary_21","parentId":"1.1","openedAt":81,"baselineTokens":23678}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":444,"output":178,"inputCacheRead":23296,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":37}}
|
||||
{"type":"context_size.measured","length":84,"tokens":23918}
|
||||
{"type":"context.append_message","message":{"id":"msgid_125","role":"assistant","content":[{"type":"think","think":"text_182"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_126"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_183"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_127"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1217,"output":224,"inputCacheRead":23552,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":38}}
|
||||
{"type":"context_size.measured","length":86,"tokens":24993}
|
||||
{"type":"context.append_message","message":{"id":"msgid_128","role":"assistant","content":[{"type":"think","think":"text_184"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_20\"}"}],"providerMessageId":"msgid_129"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_130"}}
|
||||
{"type":"spine.close","id":"1.1.15","closedAt":86,"memory":"memory_20","archivePath":"path_20"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":297,"output":105,"inputCacheRead":23296,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":39}}
|
||||
{"type":"context_size.measured","length":88,"tokens":23698}
|
||||
{"type":"context.append_message","message":{"id":"msgid_131","role":"assistant","content":[{"type":"think","think":"text_185"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_22\"}"}],"providerMessageId":"msgid_132"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_133"}}
|
||||
{"type":"spine.open","id":"1.1.16","summary":"summary_22","parentId":"1.1","openedAt":87,"baselineTokens":23701}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":467,"output":62,"inputCacheRead":23296,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":40}}
|
||||
{"type":"context_size.measured","length":90,"tokens":23825}
|
||||
{"type":"context.append_message","message":{"id":"msgid_134","role":"assistant","content":[{"type":"think","think":"text_186"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_135"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_187"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_136"}}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_141"}],"toolCalls":[],"origin":{"kind":"injection","variant":"todo_list_reminder"},"id":"msgid_137"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1273,"output":218,"inputCacheRead":23552,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":41}}
|
||||
{"type":"context_size.measured","length":93,"tokens":25043}
|
||||
{"type":"context.append_message","message":{"id":"msgid_138","role":"assistant","content":[{"type":"think","think":"text_188"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_21\"}"}],"providerMessageId":"msgid_139"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_140"}}
|
||||
{"type":"spine.close","id":"1.1.16","closedAt":93,"memory":"memory_21","archivePath":"path_21"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":422,"output":120,"inputCacheRead":23296,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":42}}
|
||||
{"type":"context_size.measured","length":95,"tokens":23838}
|
||||
{"type":"context.append_message","message":{"id":"msgid_141","role":"assistant","content":[{"type":"think","think":"text_189"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_23\"}"}],"providerMessageId":"msgid_142"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_143"}}
|
||||
{"type":"spine.open","id":"1.1.17","summary":"summary_23","parentId":"1.1","openedAt":94,"baselineTokens":23841}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":342,"output":57,"inputCacheRead":23552,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":43}}
|
||||
{"type":"context_size.measured","length":97,"tokens":23951}
|
||||
{"type":"context.append_message","message":{"id":"msgid_144","role":"assistant","content":[{"type":"think","think":"text_190"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_145"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_191"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_146"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1102,"output":186,"inputCacheRead":23808,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":44}}
|
||||
{"type":"context_size.measured","length":99,"tokens":25096}
|
||||
{"type":"context.append_message","message":{"id":"msgid_147","role":"assistant","content":[{"type":"think","think":"text_192"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_22\"}"}],"providerMessageId":"msgid_148"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_149"}}
|
||||
{"type":"spine.close","id":"1.1.17","closedAt":99,"memory":"memory_22","archivePath":"path_22"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":291,"output":159,"inputCacheRead":23552,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":45}}
|
||||
{"type":"context_size.measured","length":101,"tokens":24002}
|
||||
{"type":"context.append_message","message":{"id":"msgid_150","role":"assistant","content":[{"type":"think","think":"text_193"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_24\"}"}],"providerMessageId":"msgid_151"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_152"}}
|
||||
{"type":"spine.open","id":"1.1.18","summary":"summary_24","parentId":"1.1","openedAt":100,"baselineTokens":24005}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":500,"output":246,"inputCacheRead":23552,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":46}}
|
||||
{"type":"context_size.measured","length":103,"tokens":24298}
|
||||
{"type":"context.append_message","message":{"id":"msgid_153","role":"assistant","content":[{"type":"think","think":"text_194"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"},{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_23\"}"}],"providerMessageId":"msgid_154"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_195"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_155"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_156"}}
|
||||
{"type":"spine.close","id":"1.1.18","closedAt":104,"memory":"memory_23","archivePath":"path_23"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":416,"output":316,"inputCacheRead":23552,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":47}}
|
||||
{"type":"context_size.measured","length":106,"tokens":24284}
|
||||
{"type":"context.append_message","message":{"id":"msgid_157","role":"assistant","content":[{"type":"think","think":"text_196"},{"type":"text","text":"text_197"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_25\"}"},{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_158"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_159"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_198"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_160"}}
|
||||
{"type":"spine.open","id":"1.1.19","summary":"summary_25","parentId":"1.1","openedAt":105,"baselineTokens":25062}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1568,"output":241,"inputCacheRead":23808,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":48}}
|
||||
{"type":"context_size.measured","length":109,"tokens":25617}
|
||||
{"type":"context.append_message","message":{"id":"msgid_161","role":"assistant","content":[{"type":"think","think":"text_199"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_24\"}"}],"providerMessageId":"msgid_162"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_163"}}
|
||||
{"type":"spine.close","id":"1.1.19","closedAt":109,"memory":"memory_24","archivePath":"path_24"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":288,"output":288,"inputCacheRead":23808,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":49}}
|
||||
{"type":"context_size.measured","length":111,"tokens":24384}
|
||||
{"type":"context.append_message","message":{"id":"msgid_164","role":"assistant","content":[{"type":"think","think":"text_200"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_26\"}"},{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_165"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_166"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_201"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_167"}}
|
||||
{"type":"spine.open","id":"1.1.20","summary":"summary_26","parentId":"1.1","openedAt":110,"baselineTokens":25206}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1726,"output":228,"inputCacheRead":23808,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":50}}
|
||||
{"type":"context_size.measured","length":114,"tokens":25762}
|
||||
{"type":"context.append_message","message":{"id":"msgid_168","role":"assistant","content":[{"type":"think","think":"text_202"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_25\"}"}],"providerMessageId":"msgid_169"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_170"}}
|
||||
{"type":"spine.close","id":"1.1.20","closedAt":114,"memory":"memory_25","archivePath":"path_25"}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_141"}],"toolCalls":[],"origin":{"kind":"injection","variant":"todo_list_reminder"},"id":"msgid_171"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":507,"output":134,"inputCacheRead":23808,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":51}}
|
||||
{"type":"context_size.measured","length":117,"tokens":24449}
|
||||
{"type":"context.append_message","message":{"id":"msgid_172","role":"assistant","content":[{"type":"think","think":"text_203"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_27\"}"}],"providerMessageId":"msgid_173"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_174"}}
|
||||
{"type":"spine.open","id":"1.1.21","summary":"summary_27","parentId":"1.1","openedAt":116,"baselineTokens":24452}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":446,"output":192,"inputCacheRead":24064,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":52}}
|
||||
{"type":"context_size.measured","length":119,"tokens":24702}
|
||||
{"type":"context.append_message","message":{"id":"msgid_175","role":"assistant","content":[{"type":"think","think":"text_204"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_176"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_205"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_177"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1563,"output":201,"inputCacheRead":24320,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":53}}
|
||||
{"type":"context_size.measured","length":121,"tokens":26084}
|
||||
{"type":"context.append_message","message":{"id":"msgid_178","role":"assistant","content":[{"type":"think","think":"text_206"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_26\"}"}],"providerMessageId":"msgid_179"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_180"}}
|
||||
{"type":"spine.close","id":"1.1.21","closedAt":121,"memory":"memory_26","archivePath":"path_26"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":379,"output":129,"inputCacheRead":24064,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":54}}
|
||||
{"type":"context_size.measured","length":123,"tokens":24572}
|
||||
{"type":"context.append_message","message":{"id":"msgid_181","role":"assistant","content":[{"type":"think","think":"text_207"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_28\"}"}],"providerMessageId":"msgid_182"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_183"}}
|
||||
{"type":"spine.open","id":"1.1.22","summary":"summary_28","parentId":"1.1","openedAt":122,"baselineTokens":24575}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":308,"output":94,"inputCacheRead":24320,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":55}}
|
||||
{"type":"context_size.measured","length":125,"tokens":24722}
|
||||
{"type":"context.append_message","message":{"id":"msgid_184","role":"assistant","content":[{"type":"think","think":"text_208"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_185"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_209"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_186"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1636,"output":200,"inputCacheRead":24320,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":56}}
|
||||
{"type":"context_size.measured","length":127,"tokens":26156}
|
||||
{"type":"context.append_message","message":{"id":"msgid_187","role":"assistant","content":[{"type":"think","think":"text_210"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_27\"}"}],"providerMessageId":"msgid_188"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_189"}}
|
||||
{"type":"spine.close","id":"1.1.22","closedAt":127,"memory":"memory_27","archivePath":"path_27"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":251,"output":136,"inputCacheRead":24320,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":57}}
|
||||
{"type":"context_size.measured","length":129,"tokens":24707}
|
||||
{"type":"context.append_message","message":{"id":"msgid_190","role":"assistant","content":[{"type":"think","think":"text_211"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_29\"}"}],"providerMessageId":"msgid_191"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_192"}}
|
||||
{"type":"spine.open","id":"1.1.23","summary":"summary_29","parentId":"1.1","openedAt":128,"baselineTokens":24710}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":439,"output":80,"inputCacheRead":24320,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":58}}
|
||||
{"type":"context_size.measured","length":131,"tokens":24839}
|
||||
{"type":"context.append_message","message":{"id":"msgid_193","role":"assistant","content":[{"type":"think","think":"text_212"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_194"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_213"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_195"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1546,"output":225,"inputCacheRead":24576,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":59}}
|
||||
{"type":"context_size.measured","length":133,"tokens":26347}
|
||||
{"type":"context.append_message","message":{"id":"msgid_196","role":"assistant","content":[{"type":"think","think":"text_214"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_28\"}"}],"providerMessageId":"msgid_197"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_198"}}
|
||||
{"type":"spine.close","id":"1.1.23","closedAt":133,"memory":"memory_28","archivePath":"path_28"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":379,"output":157,"inputCacheRead":24320,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":60}}
|
||||
{"type":"context_size.measured","length":135,"tokens":24856}
|
||||
{"type":"context.append_message","message":{"id":"msgid_199","role":"assistant","content":[{"type":"think","think":"text_215"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_30\"}"},{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_200"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_201"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_216"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_202"}}
|
||||
{"type":"spine.open","id":"1.1.24","summary":"summary_30","parentId":"1.1","openedAt":134,"baselineTokens":25845}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_141"}],"toolCalls":[],"origin":{"kind":"injection","variant":"todo_list_reminder"},"id":"msgid_203"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1735,"output":233,"inputCacheRead":24576,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":61}}
|
||||
{"type":"context_size.measured","length":139,"tokens":26544}
|
||||
{"type":"context.append_message","message":{"id":"msgid_204","role":"assistant","content":[{"type":"think","think":"text_217"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_29\"}"}],"providerMessageId":"msgid_205"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_206"}}
|
||||
{"type":"spine.close","id":"1.1.24","closedAt":139,"memory":"memory_29","archivePath":"path_29"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":251,"output":169,"inputCacheRead":24576,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":62}}
|
||||
{"type":"context_size.measured","length":141,"tokens":24996}
|
||||
{"type":"context.append_message","message":{"id":"msgid_207","role":"assistant","content":[{"type":"think","think":"text_218"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_28\"}"}],"providerMessageId":"msgid_208"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_209"}}
|
||||
{"type":"spine.open","id":"1.1.25","summary":"summary_28","parentId":"1.1","openedAt":140,"baselineTokens":24999}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":476,"output":139,"inputCacheRead":24576,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":63}}
|
||||
{"type":"context_size.measured","length":143,"tokens":25191}
|
||||
{"type":"context.append_message","message":{"id":"msgid_210","role":"assistant","content":[{"type":"think","think":"text_219"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_211"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_220"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_212"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1751,"output":237,"inputCacheRead":24832,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":64}}
|
||||
{"type":"context_size.measured","length":145,"tokens":26820}
|
||||
{"type":"context.append_message","message":{"id":"msgid_213","role":"assistant","content":[{"type":"think","think":"text_221"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_30\"}"}],"providerMessageId":"msgid_214"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_215"}}
|
||||
{"type":"spine.close","id":"1.1.25","closedAt":145,"memory":"memory_30","archivePath":"path_30"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":379,"output":86,"inputCacheRead":24576,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":65}}
|
||||
{"type":"context_size.measured","length":147,"tokens":25041}
|
||||
{"type":"context.append_message","message":{"id":"msgid_216","role":"assistant","content":[{"type":"think","think":"text_222"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_31\"}"}],"providerMessageId":"msgid_217"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_218"}}
|
||||
{"type":"spine.open","id":"1.1.26","summary":"summary_31","parentId":"1.1","openedAt":146,"baselineTokens":25044}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":266,"output":51,"inputCacheRead":24832,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":66}}
|
||||
{"type":"context_size.measured","length":149,"tokens":25149}
|
||||
{"type":"context.append_message","message":{"id":"msgid_219","role":"assistant","content":[{"type":"think","think":"text_223"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_220"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_224"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_221"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1761,"output":199,"inputCacheRead":24832,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":67}}
|
||||
{"type":"context_size.measured","length":151,"tokens":26792}
|
||||
{"type":"context.append_message","message":{"id":"msgid_222","role":"assistant","content":[{"type":"think","think":"text_225"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_31\"}"}],"providerMessageId":"msgid_223"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_224"}}
|
||||
{"type":"spine.close","id":"1.1.26","closedAt":151,"memory":"memory_31","archivePath":"path_31"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":251,"output":105,"inputCacheRead":24832,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":68}}
|
||||
{"type":"context_size.measured","length":153,"tokens":25188}
|
||||
{"type":"context.append_message","message":{"id":"msgid_225","role":"assistant","content":[{"type":"think","think":"text_226"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_32\"}"}],"providerMessageId":"msgid_226"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_227"}}
|
||||
{"type":"spine.open","id":"1.1.27","summary":"summary_32","parentId":"1.1","openedAt":152,"baselineTokens":25191}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":406,"output":72,"inputCacheRead":24832,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":69}}
|
||||
{"type":"context_size.measured","length":155,"tokens":25310}
|
||||
{"type":"context.append_message","message":{"id":"msgid_228","role":"assistant","content":[{"type":"think","think":"text_227"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_229"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_228"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_230"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1712,"output":195,"inputCacheRead":25088,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":70}}
|
||||
{"type":"context_size.measured","length":157,"tokens":26995}
|
||||
{"type":"context.append_message","message":{"id":"msgid_231","role":"assistant","content":[{"type":"think","think":"text_229"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_32\"}"}],"providerMessageId":"msgid_232"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_233"}}
|
||||
{"type":"spine.close","id":"1.1.27","closedAt":157,"memory":"memory_32","archivePath":"path_32"}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_141"}],"toolCalls":[],"origin":{"kind":"injection","variant":"todo_list_reminder"},"id":"msgid_234"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":470,"output":212,"inputCacheRead":24832,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":71}}
|
||||
{"type":"context_size.measured","length":160,"tokens":25514}
|
||||
{"type":"context.append_message","message":{"id":"msgid_235","role":"assistant","content":[{"type":"think","think":"text_230"},{"type":"text","text":"text_231"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_33\"}"}],"providerMessageId":"msgid_236"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_237"}}
|
||||
{"type":"spine.open","id":"1.1.28","summary":"summary_33","parentId":"1.1","openedAt":159,"baselineTokens":25517}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":475,"output":251,"inputCacheRead":25088,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":72}}
|
||||
{"type":"context_size.measured","length":162,"tokens":25814}
|
||||
{"type":"context.append_message","message":{"id":"msgid_238","role":"assistant","content":[{"type":"think","think":"text_232"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_239"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_233"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_240"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":2006,"output":231,"inputCacheRead":25344,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":73}}
|
||||
{"type":"context_size.measured","length":164,"tokens":27581}
|
||||
{"type":"context.append_message","message":{"id":"msgid_241","role":"assistant","content":[{"type":"think","think":"text_234"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_33\"}"}],"providerMessageId":"msgid_242"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_243"}}
|
||||
{"type":"spine.close","id":"1.1.28","closedAt":164,"memory":"memory_33","archivePath":"path_33"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":342,"output":664,"inputCacheRead":25088,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":74}}
|
||||
{"type":"context_size.measured","length":166,"tokens":26094}
|
||||
{"type":"context.append_message","message":{"id":"msgid_244","role":"assistant","content":[{"type":"think","think":"text_235"},{"type":"text","text":"text_236"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_34\"}"},{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_245"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_246"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_237"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_247"}}
|
||||
{"type":"spine.open","id":"1.1.29","summary":"summary_34","parentId":"1.1","openedAt":165,"baselineTokens":27286}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":2366,"output":234,"inputCacheRead":25344,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":75}}
|
||||
{"type":"context_size.measured","length":169,"tokens":27944}
|
||||
{"type":"context.append_message","message":{"id":"msgid_248","role":"assistant","content":[{"type":"think","think":"text_238"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_34\"}"}],"providerMessageId":"msgid_249"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_250"}}
|
||||
{"type":"spine.close","id":"1.1.29","closedAt":169,"memory":"memory_34","archivePath":"path_34"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":214,"output":137,"inputCacheRead":25344,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":76}}
|
||||
{"type":"context_size.measured","length":171,"tokens":25695}
|
||||
{"type":"context.append_message","message":{"id":"msgid_251","role":"assistant","content":[{"type":"think","think":"text_239"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_35\"}"}],"providerMessageId":"msgid_252"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_253"}}
|
||||
{"type":"spine.open","id":"1.1.30","summary":"summary_35","parentId":"1.1","openedAt":170,"baselineTokens":25698}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":412,"output":84,"inputCacheRead":25344,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":77}}
|
||||
{"type":"context_size.measured","length":173,"tokens":25840}
|
||||
{"type":"context.append_message","message":{"id":"msgid_254","role":"assistant","content":[{"type":"think","think":"text_240"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_255"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_241"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_256"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1887,"output":219,"inputCacheRead":25600,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":78}}
|
||||
{"type":"context_size.measured","length":175,"tokens":27706}
|
||||
{"type":"context.append_message","message":{"id":"msgid_257","role":"assistant","content":[{"type":"think","think":"text_242"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_35\"}"}],"providerMessageId":"msgid_258"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_259"}}
|
||||
{"type":"spine.close","id":"1.1.30","closedAt":175,"memory":"memory_35","archivePath":"path_35"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":342,"output":169,"inputCacheRead":25344,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":79}}
|
||||
{"type":"context_size.measured","length":177,"tokens":25855}
|
||||
{"type":"context.append_message","message":{"id":"msgid_260","role":"assistant","content":[{"type":"think","think":"text_243"},{"type":"text","text":"text_244"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_36\"}"}],"providerMessageId":"msgid_261"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_262"}}
|
||||
{"type":"spine.open","id":"1.1.31","summary":"summary_36","parentId":"1.1","openedAt":176,"baselineTokens":25858}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":314,"output":240,"inputCacheRead":25600,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":80}}
|
||||
{"type":"context_size.measured","length":179,"tokens":26154}
|
||||
{"type":"context.append_message","message":{"id":"msgid_263","role":"assistant","content":[{"type":"think","think":"text_245"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_264"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_246"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_265"}}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_141"}],"toolCalls":[],"origin":{"kind":"injection","variant":"todo_list_reminder"},"id":"msgid_266"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":2348,"output":267,"inputCacheRead":25600,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":81}}
|
||||
{"type":"context_size.measured","length":182,"tokens":28215}
|
||||
{"type":"context.append_message","message":{"id":"msgid_267","role":"assistant","content":[{"type":"think","think":"text_247"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_36\"}"}],"providerMessageId":"msgid_268"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_269"}}
|
||||
{"type":"spine.close","id":"1.1.31","closedAt":182,"memory":"memory_36","archivePath":"path_36"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":214,"output":133,"inputCacheRead":25600,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":82}}
|
||||
{"type":"context_size.measured","length":184,"tokens":25947}
|
||||
{"type":"context.append_message","message":{"id":"msgid_270","role":"assistant","content":[{"type":"think","think":"text_248"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_37\"}"}],"providerMessageId":"msgid_271"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_272"}}
|
||||
{"type":"spine.open","id":"1.1.32","summary":"summary_37","parentId":"1.1","openedAt":183,"baselineTokens":25950}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":408,"output":61,"inputCacheRead":25600,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":83}}
|
||||
{"type":"context_size.measured","length":186,"tokens":26069}
|
||||
{"type":"context.append_message","message":{"id":"msgid_273","role":"assistant","content":[{"type":"think","think":"text_249"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_274"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_250"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_275"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":1971,"output":196,"inputCacheRead":25856,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":84}}
|
||||
{"type":"context_size.measured","length":188,"tokens":28023}
|
||||
{"type":"context.append_message","message":{"id":"msgid_276","role":"assistant","content":[{"type":"think","think":"text_251"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_37\"}"}],"providerMessageId":"msgid_277"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_278"}}
|
||||
{"type":"spine.close","id":"1.1.32","closedAt":188,"memory":"memory_37","archivePath":"path_37"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":342,"output":138,"inputCacheRead":25600,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":85}}
|
||||
{"type":"context_size.measured","length":190,"tokens":26080}
|
||||
{"type":"context.append_message","message":{"id":"msgid_279","role":"assistant","content":[{"type":"think","think":"text_252"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_38\"}"}],"providerMessageId":"msgid_280"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_281"}}
|
||||
{"type":"spine.open","id":"1.1.33","summary":"summary_38","parentId":"1.1","openedAt":189,"baselineTokens":26083}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":285,"output":400,"inputCacheRead":25856,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":86}}
|
||||
{"type":"context_size.measured","length":192,"tokens":26541}
|
||||
{"type":"context.append_message","message":{"id":"msgid_282","role":"assistant","content":[{"type":"think","think":"text_253"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"},{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_38\"}"}],"providerMessageId":"msgid_283"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_254"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_284"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_285"}}
|
||||
{"type":"spine.close","id":"1.1.33","closedAt":193,"memory":"memory_38","archivePath":"path_38"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":211,"output":179,"inputCacheRead":25856,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":87}}
|
||||
{"type":"context_size.measured","length":195,"tokens":26246}
|
||||
{"type":"context.append_message","message":{"id":"msgid_286","role":"assistant","content":[{"type":"think","think":"text_255"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_39\"}"}],"providerMessageId":"msgid_287"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_288"}}
|
||||
{"type":"spine.open","id":"1.1.34","summary":"summary_39","parentId":"1.1","openedAt":194,"baselineTokens":26249}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":448,"output":71,"inputCacheRead":25856,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":88}}
|
||||
{"type":"context_size.measured","length":197,"tokens":26375}
|
||||
{"type":"context.append_message","message":{"id":"msgid_289","role":"assistant","content":[{"type":"think","think":"text_256"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_290"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_257"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_291"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":2132,"output":226,"inputCacheRead":26112,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":89}}
|
||||
{"type":"context_size.measured","length":199,"tokens":28470}
|
||||
{"type":"context.append_message","message":{"id":"msgid_292","role":"assistant","content":[{"type":"think","think":"text_258"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_39\"}"}],"providerMessageId":"msgid_293"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_294"}}
|
||||
{"type":"spine.close","id":"1.1.34","closedAt":199,"memory":"memory_39","archivePath":"path_39"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":339,"output":138,"inputCacheRead":25856,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":90}}
|
||||
{"type":"context_size.measured","length":201,"tokens":26333}
|
||||
{"type":"context.append_message","message":{"id":"msgid_295","role":"assistant","content":[{"type":"think","think":"text_259"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_40\"}"}],"providerMessageId":"msgid_296"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_297"}}
|
||||
{"type":"spine.open","id":"1.1.35","summary":"summary_40","parentId":"1.1","openedAt":200,"baselineTokens":26336}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_141"}],"toolCalls":[],"origin":{"kind":"injection","variant":"todo_list_reminder"},"id":"msgid_298"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":373,"output":134,"inputCacheRead":26112,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":91}}
|
||||
{"type":"context_size.measured","length":204,"tokens":26619}
|
||||
{"type":"context.append_message","message":{"id":"msgid_299","role":"assistant","content":[{"type":"think","think":"text_260"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_300"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_261"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_301"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":2188,"output":213,"inputCacheRead":26368,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":92}}
|
||||
{"type":"context_size.measured","length":206,"tokens":28769}
|
||||
{"type":"context.append_message","message":{"id":"msgid_302","role":"assistant","content":[{"type":"think","think":"text_262"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_40\"}"}],"providerMessageId":"msgid_303"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_304"}}
|
||||
{"type":"spine.close","id":"1.1.35","closedAt":206,"memory":"memory_40","archivePath":"path_40"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":211,"output":154,"inputCacheRead":26112,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":93}}
|
||||
{"type":"context_size.measured","length":208,"tokens":26477}
|
||||
{"type":"context.append_message","message":{"id":"msgid_305","role":"assistant","content":[{"type":"think","think":"text_263"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_41\"}"}],"providerMessageId":"msgid_306"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_307"}}
|
||||
{"type":"spine.open","id":"1.1.36","summary":"summary_41","parentId":"1.1","openedAt":207,"baselineTokens":26480}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":426,"output":57,"inputCacheRead":26112,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":94}}
|
||||
{"type":"context_size.measured","length":210,"tokens":26595}
|
||||
{"type":"context.append_message","message":{"id":"msgid_308","role":"assistant","content":[{"type":"think","think":"text_264"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_309"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_265"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_310"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":2208,"output":189,"inputCacheRead":26368,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":95}}
|
||||
{"type":"context_size.measured","length":212,"tokens":28765}
|
||||
{"type":"context.append_message","message":{"id":"msgid_311","role":"assistant","content":[{"type":"think","think":"text_266"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_41\"}"}],"providerMessageId":"msgid_312"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_313"}}
|
||||
{"type":"spine.close","id":"1.1.36","closedAt":212,"memory":"memory_41","archivePath":"path_41"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":339,"output":213,"inputCacheRead":26112,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":96}}
|
||||
{"type":"context_size.measured","length":214,"tokens":26664}
|
||||
{"type":"context.append_message","message":{"id":"msgid_314","role":"assistant","content":[{"type":"think","think":"text_267"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_42\"}"}],"providerMessageId":"msgid_315"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_316"}}
|
||||
{"type":"spine.open","id":"1.1.37","summary":"summary_42","parentId":"1.1","openedAt":213,"baselineTokens":26667}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":357,"output":246,"inputCacheRead":26368,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":97}}
|
||||
{"type":"context_size.measured","length":216,"tokens":26971}
|
||||
{"type":"context.append_message","message":{"id":"msgid_317","role":"assistant","content":[{"type":"think","think":"text_268"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"},{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_42\"}"}],"providerMessageId":"msgid_318"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_269"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_319"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_320"}}
|
||||
{"type":"spine.close","id":"1.1.37","closedAt":217,"memory":"memory_42","archivePath":"path_42"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":208,"output":133,"inputCacheRead":26368,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":98}}
|
||||
{"type":"context_size.measured","length":219,"tokens":26709}
|
||||
{"type":"context.append_message","message":{"id":"msgid_321","role":"assistant","content":[{"type":"think","think":"text_270"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_43\"}"}],"providerMessageId":"msgid_322"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_323"}}
|
||||
{"type":"spine.open","id":"1.1.38","summary":"summary_43","parentId":"1.1","openedAt":218,"baselineTokens":26712}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":402,"output":61,"inputCacheRead":26368,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":99}}
|
||||
{"type":"context_size.measured","length":221,"tokens":26831}
|
||||
{"type":"context.append_message","message":{"id":"msgid_324","role":"assistant","content":[{"type":"think","think":"text_271"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_325"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_272"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_326"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":2300,"output":217,"inputCacheRead":26624,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":100}}
|
||||
{"type":"context_size.measured","length":223,"tokens":29141}
|
||||
{"type":"context.append_message","message":{"id":"msgid_327","role":"assistant","content":[{"type":"think","think":"text_273"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_43\"}"}],"providerMessageId":"msgid_328"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_329"}}
|
||||
{"type":"spine.close","id":"1.1.38","closedAt":223,"memory":"memory_43","archivePath":"path_43"}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_141"}],"toolCalls":[],"origin":{"kind":"injection","variant":"todo_list_reminder"},"id":"msgid_330"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":427,"output":108,"inputCacheRead":26368,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":101}}
|
||||
{"type":"context_size.measured","length":226,"tokens":26903}
|
||||
{"type":"context.append_message","message":{"id":"msgid_331","role":"assistant","content":[{"type":"think","think":"text_274"},{"type":"text","text":"text_275"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_24\"}"}],"providerMessageId":"msgid_332"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_333"}}
|
||||
{"type":"spine.open","id":"1.1.39","summary":"summary_24","parentId":"1.1","openedAt":225,"baselineTokens":26906}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":329,"output":55,"inputCacheRead":26624,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":102}}
|
||||
{"type":"context_size.measured","length":228,"tokens":27008}
|
||||
{"type":"context.append_message","message":{"id":"msgid_334","role":"assistant","content":[{"type":"think","think":"text_276"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_335"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_277"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_336"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":2268,"output":184,"inputCacheRead":26880,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":103}}
|
||||
{"type":"context_size.measured","length":230,"tokens":29332}
|
||||
{"type":"context.append_message","message":{"id":"msgid_337","role":"assistant","content":[{"type":"think","think":"text_278"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_44\"}"}],"providerMessageId":"msgid_338"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_339"}}
|
||||
{"type":"spine.close","id":"1.1.39","closedAt":230,"memory":"memory_44","archivePath":"path_44"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":299,"output":116,"inputCacheRead":26624,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":104}}
|
||||
{"type":"context_size.measured","length":232,"tokens":27039}
|
||||
{"type":"context.append_message","message":{"id":"msgid_340","role":"assistant","content":[{"type":"think","think":"text_279"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_44\"}"}],"providerMessageId":"msgid_341"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_342"}}
|
||||
{"type":"spine.open","id":"1.1.40","summary":"summary_44","parentId":"1.1","openedAt":231,"baselineTokens":27042}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":473,"output":56,"inputCacheRead":26624,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":105}}
|
||||
{"type":"context_size.measured","length":234,"tokens":27153}
|
||||
{"type":"context.append_message","message":{"id":"msgid_343","role":"assistant","content":[{"type":"think","think":"text_280"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_344"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_281"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_345"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":2468,"output":198,"inputCacheRead":26880,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":106}}
|
||||
{"type":"context_size.measured","length":236,"tokens":29546}
|
||||
{"type":"context.append_message","message":{"id":"msgid_346","role":"assistant","content":[{"type":"think","think":"text_282"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_45\"}"}],"providerMessageId":"msgid_347"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_348"}}
|
||||
{"type":"spine.close","id":"1.1.40","closedAt":236,"memory":"memory_45","archivePath":"path_45"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":171,"output":198,"inputCacheRead":26880,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":107}}
|
||||
{"type":"context_size.measured","length":238,"tokens":27249}
|
||||
{"type":"context.append_message","message":{"id":"msgid_349","role":"assistant","content":[{"type":"think","think":"text_283"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_45\"}"},{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_350"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_351"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_284"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_352"}}
|
||||
{"type":"spine.open","id":"1.1.41","summary":"summary_45","parentId":"1.1","openedAt":237,"baselineTokens":28940}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":2645,"output":220,"inputCacheRead":26880,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":108}}
|
||||
{"type":"context_size.measured","length":241,"tokens":29745}
|
||||
{"type":"context.append_message","message":{"id":"msgid_353","role":"assistant","content":[{"type":"think","think":"text_285"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_46\"}"}],"providerMessageId":"msgid_354"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_355"}}
|
||||
{"type":"spine.close","id":"1.1.41","closedAt":241,"memory":"memory_46","archivePath":"path_46"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":299,"output":292,"inputCacheRead":26880,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":109}}
|
||||
{"type":"context_size.measured","length":243,"tokens":27471}
|
||||
{"type":"context.append_message","message":{"id":"msgid_356","role":"assistant","content":[{"type":"think","think":"text_286"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_46\"}"},{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_357"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_358"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_287"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_359"}}
|
||||
{"type":"spine.open","id":"1.1.42","summary":"summary_46","parentId":"1.1","openedAt":242,"baselineTokens":29204}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":2917,"output":247,"inputCacheRead":26880,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":110}}
|
||||
{"type":"context_size.measured","length":246,"tokens":30044}
|
||||
{"type":"context.append_message","message":{"id":"msgid_360","role":"assistant","content":[{"type":"think","think":"text_288"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_47\"}"}],"providerMessageId":"msgid_361"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_362"}}
|
||||
{"type":"spine.close","id":"1.1.42","closedAt":246,"memory":"memory_47","archivePath":"path_47"}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_141"}],"toolCalls":[],"origin":{"kind":"injection","variant":"todo_list_reminder"},"id":"msgid_363"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":266,"output":225,"inputCacheRead":27136,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":111}}
|
||||
{"type":"context_size.measured","length":249,"tokens":27627}
|
||||
{"type":"context.append_message","message":{"id":"msgid_364","role":"assistant","content":[{"type":"think","think":"text_289"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_47\"}"},{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_365"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_366"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_290"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_367"}}
|
||||
{"type":"spine.open","id":"1.1.43","summary":"summary_47","parentId":"1.1","openedAt":248,"baselineTokens":29406}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":2875,"output":219,"inputCacheRead":27136,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":112}}
|
||||
{"type":"context_size.measured","length":252,"tokens":30230}
|
||||
{"type":"context.append_message","message":{"id":"msgid_368","role":"assistant","content":[{"type":"think","think":"text_291"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_48\"}"}],"providerMessageId":"msgid_369"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_370"}}
|
||||
{"type":"spine.close","id":"1.1.43","closedAt":252,"memory":"memory_48","archivePath":"path_48"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":398,"output":204,"inputCacheRead":27136,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":113}}
|
||||
{"type":"context_size.measured","length":254,"tokens":27738}
|
||||
{"type":"context.append_message","message":{"id":"msgid_371","role":"assistant","content":[{"type":"think","think":"text_292"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_48\"}"}],"providerMessageId":"msgid_372"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_373"}}
|
||||
{"type":"spine.open","id":"1.1.44","summary":"summary_48","parentId":"1.1","openedAt":253,"baselineTokens":27741}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":399,"output":67,"inputCacheRead":27392,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":114}}
|
||||
{"type":"context_size.measured","length":256,"tokens":27858}
|
||||
{"type":"context.append_message","message":{"id":"msgid_374","role":"assistant","content":[{"type":"think","think":"text_293"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_375"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_294"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_376"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":2619,"output":206,"inputCacheRead":27648,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":115}}
|
||||
{"type":"context_size.measured","length":258,"tokens":30473}
|
||||
{"type":"context.append_message","message":{"id":"msgid_377","role":"assistant","content":[{"type":"think","think":"text_295"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_49\"}"}],"providerMessageId":"msgid_378"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_379"}}
|
||||
{"type":"spine.close","id":"1.1.44","closedAt":258,"memory":"memory_49","archivePath":"path_49"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":274,"output":156,"inputCacheRead":27392,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":116}}
|
||||
{"type":"context_size.measured","length":260,"tokens":27822}
|
||||
{"type":"context.append_message","message":{"id":"msgid_380","role":"assistant","content":[{"type":"think","think":"text_296"},{"type":"text","text":"text_297"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_49\"}"}],"providerMessageId":"msgid_381"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_382"}}
|
||||
{"type":"spine.open","id":"1.1.45","summary":"summary_49","parentId":"1.1","openedAt":259,"baselineTokens":27825}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":498,"output":101,"inputCacheRead":27392,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":117}}
|
||||
{"type":"context_size.measured","length":262,"tokens":27991}
|
||||
{"type":"context.append_message","message":{"id":"msgid_383","role":"assistant","content":[{"type":"think","think":"text_298"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_384"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_299"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_385"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":2815,"output":219,"inputCacheRead":27648,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":118}}
|
||||
{"type":"context_size.measured","length":264,"tokens":30682}
|
||||
{"type":"context.append_message","message":{"id":"msgid_386","role":"assistant","content":[{"type":"think","think":"text_300"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_50\"}"}],"providerMessageId":"msgid_387"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_388"}}
|
||||
{"type":"spine.close","id":"1.1.45","closedAt":264,"memory":"memory_50","archivePath":"path_50"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":406,"output":102,"inputCacheRead":27392,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":119}}
|
||||
{"type":"context_size.measured","length":266,"tokens":27900}
|
||||
{"type":"context.append_message","message":{"id":"msgid_389","role":"assistant","content":[{"type":"think","think":"text_301"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_50\"}"}],"providerMessageId":"msgid_390"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_391"}}
|
||||
{"type":"spine.open","id":"1.1.46","summary":"summary_50","parentId":"1.1","openedAt":265,"baselineTokens":27903}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":309,"output":60,"inputCacheRead":27648,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":120}}
|
||||
{"type":"context_size.measured","length":268,"tokens":28017}
|
||||
{"type":"context.append_message","message":{"id":"msgid_392","role":"assistant","content":[{"type":"think","think":"text_302"}],"toolCalls":[{"type":"function","id":"spine_tree_1","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_393"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_303"}],"toolCalls":[],"toolCallId":"spine_tree_1","id":"msgid_394"}}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_141"}],"toolCalls":[],"origin":{"kind":"injection","variant":"todo_list_reminder"},"id":"msgid_395"}}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":2986,"output":197,"inputCacheRead":27648,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":121}}
|
||||
{"type":"context_size.measured","length":271,"tokens":30831}
|
||||
{"type":"context.append_message","message":{"id":"msgid_396","role":"assistant","content":[{"type":"think","think":"text_304"}],"toolCalls":[{"type":"function","id":"spine_close_2","name":"spine_close","arguments":"{\"memory\":\"memory_51\"}"}],"providerMessageId":"msgid_397"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_2","id":"msgid_398"}}
|
||||
{"type":"spine.close","id":"1.1.46","closedAt":271,"memory":"memory_51","archivePath":"path_51"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":282,"output":373,"inputCacheRead":27648,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":122}}
|
||||
{"type":"context_size.measured","length":273,"tokens":28303}
|
||||
{"type":"context.append_message","message":{"id":"msgid_399","role":"assistant","content":[{"type":"think","think":"text_305"}],"toolCalls":[{"type":"function","id":"spine_open_0","name":"spine_open","arguments":"{\"summary\":\"summary_51\"}"}],"providerMessageId":"msgid_400"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_open_0","id":"msgid_401"}}
|
||||
{"type":"spine.open","id":"1.1.47","summary":"summary_51","parentId":"1.1","openedAt":272,"baselineTokens":28306}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":716,"output":168,"inputCacheRead":27648,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":123}}
|
||||
{"type":"context_size.measured","length":275,"tokens":28532}
|
||||
{"type":"context.append_message","message":{"id":"msgid_402","role":"assistant","content":[{"type":"think","think":"text_306"}],"toolCalls":[{"type":"function","id":"spine_close_1","name":"spine_close","arguments":"{\"memory\":\"memory_52\"}"}],"providerMessageId":"msgid_403"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"accepted"}],"toolCalls":[],"toolCallId":"spine_close_1","id":"msgid_404"}}
|
||||
{"type":"spine.close","id":"1.1.47","closedAt":275,"memory":"memory_52","archivePath":"path_52"}
|
||||
{"type":"usage.record","model":"model_6","usage":{"inputOther":389,"output":1388,"inputCacheRead":27648,"inputCacheCreation":0},"usageScope":"turn","context":{"type":"turn","turnId":0,"step":124}}
|
||||
{"type":"context_size.measured","length":277,"tokens":29425}
|
||||
{"type":"context.append_message","message":{"id":"msgid_405","role":"assistant","content":[{"type":"think","think":"text_307"}],"toolCalls":[{"type":"function","id":"spine_tree_0","name":"spine_tree","arguments":"{}"}],"providerMessageId":"msgid_406"}}
|
||||
{"type":"context.append_message","message":{"role":"tool","content":[{"type":"text","text":"text_308"}],"toolCalls":[],"toolCallId":"spine_tree_0","id":"msgid_407"}}
|
||||
|
|
@ -0,0 +1,288 @@
|
|||
{"type":"metadata","protocol_version":"1.4","created_at":1783669665424}
|
||||
{"type":"mcp.tools_discovered","serverName":"server_1","hash":"hash_1","tools":[{"name":"tool_1","description":"text_1","inputSchema":{}},{"name":"tool_2","description":"text_2","inputSchema":{}}],"enabledNames":["tool_1","tool_2"],"time":1783669665424}
|
||||
{"type":"config.update","profileName":"name_1","systemPrompt":"prompt_8","time":1783669665434}
|
||||
{"type":"tools.set_active_tools","names":["Read","Write","Edit","Grep","Glob","Bash","TaskList","TaskOutput","TaskStop","CronCreate","CronList","CronDelete","ReadMediaFile","TodoList","Skill","WebSearch","Agent","AgentSwarm","FetchURL","AskUserQuestion","EnterPlanMode","ExitPlanMode","CreateGoal","GetGoal","SetGoalBudget","UpdateGoal","mcp__*","spine_open","spine_close","spine_next","spine_tree"],"time":1783669665434}
|
||||
{"type":"config.update","modelAlias":"model_9","thinkingEffort":"high","time":1783669665434}
|
||||
{"type":"permission.set_mode","mode":"yolo","time":1783669665435}
|
||||
{"type":"permission.set_mode","mode":"yolo","time":1783669665439}
|
||||
{"type":"turn.prompt","input":[{"type":"text","text":"text_1010"}],"origin":{"kind":"user"},"time":1783669667353}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_1010"}],"toolCalls":[],"origin":{"kind":"user"}},"time":1783669667353}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1396","turnId":"0","step":1},"time":1783669667354}
|
||||
{"type":"llm.tools_snapshot","hash":"hash_8","tools":[{"name":"Agent","description":"text_4","parameters":{}},{"name":"AgentSwarm","description":"text_5","parameters":{}},{"name":"AskUserQuestion","description":"text_1011","parameters":{}},{"name":"Bash","description":"text_79","parameters":{}},{"name":"CreateGoal","description":"text_8","parameters":{}},{"name":"CronCreate","description":"text_1012","parameters":{}},{"name":"CronDelete","description":"text_1013","parameters":{}},{"name":"CronList","description":"text_1014","parameters":{}},{"name":"Edit","description":"text_12","parameters":{}},{"name":"EnterPlanMode","description":"text_13","parameters":{}},{"name":"ExitPlanMode","description":"text_14","parameters":{}},{"name":"FetchURL","description":"text_15","parameters":{}},{"name":"GetGoal","description":"text_16","parameters":{}},{"name":"Glob","description":"text_17","parameters":{}},{"name":"Grep","description":"text_18","parameters":{}},{"name":"mcp__plugin-kimi-datasource_data__call_data_source_tool","description":"text_1","parameters":{}},{"name":"mcp__plugin-kimi-datasource_data__get_data_source_desc","description":"text_2","parameters":{}},{"name":"Read","description":"text_19","parameters":{}},{"name":"ReadMediaFile","description":"text_80","parameters":{}},{"name":"SetGoalBudget","description":"text_21","parameters":{}},{"name":"Skill","description":"text_1015","parameters":{}},{"name":"spine_close","description":"text_23","parameters":{}},{"name":"spine_next","description":"text_24","parameters":{}},{"name":"spine_open","description":"text_25","parameters":{}},{"name":"spine_tree","description":"text_26","parameters":{}},{"name":"TaskList","description":"text_27","parameters":{}},{"name":"TaskOutput","description":"text_81","parameters":{}},{"name":"TaskStop","description":"text_29","parameters":{}},{"name":"UpdateGoal","description":"text_30","parameters":{}},{"name":"WebSearch","description":"text_31","parameters":{}},{"name":"Write","description":"text_32","parameters":{}}],"time":1783669667355}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1048560,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":2,"turnStep":"0.1","time":1783669667355}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1397","turnId":"0","step":1,"stepUuid":"uuid_1396","part":{"type":"think","think":"text_1016"}},"time":1783669697695}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1398","turnId":"0","step":1,"stepUuid":"uuid_1396","part":{"type":"text","text":"text_1017"}},"time":1783669697695}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1399","turnId":"0","step":1,"stepUuid":"uuid_1396","toolCallId":"spine_open_0","name":"spine_open","args":{"summary":"summary_81"}},"time":1783669697696}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1400","turnId":"0","step":1,"stepUuid":"uuid_1396","toolCallId":"Glob_1","name":"Glob","args":{}},"time":1783669697696}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1399","toolCallId":"spine_open_0","result":{"output":"accepted"}},"time":1783669697697}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1400","toolCallId":"Glob_1","result":{"output":"text_1018"}},"time":1783669697795}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1396","turnId":"0","step":1,"finishReason":"tool_use","usage":{"inputOther":7793,"output":1506,"inputCacheRead":19200,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1898,"llmStreamDurationMs":28442,"llmRequestBuildMs":0,"llmServerFirstTokenMs":1898,"llmServerDecodeMs":28410,"llmClientConsumeMs":32,"messageId":"uuid_1401"},"time":1783669697795}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":7793,"output":1506,"inputCacheRead":19200,"inputCacheCreation":0},"usageScope":"turn","time":1783669697795}
|
||||
{"type":"spine.open","id":"1.1.1","summary":"summary_81","parentId":"1.1","openedAt":1,"baselineTokens":28631,"time":1783669697795}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1402","turnId":"0","step":2},"time":1783669697796}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1019942,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":5,"turnStep":"0.2","time":1783669697797}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1403","turnId":"0","step":2,"stepUuid":"uuid_1402","part":{"type":"think","think":"text_1019"}},"time":1783669704101}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1404","turnId":"0","step":2,"stepUuid":"uuid_1402","part":{"type":"text","text":"text_1020"}},"time":1783669704101}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1405","turnId":"0","step":2,"stepUuid":"uuid_1402","toolCallId":"spine_open_2","name":"spine_open","args":{"summary":"summary_82"}},"time":1783669704101}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1406","turnId":"0","step":2,"stepUuid":"uuid_1402","toolCallId":"Glob_3","name":"Glob","args":{}},"time":1783669704102}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1407","turnId":"0","step":2,"stepUuid":"uuid_1402","toolCallId":"Glob_4","name":"Glob","args":{}},"time":1783669704102}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1405","toolCallId":"spine_open_2","result":{"output":"accepted"}},"time":1783669704103}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1406","toolCallId":"Glob_3","result":{"output":"text_1021"}},"time":1783669704212}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1407","toolCallId":"Glob_4","result":{"output":"text_1022"}},"time":1783669704213}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1402","turnId":"0","step":2,"finishReason":"tool_use","usage":{"inputOther":1798,"output":253,"inputCacheRead":26880,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1733,"llmStreamDurationMs":4571,"llmRequestBuildMs":0,"llmServerFirstTokenMs":1733,"llmServerDecodeMs":4567,"llmClientConsumeMs":4,"messageId":"uuid_1408"},"time":1783669704213}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":1798,"output":253,"inputCacheRead":26880,"inputCacheCreation":0},"usageScope":"turn","time":1783669704213}
|
||||
{"type":"spine.open","id":"1.1.1.1","summary":"summary_82","parentId":"1.1.1","openedAt":4,"baselineTokens":30180,"time":1783669704213}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1409","turnId":"0","step":3},"time":1783669704213}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1018393,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":9,"turnStep":"0.3","time":1783669704214}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1410","turnId":"0","step":3,"stepUuid":"uuid_1409","part":{"type":"think","think":"text_1023"}},"time":1783669712469}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1411","turnId":"0","step":3,"stepUuid":"uuid_1409","part":{"type":"text","text":"text_1024"}},"time":1783669712469}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1412","turnId":"0","step":3,"stepUuid":"uuid_1409","toolCallId":"Read_5","name":"Read","args":{}},"time":1783669712469}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1413","turnId":"0","step":3,"stepUuid":"uuid_1409","toolCallId":"Read_6","name":"Read","args":{}},"time":1783669712470}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1414","turnId":"0","step":3,"stepUuid":"uuid_1409","toolCallId":"Glob_7","name":"Glob","args":{}},"time":1783669712470}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1415","turnId":"0","step":3,"stepUuid":"uuid_1409","toolCallId":"Glob_8","name":"Glob","args":{}},"time":1783669712470}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1412","toolCallId":"Read_5","result":{"output":"text_1025","note":"text_1026"}},"time":1783669712472}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1413","toolCallId":"Read_6","result":{"output":"text_1027","note":"text_1028"}},"time":1783669712473}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1414","toolCallId":"Glob_7","result":{"output":"text_1029"}},"time":1783669712565}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1415","toolCallId":"Glob_8","result":{"output":"text_1030"}},"time":1783669712566}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1409","turnId":"0","step":3,"finishReason":"tool_use","usage":{"inputOther":3139,"output":329,"inputCacheRead":26880,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2280,"llmStreamDurationMs":5975,"llmRequestBuildMs":1,"llmServerFirstTokenMs":2279,"llmServerDecodeMs":5968,"llmClientConsumeMs":7,"messageId":"uuid_1416"},"time":1783669712566}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":3139,"output":329,"inputCacheRead":26880,"inputCacheCreation":0},"usageScope":"turn","time":1783669712566}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1417","turnId":"0","step":4},"time":1783669712566}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1009226,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":14,"turnStep":"0.4","time":1783669712567}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1418","turnId":"0","step":4,"stepUuid":"uuid_1417","part":{"type":"think","think":"text_1031"}},"time":1783669723929}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1419","turnId":"0","step":4,"stepUuid":"uuid_1417","part":{"type":"text","text":"text_1032"}},"time":1783669723929}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1420","turnId":"0","step":4,"stepUuid":"uuid_1417","toolCallId":"Read_9","name":"Read","args":{}},"time":1783669723930}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1420","toolCallId":"Read_9","result":{"output":"text_1033","note":"text_1034"}},"time":1783669723933}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1417","turnId":"0","step":4,"finishReason":"tool_use","usage":{"inputOther":11805,"output":446,"inputCacheRead":28416,"inputCacheCreation":0},"llmFirstTokenLatencyMs":3071,"llmStreamDurationMs":8290,"llmRequestBuildMs":0,"llmServerFirstTokenMs":3071,"llmServerDecodeMs":8286,"llmClientConsumeMs":4,"messageId":"uuid_1421"},"time":1783669723933}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":11805,"output":446,"inputCacheRead":28416,"inputCacheCreation":0},"usageScope":"turn","time":1783669723933}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1422","turnId":"0","step":5},"time":1783669723934}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1007906,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":16,"turnStep":"0.5","time":1783669723935}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1423","turnId":"0","step":5,"stepUuid":"uuid_1422","part":{"type":"think","think":"text_1035"}},"time":1783669747874}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1424","turnId":"0","step":5,"stepUuid":"uuid_1422","part":{"type":"text","text":"text_1036"}},"time":1783669747874}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1425","turnId":"0","step":5,"stepUuid":"uuid_1422","toolCallId":"spine_next_10","name":"spine_next","args":{"summary":"summary_83","memory":"memory_83"}},"time":1783669747874}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1426","turnId":"0","step":5,"stepUuid":"uuid_1422","toolCallId":"Read_11","name":"Read","args":{}},"time":1783669747875}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1427","turnId":"0","step":5,"stepUuid":"uuid_1422","toolCallId":"Glob_12","name":"Glob","args":{}},"time":1783669747875}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1425","toolCallId":"spine_next_10","result":{"output":"accepted"}},"time":1783669747876}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1426","toolCallId":"Read_11","result":{"output":"text_1037","note":"text_1038"}},"time":1783669747880}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1427","toolCallId":"Glob_12","result":{"output":"text_1039"}},"time":1783669747975}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1422","turnId":"0","step":5,"finishReason":"tool_use","usage":{"inputOther":12634,"output":1125,"inputCacheRead":29696,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2465,"llmStreamDurationMs":21473,"llmRequestBuildMs":1,"llmServerFirstTokenMs":2464,"llmServerDecodeMs":21451,"llmClientConsumeMs":22,"messageId":"uuid_1428"},"time":1783669747975}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":12634,"output":1125,"inputCacheRead":29696,"inputCacheCreation":0},"usageScope":"turn","time":1783669747975}
|
||||
{"type":"spine.next","closedId":"1.1.1.1","closedAt":16,"memory":"memory_83","archivePath":"path_82","openedId":"1.1.1.2","summary":"summary_83","baselineTokens":46702,"time":1783669747976}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1429","turnId":"0","step":6},"time":1783669747976}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1001871,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":6,"turnStep":"0.6","time":1783669747977}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1430","turnId":"0","step":6,"stepUuid":"uuid_1429","part":{"type":"think","think":"text_1040"}},"time":1783669762499}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1431","turnId":"0","step":6,"stepUuid":"uuid_1429","part":{"type":"text","text":"text_1041"}},"time":1783669762499}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1432","turnId":"0","step":6,"stepUuid":"uuid_1429","toolCallId":"Read_2","name":"Read","args":{}},"time":1783669762501}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1433","turnId":"0","step":6,"stepUuid":"uuid_1429","toolCallId":"Read_3","name":"Read","args":{}},"time":1783669762501}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1434","turnId":"0","step":6,"stepUuid":"uuid_1429","toolCallId":"Glob_4","name":"Glob","args":{}},"time":1783669762502}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1433","toolCallId":"Read_3","result":{"output":"text_1037","note":"text_1038"}},"time":1783669762504}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1432","toolCallId":"Read_2","result":{"output":"text_1033","note":"text_1034"}},"time":1783669762504}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1434","toolCallId":"Glob_4","result":{"output":"text_1042"}},"time":1783669762607}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1429","turnId":"0","step":6,"finishReason":"tool_use","usage":{"inputOther":672,"output":691,"inputCacheRead":28416,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1739,"llmStreamDurationMs":12783,"llmRequestBuildMs":1,"llmServerFirstTokenMs":1738,"llmServerDecodeMs":12767,"llmClientConsumeMs":16,"messageId":"uuid_1435"},"time":1783669762607}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":672,"output":691,"inputCacheRead":28416,"inputCacheCreation":0},"usageScope":"turn","time":1783669762607}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1436","turnId":"0","step":7},"time":1783669762608}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1016992,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":10,"turnStep":"0.7","time":1783669762609}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1437","turnId":"0","step":7,"stepUuid":"uuid_1436","part":{"type":"think","think":"text_1043"}},"time":1783669775755}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1438","turnId":"0","step":7,"stepUuid":"uuid_1436","part":{"type":"text","text":"text_1044"}},"time":1783669775756}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1439","turnId":"0","step":7,"stepUuid":"uuid_1436","toolCallId":"Grep_5","name":"Grep","args":{}},"time":1783669775756}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1440","turnId":"0","step":7,"stepUuid":"uuid_1436","toolCallId":"Read_6","name":"Read","args":{}},"time":1783669775756}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1440","toolCallId":"Read_6","result":{"output":"text_1045","note":"text_1038"}},"time":1783669775758}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1439","toolCallId":"Grep_5","result":{"output":"text_1046"}},"time":1783669775786}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1436","turnId":"0","step":7,"finishReason":"tool_use","usage":{"inputOther":5349,"output":603,"inputCacheRead":28928,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1771,"llmStreamDurationMs":11375,"llmRequestBuildMs":0,"llmServerFirstTokenMs":1771,"llmServerDecodeMs":11361,"llmClientConsumeMs":14,"messageId":"uuid_1441"},"time":1783669775786}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":5349,"output":603,"inputCacheRead":28928,"inputCacheCreation":0},"usageScope":"turn","time":1783669775786}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1442","turnId":"0","step":8},"time":1783669775786}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1010794,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":13,"turnStep":"0.8","time":1783669775787}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1443","turnId":"0","step":8,"stepUuid":"uuid_1442","part":{"type":"think","think":"text_1047"}},"time":1783669803755}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1444","turnId":"0","step":8,"stepUuid":"uuid_1442","part":{"type":"text","text":"text_1048"}},"time":1783669803755}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1445","turnId":"0","step":8,"stepUuid":"uuid_1442","toolCallId":"Read_7","name":"Read","args":{}},"time":1783669803756}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1446","turnId":"0","step":8,"stepUuid":"uuid_1442","toolCallId":"Grep_8","name":"Grep","args":{}},"time":1783669803757}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1445","toolCallId":"Read_7","result":{"output":"text_1049","note":"text_1050"}},"time":1783669803760}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1446","toolCallId":"Grep_8","result":{"output":"text_1051"}},"time":1783669803779}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1442","turnId":"0","step":8,"finishReason":"tool_use","usage":{"inputOther":5292,"output":1385,"inputCacheRead":34048,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1923,"llmStreamDurationMs":26044,"llmRequestBuildMs":1,"llmServerFirstTokenMs":1922,"llmServerDecodeMs":26016,"llmClientConsumeMs":28,"messageId":"uuid_1447"},"time":1783669803780}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":5292,"output":1385,"inputCacheRead":34048,"inputCacheCreation":0},"usageScope":"turn","time":1783669803780}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1448","turnId":"0","step":9},"time":1783669803780}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1001647,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":16,"turnStep":"0.9","time":1783669803782}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1449","turnId":"0","step":9,"stepUuid":"uuid_1448","part":{"type":"think","think":"text_1052"}},"time":1783669821355}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1450","turnId":"0","step":9,"stepUuid":"uuid_1448","part":{"type":"text","text":"text_1053"}},"time":1783669821355}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1451","turnId":"0","step":9,"stepUuid":"uuid_1448","toolCallId":"Grep_9","name":"Grep","args":{}},"time":1783669821356}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1452","turnId":"0","step":9,"stepUuid":"uuid_1448","toolCallId":"Grep_10","name":"Grep","args":{}},"time":1783669821356}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1452","toolCallId":"Grep_10","result":{"output":"text_1054"}},"time":1783669821388}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1451","toolCallId":"Grep_9","result":{"output":"text_1055"}},"time":1783669821392}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1448","turnId":"0","step":9,"finishReason":"tool_use","usage":{"inputOther":8162,"output":838,"inputCacheRead":39168,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2117,"llmStreamDurationMs":15456,"llmRequestBuildMs":1,"llmServerFirstTokenMs":2116,"llmServerDecodeMs":15442,"llmClientConsumeMs":14,"messageId":"uuid_1453"},"time":1783669821392}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":8162,"output":838,"inputCacheRead":39168,"inputCacheCreation":0},"usageScope":"turn","time":1783669821392}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1454","turnId":"0","step":10},"time":1783669821392}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":999417,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":19,"turnStep":"0.10","time":1783669821393}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1455","turnId":"0","step":10,"stepUuid":"uuid_1454","part":{"type":"think","think":"text_1056"}},"time":1783669836396}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1456","turnId":"0","step":10,"stepUuid":"uuid_1454","part":{"type":"text","text":"text_1057"}},"time":1783669836396}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1457","turnId":"0","step":10,"stepUuid":"uuid_1454","toolCallId":"Read_11","name":"Read","args":{}},"time":1783669836396}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1458","turnId":"0","step":10,"stepUuid":"uuid_1454","toolCallId":"Read_12","name":"Read","args":{}},"time":1783669836396}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1458","toolCallId":"Read_12","result":{"output":"text_1058","note":"text_1059"}},"time":1783669836399}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1457","toolCallId":"Read_11","result":{"output":"text_1060","note":"text_1061"}},"time":1783669836400}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1454","turnId":"0","step":10,"finishReason":"tool_use","usage":{"inputOther":3410,"output":706,"inputCacheRead":47104,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2034,"llmStreamDurationMs":12968,"llmRequestBuildMs":1,"llmServerFirstTokenMs":2033,"llmServerDecodeMs":12954,"llmClientConsumeMs":14,"messageId":"uuid_1459"},"time":1783669836400}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":3410,"output":706,"inputCacheRead":47104,"inputCacheCreation":0},"usageScope":"turn","time":1783669836400}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1460","turnId":"0","step":11},"time":1783669836400}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":996387,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":22,"turnStep":"0.11","time":1783669836401}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1461","turnId":"0","step":11,"stepUuid":"uuid_1460","part":{"type":"think","think":"text_1062"}},"time":1783669871776}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1462","turnId":"0","step":11,"stepUuid":"uuid_1460","part":{"type":"text","text":"text_1063"}},"time":1783669871776}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1463","turnId":"0","step":11,"stepUuid":"uuid_1460","toolCallId":"spine_next_13","name":"spine_next","args":{"summary":"summary_84","memory":"memory_84"}},"time":1783669871777}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1463","toolCallId":"spine_next_13","result":{"output":"accepted"}},"time":1783669871779}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1460","turnId":"0","step":11,"finishReason":"tool_use","usage":{"inputOther":5572,"output":1729,"inputCacheRead":47104,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2691,"llmStreamDurationMs":32683,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2691,"llmServerDecodeMs":32646,"llmClientConsumeMs":37,"messageId":"uuid_1464"},"time":1783669871779}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":5572,"output":1729,"inputCacheRead":47104,"inputCacheCreation":0},"usageScope":"turn","time":1783669871779}
|
||||
{"type":"spine.next","closedId":"1.1.1.2","closedAt":36,"memory":"memory_84","archivePath":"path_83","openedId":"1.1.1.3","summary":"summary_84","baselineTokens":54405,"time":1783669871788}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1465","turnId":"0","step":12},"time":1783669871788}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":994168,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":7,"turnStep":"0.12","time":1783669871790}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1466","turnId":"0","step":12,"stepUuid":"uuid_1465","part":{"type":"think","think":"text_1064"}},"time":1783669878427}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1467","turnId":"0","step":12,"stepUuid":"uuid_1465","part":{"type":"text","text":"text_1065"}},"time":1783669878427}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1468","turnId":"0","step":12,"stepUuid":"uuid_1465","toolCallId":"Grep_2","name":"Grep","args":{}},"time":1783669878428}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1469","turnId":"0","step":12,"stepUuid":"uuid_1465","toolCallId":"Glob_3","name":"Glob","args":{}},"time":1783669878428}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1468","toolCallId":"Grep_2","result":{"output":"text_1066"}},"time":1783669878442}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1469","toolCallId":"Glob_3","result":{"output":"text_1067"}},"time":1783669878519}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1465","turnId":"0","step":12,"finishReason":"tool_use","usage":{"inputOther":700,"output":270,"inputCacheRead":28928,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1624,"llmStreamDurationMs":5013,"llmRequestBuildMs":0,"llmServerFirstTokenMs":1624,"llmServerDecodeMs":5008,"llmClientConsumeMs":5,"messageId":"uuid_1470"},"time":1783669878519}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":700,"output":270,"inputCacheRead":28928,"inputCacheCreation":0},"usageScope":"turn","time":1783669878519}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1471","turnId":"0","step":13},"time":1783669878520}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1017870,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":10,"turnStep":"0.13","time":1783669878521}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1472","turnId":"0","step":13,"stepUuid":"uuid_1471","part":{"type":"think","think":"text_1068"}},"time":1783669883239}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1473","turnId":"0","step":13,"stepUuid":"uuid_1471","toolCallId":"Read_4","name":"Read","args":{}},"time":1783669883240}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1474","turnId":"0","step":13,"stepUuid":"uuid_1471","toolCallId":"Read_5","name":"Read","args":{}},"time":1783669883240}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1475","turnId":"0","step":13,"stepUuid":"uuid_1471","toolCallId":"Read_6","name":"Read","args":{}},"time":1783669883241}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1473","toolCallId":"Read_4","result":{"output":"text_1069","note":"text_1070"}},"time":1783669883244}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1474","toolCallId":"Read_5","result":{"output":"text_1071","note":"text_1072"}},"time":1783669883245}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1475","toolCallId":"Read_6","result":{"output":"text_1073","note":"text_1074"}},"time":1783669883246}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1471","turnId":"0","step":13,"finishReason":"tool_use","usage":{"inputOther":1182,"output":186,"inputCacheRead":29440,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1645,"llmStreamDurationMs":3073,"llmRequestBuildMs":0,"llmServerFirstTokenMs":1645,"llmServerDecodeMs":3071,"llmClientConsumeMs":2,"messageId":"uuid_1476"},"time":1783669883246}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":1182,"output":186,"inputCacheRead":29440,"inputCacheCreation":0},"usageScope":"turn","time":1783669883246}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1477","turnId":"0","step":14},"time":1783669883246}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1011614,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":14,"turnStep":"0.14","time":1783669883247}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1478","turnId":"0","step":14,"stepUuid":"uuid_1477","part":{"type":"think","think":"text_1075"}},"time":1783669888848}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1479","turnId":"0","step":14,"stepUuid":"uuid_1477","toolCallId":"Read_7","name":"Read","args":{}},"time":1783669888849}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1480","turnId":"0","step":14,"stepUuid":"uuid_1477","toolCallId":"Read_8","name":"Read","args":{}},"time":1783669888849}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1479","toolCallId":"Read_7","result":{"output":"text_1076","note":"text_1077"}},"time":1783669888855}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1480","toolCallId":"Read_8","result":{"output":"text_1078","note":"text_1079"}},"time":1783669888858}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1477","turnId":"0","step":14,"finishReason":"tool_use","usage":{"inputOther":12069,"output":205,"inputCacheRead":30464,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2134,"llmStreamDurationMs":3465,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2134,"llmServerDecodeMs":3459,"llmClientConsumeMs":6,"messageId":"uuid_1481"},"time":1783669888858}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":12069,"output":205,"inputCacheRead":30464,"inputCacheCreation":0},"usageScope":"turn","time":1783669888858}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1482","turnId":"0","step":15},"time":1783669888859}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":997124,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":17,"turnStep":"0.15","time":1783669888860}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1483","turnId":"0","step":15,"stepUuid":"uuid_1482","part":{"type":"think","think":"text_1080"}},"time":1783669896400}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1484","turnId":"0","step":15,"stepUuid":"uuid_1482","toolCallId":"Grep_9","name":"Grep","args":{}},"time":1783669896401}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1484","toolCallId":"Grep_9","result":{"output":"text_1081"}},"time":1783669896423}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1482","turnId":"0","step":15,"finishReason":"tool_use","usage":{"inputOther":20756,"output":252,"inputCacheRead":30464,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2915,"llmStreamDurationMs":4625,"llmRequestBuildMs":1,"llmServerFirstTokenMs":2914,"llmServerDecodeMs":4621,"llmClientConsumeMs":4,"messageId":"uuid_1485"},"time":1783669896423}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":20756,"output":252,"inputCacheRead":30464,"inputCacheCreation":0},"usageScope":"turn","time":1783669896423}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1486","turnId":"0","step":16},"time":1783669896424}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":997101,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":19,"turnStep":"0.16","time":1783669896425}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1487","turnId":"0","step":16,"stepUuid":"uuid_1486","part":{"type":"think","think":"text_1082"}},"time":1783669941125}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1488","turnId":"0","step":16,"stepUuid":"uuid_1486","toolCallId":"spine_next_10","name":"spine_next","args":{"summary":"summary_85","memory":"memory_85"}},"time":1783669941126}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1488","toolCallId":"spine_next_10","result":{"output":"accepted"}},"time":1783669941127}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1486","turnId":"0","step":16,"finishReason":"tool_use","usage":{"inputOther":9409,"output":2411,"inputCacheRead":42240,"inputCacheCreation":0},"llmFirstTokenLatencyMs":3071,"llmStreamDurationMs":41628,"llmRequestBuildMs":1,"llmServerFirstTokenMs":3070,"llmServerDecodeMs":41574,"llmClientConsumeMs":54,"messageId":"uuid_1489"},"time":1783669941127}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":9409,"output":2411,"inputCacheRead":42240,"inputCacheCreation":0},"usageScope":"turn","time":1783669941127}
|
||||
{"type":"spine.next","closedId":"1.1.1.3","closedAt":50,"memory":"memory_85","archivePath":"path_84","openedId":"1.1.1.4","summary":"summary_85","baselineTokens":54060,"time":1783669941136}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1490","turnId":"0","step":17},"time":1783669941137}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":994513,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":8,"turnStep":"0.17","time":1783669941138}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1491","turnId":"0","step":17,"stepUuid":"uuid_1490","part":{"type":"think","think":"text_1083"}},"time":1783669951683}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1492","turnId":"0","step":17,"stepUuid":"uuid_1490","part":{"type":"text","text":"text_1084"}},"time":1783669951683}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1493","turnId":"0","step":17,"stepUuid":"uuid_1490","toolCallId":"Bash_2","name":"Bash","args":{}},"time":1783669951683}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1494","turnId":"0","step":17,"stepUuid":"uuid_1490","toolCallId":"Bash_3","name":"Bash","args":{}},"time":1783669951683}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1493","toolCallId":"Bash_2","result":{"output":"text_1085"}},"time":1783669951700}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1494","toolCallId":"Bash_3","result":{"output":"text_1086"}},"time":1783669951706}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1490","turnId":"0","step":17,"finishReason":"tool_use","usage":{"inputOther":1777,"output":430,"inputCacheRead":28928,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2579,"llmStreamDurationMs":7965,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2579,"llmServerDecodeMs":7951,"llmClientConsumeMs":14,"messageId":"uuid_1495"},"time":1783669951706}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":1777,"output":430,"inputCacheRead":28928,"inputCacheCreation":0},"usageScope":"turn","time":1783669951706}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1496","turnId":"0","step":18},"time":1783669951706}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1017404,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":11,"turnStep":"0.18","time":1783669951707}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1497","turnId":"0","step":18,"stepUuid":"uuid_1496","part":{"type":"think","think":"text_1087"}},"time":1783669966003}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1498","turnId":"0","step":18,"stepUuid":"uuid_1496","part":{"type":"text","text":"text_1088"}},"time":1783669966003}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1499","turnId":"0","step":18,"stepUuid":"uuid_1496","toolCallId":"Read_4","name":"Read","args":{}},"time":1783669966004}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1500","turnId":"0","step":18,"stepUuid":"uuid_1496","toolCallId":"Bash_5","name":"Bash","args":{}},"time":1783669966004}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1499","toolCallId":"Read_4","result":{"output":"text_1045","note":"text_1038"}},"time":1783669966006}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1500","toolCallId":"Bash_5","result":{"output":"text_1089","isError":true}},"time":1783669966040}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1496","turnId":"0","step":18,"finishReason":"tool_use","usage":{"inputOther":1126,"output":660,"inputCacheRead":30464,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1829,"llmStreamDurationMs":12467,"llmRequestBuildMs":1,"llmServerFirstTokenMs":1828,"llmServerDecodeMs":12457,"llmClientConsumeMs":10,"messageId":"uuid_1501"},"time":1783669966040}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":1126,"output":660,"inputCacheRead":30464,"inputCacheCreation":0},"usageScope":"turn","time":1783669966040}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1502","turnId":"0","step":19},"time":1783669966040}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1016158,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":14,"turnStep":"0.19","time":1783669966041}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1503","turnId":"0","step":19,"stepUuid":"uuid_1502","part":{"type":"think","think":"text_1090"}},"time":1783669981427}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1504","turnId":"0","step":19,"stepUuid":"uuid_1502","part":{"type":"text","text":"text_1091"}},"time":1783669981427}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1505","turnId":"0","step":19,"stepUuid":"uuid_1502","toolCallId":"Bash_6","name":"Bash","args":{}},"time":1783669981428}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1505","toolCallId":"Bash_6","result":{"output":"text_1092"}},"time":1783669981467}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1502","turnId":"0","step":19,"finishReason":"tool_use","usage":{"inputOther":2824,"output":777,"inputCacheRead":31488,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1690,"llmStreamDurationMs":13695,"llmRequestBuildMs":0,"llmServerFirstTokenMs":1690,"llmServerDecodeMs":13677,"llmClientConsumeMs":18,"messageId":"uuid_1506"},"time":1783669981468}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":2824,"output":777,"inputCacheRead":31488,"inputCacheCreation":0},"usageScope":"turn","time":1783669981468}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1507","turnId":"0","step":20},"time":1783669981469}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1013484,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":16,"turnStep":"0.20","time":1783669981471}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1508","turnId":"0","step":20,"stepUuid":"uuid_1507","part":{"type":"think","think":"text_1093"}},"time":1783670076863}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1509","turnId":"0","step":20,"stepUuid":"uuid_1507","part":{"type":"text","text":"text_1094"}},"time":1783670076863}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1510","turnId":"0","step":20,"stepUuid":"uuid_1507","toolCallId":"Write_7","name":"Write","args":{}},"time":1783670076864}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1511","turnId":"0","step":20,"stepUuid":"uuid_1507","toolCallId":"spine_close_8","name":"spine_close","args":{"memory":"memory_86"}},"time":1783670076864}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1510","toolCallId":"Write_7","result":{"output":"text_1095"}},"time":1783670076871}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1511","toolCallId":"spine_close_8","result":{"output":"accepted"}},"time":1783670076871}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1507","turnId":"0","step":20,"finishReason":"tool_use","usage":{"inputOther":3821,"output":5203,"inputCacheRead":31488,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2071,"llmStreamDurationMs":93320,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2071,"llmServerDecodeMs":93226,"llmClientConsumeMs":94,"messageId":"uuid_1512"},"time":1783670076871}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":3821,"output":5203,"inputCacheRead":31488,"inputCacheCreation":0},"usageScope":"turn","time":1783670076871}
|
||||
{"type":"spine.close","id":"1.1.1.4","closedAt":61,"memory":"memory_86","archivePath":"path_85","time":1783670076875}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1513","turnId":"0","step":21},"time":1783670076875}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1008058,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":9,"turnStep":"0.21","time":1783670076877}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1514","turnId":"0","step":21,"stepUuid":"uuid_1513","part":{"type":"think","think":"text_1096"}},"time":1783670086991}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1515","turnId":"0","step":21,"stepUuid":"uuid_1513","part":{"type":"text","text":"text_1097"}},"time":1783670086991}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1516","turnId":"0","step":21,"stepUuid":"uuid_1513","toolCallId":"Bash_2","name":"Bash","args":{}},"time":1783670086991}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1516","toolCallId":"Bash_2","result":{"output":"text_1098"}},"time":1783670087008}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1513","turnId":"0","step":21,"finishReason":"tool_use","usage":{"inputOther":509,"output":453,"inputCacheRead":30464,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1640,"llmStreamDurationMs":8474,"llmRequestBuildMs":0,"llmServerFirstTokenMs":1640,"llmServerDecodeMs":8466,"llmClientConsumeMs":8,"messageId":"uuid_1517"},"time":1783670087008}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":509,"output":453,"inputCacheRead":30464,"inputCacheCreation":0},"usageScope":"turn","time":1783670087008}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1518","turnId":"0","step":22},"time":1783670087009}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1017147,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":11,"turnStep":"0.22","time":1783670087010}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1519","turnId":"0","step":22,"stepUuid":"uuid_1518","part":{"type":"think","think":"text_1099"}},"time":1783670095667}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1520","turnId":"0","step":22,"stepUuid":"uuid_1518","part":{"type":"text","text":"text_1100"}},"time":1783670095667}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1521","turnId":"0","step":22,"stepUuid":"uuid_1518","toolCallId":"spine_close_3","name":"spine_close","args":{"memory":"memory_87"}},"time":1783670095667}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1521","toolCallId":"spine_close_3","result":{"output":"accepted"}},"time":1783670095668}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1518","turnId":"0","step":22,"finishReason":"tool_use","usage":{"inputOther":776,"output":376,"inputCacheRead":30720,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1867,"llmStreamDurationMs":6790,"llmRequestBuildMs":0,"llmServerFirstTokenMs":1867,"llmServerDecodeMs":6786,"llmClientConsumeMs":4,"messageId":"uuid_1522"},"time":1783670095668}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":776,"output":376,"inputCacheRead":30720,"inputCacheCreation":0},"usageScope":"turn","time":1783670095668}
|
||||
{"type":"spine.close","id":"1.1.1","closedAt":65,"memory":"memory_88","archivePath":"path_86","time":1783670095677}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1523","turnId":"0","step":23},"time":1783670095678}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1016701,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":3,"turnStep":"0.23","time":1783670095679}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1524","turnId":"0","step":23,"stepUuid":"uuid_1523","part":{"type":"think","think":"text_1101"}},"time":1783670108841}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1525","turnId":"0","step":23,"stepUuid":"uuid_1523","part":{"type":"text","text":"text_1102"}},"time":1783670108841}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1526","turnId":"0","step":23,"stepUuid":"uuid_1523","toolCallId":"Bash_0","name":"Bash","args":{}},"time":1783670108841}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1527","turnId":"0","step":23,"stepUuid":"uuid_1523","toolCallId":"spine_tree_1","name":"spine_tree","args":{}},"time":1783670108841}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1526","toolCallId":"Bash_0","result":{"output":"text_1103"}},"time":1783670108855}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1527","toolCallId":"spine_tree_1","result":{"output":"text_1104"}},"time":1783670108855}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1523","turnId":"0","step":23,"finishReason":"tool_use","usage":{"inputOther":10298,"output":604,"inputCacheRead":19200,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2132,"llmStreamDurationMs":11029,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2132,"llmServerDecodeMs":11018,"llmClientConsumeMs":11,"messageId":"uuid_1528"},"time":1783670108855}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":10298,"output":604,"inputCacheRead":19200,"inputCacheCreation":0},"usageScope":"turn","time":1783670108855}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1529","turnId":"0","step":24},"time":1783670108855}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1018148,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":6,"turnStep":"0.24","time":1783670108856}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1530","turnId":"0","step":24,"stepUuid":"uuid_1529","part":{"type":"think","think":"text_1105"}},"time":1783670121089}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1531","turnId":"0","step":24,"stepUuid":"uuid_1529","part":{"type":"text","text":"text_1106"}},"time":1783670121089}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1529","turnId":"0","step":24,"finishReason":"end_turn","usage":{"inputOther":4049,"output":543,"inputCacheRead":26880,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2144,"llmStreamDurationMs":10089,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2144,"llmServerDecodeMs":10077,"llmClientConsumeMs":12,"messageId":"uuid_1532"},"time":1783670121089}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":4049,"output":543,"inputCacheRead":26880,"inputCacheCreation":0},"usageScope":"turn","time":1783670121089}
|
||||
{"type":"full_compaction.begin","source":"manual","time":1783670167796}
|
||||
{"type":"llm.request","kind":"compaction","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":131072,"toolSelect":false,"systemPromptHash":"hash_9","systemPrompt":"prompt_9","toolsHash":"hash_8","messageCount":8,"time":1783670167849}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":1734,"output":1074,"inputCacheRead":30720,"inputCacheCreation":0},"usageScope":"session","time":1783670190221}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"The conversation so far has been compacted to free up context. What follows is your own working summary of this task — use it to continue your train of thought rather than starting over. Treat it as notes, not proof: where it says a step was done, tests passed, or a fix worked, verify that yourself before relying on it. Any user messages earlier in this context are preserved verbatim from the compacted conversation; where a system-reminder note among them marks an omitted middle section, the user messages it replaced are covered by this summary.\nsummary_text_1"}],"toolCalls":[],"origin":{"kind":"compaction_summary"}},"time":1783670190222}
|
||||
{"type":"spine.root_compact","epoch":2,"epochStartAt":71,"epochMemoryAt":70,"archivePath":"path_87","time":1783670190228}
|
||||
{"type":"config.update","profileName":"name_1","systemPrompt":"prompt_10","time":1783670190232}
|
||||
{"type":"full_compaction.complete","time":1783670190233}
|
||||
{"type":"turn.prompt","input":[{"type":"text","text":"text_1107"}],"origin":{"kind":"user"},"time":1783670204648}
|
||||
{"type":"context.append_message","message":{"role":"user","content":[{"type":"text","text":"text_1107"}],"toolCalls":[],"origin":{"kind":"user"}},"time":1783670204649}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1533","turnId":"1","step":1},"time":1783670204650}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1047653,"toolSelect":false,"systemPromptHash":"hash_10","systemPrompt":"prompt_11","toolsHash":"hash_8","messageCount":3,"turnStep":"1.1","time":1783670204653}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1534","turnId":"1","step":1,"stepUuid":"uuid_1533","part":{"type":"think","think":"text_1108"}},"time":1783670211912}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1535","turnId":"1","step":1,"stepUuid":"uuid_1533","part":{"type":"text","text":"text_1109"}},"time":1783670211912}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1536","turnId":"1","step":1,"stepUuid":"uuid_1533","toolCallId":"spine_tree_0","name":"spine_tree","args":{}},"time":1783670211912}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1537","turnId":"1","step":1,"stepUuid":"uuid_1533","toolCallId":"Glob_1","name":"Glob","args":{}},"time":1783670211913}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1536","toolCallId":"spine_tree_0","result":{"output":"text_1110"}},"time":1783670211914}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1537","toolCallId":"Glob_1","result":{"output":"text_84"}},"time":1783670212019}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1533","turnId":"1","step":1,"finishReason":"tool_use","usage":{"inputOther":8016,"output":297,"inputCacheRead":19200,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1913,"llmStreamDurationMs":5346,"llmRequestBuildMs":1,"llmServerFirstTokenMs":1912,"llmServerDecodeMs":5342,"llmClientConsumeMs":4,"messageId":"uuid_1538"},"time":1783670212019}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":8016,"output":297,"inputCacheRead":19200,"inputCacheCreation":0},"usageScope":"turn","time":1783670212019}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1539","turnId":"1","step":2},"time":1783670212019}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1021054,"toolSelect":false,"systemPromptHash":"hash_10","systemPrompt":"prompt_11","toolsHash":"hash_8","messageCount":6,"turnStep":"1.2","time":1783670212020}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1540","turnId":"1","step":2,"stepUuid":"uuid_1539","part":{"type":"think","think":"text_1111"}},"time":1783670221097}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1541","turnId":"1","step":2,"stepUuid":"uuid_1539","part":{"type":"text","text":"text_1112"}},"time":1783670221097}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1542","turnId":"1","step":2,"stepUuid":"uuid_1539","toolCallId":"Bash_2","name":"Bash","args":{}},"time":1783670221097}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1542","toolCallId":"Bash_2","result":{"output":"text_1113"}},"time":1783670221124}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1539","turnId":"1","step":2,"finishReason":"tool_use","usage":{"inputOther":824,"output":413,"inputCacheRead":27136,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1734,"llmStreamDurationMs":7342,"llmRequestBuildMs":0,"llmServerFirstTokenMs":1734,"llmServerDecodeMs":7335,"llmClientConsumeMs":7,"messageId":"uuid_1543"},"time":1783670221124}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":824,"output":413,"inputCacheRead":27136,"inputCacheCreation":0},"usageScope":"turn","time":1783670221124}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1544","turnId":"1","step":3},"time":1783670221124}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1020200,"toolSelect":false,"systemPromptHash":"hash_10","systemPrompt":"prompt_11","toolsHash":"hash_8","messageCount":8,"turnStep":"1.3","time":1783670221125}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1545","turnId":"1","step":3,"stepUuid":"uuid_1544","part":{"type":"think","think":"text_1114"}},"time":1783670238471}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1546","turnId":"1","step":3,"stepUuid":"uuid_1544","part":{"type":"text","text":"text_1115"}},"time":1783670238471}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.call","uuid":"uuid_1547","turnId":"1","step":3,"stepUuid":"uuid_1544","toolCallId":"Read_3","name":"Read","args":{}},"time":1783670238472}
|
||||
{"type":"context.append_loop_event","event":{"type":"tool.result","parentUuid":"uuid_1547","toolCallId":"Read_3","result":{"output":"text_1116","note":"text_1117"}},"time":1783670238475}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1544","turnId":"1","step":3,"finishReason":"tool_use","usage":{"inputOther":2765,"output":830,"inputCacheRead":27136,"inputCacheCreation":0},"llmFirstTokenLatencyMs":2070,"llmStreamDurationMs":15276,"llmRequestBuildMs":0,"llmServerFirstTokenMs":2070,"llmServerDecodeMs":15264,"llmClientConsumeMs":12,"messageId":"uuid_1548"},"time":1783670238475}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":2765,"output":830,"inputCacheRead":27136,"inputCacheCreation":0},"usageScope":"turn","time":1783670238475}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.begin","uuid":"uuid_1549","turnId":"1","step":4},"time":1783670238475}
|
||||
{"type":"llm.request","kind":"loop","provider":"name_2","model":"model_10","modelAlias":"model_9","thinkingEffort":"high","thinkingKeep":"all","maxTokens":1017842,"toolSelect":false,"systemPromptHash":"hash_10","systemPrompt":"prompt_11","toolsHash":"hash_8","messageCount":10,"turnStep":"1.4","time":1783670238476}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1550","turnId":"1","step":4,"stepUuid":"uuid_1549","part":{"type":"think","think":"text_1118"}},"time":1783670253437}
|
||||
{"type":"context.append_loop_event","event":{"type":"content.part","uuid":"uuid_1551","turnId":"1","step":4,"stepUuid":"uuid_1549","part":{"type":"text","text":"text_1119"}},"time":1783670253437}
|
||||
{"type":"context.append_loop_event","event":{"type":"step.end","uuid":"uuid_1549","turnId":"1","step":4,"finishReason":"end_turn","usage":{"inputOther":1945,"output":699,"inputCacheRead":29696,"inputCacheCreation":0},"llmFirstTokenLatencyMs":1733,"llmStreamDurationMs":13227,"llmRequestBuildMs":1,"llmServerFirstTokenMs":1732,"llmServerDecodeMs":13214,"llmClientConsumeMs":13,"messageId":"uuid_1552"},"time":1783670253437}
|
||||
{"type":"usage.record","model":"model_9","usage":{"inputOther":1945,"output":699,"inputCacheRead":29696,"inputCacheCreation":0},"usageScope":"turn","time":1783670253437}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -8,6 +8,10 @@ import type { ContextMessage } from '#/agent/contextMemory/types';
|
|||
import { MASTER_ENV } from '#/app/flag/flagService';
|
||||
import {
|
||||
ACCEPTED_OUTPUT,
|
||||
normalizeTrimOp,
|
||||
SPINE_TRIM_SNIPPED_PLACEHOLDER,
|
||||
SPINE_TRIM_THRESHOLD_BYTES,
|
||||
TRIM_ACCEPTED_OUTPUT,
|
||||
WIRE_PROTOCOL_VERSION,
|
||||
appendSpineView,
|
||||
deriveSpineState,
|
||||
|
|
@ -886,6 +890,283 @@ describe('Spine derivation from the message stream', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('Spine spawn projection', () => {
|
||||
beforeEach(() => {
|
||||
vi.stubEnv(MASTER_ENV, '0');
|
||||
vi.stubEnv(SPINE_ENV, '1');
|
||||
});
|
||||
afterEach(() => {
|
||||
vi.unstubAllEnvs();
|
||||
});
|
||||
|
||||
it('synthesizes N closed siblings from a valid spine_spawn receipt', () => {
|
||||
const state = deriveSpineState([
|
||||
userMessage('start'),
|
||||
spawnCall('s1', [
|
||||
{ summary: 'task A', prompt: 'do A' },
|
||||
{ summary: 'task B', prompt: 'do B' },
|
||||
]),
|
||||
spawnReceipt('s1', [
|
||||
spawnResult(0, 'completed', 'memory A'),
|
||||
spawnResult(1, 'completed', 'memory B'),
|
||||
]),
|
||||
]);
|
||||
|
||||
expect(state.openStack).toEqual(['1', '1.1']);
|
||||
expect(state.nodes['1.1']?.children).toEqual(['1.1.1', '1.1.2']);
|
||||
const a = state.nodes['1.1.1'];
|
||||
const b = state.nodes['1.1.2'];
|
||||
expect(a).toMatchObject({
|
||||
summary: 'task A',
|
||||
openedAt: 2,
|
||||
closedAt: 2,
|
||||
memory: 'memory A',
|
||||
});
|
||||
expect(b).toMatchObject({
|
||||
summary: 'task B',
|
||||
openedAt: 2,
|
||||
closedAt: 2,
|
||||
memory: 'memory B',
|
||||
});
|
||||
expect(a?.spawn).toEqual({ summary: 'task A', outcome: 'completed' });
|
||||
expect(b?.spawn).toEqual({ summary: 'task B', outcome: 'completed' });
|
||||
});
|
||||
|
||||
it('orders spawned nodes by input ordinal, not receipt order', () => {
|
||||
const state = deriveSpineState([
|
||||
userMessage('start'),
|
||||
spawnCall('s1', [
|
||||
{ summary: 'A', prompt: 'a' },
|
||||
{ summary: 'B', prompt: 'b' },
|
||||
{ summary: 'C', prompt: 'c' },
|
||||
]),
|
||||
spawnReceipt('s1', [
|
||||
spawnResult(2, 'completed', 'mem C'),
|
||||
spawnResult(0, 'completed', 'mem A'),
|
||||
spawnResult(1, 'completed', 'mem B'),
|
||||
]),
|
||||
]);
|
||||
|
||||
expect(state.nodes['1.1']?.children).toEqual(['1.1.1', '1.1.2', '1.1.3']);
|
||||
expect(state.nodes['1.1.1']?.summary).toBe('A');
|
||||
expect(state.nodes['1.1.2']?.summary).toBe('B');
|
||||
expect(state.nodes['1.1.3']?.summary).toBe('C');
|
||||
expect(state.nodes['1.1.1']?.memory).toBe('mem A');
|
||||
expect(state.nodes['1.1.2']?.memory).toBe('mem B');
|
||||
expect(state.nodes['1.1.3']?.memory).toBe('mem C');
|
||||
});
|
||||
|
||||
it('records errored/aborted outcomes and diagnostics on spawned nodes', () => {
|
||||
const state = deriveSpineState([
|
||||
userMessage('start'),
|
||||
spawnCall('s1', [
|
||||
{ summary: 'ok', prompt: 'x' },
|
||||
{ summary: 'bad', prompt: 'y' },
|
||||
]),
|
||||
spawnReceipt('s1', [
|
||||
spawnResult(0, 'completed', 'done'),
|
||||
spawnResult(1, 'errored', 'failed', 'disk full'),
|
||||
]),
|
||||
]);
|
||||
|
||||
expect(state.nodes['1.1']?.children).toEqual(['1.1.1', '1.1.2']);
|
||||
expect(state.nodes['1.1.1']?.spawn).toEqual({ summary: 'ok', outcome: 'completed' });
|
||||
expect(state.nodes['1.1.2']?.spawn).toEqual({
|
||||
summary: 'bad',
|
||||
outcome: 'errored',
|
||||
diagnostic: 'disk full',
|
||||
});
|
||||
});
|
||||
|
||||
it('rejects malformed spawn receipts all-or-nothing', () => {
|
||||
const tasks = [
|
||||
{ summary: 'A', prompt: 'a' },
|
||||
{ summary: 'B', prompt: 'b' },
|
||||
];
|
||||
|
||||
const badSchema = deriveSpineState([
|
||||
userMessage('start'),
|
||||
spawnCall('s1', tasks),
|
||||
rawSpawnReceipt('s1', {
|
||||
schema: 'spine.spawn.result.v0',
|
||||
results: [spawnResult(0, 'completed', 'a'), spawnResult(1, 'completed', 'b')],
|
||||
}),
|
||||
]);
|
||||
expect(badSchema.nodes['1.1']?.children).toEqual([]);
|
||||
|
||||
const gapOrdinal = deriveSpineState([
|
||||
userMessage('start'),
|
||||
spawnCall('s1', tasks),
|
||||
spawnReceipt('s1', [spawnResult(0, 'completed', 'a')]),
|
||||
]);
|
||||
expect(gapOrdinal.nodes['1.1']?.children).toEqual([]);
|
||||
|
||||
const emptyMemory = deriveSpineState([
|
||||
userMessage('start'),
|
||||
spawnCall('s1', tasks),
|
||||
spawnReceipt('s1', [
|
||||
spawnResult(0, 'completed', 'a'),
|
||||
spawnResult(1, 'completed', ''),
|
||||
]),
|
||||
]);
|
||||
expect(emptyMemory.nodes['1.1']?.children).toEqual([]);
|
||||
|
||||
const mismatchCount = deriveSpineState([
|
||||
userMessage('start'),
|
||||
spawnCall('s1', tasks),
|
||||
spawnReceipt('s1', [
|
||||
spawnResult(0, 'completed', 'a'),
|
||||
spawnResult(1, 'completed', 'b'),
|
||||
spawnResult(2, 'completed', 'c'),
|
||||
]),
|
||||
]);
|
||||
expect(mismatchCount.nodes['1.1']?.children).toEqual([]);
|
||||
|
||||
const missingDiagnostic = deriveSpineState([
|
||||
userMessage('start'),
|
||||
spawnCall('s1', tasks),
|
||||
spawnReceipt('s1', [
|
||||
spawnResult(0, 'completed', 'a'),
|
||||
spawnResult(1, 'errored', 'b'),
|
||||
]),
|
||||
]);
|
||||
expect(missingDiagnostic.nodes['1.1']?.children).toEqual([]);
|
||||
});
|
||||
|
||||
it('keeps child indices contiguous when spawn is mixed with open/close/next', () => {
|
||||
const ctx = testAgent();
|
||||
append(ctx, userMessage('start'));
|
||||
append(ctx, assistantToolCall('o1', 'spine_open', JSON.stringify({ summary: 'task A' })));
|
||||
append(ctx, spineAcceptedReceipt('o1'));
|
||||
append(ctx, assistantToolCall('c1', 'spine_close', JSON.stringify({ memory: 'did A' })));
|
||||
append(ctx, spineAcceptedReceipt('c1'));
|
||||
append(
|
||||
ctx,
|
||||
spawnCall('s1', [
|
||||
{ summary: 'spawn 1', prompt: 'p1' },
|
||||
{ summary: 'spawn 2', prompt: 'p2' },
|
||||
]),
|
||||
);
|
||||
append(
|
||||
ctx,
|
||||
spawnReceipt('s1', [
|
||||
spawnResult(0, 'completed', 'mem 1'),
|
||||
spawnResult(1, 'completed', 'mem 2'),
|
||||
]),
|
||||
);
|
||||
append(ctx, assistantToolCall('o2', 'spine_open', JSON.stringify({ summary: 'task B' })));
|
||||
append(ctx, spineAcceptedReceipt('o2'));
|
||||
|
||||
const state = deriveSpineState(ctx.context.get());
|
||||
expect(state.nodes['1.1']?.children).toEqual(['1.1.1', '1.1.2', '1.1.3', '1.1.4']);
|
||||
expect(state.nodes['1.1.1']?.summary).toBe('task A');
|
||||
expect(state.nodes['1.1.2']?.summary).toBe('spawn 1');
|
||||
expect(state.nodes['1.1.3']?.summary).toBe('spawn 2');
|
||||
expect(state.nodes['1.1.4']?.summary).toBe('task B');
|
||||
});
|
||||
|
||||
it('renders spawn evidence followed by memory and keeps the carrier visible', () => {
|
||||
const ctx = testAgent();
|
||||
append(ctx, userMessage('start'));
|
||||
append(
|
||||
ctx,
|
||||
spawnCall('s1', [
|
||||
{ summary: 'task A', prompt: 'p1' },
|
||||
{ summary: 'task B', prompt: 'p2' },
|
||||
]),
|
||||
);
|
||||
append(
|
||||
ctx,
|
||||
spawnReceipt('s1', [
|
||||
spawnResult(0, 'completed', 'mem A'),
|
||||
spawnResult(1, 'errored', 'mem B', 'disk full'),
|
||||
]),
|
||||
);
|
||||
append(ctx, userMessage('after'));
|
||||
|
||||
const folded = fold(ctx);
|
||||
const texts = folded.map(textOf);
|
||||
expect(texts).toContain('<spine_node id="1.1" summary="startup" status="live" />');
|
||||
expect(texts).toContain('[U1] start');
|
||||
expect(texts).toContain('calling spine_spawn');
|
||||
expect(texts).not.toContain('spine.spawn.result.v1');
|
||||
expect(texts).toContain('[U2] after');
|
||||
|
||||
const evidenceA = texts.find((t) => t.includes('<spine_spawn_evidence node_id="1.1.1"'));
|
||||
const evidenceB = texts.find((t) => t.includes('<spine_spawn_evidence node_id="1.1.2"'));
|
||||
expect(evidenceA).toBe(
|
||||
'<spine_spawn_evidence node_id="1.1.1" summary="task A" outcome="completed" />',
|
||||
);
|
||||
expect(evidenceB).toBe(
|
||||
'<spine_spawn_evidence node_id="1.1.2" summary="task B" outcome="errored" diagnostic="disk full" />',
|
||||
);
|
||||
|
||||
const memoryA = texts.find((t) => t.includes('<spine_memory node_id="1.1.1"'));
|
||||
const memoryB = texts.find((t) => t.includes('<spine_memory node_id="1.1.2"'));
|
||||
expect(memoryA).toBe('<spine_memory node_id="1.1.1">\nmem A\n</spine_memory>');
|
||||
expect(memoryB).toBe('<spine_memory node_id="1.1.2">\nmem B\n</spine_memory>');
|
||||
});
|
||||
|
||||
it('spawns nodes under the current cursor, including nested open nodes', () => {
|
||||
const ctx = testAgent();
|
||||
append(ctx, userMessage('start'));
|
||||
append(ctx, assistantToolCall('o1', 'spine_open', JSON.stringify({ summary: 'parent' })));
|
||||
append(ctx, spineAcceptedReceipt('o1'));
|
||||
append(
|
||||
ctx,
|
||||
spawnCall('s1', [
|
||||
{ summary: 'child A', prompt: 'a' },
|
||||
{ summary: 'child B', prompt: 'b' },
|
||||
]),
|
||||
);
|
||||
append(
|
||||
ctx,
|
||||
spawnReceipt('s1', [
|
||||
spawnResult(0, 'completed', 'mem A'),
|
||||
spawnResult(1, 'completed', 'mem B'),
|
||||
]),
|
||||
);
|
||||
|
||||
const state = deriveSpineState(ctx.context.get());
|
||||
expect(state.openStack).toEqual(['1', '1.1', '1.1.1']);
|
||||
expect(state.nodes['1.1.1']?.children).toEqual(['1.1.1.1', '1.1.1.2']);
|
||||
expect(state.nodes['1.1.1.1']?.summary).toBe('child A');
|
||||
expect(state.nodes['1.1.1.2']?.summary).toBe('child B');
|
||||
});
|
||||
|
||||
it('spawns nodes under the root epoch when the startup node is closed', () => {
|
||||
const ctx = testAgent();
|
||||
append(ctx, userMessage('start'));
|
||||
append(
|
||||
ctx,
|
||||
assistantToolCall('c1', 'spine_close', JSON.stringify({ memory: 'startup done' })),
|
||||
);
|
||||
append(ctx, spineAcceptedReceipt('c1'));
|
||||
append(
|
||||
ctx,
|
||||
spawnCall('s1', [
|
||||
{ summary: 'branch A', prompt: 'a' },
|
||||
{ summary: 'branch B', prompt: 'b' },
|
||||
]),
|
||||
);
|
||||
append(
|
||||
ctx,
|
||||
spawnReceipt('s1', [
|
||||
spawnResult(0, 'completed', 'mem A'),
|
||||
spawnResult(1, 'completed', 'mem B'),
|
||||
]),
|
||||
);
|
||||
|
||||
const state = deriveSpineState(ctx.context.get());
|
||||
expect(state.openStack).toEqual(['1']);
|
||||
expect(state.nodes['1']?.children).toEqual(['1.1', '1.2', '1.3']);
|
||||
expect(state.nodes['1.2']?.summary).toBe('branch A');
|
||||
expect(state.nodes['1.3']?.summary).toBe('branch B');
|
||||
expect(state.nodes['1.2']?.closedAt).toBe(4);
|
||||
expect(state.nodes['1.3']?.closedAt).toBe(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Spine legacy-op restore compat', () => {
|
||||
beforeEach(() => {
|
||||
vi.stubEnv(MASTER_ENV, '0');
|
||||
|
|
@ -1099,6 +1380,49 @@ function spineRejectedReceipt(toolCallId: string): ContextMessage {
|
|||
};
|
||||
}
|
||||
|
||||
function spawnCall(
|
||||
id: string,
|
||||
tasks: readonly { summary: string; prompt: string }[],
|
||||
): ContextMessage {
|
||||
return assistantToolCall(id, 'spine_spawn', JSON.stringify({ tasks }));
|
||||
}
|
||||
|
||||
type SpawnOutcome = 'completed' | 'errored' | 'aborted';
|
||||
|
||||
interface SpawnResultInput {
|
||||
readonly ordinal: number;
|
||||
readonly outcome: SpawnOutcome;
|
||||
readonly memory_body: string;
|
||||
readonly diagnostic?: string;
|
||||
}
|
||||
|
||||
function spawnReceipt(toolCallId: string, results: readonly SpawnResultInput[]): ContextMessage {
|
||||
return rawSpawnReceipt(toolCallId, { schema: 'spine.spawn.result.v1', results });
|
||||
}
|
||||
|
||||
function rawSpawnReceipt(
|
||||
toolCallId: string,
|
||||
payload: Record<string, unknown>,
|
||||
): ContextMessage {
|
||||
return {
|
||||
role: 'tool',
|
||||
content: [{ type: 'text', text: JSON.stringify(payload) }],
|
||||
toolCalls: [],
|
||||
toolCallId,
|
||||
};
|
||||
}
|
||||
|
||||
function spawnResult(
|
||||
ordinal: number,
|
||||
outcome: SpawnOutcome,
|
||||
memory_body: string,
|
||||
diagnostic?: string,
|
||||
): SpawnResultInput {
|
||||
return diagnostic === undefined
|
||||
? { ordinal, outcome, memory_body }
|
||||
: { ordinal, outcome, memory_body, diagnostic };
|
||||
}
|
||||
|
||||
/**
|
||||
* Open A → close A → open B → next C, then a rejected open and a rejected
|
||||
* close: the derivation must apply exactly the accepted chain (1.1.1 closed,
|
||||
|
|
@ -1312,3 +1636,300 @@ function normalizeTokenGauges(text: string): string {
|
|||
'$1="~N"',
|
||||
);
|
||||
}
|
||||
|
||||
describe('Spine trim projection', () => {
|
||||
const TRIM_ENV = 'KIMI_CODE_SPINE_TRIM';
|
||||
|
||||
beforeEach(() => {
|
||||
vi.stubEnv(MASTER_ENV, '0');
|
||||
vi.stubEnv(SPINE_ENV, '1');
|
||||
vi.stubEnv(TRIM_ENV, '1');
|
||||
});
|
||||
afterEach(() => {
|
||||
vi.unstubAllEnvs();
|
||||
});
|
||||
|
||||
it('tags an oversized tool result with a byte-stable TRIM_ID prefix', () => {
|
||||
const ctx = testAgent();
|
||||
append(ctx, userMessage('start'));
|
||||
append(ctx, assistantToolCall('c_big', 'Bash'));
|
||||
append(ctx, bigToolResult('c_big', oversized('BIG-BODY')));
|
||||
append(ctx, assistantToolCall('c_small', 'Read'));
|
||||
append(ctx, toolResult('c_small'));
|
||||
append(ctx, assistantText('done'));
|
||||
|
||||
const folded = fold(ctx);
|
||||
expect(textOf(folded.find((m) => m.toolCallId === 'c_big'))).toBe(
|
||||
`[TRIM_ID: trim_1]\n${oversized('BIG-BODY')}`,
|
||||
);
|
||||
expect(textOf(folded.find((m) => m.toolCallId === 'c_small'))).not.toContain('TRIM_ID');
|
||||
// The stored history is never rewritten.
|
||||
expect(textOf(ctx.context.get().find((m) => m.toolCallId === 'c_big'))).toBe(
|
||||
oversized('BIG-BODY'),
|
||||
);
|
||||
});
|
||||
|
||||
it('numbers tags in stream order across batches', () => {
|
||||
const ctx = testAgent();
|
||||
append(ctx, userMessage('start'));
|
||||
append(ctx, assistantToolCall('c_a', 'Bash'));
|
||||
append(ctx, bigToolResult('c_a', oversized('A')));
|
||||
append(ctx, assistantToolCall('c_b', 'Bash'));
|
||||
append(ctx, bigToolResult('c_b', oversized('B')));
|
||||
|
||||
const folded = fold(ctx);
|
||||
expect(textOf(folded.find((m) => m.toolCallId === 'c_a'))).toContain('[TRIM_ID: trim_1]');
|
||||
expect(textOf(folded.find((m) => m.toolCallId === 'c_b'))).toContain('[TRIM_ID: trim_2]');
|
||||
});
|
||||
|
||||
it('renders a snipped result as the cleared placeholder and drops the label', () => {
|
||||
const ctx = testAgent();
|
||||
append(ctx, userMessage('start'));
|
||||
append(ctx, assistantToolCall('c_big', 'Bash'));
|
||||
append(ctx, bigToolResult('c_big', oversized('BIG-BODY')));
|
||||
append(ctx, trimCall('t1', { TRIM_ID: 'trim_1', op: 'snip' }));
|
||||
append(ctx, trimAcceptedReceipt('t1'));
|
||||
append(ctx, assistantText('done'));
|
||||
|
||||
const folded = fold(ctx);
|
||||
expect(textOf(folded.find((m) => m.toolCallId === 'c_big'))).toBe(
|
||||
SPINE_TRIM_SNIPPED_PLACEHOLDER,
|
||||
);
|
||||
// The trim receipt itself is a control result and stays untagged.
|
||||
expect(textOf(folded.find((m) => m.toolCallId === 't1'))).toBe(TRIM_ACCEPTED_OUTPUT);
|
||||
});
|
||||
|
||||
it('renders head and tail slices by characters', () => {
|
||||
const ctx = testAgent();
|
||||
const body = `BEGIN-${'x'.repeat(SPINE_TRIM_THRESHOLD_BYTES)}-END`;
|
||||
append(ctx, userMessage('start'));
|
||||
append(
|
||||
ctx,
|
||||
assistantBatchToolCalls([
|
||||
{ id: 'c_head', name: 'Bash' },
|
||||
{ id: 'c_tail', name: 'Bash' },
|
||||
]),
|
||||
);
|
||||
append(ctx, bigToolResult('c_head', body));
|
||||
append(ctx, bigToolResult('c_tail', body));
|
||||
append(
|
||||
ctx,
|
||||
assistantBatchToolCalls([
|
||||
{
|
||||
id: 't_head',
|
||||
name: 'spine_trim',
|
||||
args: JSON.stringify({ TRIM_ID: 'trim_1', op: 'slice', head: 6 }),
|
||||
},
|
||||
{
|
||||
id: 't_tail',
|
||||
name: 'spine_trim',
|
||||
args: JSON.stringify({ TRIM_ID: 'trim_2', op: 'slice', tail: 4 }),
|
||||
},
|
||||
]),
|
||||
);
|
||||
append(ctx, trimAcceptedReceipt('t_head'));
|
||||
append(ctx, trimAcceptedReceipt('t_tail'));
|
||||
|
||||
const folded = fold(ctx);
|
||||
expect(textOf(folded.find((m) => m.toolCallId === 'c_head'))).toBe('BEGIN-');
|
||||
expect(textOf(folded.find((m) => m.toolCallId === 'c_tail'))).toBe('-END');
|
||||
});
|
||||
|
||||
it('renders an anchor slice as complete lines around the anchor line', () => {
|
||||
const ctx = testAgent();
|
||||
const noise = 'n'.repeat(SPINE_TRIM_THRESHOLD_BYTES);
|
||||
const body = `${noise}\nFAILED test X\nstack line\ntrailing noise`;
|
||||
append(ctx, userMessage('start'));
|
||||
append(ctx, assistantToolCall('c_big', 'Bash'));
|
||||
append(ctx, bigToolResult('c_big', body));
|
||||
append(
|
||||
ctx,
|
||||
trimCall('t1', { TRIM_ID: 'trim_1', op: 'slice', anchor: 'FAILED test X', following: 1 }),
|
||||
);
|
||||
append(ctx, trimAcceptedReceipt('t1'));
|
||||
|
||||
const folded = fold(ctx);
|
||||
expect(textOf(folded.find((m) => m.toolCallId === 'c_big'))).toBe(
|
||||
'FAILED test X\nstack line',
|
||||
);
|
||||
});
|
||||
|
||||
it('never tags spine control receipts or media results', () => {
|
||||
const ctx = testAgent();
|
||||
append(ctx, userMessage('start'));
|
||||
append(ctx, assistantToolCall('c_tree', 'spine_tree'));
|
||||
append(ctx, bigToolResult('c_tree', oversized('TREE')));
|
||||
append(ctx, assistantToolCall('c_img', 'Read'));
|
||||
append(ctx, mediaToolResult('c_img', oversized('IMG')));
|
||||
|
||||
const folded = fold(ctx);
|
||||
expect(textOf(folded.find((m) => m.toolCallId === 'c_tree'))).not.toContain('TRIM_ID');
|
||||
expect(textOf(folded.find((m) => m.toolCallId === 'c_img'))).not.toContain('TRIM_ID');
|
||||
});
|
||||
|
||||
it('leaves the result tagged and whole when the trim receipt is an error', () => {
|
||||
const ctx = testAgent();
|
||||
append(ctx, userMessage('start'));
|
||||
append(ctx, assistantToolCall('c_big', 'Bash'));
|
||||
append(ctx, bigToolResult('c_big', oversized('BIG-BODY')));
|
||||
append(ctx, trimCall('t1', { TRIM_ID: 'trim_1', op: 'snip' }));
|
||||
append(ctx, trimRejectedReceipt('t1'));
|
||||
|
||||
const folded = fold(ctx);
|
||||
expect(textOf(folded.find((m) => m.toolCallId === 'c_big'))).toBe(
|
||||
`[TRIM_ID: trim_1]\n${oversized('BIG-BODY')}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('accepts a trim inside the window and rejects a repeat (one-shot)', () => {
|
||||
const ctx = testAgent();
|
||||
append(ctx, userMessage('start'));
|
||||
append(ctx, assistantToolCall('c_big', 'Bash'));
|
||||
append(ctx, bigToolResult('c_big', oversized('BIG-BODY')));
|
||||
|
||||
const spine = ctx.get(IAgentSpineService);
|
||||
expect(spine.acceptTrim('trim_1', { kind: 'snip' })).toEqual({ accepted: true });
|
||||
|
||||
append(ctx, trimCall('t1', { TRIM_ID: 'trim_1', op: 'snip' }));
|
||||
append(ctx, trimAcceptedReceipt('t1'));
|
||||
|
||||
const repeat = spine.acceptTrim('trim_1', { kind: 'snip' });
|
||||
expect(repeat.accepted).toBe(false);
|
||||
if (repeat.accepted) return;
|
||||
expect(repeat.reason).toContain('already trimmed');
|
||||
expect(repeat.reason).toContain('Do not retry');
|
||||
});
|
||||
|
||||
it('expires ids once a newer batch completes, but not on interleaved assistant text', () => {
|
||||
const ctx = testAgent();
|
||||
append(ctx, userMessage('start'));
|
||||
append(ctx, assistantToolCall('c_a', 'Bash'));
|
||||
append(ctx, bigToolResult('c_a', oversized('A')));
|
||||
append(ctx, assistantText('thinking out loud'));
|
||||
|
||||
const spine = ctx.get(IAgentSpineService);
|
||||
// Interleaved assistant text does not expire the window — and the accept
|
||||
// itself records nothing (receipt-only, no side effect).
|
||||
expect(spine.acceptTrim('trim_1', { kind: 'snip' })).toEqual({ accepted: true });
|
||||
|
||||
append(ctx, assistantToolCall('c_b', 'Bash'));
|
||||
append(ctx, bigToolResult('c_b', oversized('B')));
|
||||
|
||||
const expired = spine.acceptTrim('trim_1', { kind: 'snip' });
|
||||
expect(expired.accepted).toBe(false);
|
||||
if (expired.accepted) return;
|
||||
expect(expired.reason).toContain('immediately preceding');
|
||||
expect(expired.reason).toContain('Do not retry');
|
||||
});
|
||||
|
||||
it('rejects unknown ids and missing anchors with do-not-retry reasons', () => {
|
||||
const ctx = testAgent();
|
||||
append(ctx, userMessage('start'));
|
||||
append(ctx, assistantToolCall('c_big', 'Bash'));
|
||||
append(ctx, bigToolResult('c_big', oversized('body with a NEEDLE inside')));
|
||||
|
||||
const spine = ctx.get(IAgentSpineService);
|
||||
const unknown = spine.acceptTrim('trim_99', { kind: 'snip' });
|
||||
expect(unknown.accepted).toBe(false);
|
||||
if (unknown.accepted) return;
|
||||
expect(unknown.reason).toContain('Unknown TRIM_ID');
|
||||
expect(unknown.reason).toContain('Do not retry');
|
||||
|
||||
const missing = spine.acceptTrim('trim_1', {
|
||||
kind: 'slice',
|
||||
shape: { type: 'anchor', anchor: 'NO_SUCH_TEXT', preceding: 0, following: 0 },
|
||||
});
|
||||
expect(missing.accepted).toBe(false);
|
||||
if (missing.accepted) return;
|
||||
expect(missing.reason).toContain('Anchor text not found');
|
||||
expect(missing.reason).toContain('Do not retry');
|
||||
|
||||
expect(
|
||||
spine.acceptTrim('trim_1', {
|
||||
kind: 'slice',
|
||||
shape: { type: 'anchor', anchor: 'NEEDLE', preceding: 0, following: 0 },
|
||||
}),
|
||||
).toEqual({ accepted: true });
|
||||
});
|
||||
|
||||
it('normalizes flat trim arguments into ops', () => {
|
||||
expect(normalizeTrimOp('snip', {})).toEqual({ kind: 'snip' });
|
||||
expect(normalizeTrimOp('slice', { head: 5 })).toEqual({
|
||||
kind: 'slice',
|
||||
shape: { type: 'head', chars: 5 },
|
||||
});
|
||||
expect(normalizeTrimOp('slice', { tail: 5 })).toEqual({
|
||||
kind: 'slice',
|
||||
shape: { type: 'tail', chars: 5 },
|
||||
});
|
||||
expect(normalizeTrimOp('slice', { anchor: 'a', preceding: 1 })).toEqual({
|
||||
kind: 'slice',
|
||||
shape: { type: 'anchor', anchor: 'a', preceding: 1, following: 0 },
|
||||
});
|
||||
expect(normalizeTrimOp('slice', {})).toBeUndefined();
|
||||
expect(normalizeTrimOp('slice', { head: 5, tail: 5 })).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
function bigToolResult(toolCallId: string, text: string): ContextMessage {
|
||||
return {
|
||||
role: 'tool',
|
||||
content: [{ type: 'text', text }],
|
||||
toolCalls: [],
|
||||
toolCallId,
|
||||
};
|
||||
}
|
||||
|
||||
function mediaToolResult(toolCallId: string, text: string): ContextMessage {
|
||||
return {
|
||||
role: 'tool',
|
||||
content: [
|
||||
{ type: 'image_url', imageUrl: { url: 'https://example.com/pixel.png' } },
|
||||
{ type: 'text', text },
|
||||
],
|
||||
toolCalls: [],
|
||||
toolCallId,
|
||||
};
|
||||
}
|
||||
|
||||
function assistantBatchToolCalls(
|
||||
calls: readonly { id: string; name: string; args?: string }[],
|
||||
): ContextMessage {
|
||||
return {
|
||||
role: 'assistant',
|
||||
content: [{ type: 'text', text: 'batch' }],
|
||||
toolCalls: calls.map((call) => ({
|
||||
type: 'function' as const,
|
||||
id: call.id,
|
||||
name: call.name,
|
||||
arguments: call.args ?? '{}',
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
function trimCall(id: string, args: Record<string, unknown>): ContextMessage {
|
||||
return assistantToolCall(id, 'spine_trim', JSON.stringify(args));
|
||||
}
|
||||
|
||||
function trimAcceptedReceipt(toolCallId: string): ContextMessage {
|
||||
return {
|
||||
role: 'tool',
|
||||
content: [{ type: 'text', text: TRIM_ACCEPTED_OUTPUT }],
|
||||
toolCalls: [],
|
||||
toolCallId,
|
||||
};
|
||||
}
|
||||
|
||||
function trimRejectedReceipt(toolCallId: string): ContextMessage {
|
||||
return {
|
||||
role: 'tool',
|
||||
content: [{ type: 'text', text: 'rejected: do not retry' }],
|
||||
toolCalls: [],
|
||||
toolCallId,
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
|
||||
function oversized(body: string): string {
|
||||
return body + 'x'.repeat(SPINE_TRIM_THRESHOLD_BYTES);
|
||||
}
|
||||
|
|
|
|||
442
packages/agent-core-v2/test/spine/legacyReplay.test.ts
Normal file
442
packages/agent-core-v2/test/spine/legacyReplay.test.ts
Normal file
|
|
@ -0,0 +1,442 @@
|
|||
/**
|
||||
* `spine` domain (L4) — P3.5 regression net: replay REAL pre-rewrite session
|
||||
* wire logs and diff the op-replayed `SpineModel` state against the pure
|
||||
* derivation (`deriveSpineState` over the restored `contextMemory` stream).
|
||||
*
|
||||
* Fixtures (`./fixtures/*.jsonl`) are sanitized real v2 wire logs from local
|
||||
* pre-derivation sessions (2026-07-31 sanitization, one-off script kept out of
|
||||
* tree): record count/order untouched, spine op payloads and message-side
|
||||
* spine_* args mapped through one global dictionary to deterministic
|
||||
* placeholders (so op-side == message-side exactly when the raw strings were
|
||||
* equal), accepted receipts kept verbatim, all other free text placeholdered,
|
||||
* blobref media neutralized to inline text parts. Sources:
|
||||
* - legacy-open-close.jsonl 0feff1ef (2026-07-14 build, open/close chain)
|
||||
* - legacy-next.jsonl 2fddef08 (2026-07-14 build, spine.next ×2, ends mid-session)
|
||||
* - legacy-receipt-anchor.jsonl 01KX07W6 (2026-07-08 build, pre f0c56f31b)
|
||||
* - legacy-undo-divergence.jsonl 2f793f68 (2026-07-16 build, undo ×7 +
|
||||
* truncate_repair ×4 + spine.next; tail cut right after the last
|
||||
* truncate_repair — a prefix cut never shifts message indices)
|
||||
* - legacy-root-compact.jsonl mremv61a (2026-07-10 build, spine.root_compact
|
||||
* ×1 → 2 root epochs). The only other real root_compact sample found
|
||||
* (mre987c4, 5 epochs) was rejected: 34 MB and a pre-fix build. Further
|
||||
* synthetic root_compact coverage lives in `compaction.test.ts`.
|
||||
*
|
||||
* ASSERTION GROUPS — the op-replay world and the derivation agree on real
|
||||
* logs only up to three documented historical semantic differences (verified
|
||||
* 2026-07-31 against 12 real sessions, none are derivation defects):
|
||||
*
|
||||
* 1. Span anchors (f0c56f31b, 2026-07-13). The legacy commit path persisted
|
||||
* close/next span ends at the transition's RECEIPT index (and some builds
|
||||
* anchored opens at carrier+1); f0c56f31b moved close/next to carrier−1
|
||||
* so the carrier and its receipt stay visible in the parent context.
|
||||
* Sessions written by older builds replay with the old anchors — the
|
||||
* receipt-anchor group pins the exact relation instead of equality.
|
||||
* 2. Stored memory form (P5, plan/spine-v3-alignment.md). The legacy commit
|
||||
* path persisted `assembleMemoryBody()` output (## User Message / ##
|
||||
* Child Memory sections), and f0c56f31b's interrupted-transition commit
|
||||
* could persist a pending body whose accepted receipt never landed. The
|
||||
* derivation keeps the model-written close/next body verbatim (the fold
|
||||
* re-materializes user requests and child slots at read time). Where a
|
||||
* fixture exhibits this, the differing memory values are pinned exactly.
|
||||
* 3. Witness-removing undos (the derivation's documented contract: "a
|
||||
* transition the stream does not fully witness is not a transition").
|
||||
* The op world kept frozen nodes for unwitnessed transitions
|
||||
* (truncate_repair voids/restarts spans); the derivation drops them and
|
||||
* re-derives ids/parents from the surviving stream. The undo-divergence
|
||||
* group pins both topologies and their documented relationship exactly.
|
||||
*
|
||||
* TOLERATED DRIFT (only): `baselineTokens` / `finalTokens` are not in the
|
||||
* message stream and `archivePath` is deterministically re-derived, so the
|
||||
* derivation never carries them; the exact-match group asserts they are
|
||||
* absent on the derived side while present in the replayed legacy ops.
|
||||
*
|
||||
* Every fixture additionally asserts: restore reports ZERO unknown/malformed
|
||||
* record skips (the "legacy op definitions stay registered" acceptance), all
|
||||
* span indices stay inside the restored message bounds, and the open stack is
|
||||
* self-consistent (ids exist, are open, and chain through `children`).
|
||||
*/
|
||||
|
||||
import { readFileSync } from 'node:fs';
|
||||
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import {
|
||||
resetUnexpectedErrorHandler,
|
||||
setUnexpectedErrorHandler,
|
||||
} from '#/_base/errors/unexpectedError';
|
||||
import type { ContextMessage } from '#/agent/contextMemory/types';
|
||||
import { SPINE_TOOL_CLOSE } from '#/agent/spine/spine';
|
||||
import type { SpineState } from '#/agent/spine/spineOps';
|
||||
import type { WireRecord } from '#/wire/record';
|
||||
import {
|
||||
deriveSpineState,
|
||||
IAgentContextMemoryService,
|
||||
IWireService,
|
||||
SpineModel,
|
||||
SPINE_VOID_OPENED_AT,
|
||||
} from '#/index';
|
||||
|
||||
import {
|
||||
InMemoryWireRecordPersistence,
|
||||
testAgent,
|
||||
wireRecordPersistenceServices,
|
||||
} from '../harness';
|
||||
|
||||
interface RestoredFixture {
|
||||
readonly replayed: SpineState;
|
||||
readonly derived: SpineState;
|
||||
readonly messages: readonly ContextMessage[];
|
||||
readonly unexpected: readonly unknown[];
|
||||
}
|
||||
|
||||
function loadFixtureRecords(name: string): WireRecord[] {
|
||||
const path = new URL(`./fixtures/${name}.jsonl`, import.meta.url);
|
||||
const records: WireRecord[] = [];
|
||||
for (const line of readFileSync(path, 'utf8').split('\n')) {
|
||||
if (line.trim().length === 0) continue;
|
||||
records.push(JSON.parse(line) as WireRecord);
|
||||
}
|
||||
return records;
|
||||
}
|
||||
|
||||
async function restoreFixture(name: string): Promise<RestoredFixture> {
|
||||
const unexpected: unknown[] = [];
|
||||
setUnexpectedErrorHandler((err) => unexpected.push(err));
|
||||
try {
|
||||
const ctx = testAgent(
|
||||
wireRecordPersistenceServices(new InMemoryWireRecordPersistence(loadFixtureRecords(name))),
|
||||
);
|
||||
await ctx.restorePersisted();
|
||||
const messages = ctx.get(IAgentContextMemoryService).get();
|
||||
return {
|
||||
replayed: ctx.get(IWireService).getModel(SpineModel) as SpineState,
|
||||
derived: deriveSpineState(messages),
|
||||
messages,
|
||||
unexpected,
|
||||
};
|
||||
} finally {
|
||||
resetUnexpectedErrorHandler();
|
||||
}
|
||||
}
|
||||
|
||||
/** The legacy-op acceptance: nothing in a real old log may be skipped. */
|
||||
function expectZeroSkips(unexpected: readonly unknown[]): void {
|
||||
expect(unexpected.map(String)).toEqual([]);
|
||||
}
|
||||
|
||||
function expectSpanInvariants(state: SpineState, messageCount: number): void {
|
||||
for (const node of Object.values(state.nodes)) {
|
||||
// A voided span (openedAt === SPINE_VOID_OPENED_AT) is fold-excluded and
|
||||
// kept for reference only: its stale closedAt may index messages a prefix
|
||||
// truncation cut away, so bounds apply to live spans only.
|
||||
if (node.openedAt === SPINE_VOID_OPENED_AT) continue;
|
||||
expect(node.openedAt, `${node.id} openedAt`).toBeGreaterThanOrEqual(0);
|
||||
expect(node.openedAt, `${node.id} openedAt`).toBeLessThan(messageCount);
|
||||
if (node.closedAt !== undefined) {
|
||||
expect(node.closedAt, `${node.id} closedAt`).toBeGreaterThanOrEqual(0);
|
||||
expect(node.closedAt, `${node.id} closedAt`).toBeLessThan(messageCount);
|
||||
expect(node.closedAt, `${node.id} span`).toBeGreaterThanOrEqual(node.openedAt);
|
||||
}
|
||||
}
|
||||
expect(state.openStack.length).toBeGreaterThan(0);
|
||||
expect(state.openStack[0]).toBe(String(state.rootEpoch));
|
||||
for (let i = 0; i < state.openStack.length; i++) {
|
||||
const id = state.openStack[i]!;
|
||||
const node = state.nodes[id];
|
||||
expect(node, `openStack id ${id}`).toBeDefined();
|
||||
expect(node?.closedAt, `openStack id ${id} stays open`).toBeUndefined();
|
||||
if (i > 0) {
|
||||
const parent = state.nodes[state.openStack[i - 1]!];
|
||||
expect(parent?.children, `openStack ${state.openStack[i - 1]!} → ${id}`).toContain(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Span {
|
||||
readonly openedAt: number;
|
||||
readonly closedAt?: number;
|
||||
}
|
||||
|
||||
function expectSpans(state: SpineState, spans: Readonly<Record<string, Span>>): void {
|
||||
expect(Object.keys(state.nodes).sort()).toEqual(Object.keys(spans).sort());
|
||||
for (const [id, span] of Object.entries(spans)) {
|
||||
const node = state.nodes[id];
|
||||
expect(node?.openedAt, `${id} openedAt`).toBe(span.openedAt);
|
||||
expect(node?.closedAt, `${id} closedAt`).toBe(span.closedAt);
|
||||
}
|
||||
}
|
||||
|
||||
function parentOf(state: SpineState, id: string): string | null {
|
||||
for (const [candidate, node] of Object.entries(state.nodes)) {
|
||||
if (node.children.includes(id)) return candidate;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
describe('Spine legacy wire replay (exact-match group)', () => {
|
||||
/**
|
||||
* Sessions written by the final op-based build (post-f0c56f31b anchors,
|
||||
* verbatim memory) with no witness-removing undo: the derivation must
|
||||
* reproduce the op-replayed tree field by field.
|
||||
*/
|
||||
function expectSameTree(replayed: SpineState, derived: SpineState): void {
|
||||
expect(Object.keys(derived.nodes).sort()).toEqual(Object.keys(replayed.nodes).sort());
|
||||
for (const [id, r] of Object.entries(replayed.nodes)) {
|
||||
const d = derived.nodes[id]!;
|
||||
expect(d.summary, `${id} summary`).toBe(r.summary);
|
||||
expect(d.openedAt, `${id} openedAt`).toBe(r.openedAt);
|
||||
expect(d.closedAt, `${id} closedAt`).toBe(r.closedAt);
|
||||
expect(d.memory, `${id} memory`).toBe(r.memory);
|
||||
expect(d.children, `${id} children`).toEqual(r.children);
|
||||
// Tolerated drift: token gauges and archive paths are not derivable.
|
||||
expect(d.baselineTokens, `${id} baselineTokens`).toBeUndefined();
|
||||
expect(d.finalTokens, `${id} finalTokens`).toBeUndefined();
|
||||
expect(d.archivePath, `${id} archivePath`).toBeUndefined();
|
||||
}
|
||||
expect(derived.openStack).toEqual(replayed.openStack);
|
||||
expect(derived.rootEpoch).toBe(replayed.rootEpoch);
|
||||
expect(derived.epochStartAt).toBe(replayed.epochStartAt);
|
||||
expect(derived.epochMemoryAt).toBe(replayed.epochMemoryAt);
|
||||
}
|
||||
|
||||
it('legacy-open-close: 47-transition-free open/close chain replays identically', async () => {
|
||||
const { replayed, derived, messages, unexpected } = await restoreFixture('legacy-open-close');
|
||||
expectZeroSkips(unexpected);
|
||||
expect(messages.length).toBe(34);
|
||||
expect(Object.keys(replayed.nodes).length).toBe(5);
|
||||
// The tolerated drift is real: the legacy ops carry token gauges.
|
||||
expect(Object.values(replayed.nodes).some((n) => n.baselineTokens !== undefined)).toBe(true);
|
||||
expectSameTree(replayed, derived);
|
||||
expectSpanInvariants(replayed, messages.length);
|
||||
expectSpanInvariants(derived, messages.length);
|
||||
});
|
||||
|
||||
it('legacy-next: spine.next siblings and an open cursor replay identically', async () => {
|
||||
const { replayed, derived, messages, unexpected } = await restoreFixture('legacy-next');
|
||||
expectZeroSkips(unexpected);
|
||||
expect(messages.length).toBe(41);
|
||||
expect(Object.keys(replayed.nodes).length).toBe(5);
|
||||
// Mid-session snapshot: the cursor node is still open.
|
||||
expect(replayed.openStack).toEqual(['1', '1.1', '1.1.3']);
|
||||
expect(replayed.nodes['1.1.3']?.closedAt).toBeUndefined();
|
||||
expectSameTree(replayed, derived);
|
||||
expectSpanInvariants(replayed, messages.length);
|
||||
expectSpanInvariants(derived, messages.length);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Spine legacy wire replay (receipt-anchor group)', () => {
|
||||
/**
|
||||
* The index of the first tool message answering the spine_close call whose
|
||||
* carrier sits at `carrierIndex` — i.e. where a pre-f0c56f31b build
|
||||
* anchored the span end.
|
||||
*/
|
||||
function closeReceiptIndex(messages: readonly ContextMessage[], carrierIndex: number): number {
|
||||
const carrier = messages[carrierIndex];
|
||||
expect(carrier?.role, `carrier at ${carrierIndex}`).toBe('assistant');
|
||||
const call = carrier?.toolCalls.find((c) => c.name === SPINE_TOOL_CLOSE);
|
||||
expect(call, `spine_close call at ${carrierIndex}`).toBeDefined();
|
||||
for (let i = carrierIndex + 1; i < messages.length; i++) {
|
||||
const message = messages[i]!;
|
||||
if (message.role === 'tool' && message.toolCallId === call!.id) return i;
|
||||
}
|
||||
throw new Error(`no receipt found for the close call at ${carrierIndex}`);
|
||||
}
|
||||
|
||||
it('legacy-receipt-anchor: tree identical, closedAt pinned to the receipt index', async () => {
|
||||
const { replayed, derived, messages, unexpected } = await restoreFixture('legacy-receipt-anchor');
|
||||
expectZeroSkips(unexpected);
|
||||
expect(messages.length).toBe(278);
|
||||
expect(Object.keys(replayed.nodes).length).toBe(49);
|
||||
|
||||
// Tree shape and content agree everywhere — only span ends drift.
|
||||
expect(Object.keys(derived.nodes).sort()).toEqual(Object.keys(replayed.nodes).sort());
|
||||
let closedCount = 0;
|
||||
for (const [id, d] of Object.entries(derived.nodes)) {
|
||||
const r = replayed.nodes[id]!;
|
||||
expect(r.summary, `${id} summary`).toBe(d.summary);
|
||||
expect(r.children, `${id} children`).toEqual(d.children);
|
||||
expect(r.memory, `${id} memory`).toBe(d.memory);
|
||||
expect(r.openedAt, `${id} openedAt`).toBe(d.openedAt);
|
||||
if (d.closedAt === undefined) continue;
|
||||
closedCount++;
|
||||
// Pre-f0c56f31b anchor: the persisted span end IS the receipt index;
|
||||
// the derivation ends the span right before the carrier instead.
|
||||
const carrier = d.closedAt + 1;
|
||||
expect(r.closedAt, `${id} closedAt anchors at the receipt`).toBe(
|
||||
closeReceiptIndex(messages, carrier),
|
||||
);
|
||||
expect(r.closedAt, `${id} drift`).toBeGreaterThan(d.closedAt);
|
||||
}
|
||||
expect(closedCount).toBe(47);
|
||||
expect(derived.openStack).toEqual(replayed.openStack);
|
||||
expectSpanInvariants(replayed, messages.length);
|
||||
expectSpanInvariants(derived, messages.length);
|
||||
});
|
||||
|
||||
it('legacy-root-compact: two epochs identical, spans and one memory pinned', async () => {
|
||||
const { replayed, derived, messages, unexpected } = await restoreFixture('legacy-root-compact');
|
||||
expectZeroSkips(unexpected);
|
||||
expect(messages.length).toBe(80);
|
||||
|
||||
// The root_compact acceptance: the derivation reconstructs the epoch
|
||||
// boundary from the compaction-summary message exactly as the persisted
|
||||
// spine.root_compact op replayed it.
|
||||
expect(derived.rootEpoch).toBe(2);
|
||||
expect(derived.epochStartAt).toBe(71);
|
||||
expect(derived.epochMemoryAt).toBe(70);
|
||||
expect(replayed.rootEpoch).toBe(2);
|
||||
expect(replayed.epochStartAt).toBe(71);
|
||||
expect(replayed.epochMemoryAt).toBe(70);
|
||||
expect(derived.openStack).toEqual(['2', '2.1']);
|
||||
expect(replayed.openStack).toEqual(['2', '2.1']);
|
||||
|
||||
// Tree shape and content agree (ids, summaries, children).
|
||||
expect(Object.keys(derived.nodes).sort()).toEqual(Object.keys(replayed.nodes).sort());
|
||||
for (const [id, d] of Object.entries(derived.nodes)) {
|
||||
const r = replayed.nodes[id]!;
|
||||
expect(r.summary, `${id} summary`).toBe(d.summary);
|
||||
expect(r.children, `${id} children`).toEqual(d.children);
|
||||
}
|
||||
|
||||
// Pre-f0c56f31b span anchors (this 2026-07-10 build also anchored nested
|
||||
// opens late): both span tables pinned exactly.
|
||||
expectSpans(replayed, {
|
||||
1: { openedAt: SPINE_VOID_OPENED_AT },
|
||||
2: { openedAt: SPINE_VOID_OPENED_AT },
|
||||
'1.1': { openedAt: 0 },
|
||||
'1.1.1': { openedAt: 1, closedAt: 65 },
|
||||
'1.1.1.1': { openedAt: 4, closedAt: 16 },
|
||||
'1.1.1.2': { openedAt: 17, closedAt: 36 },
|
||||
'1.1.1.3': { openedAt: 37, closedAt: 50 },
|
||||
'1.1.1.4': { openedAt: 51, closedAt: 61 },
|
||||
'2.1': { openedAt: 71 },
|
||||
});
|
||||
expectSpans(derived, {
|
||||
1: { openedAt: SPINE_VOID_OPENED_AT },
|
||||
2: { openedAt: SPINE_VOID_OPENED_AT },
|
||||
'1.1': { openedAt: 0 },
|
||||
'1.1.1': { openedAt: 1, closedAt: 63 },
|
||||
'1.1.1.1': { openedAt: 4, closedAt: 14 },
|
||||
'1.1.1.2': { openedAt: 15, closedAt: 34 },
|
||||
'1.1.1.3': { openedAt: 35, closedAt: 48 },
|
||||
'1.1.1.4': { openedAt: 49, closedAt: 58 },
|
||||
'2.1': { openedAt: 71 },
|
||||
});
|
||||
|
||||
// P5 memory-form difference on the one node with closed children: the
|
||||
// legacy op stored an assembleMemoryBody() composite (from an interrupted
|
||||
// pending commit); the derivation keeps the surviving close call's body
|
||||
// verbatim. Values are the sanitization dictionary's placeholders.
|
||||
expect(replayed.nodes['1.1.1']?.memory).toBe('memory_88');
|
||||
expect(derived.nodes['1.1.1']?.memory).toBe('memory_87');
|
||||
for (const id of ['1.1.1.1', '1.1.1.2', '1.1.1.3', '1.1.1.4']) {
|
||||
expect(derived.nodes[id]?.memory, `${id} memory`).toBe(replayed.nodes[id]?.memory);
|
||||
}
|
||||
|
||||
expectSpanInvariants(replayed, messages.length);
|
||||
expectSpanInvariants(derived, messages.length);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Spine legacy wire replay (undo-divergence group)', () => {
|
||||
it('legacy-undo-divergence: both topologies and their documented relationship', async () => {
|
||||
const { replayed, derived, messages, unexpected } = await restoreFixture('legacy-undo-divergence');
|
||||
expectZeroSkips(unexpected);
|
||||
expect(messages.length).toBe(592);
|
||||
expectSpanInvariants(replayed, messages.length);
|
||||
expectSpanInvariants(derived, messages.length);
|
||||
|
||||
// ---- The op-replay world (frozen at crash time): 32 nodes. ----
|
||||
expect(Object.keys(replayed.nodes).length).toBe(32);
|
||||
expect(replayed.openStack).toEqual(['1', '1.1', '1.1.28']);
|
||||
expect(replayed.nodes['1']?.children).toEqual(['1.1']);
|
||||
const replayedWorkChildren = replayed.nodes['1.1']?.children ?? [];
|
||||
expect(replayedWorkChildren.length).toBe(28);
|
||||
expect(replayedWorkChildren.slice(0, 8)).toEqual([
|
||||
'1.1.1', '1.1.2', '1.1.3', '1.1.4', '1.1.5', '1.1.6', '1.1.7', '1.1.8',
|
||||
]);
|
||||
expect(replayedWorkChildren).toContain('1.1.9');
|
||||
expect(replayedWorkChildren.at(-1)).toBe('1.1.28');
|
||||
// truncate_repair voided the spans whose witnesses the first and last
|
||||
// undos removed (openedAt = SPINE_VOID_OPENED_AT, kept for reference).
|
||||
expect(replayed.nodes['1.1.2']?.openedAt).toBe(SPINE_VOID_OPENED_AT);
|
||||
expect(replayed.nodes['1.1.2']?.closedAt).toBe(41);
|
||||
expect(replayed.nodes['1.1.27']?.openedAt).toBe(SPINE_VOID_OPENED_AT);
|
||||
expect(replayed.nodes['1.1.27']?.closedAt).toBe(601);
|
||||
// The nesting the second undo made unwitnessed: 1.1.8 → {1.1.8.1, 1.1.8.2}.
|
||||
expect(replayed.nodes['1.1.8']?.children).toEqual(['1.1.8.1', '1.1.8.2']);
|
||||
expect(replayed.nodes['1.1.8']?.openedAt).toBe(160);
|
||||
expect(replayed.nodes['1.1.8']?.closedAt).toBe(180);
|
||||
expect(replayed.nodes['1.1.8.1']?.openedAt).toBe(161);
|
||||
expect(replayed.nodes['1.1.8.1']?.closedAt).toBe(167);
|
||||
expect(replayed.nodes['1.1.8.2']?.openedAt).toBe(172);
|
||||
expect(replayed.nodes['1.1.8.2']?.closedAt).toBe(177);
|
||||
// The node whose open the third undo unwitnessed: kept frozen by the ops.
|
||||
expect(replayed.nodes['1.1.9']?.openedAt).toBe(181);
|
||||
expect(replayed.nodes['1.1.9']?.closedAt).toBe(181);
|
||||
|
||||
// ---- The derivation (surviving-stream truth): exact topology. ----
|
||||
const DERIVED_TOPOLOGY: Readonly<Record<string, { parent: string | null } & Span>> = {
|
||||
1: { parent: null, openedAt: SPINE_VOID_OPENED_AT },
|
||||
'1.1': { parent: '1', openedAt: 0, closedAt: 181 },
|
||||
'1.1.1': { parent: '1.1', openedAt: 1, closedAt: 12 },
|
||||
'1.1.2': { parent: '1.1', openedAt: 17, closedAt: 46 },
|
||||
'1.1.3': { parent: '1.1', openedAt: 51, closedAt: 88 },
|
||||
'1.1.4': { parent: '1.1', openedAt: 102, closedAt: 115 },
|
||||
'1.1.5': { parent: '1.1', openedAt: 120, closedAt: 129 },
|
||||
'1.1.6': { parent: '1.1', openedAt: 134, closedAt: 156 },
|
||||
'1.1.7': { parent: '1.1', openedAt: 161, closedAt: 167 },
|
||||
'1.1.8': { parent: '1.1', openedAt: 172, closedAt: 177 },
|
||||
'1.2': { parent: '1', openedAt: 182, closedAt: 198 },
|
||||
'1.3': { parent: '1', openedAt: 205, closedAt: 209 },
|
||||
'1.4': { parent: '1', openedAt: 214, closedAt: 226 },
|
||||
'1.5': { parent: '1', openedAt: 231, closedAt: 262 },
|
||||
'1.6': { parent: '1', openedAt: 267, closedAt: 274 },
|
||||
'1.7': { parent: '1', openedAt: 279, closedAt: 284 },
|
||||
'1.8': { parent: '1', openedAt: 289, closedAt: 291 },
|
||||
'1.9': { parent: '1', openedAt: 296, closedAt: 304 },
|
||||
'1.10': { parent: '1', openedAt: 309, closedAt: 342 },
|
||||
'1.11': { parent: '1', openedAt: 347, closedAt: 375 },
|
||||
'1.12': { parent: '1', openedAt: 381, closedAt: 390 },
|
||||
'1.13': { parent: '1', openedAt: 397, closedAt: 405 },
|
||||
'1.14': { parent: '1', openedAt: 415, closedAt: 423 },
|
||||
'1.15': { parent: '1', openedAt: 449, closedAt: 460 },
|
||||
'1.16': { parent: '1', openedAt: 461, closedAt: 526 },
|
||||
'1.17': { parent: '1', openedAt: 529, closedAt: 564 },
|
||||
'1.18': { parent: '1', openedAt: 571, closedAt: 580 },
|
||||
'1.19': { parent: '1', openedAt: 590 },
|
||||
};
|
||||
expect(Object.keys(derived.nodes).sort()).toEqual(Object.keys(DERIVED_TOPOLOGY).sort());
|
||||
for (const [id, expected] of Object.entries(DERIVED_TOPOLOGY)) {
|
||||
const node = derived.nodes[id];
|
||||
expect(node?.openedAt, `${id} openedAt`).toBe(expected.openedAt);
|
||||
expect(node?.closedAt, `${id} closedAt`).toBe(expected.closedAt);
|
||||
expect(parentOf(derived, id), `${id} parent`).toBe(expected.parent);
|
||||
}
|
||||
expect(derived.openStack).toEqual(['1', '1.19']);
|
||||
expect(derived.rootEpoch).toBe(1);
|
||||
expect(derived.epochStartAt).toBe(0);
|
||||
expect(derived.epochMemoryAt).toBeUndefined();
|
||||
|
||||
// ---- The documented relationship between the two worlds. ----
|
||||
// Undo #3 unwitnessed 1.1.9's open: the surviving spine.next closes the
|
||||
// derivation's cursor (the startup node) with 1.1.9's redirect memory and
|
||||
// re-parents everything after it to the root epoch.
|
||||
expect(derived.nodes['1.1.9']).toBeUndefined();
|
||||
expect(derived.nodes['1.1.8.1']).toBeUndefined();
|
||||
expect(derived.nodes['1.1.27']).toBeUndefined();
|
||||
expect(derived.nodes['1.1']?.memory).toBe(replayed.nodes['1.1.9']?.memory);
|
||||
expect(derived.nodes['1.2']?.summary).toBe(replayed.nodes['1.1.10']?.summary);
|
||||
// Undo #1 unwitnessed the first "1.1.2": the derivation reuses the id for
|
||||
// the redo the ops numbered 1.1.3 (the whole 1.1.x series shifts by one).
|
||||
expect(derived.nodes['1.1.2']?.summary).toBe(replayed.nodes['1.1.3']?.summary);
|
||||
// Undo #2 unwitnessed 1.1.8's open: nested 1.1.8.1/1.1.8.2 flatten into
|
||||
// the derivation's sibling 1.1.7/1.1.8.
|
||||
expect(derived.nodes['1.1.7']?.summary).toBe(replayed.nodes['1.1.8.1']?.summary);
|
||||
expect(derived.nodes['1.1.8']?.summary).toBe(replayed.nodes['1.1.8.2']?.summary);
|
||||
// The last undo (cut=589) voided 1.1.27 in the op world; the derivation's
|
||||
// open cursor is the redo the ops numbered 1.1.28.
|
||||
expect(derived.nodes['1.19']?.summary).toBe(replayed.nodes['1.1.28']?.summary);
|
||||
});
|
||||
});
|
||||
290
packages/agent-core-v2/test/spine/spawnExecutor.test.ts
Normal file
290
packages/agent-core-v2/test/spine/spawnExecutor.test.ts
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import type { IAgentScopeHandle } from '#/_base/di/scope';
|
||||
import type { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle';
|
||||
import type {
|
||||
AgentRunHandle,
|
||||
AgentRunRequest,
|
||||
ISessionSubagentService,
|
||||
RunAgentOptions,
|
||||
} from '#/session/subagent/subagent';
|
||||
import type { SpineSpawnTaskInput } from '#/agent/spine/spine';
|
||||
import {
|
||||
executeSpawnBranches,
|
||||
maxSpawnBranchCount,
|
||||
resolveMaxThreads,
|
||||
taskEnvelope,
|
||||
type SpawnBranchResult,
|
||||
} from '#/agent/spine/spineSpawn';
|
||||
|
||||
interface FakeAgent {
|
||||
readonly id: string;
|
||||
removed: boolean;
|
||||
cancelled: boolean;
|
||||
completionValue: Promise<{ summary: string }>;
|
||||
}
|
||||
|
||||
function fakeRunHandle(turnId: number, completion: Promise<{ summary: string }>): AgentRunHandle {
|
||||
const controller = new AbortController();
|
||||
return {
|
||||
agentId: `agent-${String(turnId)}`,
|
||||
turn: {
|
||||
id: turnId,
|
||||
signal: controller.signal,
|
||||
cancel: (reason?: unknown) => {
|
||||
controller.abort(reason);
|
||||
return true;
|
||||
},
|
||||
ready: Promise.resolve(),
|
||||
result: Promise.resolve({ type: 'completed', steps: 0 } as never),
|
||||
},
|
||||
completion,
|
||||
};
|
||||
}
|
||||
|
||||
function buildFakes(tasks: readonly SpineSpawnTaskInput[]): {
|
||||
readonly lifecycle: IAgentLifecycleService;
|
||||
readonly subagentService: ISessionSubagentService;
|
||||
readonly agents: FakeAgent[];
|
||||
readonly runCompletionControllers: ReturnType<typeof buildCompletionController>[];
|
||||
} {
|
||||
const agents: FakeAgent[] = [];
|
||||
const runCompletionControllers = tasks.map(() => buildCompletionController());
|
||||
|
||||
const lifecycle: IAgentLifecycleService = {
|
||||
_serviceBrand: undefined,
|
||||
onDidCreate: { event: () => ({ dispose: () => undefined }) } as never,
|
||||
onDidDispose: { event: () => ({ dispose: () => undefined }) } as never,
|
||||
create: () => Promise.reject(new Error('not used')),
|
||||
fork: async (_sourceAgentId, opts) => {
|
||||
const id = `agent-${String(agents.length)}`;
|
||||
const agent: FakeAgent = {
|
||||
id,
|
||||
removed: false,
|
||||
cancelled: false,
|
||||
completionValue: Promise.resolve({ summary: '' }),
|
||||
};
|
||||
agents.push(agent);
|
||||
return {
|
||||
id,
|
||||
accessor: {
|
||||
get: () => {
|
||||
throw new Error('unexpected accessor call');
|
||||
},
|
||||
},
|
||||
dispose: () => undefined,
|
||||
} as unknown as IAgentScopeHandle;
|
||||
},
|
||||
get: () => undefined,
|
||||
list: () => [],
|
||||
broadcastPermissionMode: () => undefined,
|
||||
remove: async (agentId) => {
|
||||
const agent = agents.find((a) => a.id === agentId);
|
||||
if (agent !== undefined) agent.removed = true;
|
||||
},
|
||||
};
|
||||
|
||||
const subagentService: ISessionSubagentService = {
|
||||
_serviceBrand: undefined,
|
||||
hooks: { onWillStartAgentTask: { register: () => ({ dispose: () => undefined }) } },
|
||||
onDidStopAgentTask: { event: () => ({ dispose: () => undefined }) },
|
||||
run: async (agentId: string, _request: AgentRunRequest, opts: RunAgentOptions) => {
|
||||
const index = agents.findIndex((a) => a.id === agentId);
|
||||
const agent = agents[index];
|
||||
if (agent === undefined) throw new Error(`unknown agent ${agentId}`);
|
||||
const controller = runCompletionControllers[index];
|
||||
if (controller === undefined) throw new Error(`no completion controller for ${agentId}`);
|
||||
|
||||
// Wire cancellation: when the provided signal aborts, cancel the turn.
|
||||
const onAbort = () => {
|
||||
agent.cancelled = true;
|
||||
};
|
||||
opts.signal.addEventListener('abort', onAbort, { once: true });
|
||||
|
||||
agent.completionValue = controller.promise;
|
||||
const completion = agent.completionValue.finally(() => {
|
||||
opts.signal.removeEventListener('abort', onAbort);
|
||||
});
|
||||
return fakeRunHandle(index, completion);
|
||||
},
|
||||
notifyAgentTaskStopped: () => undefined,
|
||||
} as unknown as ISessionSubagentService;
|
||||
|
||||
return { lifecycle, subagentService, agents, runCompletionControllers };
|
||||
}
|
||||
|
||||
function buildCompletionController() {
|
||||
let resolve!: (value: { summary: string }) => void;
|
||||
let reject!: (reason?: unknown) => void;
|
||||
const promise = new Promise<{ summary: string }>((res, rej) => {
|
||||
resolve = res;
|
||||
reject = rej;
|
||||
});
|
||||
return { promise, resolve, reject };
|
||||
}
|
||||
|
||||
function makeSignal(): AbortSignal {
|
||||
return new AbortController().signal;
|
||||
}
|
||||
|
||||
const TASKS: SpineSpawnTaskInput[] = [
|
||||
{ summary: 'branch A', prompt: 'do A' },
|
||||
{ summary: 'branch B', prompt: 'do B' },
|
||||
];
|
||||
|
||||
describe('executeSpawnBranches', () => {
|
||||
it('forks with trimTrailingToolCallBatch enabled', async () => {
|
||||
const { lifecycle, subagentService, runCompletionControllers } = buildFakes(TASKS);
|
||||
const forkSpy = vi.spyOn(lifecycle, 'fork');
|
||||
const promise = executeSpawnBranches({ lifecycle, subagentService }, TASKS, makeSignal());
|
||||
runCompletionControllers[0]!.resolve({ summary: 'memory A' });
|
||||
runCompletionControllers[1]!.resolve({ summary: 'memory B' });
|
||||
await promise;
|
||||
expect(forkSpy).toHaveBeenCalledTimes(2);
|
||||
expect(forkSpy).toHaveBeenCalledWith('main', { trimTrailingToolCallBatch: true });
|
||||
});
|
||||
|
||||
it('wraps the task in the expected envelope', () => {
|
||||
const envelope = taskEnvelope({ summary: 'branch A', prompt: 'do A' });
|
||||
expect(envelope).toContain('You are one branch of a spine_spawn fission');
|
||||
expect(envelope).toContain('The original continuation is suspended during this fission');
|
||||
expect(envelope).toContain('no supervisory model is active');
|
||||
expect(envelope).toContain('Branch label and outcome: branch A');
|
||||
expect(envelope).toContain('Assignment:\ndo A');
|
||||
expect(envelope).toContain('When you finish, return only the terminal memory for this branch.');
|
||||
});
|
||||
|
||||
it('returns a completed receipt when all branches succeed', async () => {
|
||||
const { lifecycle, subagentService, runCompletionControllers } = buildFakes(TASKS);
|
||||
const promise = executeSpawnBranches({ lifecycle, subagentService }, TASKS, makeSignal());
|
||||
runCompletionControllers[0]!.resolve({ summary: 'memory A' });
|
||||
runCompletionControllers[1]!.resolve({ summary: 'memory B' });
|
||||
const results = await promise;
|
||||
expect(results).toEqual<readonly SpawnBranchResult[]>([
|
||||
{ summary: 'branch A', outcome: 'completed', memoryBody: 'memory A' },
|
||||
{ summary: 'branch B', outcome: 'completed', memoryBody: 'memory B' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('isolates a single errored branch and keeps the rest', async () => {
|
||||
const { lifecycle, subagentService, runCompletionControllers } = buildFakes(TASKS);
|
||||
const promise = executeSpawnBranches({ lifecycle, subagentService }, TASKS, makeSignal());
|
||||
runCompletionControllers[0]!.reject(new Error('boom'));
|
||||
runCompletionControllers[1]!.resolve({ summary: 'memory B' });
|
||||
const results = await promise;
|
||||
expect(results[0]?.outcome).toBe('errored');
|
||||
expect(results[0]?.diagnostic).toContain('boom');
|
||||
expect(results[1]).toEqual({ summary: 'branch B', outcome: 'completed', memoryBody: 'memory B' });
|
||||
});
|
||||
|
||||
it('isolates a single aborted branch and keeps the rest', async () => {
|
||||
const { lifecycle, subagentService, runCompletionControllers } = buildFakes(TASKS);
|
||||
const promise = executeSpawnBranches({ lifecycle, subagentService }, TASKS, makeSignal());
|
||||
const abortError = new Error('user cancelled');
|
||||
abortError.name = 'AbortError';
|
||||
runCompletionControllers[0]!.reject(abortError);
|
||||
runCompletionControllers[1]!.resolve({ summary: 'memory B' });
|
||||
const results = await promise;
|
||||
expect(results[0]?.outcome).toBe('aborted');
|
||||
expect(results[0]?.diagnostic).toContain('user cancelled');
|
||||
expect(results[1]).toEqual({ summary: 'branch B', outcome: 'completed', memoryBody: 'memory B' });
|
||||
});
|
||||
|
||||
it('treats an empty summary as errored', async () => {
|
||||
const { lifecycle, subagentService, runCompletionControllers } = buildFakes(TASKS);
|
||||
const promise = executeSpawnBranches({ lifecycle, subagentService }, TASKS, makeSignal());
|
||||
runCompletionControllers[0]!.resolve({ summary: ' ' });
|
||||
runCompletionControllers[1]!.resolve({ summary: 'memory B' });
|
||||
const results = await promise;
|
||||
expect(results[0]?.outcome).toBe('errored');
|
||||
expect(results[0]?.diagnostic).toBe('child completed without a non-empty final memory');
|
||||
expect(results[0]?.memoryBody).toBe('child completed without a non-empty final memory');
|
||||
expect(results[1]).toEqual({ summary: 'branch B', outcome: 'completed', memoryBody: 'memory B' });
|
||||
});
|
||||
|
||||
it('aborts unfinished branches when the turn signal is aborted and releases all agents', async () => {
|
||||
const { lifecycle, subagentService, agents } = buildFakes(TASKS);
|
||||
const controller = new AbortController();
|
||||
const promise = executeSpawnBranches(
|
||||
{ lifecycle, subagentService },
|
||||
TASKS,
|
||||
controller.signal,
|
||||
);
|
||||
// Let both starts land, then abort before any branch completes.
|
||||
await Promise.resolve();
|
||||
controller.abort('turn cancelled');
|
||||
const results = await promise;
|
||||
expect(results.every((r) => r.outcome === 'aborted')).toBe(true);
|
||||
expect(agents.every((a) => a.removed)).toBe(true);
|
||||
});
|
||||
|
||||
it('releases all agents in finally even when some fail', async () => {
|
||||
const { lifecycle, subagentService, agents, runCompletionControllers } = buildFakes(TASKS);
|
||||
const promise = executeSpawnBranches({ lifecycle, subagentService }, TASKS, makeSignal());
|
||||
runCompletionControllers[0]!.resolve({ summary: 'memory A' });
|
||||
runCompletionControllers[1]!.reject(new Error('boom'));
|
||||
await promise;
|
||||
expect(agents.every((a) => a.removed)).toBe(true);
|
||||
});
|
||||
|
||||
it('errors a branch whose fork fails, aborts live siblings, and still releases them', async () => {
|
||||
const { lifecycle, subagentService, agents, runCompletionControllers } = buildFakes(TASKS);
|
||||
const originalFork = lifecycle.fork;
|
||||
let forkCalls = 0;
|
||||
lifecycle.fork = async (sourceAgentId, opts) => {
|
||||
forkCalls += 1;
|
||||
if (forkCalls === 2) throw new Error('fork denied');
|
||||
return originalFork(sourceAgentId, opts);
|
||||
};
|
||||
|
||||
const promise = executeSpawnBranches({ lifecycle, subagentService }, TASKS, makeSignal());
|
||||
// The started branch's run is cancelled by the batch; simulate its turn
|
||||
// settling as an abort, the way a cancelled turn's completion rejects.
|
||||
const abortError = new Error('turn cancelled');
|
||||
abortError.name = 'AbortError';
|
||||
runCompletionControllers[0]!.reject(abortError);
|
||||
const results = await promise;
|
||||
|
||||
expect(results[0]?.outcome).toBe('aborted');
|
||||
expect(results[0]?.diagnostic).toContain('a sibling branch failed to start');
|
||||
expect(results[1]?.outcome).toBe('errored');
|
||||
expect(results[1]?.diagnostic).toContain('fork denied');
|
||||
// Only one fork succeeded, and that agent was released despite the failure.
|
||||
expect(agents).toHaveLength(1);
|
||||
expect(agents[0]?.removed).toBe(true);
|
||||
});
|
||||
|
||||
it('returns results even when releasing a branch fails', async () => {
|
||||
const { lifecycle, subagentService, runCompletionControllers } = buildFakes(TASKS);
|
||||
lifecycle.remove = async () => {
|
||||
throw new Error('remove failed');
|
||||
};
|
||||
const promise = executeSpawnBranches({ lifecycle, subagentService }, TASKS, makeSignal());
|
||||
runCompletionControllers[0]!.resolve({ summary: 'memory A' });
|
||||
runCompletionControllers[1]!.resolve({ summary: 'memory B' });
|
||||
const results = await promise;
|
||||
expect(results.every((r) => r.outcome === 'completed')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('resolveMaxThreads', () => {
|
||||
it('defaults to 4', () => {
|
||||
expect(resolveMaxThreads(undefined)).toBe(4);
|
||||
expect(resolveMaxThreads('')).toBe(4);
|
||||
});
|
||||
|
||||
it('parses a valid positive integer', () => {
|
||||
expect(resolveMaxThreads('8')).toBe(8);
|
||||
});
|
||||
|
||||
it('falls back for invalid values', () => {
|
||||
expect(resolveMaxThreads('abc')).toBe(4);
|
||||
expect(resolveMaxThreads('1')).toBe(4);
|
||||
expect(resolveMaxThreads('3.5')).toBe(4);
|
||||
});
|
||||
|
||||
it('computes branch capacity as maxThreads - 1', () => {
|
||||
expect(maxSpawnBranchCount(4)).toBe(3);
|
||||
expect(maxSpawnBranchCount(2)).toBe(1);
|
||||
});
|
||||
});
|
||||
|
|
@ -11,11 +11,14 @@ import { SPINE_FLAG_ID } from '#/agent/spine/flag';
|
|||
import { SpineCloseTool } from '#/agent/spine/tools/spine-close';
|
||||
import { SpineNextTool } from '#/agent/spine/tools/spine-next';
|
||||
import { SpineOpenTool } from '#/agent/spine/tools/spine-open';
|
||||
import { SpineSpawnTool } from '#/agent/spine/tools/spine-spawn';
|
||||
import { SpineTreeTool } from '#/agent/spine/tools/spine-tree';
|
||||
import { SpineTrimTool } from '#/agent/spine/tools/spine-trim';
|
||||
import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext';
|
||||
import { IFlagService } from '#/app/flag/flag';
|
||||
import { getToolContributions } from '#/agent/toolRegistry/toolContribution';
|
||||
import type { ServicesAccessor } from '#/_base/di/instantiation';
|
||||
import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory';
|
||||
import type { ContextMessage } from '#/agent/contextMemory/types';
|
||||
import {
|
||||
IAgentSpineService,
|
||||
|
|
@ -33,6 +36,7 @@ import type { Message } from '#/kosong/contract/message';
|
|||
import {
|
||||
createCommandRunner,
|
||||
execEnvServices,
|
||||
sessionService,
|
||||
testAgent,
|
||||
type TestAgentContext,
|
||||
type TestAgentOptions,
|
||||
|
|
@ -259,7 +263,7 @@ describe('Spine control tools', () => {
|
|||
vi.unstubAllEnvs();
|
||||
});
|
||||
|
||||
it('registers the four spine tools when enabled', () => {
|
||||
it('registers the four core spine tools when enabled', () => {
|
||||
const ctx = testAgent();
|
||||
const names = spineToolNames(ctx);
|
||||
expect(names).toEqual(
|
||||
|
|
@ -268,6 +272,28 @@ describe('Spine control tools', () => {
|
|||
expect(names).toHaveLength(4);
|
||||
});
|
||||
|
||||
it('registers spine_spawn when the spawn flag is also on', () => {
|
||||
vi.stubEnv('KIMI_CODE_SPINE_SPAWN', '1');
|
||||
const ctx = testAgent();
|
||||
expect(spineToolNames(ctx)).toContain('spine_spawn');
|
||||
});
|
||||
|
||||
it('does not register spine_spawn without the spawn flag', () => {
|
||||
const ctx = testAgent();
|
||||
expect(spineToolNames(ctx)).not.toContain('spine_spawn');
|
||||
});
|
||||
|
||||
it('registers spine_trim when the trim flag is also on', () => {
|
||||
vi.stubEnv('KIMI_CODE_SPINE_TRIM', '1');
|
||||
const ctx = testAgent();
|
||||
expect(spineToolNames(ctx)).toContain('spine_trim');
|
||||
});
|
||||
|
||||
it('does not register spine_trim without the trim flag', () => {
|
||||
const ctx = testAgent();
|
||||
expect(spineToolNames(ctx)).not.toContain('spine_trim');
|
||||
});
|
||||
|
||||
it('default agent profile whitelists the spine tools', () => {
|
||||
// The profile's active-tool whitelist gates what reaches the LLM request.
|
||||
// If the spine tools are absent here, `profile.isToolActive` filters them
|
||||
|
|
@ -276,14 +302,14 @@ describe('Spine control tools', () => {
|
|||
const ctx = testAgent();
|
||||
const profile = ctx.get(IAgentProfileCatalogService).getDefault();
|
||||
expect(profile.tools).toEqual(
|
||||
expect.arrayContaining(['spine_open', 'spine_close', 'spine_next', 'spine_tree']),
|
||||
expect.arrayContaining(['spine_open', 'spine_close', 'spine_next', 'spine_tree', 'spine_trim', 'spine_spawn']),
|
||||
);
|
||||
});
|
||||
|
||||
it('keeps spine tools active under a whitelist that lists them', () => {
|
||||
const ctx = testAgent();
|
||||
ctx.configure({
|
||||
tools: ['Read', 'spine_open', 'spine_close', 'spine_next', 'spine_tree'],
|
||||
tools: ['Read', 'spine_open', 'spine_close', 'spine_next', 'spine_tree', 'spine_trim', 'spine_spawn'],
|
||||
});
|
||||
const spine = ctx.toolsData().filter((tool) => tool.name.startsWith('spine_'));
|
||||
expect(spine).toHaveLength(4);
|
||||
|
|
@ -771,34 +797,51 @@ describe('spine control tool main-agent gating', () => {
|
|||
['spine_close', SpineCloseTool],
|
||||
['spine_next', SpineNextTool],
|
||||
['spine_tree', SpineTreeTool],
|
||||
['spine_trim', SpineTrimTool],
|
||||
['spine_spawn', SpineSpawnTool],
|
||||
] as const;
|
||||
|
||||
function accessorFor(agentId: string, spineEnabled: boolean): ServicesAccessor {
|
||||
function accessorFor(agentId: string, flags: { spine: boolean; trim: boolean; spawn: boolean }): ServicesAccessor {
|
||||
const scopeContext: IAgentScopeContext = {
|
||||
_serviceBrand: undefined,
|
||||
agentId,
|
||||
scope: () => '',
|
||||
};
|
||||
const flags = {
|
||||
enabled: (id: string) => id === SPINE_FLAG_ID && spineEnabled,
|
||||
const flagService = {
|
||||
enabled: (id: string) => {
|
||||
if (id === SPINE_FLAG_ID) return flags.spine;
|
||||
if (id === 'spine_trim') return flags.trim;
|
||||
if (id === 'spine_spawn') return flags.spawn;
|
||||
return false;
|
||||
},
|
||||
} as unknown as IFlagService;
|
||||
return {
|
||||
get: (id: unknown) => {
|
||||
if (id === IAgentScopeContext) return scopeContext;
|
||||
if (id === IFlagService) return flags;
|
||||
if (id === IFlagService) return flagService;
|
||||
throw new Error(`unexpected service identifier: ${String(id)}`);
|
||||
},
|
||||
} as unknown as ServicesAccessor;
|
||||
}
|
||||
|
||||
it.each(gatedTools)('%s registers only on the main agent with the flag on', (name, ctor) => {
|
||||
it.each(gatedTools)('%s registers only on the main agent with the required flags', (name, ctor) => {
|
||||
const contribution = getToolContributions().find((c) => c.ctor === ctor);
|
||||
expect(contribution, `${name} contribution`).toBeDefined();
|
||||
const when = contribution?.options.when;
|
||||
expect(when, `${name} must gate on flag + main-agent identity`).toBeDefined();
|
||||
expect(when?.(accessorFor('main', true))).toBe(true);
|
||||
expect(when?.(accessorFor('sub-1', true))).toBe(false);
|
||||
expect(when?.(accessorFor('main', false))).toBe(false);
|
||||
expect(when, `${name} must gate on flags + main-agent identity`).toBeDefined();
|
||||
const needsSpawn = name === 'spine_spawn';
|
||||
const needsTrim = name === 'spine_trim';
|
||||
expect(when?.(accessorFor('main', { spine: true, trim: needsTrim, spawn: needsSpawn }))).toBe(true);
|
||||
expect(when?.(accessorFor('sub-1', { spine: true, trim: needsTrim, spawn: needsSpawn }))).toBe(false);
|
||||
expect(when?.(accessorFor('main', { spine: false, trim: needsTrim, spawn: needsSpawn }))).toBe(false);
|
||||
});
|
||||
|
||||
it('spine_spawn requires capacity for at least two branches', () => {
|
||||
vi.stubEnv('KIMI_CODE_SPINE_SPAWN_MAX_THREADS', '2');
|
||||
const contribution = getToolContributions().find((c) => c.ctor === SpineSpawnTool);
|
||||
const when = contribution?.options.when;
|
||||
expect(when?.(accessorFor('main', { spine: true, trim: false, spawn: true }))).toBe(false);
|
||||
vi.unstubAllEnvs();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -900,3 +943,250 @@ function spineReceipt(toolCallId: string): ContextMessage {
|
|||
toolCallId,
|
||||
};
|
||||
}
|
||||
import { IAgentLoopService } from '#/agent/loop/loop';
|
||||
import { ISessionSubagentService } from '#/session/subagent/subagent';
|
||||
import type { AgentRunHandle } from '#/session/subagent/subagent';
|
||||
import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle';
|
||||
import type { IAgentScopeHandle } from '#/_base/di/scope';
|
||||
|
||||
/**
|
||||
* Minimal working `IAgentLifecycleService.fork` for spawn tests: mints
|
||||
* `agent-N` ids in order so the paired `mockSubagentService` summaries line
|
||||
* up. The run side is faked separately, so no context copying is needed.
|
||||
*/
|
||||
function mockLifecycleService(): IAgentLifecycleService {
|
||||
let minted = 0;
|
||||
const handles = new Map<string, IAgentScopeHandle>();
|
||||
return {
|
||||
_serviceBrand: undefined,
|
||||
onDidCreate: () => ({ dispose: () => undefined }),
|
||||
onDidDispose: () => ({ dispose: () => undefined }),
|
||||
create: () => Promise.reject(new Error('create is not used in spawn tests')),
|
||||
fork: (sourceAgentId: string, _opts?: unknown) => {
|
||||
if (sourceAgentId !== 'main') return Promise.reject(new Error(`unknown source ${sourceAgentId}`));
|
||||
const id = `agent-${String(minted++)}`;
|
||||
const handle = { id } as unknown as IAgentScopeHandle;
|
||||
handles.set(id, handle);
|
||||
return Promise.resolve(handle);
|
||||
},
|
||||
get: (agentId: string) => handles.get(agentId),
|
||||
list: () => [...handles.values()],
|
||||
broadcastPermissionMode: () => undefined,
|
||||
remove: (agentId: string) => {
|
||||
handles.delete(agentId);
|
||||
return Promise.resolve();
|
||||
},
|
||||
} as unknown as IAgentLifecycleService;
|
||||
}
|
||||
|
||||
function mockSubagentService(
|
||||
summaries: Record<string, string>,
|
||||
): ISessionSubagentService {
|
||||
return {
|
||||
_serviceBrand: undefined,
|
||||
hooks: { onWillStartAgentTask: { register: () => ({ dispose: () => undefined }) } },
|
||||
onDidStopAgentTask: () => ({ dispose: () => undefined }),
|
||||
run: async (agentId: string) => {
|
||||
const summary = summaries[agentId] ?? '';
|
||||
const controller = new AbortController();
|
||||
const handle: AgentRunHandle = {
|
||||
agentId,
|
||||
turn: {
|
||||
id: 1,
|
||||
signal: controller.signal,
|
||||
cancel: () => {
|
||||
controller.abort();
|
||||
return true;
|
||||
},
|
||||
ready: Promise.resolve(),
|
||||
result: Promise.resolve({ type: 'completed', steps: 0 } as never),
|
||||
},
|
||||
completion: Promise.resolve({ summary }),
|
||||
};
|
||||
return handle;
|
||||
},
|
||||
notifyAgentTaskStopped: () => undefined,
|
||||
} as unknown as ISessionSubagentService;
|
||||
}
|
||||
|
||||
function buildCompletionController() {
|
||||
let resolve!: (value: { summary: string }) => void;
|
||||
let reject!: (reason?: unknown) => void;
|
||||
const promise = new Promise<{ summary: string }>((res, rej) => {
|
||||
resolve = res;
|
||||
reject = rej;
|
||||
});
|
||||
return { promise, resolve, reject };
|
||||
}
|
||||
|
||||
describe('spine_spawn service', () => {
|
||||
beforeEach(() => {
|
||||
vi.stubEnv(MASTER_ENV, '0');
|
||||
vi.stubEnv(SPINE_ENV, '1');
|
||||
vi.stubEnv('KIMI_CODE_SPINE_SPAWN', '1');
|
||||
});
|
||||
afterEach(() => {
|
||||
vi.unstubAllEnvs();
|
||||
});
|
||||
|
||||
it('rejects spawn when it conflicts with another transition in the same step', async () => {
|
||||
const ctx = testAgent();
|
||||
const spine = ctx.get(IAgentSpineService);
|
||||
spine.acceptOpen('task A');
|
||||
const result = await spine.executeSpawn(
|
||||
[
|
||||
{ summary: 'branch A', prompt: 'do A' },
|
||||
{ summary: 'branch B', prompt: 'do B' },
|
||||
],
|
||||
new AbortController().signal,
|
||||
);
|
||||
expect(result.accepted).toBe(false);
|
||||
if (!result.accepted) {
|
||||
expect(result.reason).toContain('at most one Spine transition');
|
||||
}
|
||||
});
|
||||
|
||||
it('rejects a second spawn in the same step', async () => {
|
||||
const ctx = testAgent(
|
||||
sessionService(IAgentLifecycleService, mockLifecycleService()),
|
||||
sessionService(ISessionSubagentService, mockSubagentService({})),
|
||||
);
|
||||
const spine = ctx.get(IAgentSpineService);
|
||||
const first = await spine.executeSpawn(
|
||||
[
|
||||
{ summary: 'branch A', prompt: 'do A' },
|
||||
{ summary: 'branch B', prompt: 'do B' },
|
||||
],
|
||||
new AbortController().signal,
|
||||
);
|
||||
expect(first.accepted).toBe(true);
|
||||
const second = await spine.executeSpawn(
|
||||
[
|
||||
{ summary: 'branch C', prompt: 'do C' },
|
||||
{ summary: 'branch D', prompt: 'do D' },
|
||||
],
|
||||
new AbortController().signal,
|
||||
);
|
||||
expect(second.accepted).toBe(false);
|
||||
if (!second.accepted) {
|
||||
expect(second.reason).toContain('at most one Spine transition');
|
||||
}
|
||||
});
|
||||
|
||||
it('rejects all-or-nothing when capacity is unavailable', async () => {
|
||||
vi.stubEnv('KIMI_CODE_SPINE_SPAWN_MAX_THREADS', '3');
|
||||
const completions: ReturnType<typeof buildCompletionController>[] = [];
|
||||
const hangingSubagent: ISessionSubagentService = {
|
||||
_serviceBrand: undefined,
|
||||
hooks: { onWillStartAgentTask: { register: () => ({ dispose: () => undefined }) } },
|
||||
onDidStopAgentTask: () => ({ dispose: () => undefined }),
|
||||
run: async (agentId: string) => {
|
||||
const controller = new AbortController();
|
||||
const completion = buildCompletionController();
|
||||
completions.push(completion);
|
||||
return {
|
||||
agentId,
|
||||
turn: {
|
||||
id: 1,
|
||||
signal: controller.signal,
|
||||
cancel: () => {
|
||||
controller.abort();
|
||||
return true;
|
||||
},
|
||||
ready: Promise.resolve(),
|
||||
result: Promise.resolve({ type: 'completed', steps: 0 } as never),
|
||||
},
|
||||
completion: completion.promise,
|
||||
} as AgentRunHandle;
|
||||
},
|
||||
notifyAgentTaskStopped: () => undefined,
|
||||
} as unknown as ISessionSubagentService;
|
||||
|
||||
const ctx = testAgent(
|
||||
sessionService(IAgentLifecycleService, mockLifecycleService()),
|
||||
sessionService(ISessionSubagentService, hangingSubagent),
|
||||
);
|
||||
const spine = ctx.get(IAgentSpineService);
|
||||
|
||||
// Start the first batch but do not let it complete so activeSpawnBranches stays at 2.
|
||||
const firstPromise = spine.executeSpawn(
|
||||
[
|
||||
{ summary: 'branch A', prompt: 'do A' },
|
||||
{ summary: 'branch B', prompt: 'do B' },
|
||||
],
|
||||
new AbortController().signal,
|
||||
);
|
||||
await Promise.resolve();
|
||||
|
||||
// A second overlapping batch of two cannot fit under the limit of 2.
|
||||
const second = await spine.executeSpawn(
|
||||
[
|
||||
{ summary: 'branch C', prompt: 'do C' },
|
||||
{ summary: 'branch D', prompt: 'do D' },
|
||||
],
|
||||
new AbortController().signal,
|
||||
);
|
||||
expect(second.accepted).toBe(false);
|
||||
if (!second.accepted) {
|
||||
expect(second.reason).toContain('aggregate admission requested 2 child agents');
|
||||
expect(second.reason).toContain('all-or-nothing');
|
||||
expect(second.reason).toContain('KIMI_CODE_SPINE_SPAWN_MAX_THREADS');
|
||||
}
|
||||
|
||||
// Unblock the first batch and drain it.
|
||||
completions.forEach((c) => c.resolve({ summary: 'done' }));
|
||||
await firstPromise;
|
||||
});
|
||||
|
||||
it('produces a receipt that derive accepts and synthesizes closed nodes', async () => {
|
||||
const ctx = testAgent(
|
||||
sessionService(IAgentLifecycleService, mockLifecycleService()),
|
||||
sessionService(
|
||||
ISessionSubagentService,
|
||||
mockSubagentService({
|
||||
'agent-0': 'memory A',
|
||||
'agent-1': 'memory B',
|
||||
}),
|
||||
),
|
||||
);
|
||||
const spine = ctx.get(IAgentSpineService);
|
||||
const result = await spine.executeSpawn(
|
||||
[
|
||||
{ summary: 'branch A', prompt: 'do A' },
|
||||
{ summary: 'branch B', prompt: 'do B' },
|
||||
],
|
||||
new AbortController().signal,
|
||||
);
|
||||
expect(result.accepted).toBe(true);
|
||||
expect(result.receipt).toBeDefined();
|
||||
const receipt = JSON.parse(result.receipt!);
|
||||
expect(receipt.schema).toBe('spine.spawn.result.v1');
|
||||
expect(receipt.results).toHaveLength(2);
|
||||
expect(receipt.results[0]).toMatchObject({ ordinal: 0, outcome: 'completed', memory_body: 'memory A' });
|
||||
expect(receipt.results[1]).toMatchObject({ ordinal: 1, outcome: 'completed', memory_body: 'memory B' });
|
||||
|
||||
// Simulate the receipt landing in contextMemory and assert derive picks it up.
|
||||
ctx.get(IAgentContextMemoryService).append(
|
||||
assistantSpineCall('call_spawn', 'spine_spawn', {
|
||||
tasks: [
|
||||
{ summary: 'branch A', prompt: 'do A' },
|
||||
{ summary: 'branch B', prompt: 'do B' },
|
||||
],
|
||||
}),
|
||||
{
|
||||
role: 'tool',
|
||||
content: [{ type: 'text', text: result.receipt! }],
|
||||
toolCallId: 'call_spawn',
|
||||
isError: false,
|
||||
} as ContextMessage,
|
||||
);
|
||||
|
||||
const state = readSpine(ctx);
|
||||
expect(state.nodes['1.1.1']?.summary).toBe('branch A');
|
||||
expect(state.nodes['1.1.1']?.memory).toBe('memory A');
|
||||
expect(state.nodes['1.1.1']?.closedAt).toBeDefined();
|
||||
expect(state.nodes['1.1.2']?.summary).toBe('branch B');
|
||||
expect(state.nodes['1.1.2']?.memory).toBe('memory B');
|
||||
expect(state.nodes['1.1.2']?.closedAt).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue