/** * Session usage / cost / stats accounting, context-window usage, and session export. * * Extracted verbatim from agent-session.ts (god-file decomposition). Read-only over the session * except for its two owned memo caches (`_spawnedUsageCache`, `_dailyUsageCache`) — it never mutates * agent or session state. Single source of truth for "how much did this session and its spawned * subtree spend" (footer roll-up, print-mode child reporting), the daily cross-session totals, the * /context window estimate, and HTML/JSONL export of the current branch. */ import { type SessionManager } from "@caupulican/pi-agent-core/session"; import type { AgentMessage, AgentState } from "@caupulican/pi-agent-core/types"; import type { Model, Usage } from "@caupulican/pi-ai"; import { type SessionStats, type SpawnedUsageTotals } from "./agent-session-contracts.ts"; import { type SessionCostSummary } from "./cost/cost-summary.ts"; import { type DailyUsageTotals } from "./cost/daily-usage.ts"; import type { ContextUsage, ToolDefinition } from "./extensions/index.ts"; import type { SettingsManager } from "./settings-manager.ts"; import { type ToolArgumentValidationLogRecord } from "./tool-recovery-log-records.ts"; import { type ToolArgumentValidationStats } from "./tool-recovery-stats.ts"; export declare const TOOL_ARGUMENT_VALIDATION_CUSTOM_TYPE = "tool_argument_validation"; export interface SessionAnalyticsDeps { /** Live agent state — assistant-message usage and message counts are read from here. */ getState(): AgentState; /** All messages (agent state view) — used for context-window estimation and last-assistant text. */ getMessages(): AgentMessage[]; /** Current session model — its context window bounds the /context estimate. */ getModel(): Model | undefined; /** Session log — entries feed spawned-usage roll-up, daily totals, branch export. */ getSessionManager(): SessionManager; /** Settings — the export theme is read here. */ getSettingsManager(): SettingsManager; /** Resolve a tool definition for the HTML export's custom-tool renderer. */ getToolDefinition(name: string): ToolDefinition | undefined; /** Sidecar recovery telemetry log; read on demand so turn handling never writes session custom entries. */ getToolRecoveryEventLogPath(): string; } export declare class SessionAnalytics { /** Incremental aggregate over append-ordered session entries. */ private _currentSessionCostCache?; /** Memoized daily usage totals with a short TTL, keyed by the resolved scope dir and local-day window. */ private _dailyUsageCache?; /** Memoized full cost summary. The footer renders on every streamed delta and keystroke, so * rescanning a long session log there turns redraw into O(entries) work per frame. */ private _costSummaryCache?; /** Cumulative stats initialized once from persisted telemetry, then updated without retaining record details. */ private _toolArgumentValidationStats; /** Incremental context-usage state keyed by the append-only branch leaf. */ private _postCompactionUsageCache?; private readonly deps; constructor(deps: SessionAnalyticsDeps); getSessionStats(): SessionStats; getCompactionGateStats(): SessionStats["compactionGates"]; recordToolArgumentValidation(record: ToolArgumentValidationLogRecord): void; private readToolArgumentValidationSidecarRecords; getToolArgumentValidationStats(): ToolArgumentValidationStats; /** * Cumulative usage (full breakdown) for this session's entire spawn subtree: its own * assistant messages PLUS every `spawned_usage` report it has rolled up. Single source of * truth for "how much did this session and everything it spawned spend" — used by print-mode * to emit a child's total so a spawner can roll it up via {@link addSpawnedUsage}. * * Including the `spawned_usage` reports is what keeps the single-hop invariant intact: a child * that itself spawned grandchildren must report own + sub-usage in one number, or the parent * silently under-counts the grandchildren. */ getCumulativeUsage(): Usage; /** * Record usage spent by a spawned/subagent session so the footer can roll it into the * displayed cost. Persisted as a `CustomEntry` (`customType: "spawned_usage"`, Model A) so * it survives reload and is reconstructed exactly like main usage; a new/forked session * starts fresh because it owns a new log file. * * Idempotent on `opts.reportId`: a re-report (retry, duplicate `agent_end`) with a * previously-seen id is ignored, so cost cannot be double-counted. Honors the single-hop * invariant documented on {@link SpawnedUsageReport}. * * @returns the id of the appended entry, or `undefined` if the report was a duplicate. */ addSpawnedUsage(usage: Usage, opts?: { label?: string; sourceSessionId?: string; reportId?: string; }): string | undefined; private getCurrentSessionCostTotals; /** * Aggregate all recorded spawned-usage reports (see {@link addSpawnedUsage}). The append-ordered * accumulator processes only new entries, so repeated turns do not rescan the full session. */ getSpawnedUsage(): SpawnedUsageTotals; getCostSummary(now?: Date): SessionCostSummary; getDailyUsageTotals(now?: Date): DailyUsageTotals; getDailyUsageBreakdown(formatLabel?: (label: string) => string, now?: Date): string; private getPostCompactionUsageState; getContextUsage(): ContextUsage | undefined; /** * Export session to HTML. * @param outputPath Optional output path (defaults to session directory) * @returns Path to exported file */ exportToHtml(outputPath?: string): Promise; /** * Export the current session branch to a JSONL file. * Writes the session header followed by all entries on the current branch path. * @param outputPath Target file path. If omitted, generates a timestamped file in cwd. * @returns The resolved output file path. */ exportToJsonl(outputPath?: string): string; /** * Get text content of last assistant message. * Useful for /copy command. * @returns Text content, or undefined if no assistant message exists */ getLastAssistantText(): string | undefined; } //# sourceMappingURL=session-analytics.d.ts.map