import { type ToolCallRequest } from "../statelog/wireAccessors.js"; import { type HistoryRewrite, type WireMessage } from "./messageDelta.js"; import { type HostedStoryRow, type StoryRow, type ToolStoryRow, type Interrupt } from "./story.js"; import { type TraceError } from "./problems.js"; import { type Round, type ThreadKey } from "./timeline/rounds.js"; import { type Turn } from "./timeline/turns.js"; import type { TreeNode } from "./types.js"; /** `at` orders blocks by the time of the event each one comes from, so an * error block lands where the error happened and not at a round's end. */ type BlockBase = { id: string; roundId: string | undefined; thread: ThreadKey; at: number; /** The thread's name, as `Round.threadLabel` gives it; undefined reads as `unnamed`. */ threadLabel: string | undefined; /** How many tool calls deep the thread was started: the call list indents by it. */ depth: number; /** The `llmCall` spans the block is inside, outermost first, as the * trace groups them: the top-level conversation, then the sub-agent's * thread under its tool, and so on. A fold on a group hides every block * whose path holds it. */ groupPath: string[]; }; export type TranscriptBlock = BlockBase & ({ kind: "system"; text: string; /** The LLM call that first carried this prompt. `roundId` stays * undefined on a system block, because the screen reads it to * decide focus; this field is for finding the block's row. */ ownerRoundId: string; } /** A thread group, one per `llmCall` span, named as the trace names * it: `calls` counts the span's own LLM calls, `tool` is the tool * that started it (undefined for a top-level thread), and `complete` * is the trace's fold rule for it. Its id is `group:`. */ | { kind: "thread"; label: string; calls: number; tool: string | undefined; complete: boolean; } /** A message the person sent, when the trace has more than one. The * wait before it is the end of the previous turn. */ | { kind: "turn"; turn: Turn; waitedMs: number | undefined; } | { kind: "error"; error: TraceError; } | { kind: "pause"; pausedMs: number | undefined; resumed: boolean; } /** A user-role message. `promptTo` names who the program wrote it for * (the tool whose body made the call, else the thread), for a message * the program composed; undefined for one the person sent. */ | { kind: "user"; text: string; promptTo: string | undefined; } /** The user-role message the runtime pushes when a handoff returns: * `[name finished. …]` or `[name stopped before finishing: …]`. */ | { kind: "handback"; tool: string; text: string; } | { kind: "history"; message: WireMessage; text: string; } | { kind: "assistant"; round: Round; text: string | undefined; structured: unknown | undefined; message: WireMessage | undefined; /** Requests no tool block stands for, such as a tool the runtime * never ran; the block shows these itself. */ unpaired: ToolCallRequest[]; } | { kind: "tool"; row: ToolStoryRow; interrupts: Interrupt[]; output: string | undefined; outputLines: number; /** The tool message the model read when it differs from the * recorded output: a capped result, or an error with the loop's * advice appended. Set once the next round's input shows it. */ modelSaw: string | undefined; } /** A tool the provider ran inside the round, such as its web search. * The model read its result inside the call, so no message holds it. */ | { kind: "hosted"; row: HostedStoryRow; } | ({ kind: "rewrite"; label: "CONTEXT COMPACTED" | "HISTORY CHANGED"; } & HistoryRewrite)); export declare function threadKey(thread: ThreadKey): string; /** Whether an input message is one already shown. Equal keys match. So * does an assistant message that kept a completion's text and lost some * of its tool calls, which is what a handoff leaves in the caller's * history in place of the call that dispatched it. A tool reply matches * the tool it answers by call id whatever its content, since the content * the model read is laid beside the tool block instead. */ export declare function represents(shown: WireMessage, message: WireMessage): boolean; /** The tool a handoff's hand-back message names, or undefined. */ export declare function handBackTool(text: string): string | undefined; /** A trace's transcript, with the story outline it was built from, so a * caller that maps blocks to rows (`blockRowId`) reuses it. */ export type Transcript = { blocks: TranscriptBlock[]; story: StoryRow[]; }; export declare function transcriptBlocks(trace: TreeNode): TranscriptBlock[]; export declare function transcriptOf(trace: TreeNode): Transcript; /** The story row a block stands for, or undefined for a block with no * row. `roundUser` falls back to the call when the outline has no user * row for it. Ids are looked up in `story`, never parsed (see "Row IDs * are a contract" in docs/dev/cli/logs-viewer.md). The transcript * screen's `A` and `agency logs search` both use this. */ export declare function blockRowId(block: TranscriptBlock, story: readonly StoryRow[]): string | undefined; export declare function messageText(message: WireMessage): string; export declare function transcriptText(block: TranscriptBlock): string; export {};