{"version":3,"sources":["../../src/log/types.ts","../../src/log/view.ts"],"names":["i"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * The Call Log — envelope + closed vocabulary (CALL_LOG_SPEC.md §1, §2).\n *\n * ─────────────────────────────────────────────────────────────────────────\n * WIRE SHAPE. This module speaks the WIRE, verbatim.\n *\n * Envelope keys are exactly the seven of spec §1 (`seq`, `ts`, `call`,\n * `agent`, `type`, `ephemeral`, `data`) and every key INSIDE `data` is\n * snake_case, exactly as the server appends it. There is deliberately NO\n * codec in the path: the server emits an envelope, the browser applies that\n * same envelope, and `GET /v1/calls/{id}/events` returns the same bytes\n * during the call and after it (spec §10.4). A camelCase translation layer\n * would make \"identical\" a claim about a transform rather than about bytes.\n *\n * `src/protocol/events.ts` (camelCase, legacy SDK surface) is a DIFFERENT,\n * frozen vocabulary and stays untouched — see spec §8.\n * ─────────────────────────────────────────────────────────────────────────\n *\n * ZERO DEPENDENCIES. Nothing under `src/log/**` imports anything outside\n * itself. The `@pinecall/sdk` root entrypoint pulls in `ws` and node\n * builtins; the `./log` subpath must be usable from a browser bundle, so\n * the isolation is enforced by a test (`tests/log-browser-safe.test.ts`).\n *\n * FORWARD COMPATIBILITY. Unknown `type`s MUST be ignored (§1). The unions\n * below are closed for what a consumer may *rely* on, not for what may\n * arrive: `AnyLogEntry` therefore admits an unknown-type arm, and the\n * reducer's switch is exhaustive over the known arms.\n */\n\nimport type { LogGapSnapshot } from \"./view.js\";\n\n// ── §1 The envelope ──────────────────────────────────────────────────────\n\n/** Every fact a session produces becomes exactly one of these. */\nexport interface LogEntry<T extends LogEventType = LogEventType, D = LogData<T>> {\n    /**\n     * Monotonic per call, assigned only at the append point. The cursor AND\n     * the dedupe key. May have holes after compaction — never assume\n     * contiguity; \"caught up\" is signalled by `log.caught_up`, never inferred.\n     */\n    seq: number;\n    /** Server wall clock, float seconds. */\n    ts: number;\n    /** Call id. `null` on the agent's lifecycle-only log (§2, \"The agent log\"). */\n    call: string | null;\n    /** Agent id. */\n    agent: string;\n    /** One vocabulary (§2). No per-channel dialects. */\n    type: T;\n    /** `true` → delivered live, never persisted (§4). */\n    ephemeral: boolean;\n    /** Type-specific payload (§2). Additive-only per type. */\n    data: D;\n}\n\n// ── §2 The vocabulary — data payloads ────────────────────────────────────\n\nexport type CallDirection = \"inbound\" | \"outbound\";\n\n/** `call.ringing` — outbound: exists before pickup. */\nexport interface CallRingingData {\n    direction: CallDirection;\n    from: string;\n    to: string;\n}\n\n/** `call.started` — `metadata` is the sealed token metadata. */\nexport interface CallStartedData {\n    direction: CallDirection;\n    from: string;\n    to: string;\n    channel: string;\n    metadata?: Record<string, unknown>;\n}\n\n/** `call.ended` */\nexport interface CallEndedData {\n    reason: string;\n    duration: number;\n}\n\n/** One latency distribution inside `call.summary`. */\nexport interface MetricDistribution {\n    p50: number;\n    p90: number;\n    p95: number;\n    max: number;\n    n: number;\n}\n\nexport interface CallSummaryMetrics {\n    e2e: MetricDistribution;\n    asr: MetricDistribution;\n    llm_ttft: MetricDistribution;\n    tts_ttfb: MetricDistribution;\n}\n\n/** `call.summary` — ALWAYS the last entry. History needs no second API. */\nexport interface CallSummaryData {\n    metrics: CallSummaryMetrics;\n    cost?: number;\n    reason: string;\n    /** Recordings are referenced, never embedded (§8). */\n    recording_url?: string;\n}\n\n/** `user.speaking` — ephemeral. */\nexport interface UserSpeakingData {\n    active: boolean;\n}\n\n/** `user.message` — partials ephemeral, finals persisted. */\nexport interface UserMessageData {\n    id: string;\n    text: string;\n    final: boolean;\n    language?: string;\n}\n\n/** One word of TTS alignment, carried INSIDE `bot.speaking`. */\nexport interface WordTiming {\n    w: string;\n    t0: number;\n    t1: number;\n}\n\n/** `bot.speaking` — word alignment inside the event when TTS provides it. */\nexport interface BotSpeakingData {\n    id: string;\n    text: string;\n    words?: WordTiming[];\n}\n\n/** `bot.word` — ephemeral; live typing effect only. */\nexport interface BotWordData {\n    id: string;\n    w: string;\n}\n\n/** `bot.finished` */\nexport interface BotFinishedData {\n    id: string;\n}\n\n/** `bot.interrupted` */\nexport interface BotInterruptedData {\n    id: string;\n    at_word?: number;\n}\n\n/**\n * `bot.corrected` — the transcript self-heals. An EVENT, not a mutation:\n * consumers replace the text of the entry named by `supersedes`.\n */\nexport interface BotCorrectedData {\n    supersedes: number;\n    id: string;\n    text: string;\n}\n\nexport type TurnRole = \"user\" | \"bot\";\n\n/** `turn.start` */\nexport interface TurnStartData {\n    turn: number;\n    role: TurnRole;\n}\n\n/** Per-turn latency is first-class. */\nexport interface TurnLatency {\n    vad: number;\n    asr: number;\n    eou: number;\n    llm_ttft: number;\n    tts_ttfb: number;\n    e2e: number;\n}\n\n/** `turn.end` */\nexport interface TurnEndData {\n    turn: number;\n    latency: TurnLatency;\n}\n\n/** `tool.call` — reaches EVERY audience, correlated with `tool.result` by `id`. */\nexport interface ToolCallData {\n    id: string;\n    name: string;\n    /** Providers send either a parsed object or a JSON string. Both are legal. */\n    args: Record<string, unknown> | string;\n}\n\n/** `tool.result` */\nexport interface ToolResultData {\n    id: string;\n    name: string;\n    result: unknown;\n    ms: number;\n    error?: string;\n}\n\n/** `docs.sources` — RAG citations. */\nexport interface DocsSourcesData {\n    sources: unknown[];\n}\n\n/** `skill.loaded` / `skill.unloaded` */\nexport interface SkillData {\n    skill: string;\n    by: string;\n}\n\n/** `audio.metrics` — ephemeral; rolled up into `call.summary`. */\nexport interface AudioMetricsData {\n    mos?: number;\n    jitter?: number;\n    loss?: number;\n    [k: string]: unknown;\n}\n\n/** `handoff.requested` / `handoff.active` / `handoff.released` */\nexport interface HandoffData {\n    by: string;\n}\n\n/** `supervisor.said` / `supervisor.whispered` — audit trail of the §7 verbs. */\nexport interface SupervisorData {\n    text: string;\n    by: string;\n}\n\n/**\n * `log.gap` (§3, anti-Slack rule) — a gap is DECLARED, never silently\n * papered over. `snapshot` is consolidated call state so the consumer can\n * render immediately and continue from `resume_from`.\n */\nexport interface LogGapData {\n    from: number;\n    resume_from: number;\n    /** Consolidated state — see `LogGapSnapshot` in view.ts for the exact keys. */\n    snapshot?: LogGapSnapshot;\n}\n\n/** `log.caught_up` (§5) — backlog drained, live entries follow. */\nexport interface LogCaughtUpData {\n    seq: number;\n}\n\n/**\n * `custom` — the one open extension point: `call.log(name, value)`. The\n * reducer never interprets `value`; it projects the latest value per\n * `(name, id)` into `state.custom` (upsert — the wire itself stays\n * append-only). Ephemeral ones are fanned out live and never stored.\n */\nexport interface CustomData {\n    name: string;\n    value: unknown;\n    /** Upsert key in the projection; absent → the entry's seq. */\n    id?: string;\n    /** Server-stamped turn id, when the session has turns. */\n    turn?: number;\n}\n\n// ── The closed type union ────────────────────────────────────────────────\n\n/**\n * The complete vocabulary. A fact that does not fit one of these is a\n * finding to report, not a new type to mint.\n */\nexport interface LogDataMap {\n    \"call.ringing\": CallRingingData;\n    \"call.started\": CallStartedData;\n    \"call.ended\": CallEndedData;\n    \"call.summary\": CallSummaryData;\n    \"user.speaking\": UserSpeakingData;\n    \"user.message\": UserMessageData;\n    \"bot.speaking\": BotSpeakingData;\n    \"bot.word\": BotWordData;\n    \"bot.finished\": BotFinishedData;\n    \"bot.interrupted\": BotInterruptedData;\n    \"bot.corrected\": BotCorrectedData;\n    \"turn.start\": TurnStartData;\n    \"turn.end\": TurnEndData;\n    \"tool.call\": ToolCallData;\n    \"tool.result\": ToolResultData;\n    \"docs.sources\": DocsSourcesData;\n    \"skill.loaded\": SkillData;\n    \"skill.unloaded\": SkillData;\n    \"audio.metrics\": AudioMetricsData;\n    \"handoff.requested\": HandoffData;\n    \"handoff.active\": HandoffData;\n    \"handoff.released\": HandoffData;\n    \"supervisor.said\": SupervisorData;\n    \"supervisor.whispered\": SupervisorData;\n    \"log.gap\": LogGapData;\n    \"log.caught_up\": LogCaughtUpData;\n    \"custom\": CustomData;\n}\n\n/** Every legal `type` value. Closed — see §2. */\nexport type LogEventType = keyof LogDataMap;\n\n/** The payload that belongs to a given `type`. */\nexport type LogData<T extends LogEventType> = LogDataMap[T];\n\n/** The discriminated union of all known entries — what the reducer switches on. */\nexport type KnownLogEntry = {\n    [T in LogEventType]: LogEntry<T, LogDataMap[T]>;\n}[LogEventType];\n\n/**\n * An entry as it arrives off the wire: either a known one, or one whose\n * `type` this SDK version has never heard of. §1 requires the latter be\n * ignored rather than rejected, so it is part of the input type.\n */\nexport type UnknownLogEntry = Omit<LogEntry<LogEventType, unknown>, \"type\"> & {\n    type: string;\n};\n\nexport type AnyLogEntry = KnownLogEntry | UnknownLogEntry;\n\n/** The set of `type` values this build understands. */\nexport const LOG_EVENT_TYPES: readonly LogEventType[] = [\n    \"call.ringing\",\n    \"call.started\",\n    \"call.ended\",\n    \"call.summary\",\n    \"user.speaking\",\n    \"user.message\",\n    \"bot.speaking\",\n    \"bot.word\",\n    \"bot.finished\",\n    \"bot.interrupted\",\n    \"bot.corrected\",\n    \"turn.start\",\n    \"turn.end\",\n    \"tool.call\",\n    \"tool.result\",\n    \"docs.sources\",\n    \"skill.loaded\",\n    \"skill.unloaded\",\n    \"audio.metrics\",\n    \"handoff.requested\",\n    \"handoff.active\",\n    \"handoff.released\",\n    \"supervisor.said\",\n    \"supervisor.whispered\",\n    \"log.gap\",\n    \"log.caught_up\",\n    \"custom\",\n] as const;\n\nconst KNOWN = new Set<string>(LOG_EVENT_TYPES);\n\n/** Narrow an off-the-wire entry to the known vocabulary. */\nexport function isKnownLogEntry(entry: AnyLogEntry): entry is KnownLogEntry {\n    return KNOWN.has(entry.type);\n}\n\n/**\n * Structural check for the §1 envelope. Anything that fails this is not a\n * log entry and must not be fed to a view.\n */\nexport function isLogEntry(value: unknown): value is AnyLogEntry {\n    if (typeof value !== \"object\" || value === null) return false;\n    const v = value as Record<string, unknown>;\n    return (\n        typeof v.seq === \"number\" &&\n        typeof v.ts === \"number\" &&\n        typeof v.type === \"string\" &&\n        typeof v.agent === \"string\" &&\n        (typeof v.call === \"string\" || v.call === null)\n    );\n}\n","/**\n * CallLogView — THE reducer (CALL_LOG_SPEC.md §6).\n *\n * \"Client SDKs maintain ONE reducer (log → {phase, messages, toolCalls,\n * turns, metrics}) fed by any pipe, deduped by seq.\"\n *\n * This is the whole point of the module: WS attach, WebRTC DataChannel, GET\n * polling and replay are four pipes carrying one envelope, and they must\n * land on one piece of state-building code. A second reducer would be a\n * second vocabulary in disguise.\n *\n * ── Semantics ────────────────────────────────────────────────────────────\n * Ported from the proven `VoiceSession.handleDataChannelMessage` switch\n * (@pinecall/web, src/core/VoiceSession.ts:303-502) — word reassembly,\n * `mergeUserTurn` interim merging, tool-argument parsing — with four\n * deliberate corrections:\n *\n *   1. NO transport coupling and no `trackedTools` filter. The view exposes\n *      every tool call; a UI that wants a subset filters at render time.\n *      Filtering during reduction makes the state depend on widget config.\n *   2. NO `disconnect()` back-edge. VoiceSession called `this.disconnect()`\n *      from inside the switch (:418) — a reducer reaching into a socket.\n *      Here, terminal facts produce an *intent* on the state; the owner of\n *      the transport decides what to do about it.\n *   3. Duration is derived from entry `ts`, never from wall clock, so a\n *      replay of a finished call reproduces the same state as watching it\n *      live (§10.5).\n *   4. `phase` gains \"ended\", and `bot.corrected` REPLACES the text of the\n *      entry it supersedes (§2) rather than appending a second bubble.\n *\n * ── Idempotence and order independence ───────────────────────────────────\n * `apply()` is idempotent by `seq` and independent of arrival order. It is\n * not a naive running fold: entries are retained in a seq-keyed map and the\n * state is the fold over them in seq order. Applying an entry newer than\n * everything seen (the live case) folds incrementally in O(1); an\n * out-of-order or backfilled entry rebuilds, which is what correctness\n * costs and what makes in-order === shuffled === resumed.\n *\n * ── Immutability ─────────────────────────────────────────────────────────\n * State is produced by structural sharing, never by mutation: an apply\n * yields a new state object, new arrays, and new objects for exactly the\n * entries it changed. Reference equality on a message therefore MEANS \"this\n * line did not change\" — the contract a memoized transcript line depends on.\n */\n\nimport type {\n    AnyLogEntry,\n    CallSummaryData,\n    KnownLogEntry,\n    TurnLatency,\n    TurnRole,\n    WordTiming,\n} from \"./types.js\";\nimport { isKnownLogEntry, isLogEntry } from \"./types.js\";\n\n// ── State ────────────────────────────────────────────────────────────────\n\nexport type CallPhase =\n    | \"idle\"\n    | \"ringing\"\n    | \"listening\"\n    | \"thinking\"\n    | \"speaking\"\n    | \"ended\";\n\nexport type MessageRole = \"user\" | \"bot\" | \"system\";\n\n/** One transcript bubble. `seq` is the entry that created it — `bot.corrected.supersedes` points here. */\nexport interface CallMessage {\n    /** The seq of the entry that created this message. Stable identity. */\n    seq: number;\n    role: MessageRole;\n    text: string;\n    /** Provider message id (`user.message.id`, `bot.speaking.id`, …). */\n    id?: string;\n    /** True while a non-final `user.message` is the latest word on this turn. */\n    interim?: boolean;\n    /** True between `bot.speaking` and `bot.finished`/`bot.interrupted`. */\n    speaking?: boolean;\n    interrupted?: boolean;\n    /** Set on the system bubble that mirrors a `tool.call`. */\n    toolCallId?: string;\n    /** Word alignment when TTS provided it (`bot.speaking.words`). */\n    words?: WordTiming[];\n    /** True once a `bot.corrected` entry replaced this text. */\n    corrected?: boolean;\n}\n\nexport interface CallToolCall {\n    id: string;\n    name: string;\n    args: Record<string, unknown>;\n    /** seq of the `tool.call` entry. */\n    seq: number;\n    /** Present once the correlated `tool.result` arrives. */\n    result?: unknown;\n    ms?: number;\n    error?: string;\n    done: boolean;\n}\n\nexport interface CallTurn {\n    turn: number;\n    role?: TurnRole;\n    latency?: TurnLatency;\n    startedAt?: number;\n    endedAt?: number;\n}\n\nexport interface CallMetrics {\n    /** Rolled-up distributions, present once `call.summary` lands. */\n    summary?: CallSummaryData[\"metrics\"];\n    cost?: number;\n    recordingUrl?: string;\n    /** Mean end-to-end latency over the `turn.end` entries seen so far. */\n    e2eMean?: number;\n    turnCount: number;\n}\n\n/**\n * Something the log says should happen to the transport, surfaced instead of\n * done. Correction #2 above: the reducer never touches a socket.\n */\nexport interface CallIntent {\n    kind: \"disconnect\";\n    reason: string;\n    seq: number;\n}\n\n/**\n * One row of `state.custom`: the latest value per `(name, id)`, in first-seen\n * order. The wire stays append-only — every `call.log()` is its own entry\n * with its own seq — the upsert is a projection of this reducer only.\n */\nexport interface CallCustomEntry<V = unknown> {\n    name: string;\n    /** `data.id ?? String(seq)` — the upsert key together with `name`. */\n    id: string;\n    value: V;\n    /** seq of the entry that LAST set this value. */\n    seq: number;\n    ts: number;\n    /** Server-stamped turn id, when the session has turns. */\n    turn?: number;\n}\n\nexport interface CallLogState {\n    phase: CallPhase;\n    messages: CallMessage[];\n    toolCalls: CallToolCall[];\n    turns: CallTurn[];\n    metrics: CallMetrics;\n    /** False once `call.ended` is applied. */\n    live: boolean;\n    /** Highest seq applied. The cursor to resume from (`after=`). */\n    lastSeq: number;\n    /** Call id, from the first entry that carried one. */\n    call: string | null;\n    agent: string | null;\n    /** Seconds, derived from entry `ts` — never from wall clock. */\n    duration: number;\n    /** True after `log.caught_up`; never inferred from contiguity (§1). */\n    caughtUp: boolean;\n    /** Declared gaps (§3). Never silently papered over. */\n    gaps: { from: number; resumeFrom: number }[];\n    userSpeaking: boolean;\n    botSpeaking: boolean;\n    /** Reason from `call.ended`, if any. */\n    endedReason?: string;\n    /** Human takeover state (`handoff.*`). */\n    handoff: \"none\" | \"requested\" | \"active\";\n    /** Skills currently loaded (`skill.loaded` / `skill.unloaded`). */\n    skills: string[];\n    /** Latest RAG citations (`docs.sources`). */\n    sources: unknown[];\n    /** Things the log asked the transport to do (§ correction #2). */\n    intents: CallIntent[];\n    /** Durable `custom` entries, upserted by (name, id). Ephemeral ones never land here. */\n    custom: CallCustomEntry[];\n}\n\nfunction emptyState(): CallLogState {\n    return {\n        phase: \"idle\",\n        messages: [],\n        toolCalls: [],\n        turns: [],\n        metrics: { turnCount: 0 },\n        live: true,\n        lastSeq: 0,\n        call: null,\n        agent: null,\n        duration: 0,\n        caughtUp: false,\n        gaps: [],\n        userSpeaking: false,\n        botSpeaking: false,\n        handoff: \"none\",\n        skills: [],\n        sources: [],\n        intents: [],\n        custom: [],\n    };\n}\n\n/**\n * What a `log.gap` carries in `data.snapshot` — the consolidated state of\n * everything the server could still see when it declared the gap, so a\n * client lands with a populated view instead of an empty one (§3, ag-ui\n * \"For Pinecall\" 5 and 9). This is the wire contract between\n * `calls_api._snapshot()` and `CallLogView`: the server emits exactly these\n * keys, the reducer hydrates exactly these fields.\n *\n * Rows reuse the reducer's own row types, so hydration is a keyed merge\n * rather than a second fold: `messages` by `seq` (bot bubbles by `id`),\n * `tool_calls` by `id`, `turns` by `turn`, `custom` by `(name, id)`.\n * Scalars are values — the snapshot's word wins. Every key is optional: a\n * missing key leaves the local state untouched, and an unknown key is\n * ignored (§1 forward compatibility).\n *\n * Not carried, by design: `metrics.summary`/`cost` (only `call.summary` sets\n * them, and it is never skipped — a sealed cursor answers 204), `intents`\n * (transport asks, not call facts) and the `log.*` control state.\n */\nexport interface LogGapSnapshot {\n    phase?: CallPhase;\n    live?: boolean;\n    /** ts of `call.started` — the duration anchor. */\n    started_at?: number | null;\n    ended_reason?: string;\n    user_speaking?: boolean;\n    bot_speaking?: boolean;\n    handoff?: CallLogState[\"handoff\"];\n    skills?: string[];\n    sources?: unknown[];\n    messages?: CallMessage[];\n    tool_calls?: CallToolCall[];\n    turns?: CallTurn[];\n    custom?: CallCustomEntry[];\n}\n\n/**\n * Project a state into the snapshot a `log.gap` would carry for it — the\n * inverse of hydration. The golden test feeds `snapshotOf(prefix)` into a\n * gap and asserts the result equals the full replay; a server that wants\n * to mint gaps against a TS reducer can use it directly.\n */\nexport function snapshotOf(state: Readonly<CallLogState>, startedAt: number | null = null): LogGapSnapshot {\n    return {\n        phase: state.phase,\n        live: state.live,\n        started_at: startedAt,\n        ...(state.endedReason !== undefined ? { ended_reason: state.endedReason } : {}),\n        user_speaking: state.userSpeaking,\n        bot_speaking: state.botSpeaking,\n        handoff: state.handoff,\n        skills: [...state.skills],\n        sources: [...state.sources],\n        messages: state.messages.map((m) => ({ ...m })),\n        tool_calls: state.toolCalls.map((t) => ({ ...t })),\n        turns: state.turns.map((t) => ({ ...t })),\n        custom: state.custom.map((c) => ({ ...c })),\n    };\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────\n\n/**\n * Merge a user transcript into the CURRENT turn's user bubble — the last\n * user message with no bot reply after it — instead of appending a new one.\n * STT emits several interim AND several final transcripts per turn (Deepgram\n * Flux fires multiple finals), so appending per event duplicates the bubble.\n * A new turn starts only after a bot reply. Ported verbatim in spirit from\n * VoiceSession.ts:38-50.\n */\nfunction mergeUserTurn(\n    messages: CallMessage[],\n    seq: number,\n    id: string,\n    text: string,\n    interim: boolean,\n): void {\n    let lastUser = -1;\n    for (let i = messages.length - 1; i >= 0; i--) {\n        if (messages[i]!.role === \"user\") { lastUser = i; break; }\n    }\n    let botAfter = false;\n    for (let i = lastUser + 1; i < messages.length; i++) {\n        if (messages[i]!.role === \"bot\") { botAfter = true; break; }\n    }\n    if (lastUser >= 0 && !botAfter) {\n        const m = cow(messages, lastUser);\n        m.text = text;\n        m.interim = interim;\n        m.id = id;\n        return;\n    }\n    messages.push({ seq, role: \"user\", text, id, interim });\n}\n\n/**\n * Copy-on-write: replace `list[i]` with a shallow copy and return it, so the\n * caller mutates the copy and never an object a consumer already holds.\n *\n * Structural sharing of the touched path, not a deep clone — untouched\n * siblings keep their references. This matters because the hottest render\n * path in the whole system is word-by-word typing (`bot.word`), where the\n * obvious consumer optimization is a memoized transcript line keyed on the\n * message object. Mutating in place under a stable reference makes that line\n * freeze mid-sentence while the text underneath keeps changing; a fresh\n * ARRAY reference does not help, because the memo never looks at the array.\n * VoiceSession got this right by replacing the tail object per word, so the\n * reducer that supersedes it must not regress there.\n */\nfunction cow<T extends object>(list: T[], i: number): T {\n    const copy = { ...list[i]! };\n    list[i] = copy;\n    return copy;\n}\n\n/** Tool args arrive parsed or as a JSON string, depending on the provider. */\nfunction parseArgs(args: Record<string, unknown> | string): Record<string, unknown> {\n    if (typeof args !== \"string\") return args ?? {};\n    try {\n        const parsed: unknown = JSON.parse(args);\n        return typeof parsed === \"object\" && parsed !== null\n            ? (parsed as Record<string, unknown>)\n            : {};\n    } catch {\n        return {};\n    }\n}\n\n/** A `tool.result` may carry a JSON string; surface the parsed value. */\nfunction parseResult(result: unknown): unknown {\n    if (typeof result !== \"string\") return result;\n    try {\n        return JSON.parse(result);\n    } catch {\n        return result;\n    }\n}\n\nconst PHASES: ReadonlySet<string> = new Set([\"idle\", \"ringing\", \"listening\", \"thinking\", \"speaking\", \"ended\"]);\nconst HANDOFFS: ReadonlySet<string> = new Set([\"none\", \"requested\", \"active\"]);\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n    return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** Rows of a snapshot array that are at least objects; anything else is ignored (§1). */\nfunction rows<T>(v: unknown, ok: (r: Record<string, unknown>) => boolean): T[] {\n    if (!Array.isArray(v)) return [];\n    return v.filter((r): r is Record<string, unknown> => isRecord(r) && ok(r)) as unknown as T[];\n}\n\n// ── The reducer ──────────────────────────────────────────────────────────\n\n/** Mutable scratch carried across the fold — never part of the public state. */\ninterface FoldContext {\n    /** Live word buffers keyed by bot message id (`bot.word` reassembly). */\n    botWords: Map<string, string[]>;\n    /** bot message id → index in `messages`. */\n    botIndex: Map<string, number>;\n    /** tool call id → index in `toolCalls`. */\n    toolIndex: Map<string, number>;\n    /** turn number → index in `turns`. */\n    turnIndex: Map<number, number>;\n    /** message seq → index in `messages` (for `bot.corrected.supersedes`). */\n    bySeq: Map<number, number>;\n    /** `name + \"/\" + id` → index in `custom` (the (name, id) upsert). */\n    customIndex: Map<string, number>;\n    /** ts of the first entry / of `call.started`. */\n    startTs: number | null;\n    lastTs: number | null;\n    e2eSum: number;\n    e2eN: number;\n}\n\nfunction emptyContext(): FoldContext {\n    return {\n        botWords: new Map(),\n        botIndex: new Map(),\n        toolIndex: new Map(),\n        turnIndex: new Map(),\n        bySeq: new Map(),\n        customIndex: new Map(),\n        startTs: null,\n        lastTs: null,\n        e2eSum: 0,\n        e2eN: 0,\n    };\n}\n\n/**\n * A single log view. Feed it entries from any pipe, in any order, as many\n * times as you like; read `state`.\n */\nexport class CallLogView {\n    #entries = new Map<number, KnownLogEntry>();\n    #state: CallLogState = emptyState();\n    #ctx: FoldContext = emptyContext();\n    #maxSeq = -1;\n    /**\n     * Every `log.gap` applied, in arrival order. Markers are never stored in\n     * `#entries` (§5), but a gap HYDRATES — so an out-of-order rebuild must\n     * re-step each gap at its place in the seq order or the hydrated stretch\n     * would evaporate.\n     */\n    #gaps: KnownLogEntry[] = [];\n    #listeners = new Set<(state: CallLogState) => void>();\n\n    /**\n     * How many entries to retain for out-of-order rebuilds. The retained\n     * window bounds memory on a long call; entries older than the window are\n     * still reflected in the state, they just cannot be re-folded. Default\n     * 10_000 (the hot buffer is 1000, so this is generous by 10x).\n     */\n    constructor(private readonly retain = 10_000) {}\n\n    /**\n     * Read-only snapshot, safe to retain and to compare by reference.\n     *\n     * Every state-affecting apply produces a new state object, new\n     * `messages`/`toolCalls`/`turns`/`custom` arrays, and new objects for exactly the\n     * entries that changed — untouched siblings keep their identity. So\n     * `prev.messages[3] === next.messages[3]` is a truthful \"this line did\n     * not change\", which is what makes a memoized transcript line correct\n     * rather than merely fast.\n     */\n    get state(): Readonly<CallLogState> {\n        return this.#state;\n    }\n\n    /** The cursor to resume from: `?after=<lastSeq>`. */\n    get lastSeq(): number {\n        return this.#state.lastSeq;\n    }\n\n    /** Subscribe to state changes. Returns an unsubscribe function. */\n    subscribe(fn: (state: CallLogState) => void): () => void {\n        this.#listeners.add(fn);\n        return () => { this.#listeners.delete(fn); };\n    }\n\n    /** The entries this view retains, in seq order — the resume payload. */\n    entries(): KnownLogEntry[] {\n        return [...this.#entries.keys()].sort((a, b) => a - b).map((s) => this.#entries.get(s)!);\n    }\n\n    /** True if this exact seq has already been applied. */\n    has(seq: number): boolean {\n        return this.#entries.has(seq);\n    }\n\n    /**\n     * Apply one entry. Idempotent by `seq`, order-independent.\n     * Returns true if the view changed.\n     */\n    apply(entry: AnyLogEntry): boolean {\n        if (!isLogEntry(entry)) return false;\n        // §1: unknown types MUST be ignored, not rejected.\n        if (!isKnownLogEntry(entry)) return false;\n\n        // §5: control markers are FULL envelopes whose seq REPEATS the last\n        // seq delivered — the dedupe below would swallow them, and storing\n        // them would poison entries(), which is the resume payload. Dispatch\n        // immediately; never store, never advance the cursor.\n        if (entry.type === \"log.caught_up\" || entry.type === \"log.gap\") {\n            if (entry.type === \"log.gap\") this.#gaps.push(entry);\n            this.#state = {\n                ...this.#state,\n                messages: [...this.#state.messages],\n                toolCalls: [...this.#state.toolCalls],\n                turns: [...this.#state.turns],\n                custom: [...this.#state.custom],\n            };\n            this.#step(this.#state, this.#ctx, entry);\n            this.#finish(this.#state, this.#ctx);\n            for (const fn of this.#listeners) fn(this.#state);\n            return true;\n        }\n\n        // §1: consumers MUST dedupe by seq — transports overlap.\n        if (this.#entries.has(entry.seq)) return false;\n\n        this.#entries.set(entry.seq, entry);\n\n        if (entry.seq > this.#maxSeq) {\n            // Live path: strictly newer than anything seen — fold forward.\n            this.#maxSeq = entry.seq;\n            // New top-level and array references so snapshot consumers\n            // (useSyncExternalStore and friends) see a change.\n            this.#state = {\n                ...this.#state,\n                messages: [...this.#state.messages],\n                toolCalls: [...this.#state.toolCalls],\n                turns: [...this.#state.turns],\n                custom: [...this.#state.custom],\n            };\n            this.#step(this.#state, this.#ctx, entry);\n            this.#finish(this.#state, this.#ctx);\n            this.#trim();\n        } else {\n            // Backfill / out-of-order: the fold must run in seq order.\n            this.#trim();\n            this.#rebuild();\n        }\n\n        for (const fn of this.#listeners) fn(this.#state);\n        return true;\n    }\n\n    /** Apply many. Returns how many changed the view. */\n    applyAll(entries: readonly AnyLogEntry[]): number {\n        let n = 0;\n        for (const e of entries) if (this.apply(e)) n++;\n        return n;\n    }\n\n    /** Drop everything and start over. */\n    reset(): void {\n        this.#entries.clear();\n        this.#state = emptyState();\n        this.#ctx = emptyContext();\n        this.#maxSeq = -1;\n        this.#gaps = [];\n        for (const fn of this.#listeners) fn(this.#state);\n    }\n\n    // ── Internals ──\n\n    #trim(): void {\n        if (this.#entries.size <= this.retain) return;\n        const keys = [...this.#entries.keys()].sort((a, b) => a - b);\n        const drop = keys.length - this.retain;\n        for (let i = 0; i < drop; i++) this.#entries.delete(keys[i]!);\n    }\n\n    #rebuild(): void {\n        const state = emptyState();\n        const ctx = emptyContext();\n        // Gaps are re-stepped in seq order, interleaved with the entries: a\n        // gap's seq sits right before the first entry it resumes at, so\n        // everything at or below it folds first, then the snapshot lands,\n        // then the rest — the order the transport delivered.\n        const gaps = [...this.#gaps].sort((a, b) => a.seq - b.seq);\n        let g = 0;\n        for (const entry of this.entries()) {\n            while (g < gaps.length && gaps[g]!.seq < entry.seq) this.#step(state, ctx, gaps[g++]!);\n            this.#step(state, ctx, entry);\n        }\n        while (g < gaps.length) this.#step(state, ctx, gaps[g++]!);\n        this.#finish(state, ctx);\n        // Caught-up is a TRANSPORT signal, not a log fact: the marker is never\n        // stored, so a rebuild cannot re-derive it. Carry the transport's\n        // last word across.\n        state.caughtUp = this.#state.caughtUp;\n        this.#state = state;\n        this.#ctx = ctx;\n    }\n\n    #finish(state: CallLogState, ctx: FoldContext): void {\n        // Correction #3: duration comes from entry ts, never wall clock.\n        state.duration =\n            ctx.startTs !== null && ctx.lastTs !== null\n                ? Math.max(0, ctx.lastTs - ctx.startTs)\n                : 0;\n        state.metrics = {\n            ...state.metrics,\n            turnCount: state.turns.length,\n            ...(ctx.e2eN > 0 ? { e2eMean: ctx.e2eSum / ctx.e2eN } : {}),\n        };\n    }\n\n    /**\n     * Fold one entry into `state`. Exhaustive over the closed vocabulary —\n     * the `never` in the default arm is the compile-time guarantee that a\n     * new §2 type cannot be added without teaching the reducer about it.\n     */\n    #step(state: CallLogState, ctx: FoldContext, entry: KnownLogEntry): void {\n        state.lastSeq = Math.max(state.lastSeq, entry.seq);\n        if (entry.call && !state.call) state.call = entry.call;\n        if (entry.agent && !state.agent) state.agent = entry.agent;\n        // Control markers are minted by the transport at wall-clock time —\n        // they say nothing about when the call happened, so they never move\n        // the duration anchors (correction #3).\n        if (entry.type !== \"log.caught_up\" && entry.type !== \"log.gap\") {\n            if (ctx.startTs === null) ctx.startTs = entry.ts;\n            ctx.lastTs = ctx.lastTs === null ? entry.ts : Math.max(ctx.lastTs, entry.ts);\n        }\n\n        const messages = state.messages;\n\n        switch (entry.type) {\n            // ── Lifecycle ──\n            case \"call.ringing\":\n                state.phase = \"ringing\";\n                break;\n\n            case \"call.started\":\n                ctx.startTs = entry.ts;\n                state.phase = \"listening\";\n                state.live = true;\n                break;\n\n            case \"call.ended\":\n                state.phase = \"ended\";\n                state.live = false;\n                state.userSpeaking = false;\n                state.botSpeaking = false;\n                state.endedReason = entry.data.reason;\n                // Correction #2: surface the intent, never call disconnect().\n                state.intents = [\n                    ...state.intents,\n                    { kind: \"disconnect\", reason: entry.data.reason, seq: entry.seq },\n                ];\n                break;\n\n            case \"call.summary\":\n                state.metrics = {\n                    ...state.metrics,\n                    summary: entry.data.metrics,\n                    ...(entry.data.cost !== undefined ? { cost: entry.data.cost } : {}),\n                    ...(entry.data.recording_url\n                        ? { recordingUrl: entry.data.recording_url }\n                        : {}),\n                };\n                state.live = false;\n                if (state.phase !== \"ended\") state.phase = \"ended\";\n                break;\n\n            // ── Speech & transcript ──\n            case \"user.speaking\":\n                state.userSpeaking = entry.data.active;\n                if (entry.data.active && state.phase !== \"ended\") state.phase = \"listening\";\n                break;\n\n            case \"user.message\": {\n                if (entry.data.text) {\n                    mergeUserTurn(\n                        messages,\n                        entry.seq,\n                        entry.data.id,\n                        entry.data.text,\n                        !entry.data.final,\n                    );\n                    this.#reindex(ctx, messages);\n                }\n                if (entry.data.final) {\n                    state.userSpeaking = false;\n                    if (state.phase !== \"ended\") state.phase = \"thinking\";\n                }\n                break;\n            }\n\n            case \"bot.speaking\": {\n                const id = entry.data.id;\n                ctx.botWords.set(id, []);\n                const idx = ctx.botIndex.get(id);\n                const words = entry.data.words;\n                if (idx === undefined) {\n                    messages.push({\n                        seq: entry.seq,\n                        role: \"bot\",\n                        text: entry.data.text ?? \"\",\n                        id,\n                        speaking: true,\n                        ...(words ? { words } : {}),\n                    });\n                    this.#reindex(ctx, messages);\n                } else {\n                    const m = cow(messages, idx);\n                    if (entry.data.text) m.text = entry.data.text;\n                    if (words) m.words = words;\n                    m.speaking = true;\n                }\n                state.botSpeaking = true;\n                if (state.phase !== \"ended\") state.phase = \"speaking\";\n                break;\n            }\n\n            case \"bot.word\": {\n                // Ephemeral typing effect. §2's bot.word carries no index, so\n                // reassembly is append-in-seq-order — deterministic because the\n                // fold always runs in seq order.\n                const id = entry.data.id;\n                let buf = ctx.botWords.get(id);\n                if (!buf) { buf = []; ctx.botWords.set(id, buf); }\n                buf.push(entry.data.w);\n                const text = buf.join(\" \");\n                const idx = ctx.botIndex.get(id);\n                if (idx === undefined) {\n                    messages.push({ seq: entry.seq, role: \"bot\", text, id, speaking: true });\n                    this.#reindex(ctx, messages);\n                } else {\n                    // Never clobber an authoritative bot.speaking.text with a\n                    // partial word buffer.\n                    const m = cow(messages, idx);\n                    if (!m.corrected && buf.length > 0 && m.text.length <= text.length) {\n                        m.text = text;\n                    }\n                    m.speaking = true;\n                }\n                state.botSpeaking = true;\n                if (state.phase !== \"ended\") state.phase = \"speaking\";\n                break;\n            }\n\n            case \"bot.finished\": {\n                const idx = ctx.botIndex.get(entry.data.id);\n                if (idx !== undefined) {\n                    // The LLM went straight to a tool call: drop the phantom\n                    // bubble rather than copying it only to remove it.\n                    if (!messages[idx]!.text) {\n                        messages.splice(idx, 1);\n                        this.#reindex(ctx, messages);\n                    } else {\n                        cow(messages, idx).speaking = false;\n                    }\n                }\n                state.botSpeaking = false;\n                if (state.phase !== \"ended\") state.phase = \"listening\";\n                break;\n            }\n\n            case \"bot.interrupted\": {\n                const idx = ctx.botIndex.get(entry.data.id);\n                if (idx !== undefined) {\n                    const m = cow(messages, idx);\n                    m.speaking = false;\n                    m.interrupted = true;\n                }\n                state.botSpeaking = false;\n                if (state.phase !== \"ended\") state.phase = \"listening\";\n                break;\n            }\n\n            case \"bot.corrected\": {\n                // Correction #4 / §2: replace the text of the superseded entry.\n                // An event, not a mutation — replay reaches the same place.\n                const idx = ctx.bySeq.get(entry.data.supersedes);\n                if (idx !== undefined) {\n                    const m = cow(messages, idx);\n                    m.text = entry.data.text;\n                    m.corrected = true;\n                } else {\n                    messages.push({\n                        seq: entry.seq,\n                        role: \"bot\",\n                        text: entry.data.text,\n                        id: entry.data.id,\n                        corrected: true,\n                    });\n                    this.#reindex(ctx, messages);\n                }\n                break;\n            }\n\n            // ── Turns & latency ──\n            case \"turn.start\": {\n                const i = ctx.turnIndex.get(entry.data.turn);\n                if (i === undefined) {\n                    ctx.turnIndex.set(entry.data.turn, state.turns.length);\n                    state.turns.push({\n                        turn: entry.data.turn,\n                        role: entry.data.role,\n                        startedAt: entry.ts,\n                    });\n                } else {\n                    state.turns[i] = {\n                        ...state.turns[i]!,\n                        role: entry.data.role,\n                        startedAt: entry.ts,\n                    };\n                }\n                break;\n            }\n\n            case \"turn.end\": {\n                const i = ctx.turnIndex.get(entry.data.turn);\n                // A hydrated turn may already carry an e2e (the gap snapshot\n                // folds the entries it is served with): retire it before the\n                // entry's own counts, so re-application never double-counts.\n                const prev = i !== undefined ? state.turns[i]!.latency?.e2e : undefined;\n                if (typeof prev === \"number\") { ctx.e2eSum -= prev; ctx.e2eN -= 1; }\n                if (i === undefined) {\n                    ctx.turnIndex.set(entry.data.turn, state.turns.length);\n                    state.turns.push({\n                        turn: entry.data.turn,\n                        latency: entry.data.latency,\n                        endedAt: entry.ts,\n                    });\n                } else {\n                    state.turns[i] = {\n                        ...state.turns[i]!,\n                        latency: entry.data.latency,\n                        endedAt: entry.ts,\n                    };\n                }\n                if (typeof entry.data.latency?.e2e === \"number\") {\n                    ctx.e2eSum += entry.data.latency.e2e;\n                    ctx.e2eN += 1;\n                }\n                break;\n            }\n\n            // ── Tools, knowledge, skills ──\n            case \"tool.call\": {\n                // Correction #1: no trackedTools filter — expose everything.\n                const id = entry.data.id;\n                if (ctx.toolIndex.get(id) === undefined) {\n                    ctx.toolIndex.set(id, state.toolCalls.length);\n                    state.toolCalls.push({\n                        id,\n                        name: entry.data.name,\n                        args: parseArgs(entry.data.args),\n                        seq: entry.seq,\n                        done: false,\n                    });\n                    messages.push({\n                        seq: entry.seq,\n                        role: \"system\",\n                        text: `Using ${entry.data.name}…`,\n                        toolCallId: id,\n                    });\n                    this.#reindex(ctx, messages);\n                }\n                break;\n            }\n\n            case \"tool.result\": {\n                const i = ctx.toolIndex.get(entry.data.id);\n                if (i !== undefined) {\n                    state.toolCalls[i] = {\n                        ...state.toolCalls[i]!,\n                        result: parseResult(entry.data.result),\n                        ms: entry.data.ms,\n                        ...(entry.data.error ? { error: entry.data.error } : {}),\n                        done: true,\n                    };\n                } else {\n                    // Result without its call (backlog started mid-pair).\n                    ctx.toolIndex.set(entry.data.id, state.toolCalls.length);\n                    state.toolCalls.push({\n                        id: entry.data.id,\n                        name: entry.data.name,\n                        args: {},\n                        seq: entry.seq,\n                        result: parseResult(entry.data.result),\n                        ms: entry.data.ms,\n                        ...(entry.data.error ? { error: entry.data.error } : {}),\n                        done: true,\n                    });\n                }\n                for (let i = 0; i < messages.length; i++) {\n                    if (messages[i]!.toolCallId === entry.data.id) {\n                        cow(messages, i).text = entry.data.error\n                            ? `${entry.data.name} failed`\n                            : `${entry.data.name}`;\n                    }\n                }\n                break;\n            }\n\n            case \"docs.sources\":\n                state.sources = entry.data.sources ?? [];\n                break;\n\n            case \"skill.loaded\":\n                if (!state.skills.includes(entry.data.skill)) {\n                    state.skills = [...state.skills, entry.data.skill];\n                }\n                break;\n\n            case \"skill.unloaded\":\n                state.skills = state.skills.filter((s) => s !== entry.data.skill);\n                break;\n\n            // ── Metrics & control ──\n            case \"audio.metrics\":\n                // Ephemeral; rolled up into call.summary server-side (§4).\n                break;\n\n            case \"handoff.requested\":\n                state.handoff = \"requested\";\n                break;\n            case \"handoff.active\":\n                state.handoff = \"active\";\n                break;\n            case \"handoff.released\":\n                state.handoff = \"none\";\n                break;\n\n            case \"supervisor.said\":\n            case \"supervisor.whispered\":\n                // A gap snapshot may already carry this line (its fold covers\n                // the entries it is served with) — keyed by seq, once.\n                if (!ctx.bySeq.has(entry.seq)) {\n                    messages.push({\n                        seq: entry.seq,\n                        role: \"system\",\n                        text: entry.data.text,\n                    });\n                    this.#reindex(ctx, messages);\n                }\n                break;\n\n            // ── Log control ──\n            case \"log.caught_up\":\n                state.caughtUp = true;\n                break;\n\n            case \"log.gap\":\n                // §3: declare the gap, land the snapshot, move the cursor.\n                // `after=` is exclusive (seq > after), so the cursor that\n                // resumes AT resume_from is resume_from - 1 — the seq the\n                // server stamps on the marker itself.\n                state.gaps = [\n                    ...state.gaps,\n                    { from: entry.data.from, resumeFrom: entry.data.resume_from },\n                ];\n                state.caughtUp = false;\n                state.lastSeq = Math.max(state.lastSeq, entry.data.resume_from - 1);\n                if (isRecord(entry.data.snapshot)) {\n                    this.#hydrate(state, ctx, entry.data.snapshot as LogGapSnapshot);\n                }\n                break;\n\n            // ── Custom entries (`call.log()`) ──\n            case \"custom\": {\n                // Ephemeral: fanned out to listeners, never projected — the\n                // store never has it, so live state must not have it either\n                // (replay === live). Durable: upsert by (name, id) — the row\n                // is REPLACED wholesale (value, seq, ts, turn), never merged,\n                // so the final state never depends on which entries were\n                // skipped. Absent id → the entry's own seq, i.e. append.\n                if (entry.ephemeral) break;\n                const id = entry.data.id ?? String(entry.seq);\n                const key = `${entry.data.name}/${id}`;\n                const row: CallCustomEntry = {\n                    name: entry.data.name,\n                    id,\n                    value: entry.data.value,\n                    seq: entry.seq,\n                    ts: entry.ts,\n                    ...(entry.data.turn !== undefined ? { turn: entry.data.turn } : {}),\n                };\n                const i = ctx.customIndex.get(key);\n                if (i === undefined) {\n                    ctx.customIndex.set(key, state.custom.length);\n                    state.custom.push(row);\n                } else {\n                    state.custom[i] = row;\n                }\n                break;\n            }\n\n            default: {\n                // Exhaustiveness: adding a §2 type without a case fails to compile.\n                const _never: never = entry;\n                void _never;\n            }\n        }\n    }\n\n    /**\n     * Merge a `log.gap` snapshot into `state` (ag-ui \"For Pinecall\" 9:\n     * MESSAGES_SNAPSHOT's rule — merge by id, never wipe).\n     *\n     *   - `messages`: keyed by `seq` (bot bubbles by `id`). A snapshot row\n     *     REPLACES its local counterpart and a new one is inserted; local-only\n     *     rows survive. Result is re-sorted by seq — the order the fold would\n     *     have produced.\n     *   - `tool_calls`: keyed by `id`, same rule, sorted by seq.\n     *   - `turns`: keyed by `turn`, field-merged (`{...local, ...row}`) so a\n     *     `turn.end` already folded locally is not lost to a snapshot that\n     *     only saw the `turn.start`. Latency sums are recomputed from the\n     *     merged turns.\n     *   - `custom`: keyed by `(name, id)`; the row with the HIGHER seq wins —\n     *     the one rule the upsert already has. First-seen order kept, new\n     *     keys appended.\n     *   - scalars (`phase`, `live`, `started_at`, `ended_reason`,\n     *     `user_speaking`, `bot_speaking`, `handoff`, `skills`, `sources`):\n     *     values — present wins, absent leaves local alone.\n     *\n     * Re-applying the entries the snapshot was folded from is a no-op for\n     * what it carried: every case in `#step` is keyed the same way.\n     */\n    #hydrate(state: CallLogState, ctx: FoldContext, snap: LogGapSnapshot): void {\n        if (typeof snap.phase === \"string\" && PHASES.has(snap.phase)) state.phase = snap.phase;\n        if (typeof snap.live === \"boolean\") state.live = snap.live;\n        if (typeof snap.started_at === \"number\") ctx.startTs = snap.started_at;\n        if (typeof snap.ended_reason === \"string\") state.endedReason = snap.ended_reason;\n        if (typeof snap.user_speaking === \"boolean\") state.userSpeaking = snap.user_speaking;\n        if (typeof snap.bot_speaking === \"boolean\") state.botSpeaking = snap.bot_speaking;\n        if (typeof snap.handoff === \"string\" && HANDOFFS.has(snap.handoff)) state.handoff = snap.handoff;\n        if (Array.isArray(snap.skills)) state.skills = snap.skills.filter((x) => typeof x === \"string\");\n        if (Array.isArray(snap.sources)) state.sources = [...snap.sources];\n\n        const msgRows = rows<CallMessage>(snap.messages, (r) => typeof r.seq === \"number\" && typeof r.role === \"string\");\n        if (msgRows.length) {\n            const messages = state.messages;\n            for (const r of msgRows) {\n                const row: CallMessage = { ...r, text: typeof r.text === \"string\" ? r.text : \"\" };\n                const idx = row.role === \"bot\" && row.id !== undefined\n                    ? ctx.botIndex.get(row.id) ?? ctx.bySeq.get(row.seq)\n                    : ctx.bySeq.get(row.seq);\n                if (idx === undefined) messages.push(row);\n                else messages[idx] = row;\n                this.#reindex(ctx, messages);\n            }\n            messages.sort((a, b) => a.seq - b.seq);\n            this.#reindex(ctx, messages);\n        }\n\n        const toolRows = rows<CallToolCall>(snap.tool_calls, (r) => typeof r.id === \"string\" && typeof r.seq === \"number\");\n        if (toolRows.length) {\n            for (const r of toolRows) {\n                const row: CallToolCall = {\n                    ...r,\n                    name: typeof r.name === \"string\" ? r.name : \"\",\n                    args: isRecord(r.args) ? r.args : {},\n                    done: r.done === true,\n                };\n                const i = ctx.toolIndex.get(row.id);\n                if (i === undefined) state.toolCalls.push(row);\n                else state.toolCalls[i] = row;\n                ctx.toolIndex.set(row.id, state.toolCalls.length - 1);\n            }\n            state.toolCalls.sort((a, b) => a.seq - b.seq);\n            ctx.toolIndex.clear();\n            state.toolCalls.forEach((t, i) => ctx.toolIndex.set(t.id, i));\n        }\n\n        const turnRows = rows<CallTurn>(snap.turns, (r) => typeof r.turn === \"number\");\n        if (turnRows.length) {\n            for (const r of turnRows) {\n                const i = ctx.turnIndex.get(r.turn);\n                if (i === undefined) state.turns.push({ ...r });\n                else state.turns[i] = { ...state.turns[i]!, ...r };\n                ctx.turnIndex.set(r.turn, i ?? state.turns.length - 1);\n            }\n            state.turns.sort((a, b) => a.turn - b.turn);\n            ctx.turnIndex.clear();\n            ctx.e2eSum = 0;\n            ctx.e2eN = 0;\n            state.turns.forEach((t, i) => {\n                ctx.turnIndex.set(t.turn, i);\n                if (typeof t.latency?.e2e === \"number\") { ctx.e2eSum += t.latency.e2e; ctx.e2eN += 1; }\n            });\n        }\n\n        const customRows = rows<CallCustomEntry>(snap.custom, (r) => typeof r.name === \"string\" && typeof r.seq === \"number\");\n        for (const r of customRows) {\n            const id = r.id !== undefined && r.id !== null ? String(r.id) : String(r.seq);\n            const row: CallCustomEntry = { ...r, id };\n            const key = `${row.name}/${id}`;\n            const i = ctx.customIndex.get(key);\n            if (i === undefined) {\n                ctx.customIndex.set(key, state.custom.length);\n                state.custom.push(row);\n            } else if (row.seq >= state.custom[i]!.seq) {\n                state.custom[i] = row;\n            }\n        }\n    }\n\n    /** Rebuild the id→index maps after a splice/push. Cheap: messages are small. */\n    #reindex(ctx: FoldContext, messages: CallMessage[]): void {\n        ctx.botIndex.clear();\n        ctx.bySeq.clear();\n        for (let i = 0; i < messages.length; i++) {\n            const m = messages[i]!;\n            ctx.bySeq.set(m.seq, i);\n            if (m.role === \"bot\" && m.id !== undefined) ctx.botIndex.set(m.id, i);\n        }\n    }\n}\n\n/** Build a view from a batch of entries. */\nexport function createCallLogView(entries?: readonly AnyLogEntry[]): CallLogView {\n    const view = new CallLogView();\n    if (entries) view.applyAll(entries);\n    return view;\n}\n"]}