/**
 * Server-saved diagnostics (GENC-1351 §5.8) — the forward-only stream that lets
 * the debug log persist across a whole session lifetime, not just the current
 * page load. This module owns the *pure* pieces: the entry type and the
 * reassembly back into the `{ readme, sessionUsage, timeline, meta }` debug-log
 * shape. The element owns capture/cadence; the provider owns storage layout.
 *
 * @packageDocumentation
 */
import type { AggregateUsage } from '@genesislcap/foundation-ai';
/**
 * One entry in the diagnostics stream — the debug-log timeline-entry union
 * (`message` / `turn` / `event`, as `getDebugLog()` builds) plus a point-in-time
 * **`meta-snapshot`** carrying the export-time `meta` block (agent summary,
 * context, active debug snapshot, …). Kept permissive: a provider stores and
 * returns these opaquely, and reassembly reads only `kind`, `timestamp` (for
 * ordering), `usage` (on a turn) and `meta` (on a snapshot).
 *
 * @public
 */
export interface DiagnosticEntry {
    kind: 'message' | 'turn' | 'event' | 'meta-snapshot';
    /** ISO timestamp — string-comparable, so it orders the stream chronologically. */
    timestamp?: string;
    /** Present on `meta-snapshot` entries: the export-time `meta` block. */
    meta?: unknown;
    /**
     * Present on a `turn` entry once its model call has returned and reported usage —
     * the four token buckets plus USD for that one call (`TurnSnapshot.usage`).
     *
     * Read by the forward-capture delta as well as by readers: the turn entry is
     * created *before* the call, so a flush that lands mid-call persists it without
     * usage, and the delta re-emits it once (see `collectDiagnosticsDelta`) so the
     * priced copy reaches the stream. {@link assembleDebugLog} then collapses the pair.
     */
    usage?: AggregateUsage;
    /**
     * Present on `meta-snapshot` entries: a stable signature of the near-static config
     * (excludes volatile timestamp/context/debug-snapshot), used by the forward-capture
     * delta to skip re-appending an unchanged block (GENC-1351 §5.8). Absent on other
     * kinds and on pre-signature entries (the delta falls back to the full `meta` then).
     */
    dedupSignature?: string;
    [key: string]: unknown;
}
/** The reassembled debug log — the exact shape `getDebugLog()` returns. @public */
export interface DebugLog {
    readme: readonly string[];
    /**
     * Session usage — the four token buckets plus USD cost — lifted out of the newest
     * `meta-snapshot`'s `meta.context.sessionUsage` so the headline spend figures sit at
     * the top of an exported log rather than buried under the (large) `meta` block. The
     * same object, not a second derivation.
     *
     * `undefined` when the stream carries no `meta-snapshot`, or one written before the
     * field existed. Never re-derived from the timeline: the per-request costs the
     * transports stamped are authoritative, and a ring-buffered timeline can have lost
     * entries the total still legitimately counts.
     *
     * **As current as the snapshot it came from, which is not automatically "now".** The
     * forward-capture delta only re-appends a `meta-snapshot` when the near-static config
     * signature changes, so the newest STORED snapshot of a session whose config never
     * changed is its first — with the totals frozen there. A caller reassembling a stored
     * stream on its own therefore gets stale figures unless it appends an export-time
     * snapshot first: see {@link withFreshMetaSnapshot}, which is what the assistant's own
     * download path does. `meta.timestamp` against the newest timeline entry tells you
     * which case you are holding.
     */
    sessionUsage?: AggregateUsage;
    timeline: DiagnosticEntry[];
    meta: unknown;
}
/**
 * Stable identity for a message diagnostic entry — `timestamp::role::subAgentOf::category`.
 * Used by the forward-capture delta (skip already-emitted messages) and by the
 * restore watermark (skip messages already present in a prior load's stream).
 * `null` when the entry has no timestamp → treat as always-new. Shared so the
 * element's diagnostics capture and the `SessionPersister`'s restore watermark
 * compute identity identically (GENC-1351 §5.8/§5.10).
 *
 * `category` is part of the key because the reasoning/narration/answer split (GENC-1411) emits
 * SEVERAL messages from one model response — the thought summary, any interstitial narration, and
 * the answer/tool-call message — which share `timestamp` + `role` + `subAgentOf`. Keying on those
 * alone collapsed them to one, so the forward-capture dropped all but the first: a server
 * generation's answer message vanished from the persisted debug log while its reasoning survived
 * (GENC-1461). `category` is stable across a message's in-place annotation (only `toolCalls` change,
 * which is deliberately excluded), so a genuine re-append of the same message still dedups.
 *
 * @internal
 */
export declare function diagnosticsMessageKey(entry: DiagnosticEntry): string | null;
/**
 * Reassemble diagnostic entries into the `{ readme, sessionUsage, timeline, meta }`
 * debug-log shape (GENC-1351 §5.8). `timeline` = the `message`/`turn`/`event` entries sorted
 * by ISO `timestamp` (kind-rank tie-break). `meta` = the **newest** `meta-snapshot`'s
 * block only — a "state at export" photo, matching the single-page log. The older
 * snapshots are intentionally dropped: the per-turn evolution they would show is
 * already in the timeline (`turn.agentSnapshot` + `context.updated` events), so
 * keeping them would just repeat the bulky, near-static `agentSummary`. `readme` =
 * the passed (current) constant. `sessionUsage` = that same newest snapshot's
 * `meta.context.sessionUsage`, lifted to the top level. Pure — reused for both the
 * live current-page log and the reassembled lifetime log stitched from the persisted
 * stream, so both come out shape-identical.
 *
 * NOTE for a caller stitching a STORED stream (a headless consumer harvesting its own
 * lifetime log, say): the newest stored `meta-snapshot` is frozen at the last
 * config-signature change, so `meta` and `sessionUsage` are as old as that unless you
 * pass a fresh snapshot of your own — {@link withFreshMetaSnapshot} does exactly that,
 * and the element's download path goes through it.
 */
export declare function assembleDebugLog(entries: DiagnosticEntry[], readme: readonly string[]): DebugLog;
/**
 * A stored diagnostics stream with its `meta-snapshot`s replaced by `fresh` — what to
 * pass {@link assembleDebugLog} when reassembling a persisted stream for export.
 *
 * The stored snapshots are dropped rather than out-timestamped. `assembleDebugLog` keeps
 * whichever claims the later time, and a stream written on another machine can carry a
 * skewed clock; `fresh` is built from live state and so is the more current by
 * construction. Only one snapshot ever survives reassembly, so the count is unchanged —
 * though a snapshot taken while the driver is unwired (mid-popout) can leave
 * `activeFoldStack`/`activeDebugSnapshot` unset where a stored one had them. The figures
 * this exists for — the context block and `sessionUsage` — read the session store and
 * element props, which survive an unwire.
 *
 * Pure, and separate from the element for that reason: the swap it performs is the fix
 * for a silent bug (a lifetime log reporting near-zero spend against a transcript full of
 * priced messages), so it needs to be testable without mounting anything.
 */
export declare function withFreshMetaSnapshot(stored: readonly DiagnosticEntry[], fresh: DiagnosticEntry): DiagnosticEntry[];
//# sourceMappingURL=diagnostics.d.ts.map