/** * Pure helpers for AgentSession reporting and export. * * These functions derive statistics, context-usage, forkable user messages, and * JSONL exports from session state without touching the live agent or extension * runner. AgentSession delegates to them so the class stays focused on lifecycle * and event wiring. */ import type { AgentMessage } from "@kolisachint/hoocode-agent-core"; import type { Model } from "@kolisachint/hoocode-ai"; import type { ContextUsage } from "./extensions/index.js"; import type { SessionEntry, SessionManager } from "./session-manager.js"; /** Session statistics for /session command */ export interface SessionStats { sessionFile: string | undefined; sessionId: string; userMessages: number; assistantMessages: number; toolCalls: number; toolResults: number; totalMessages: number; tokens: { input: number; output: number; cacheRead: number; cacheWrite: number; total: number; }; cost: number; contextUsage?: ContextUsage; } /** Token + cost totals accumulated across a session's assistant messages. */ export interface AssistantUsageTotals { input: number; output: number; cacheRead: number; cacheWrite: number; cost: number; } /** * Sum token + cost usage over every assistant message in a set of session * entries. Shared by the footer (cumulative session vitals) and the per-request * cost line the transcript emits at agent_end, which diffs two snapshots of this * against each other — one source of truth, so the two can never disagree about * what a request cost. */ export declare function sumAssistantUsage(entries: readonly SessionEntry[]): AssistantUsageTotals; /** Extract concatenated text from a user message content value. */ export declare function extractUserMessageText(content: string | Array<{ type: string; text?: string; }>): string; /** Compute aggregate statistics (message counts, token usage, cost) for a session. */ export declare function computeSessionStats(params: { messages: AgentMessage[]; sessionFile: string | undefined; sessionId: string; contextUsage: ContextUsage | undefined; }): SessionStats; /** * Estimate current context-window usage. * * After compaction, the last assistant usage reflects pre-compaction context * size, so usage is only trusted from an assistant that responded after the * latest compaction boundary. When no such assistant exists yet, tokens are * reported as null (unknown until the next LLM response). */ export declare function computeContextUsage(params: { model: Model | undefined; sessionManager: SessionManager; messages: AgentMessage[]; }): ContextUsage | undefined; /** Collect all user messages on the session (for the fork selector). */ export declare function collectUserMessagesForForking(sessionManager: SessionManager): Array<{ entryId: string; text: string; }>; /** * Get the text content of the last non-empty assistant message (for /copy). * Returns undefined if no assistant message with text exists. */ export declare function getLastAssistantText(messages: AgentMessage[]): string | undefined; /** How much of a session a copy takes. */ export interface TranscriptSelection { /** * Exchanges to take, counting back from the newest. Undefined takes the lot. * An "exchange" starts at a user message and runs to the next one. */ turns?: number; /** Label for the user's messages; the agent's is the app's name. */ userLabel?: string; /** Label for the agent's messages. */ agentLabel?: string; } /** * The conversation as markdown, for the clipboard and for a file. * * ## Why not what is on screen * * What the terminal shows is markdown already *rendered*: a table is box * drawing, a code block is a bordered panel, every line is hard-wrapped to the * width the window happened to be. Selecting that with the mouse and pasting it * somewhere gives you a picture of a conversation — dotted rules and broken * table edges — because a terminal's clipboard carries glyphs and nothing else. * The structure the user wanted is in the source the model wrote, which is what * this returns. * * ## What is in it * * The conversation: what was asked and what was answered, each under a heading * so a reader can find the turn they came for. Tool calls are left out. They * are the agent's working, they are the bulk of a long session by a wide * margin, and nobody has ever pasted a file-read into a document on purpose — * `/export` is there for the whole record, including the parts this drops. */ export declare function sessionToMarkdown(messages: AgentMessage[], selection?: TranscriptSelection): string; /** * Export the current session branch to a JSONL file. * Writes the session header followed by all entries on the current branch path, * re-chaining parentIds into a linear sequence. * @returns The resolved output file path. */ export declare function exportSessionBranchToJsonl(sessionManager: SessionManager, outputPath?: string): string; //# sourceMappingURL=agent-session-stats.d.ts.map