import type { ModelTurnResult } from './spi/model-provider.js';
import type { SinkWriter } from './spi/token-stream-sink.js';
import type { AgentUiComponent } from './stream-events.js';
/** What a model turn streamed that the persisted message keeps, beyond its text and tool calls. */
export interface TurnFrameSummary {
    reasoning?: string;
    reasoningMs?: number;
    ui?: AgentUiComponent[];
}
export interface ObservedTurnFrames {
    /** Hand THIS to the provider: every write passes through to the wrapped writer unchanged. */
    writer: SinkWriter;
    /** What was seen so far. Closes an open thinking burst at the moment it is called. */
    summary(): TurnFrameSummary;
}
/**
 * Watch the frames a model turn writes, to learn what the stream showed that the provider's result
 * does not carry: the model's thinking (text and how long it took) and any pushed UI components.
 *
 * Derived from the FRAMES rather than asked of each provider, so every provider that streams
 * `reasoning` gets it persisted without implementing anything. Thinking time is the sum of each burst
 * of consecutive `reasoning` frames — from the first one to the next frame that is not reasoning (or
 * the end of the turn) — which is what a reader watched as "thinking".
 *
 * Call it inside the step that runs the model, so the summary rides that step's journaled result and
 * a replay reads the same numbers back instead of re-measuring a turn that is not happening. The same
 * derivation as `observeTurnFrames` in `@dudousxd/nestjs-agent-core`, over typed frames instead of
 * NDJSON bytes.
 */
export declare function observeTurnFrames(writer: SinkWriter, now?: () => number): ObservedTurnFrames;
/** Fill what a provider did not report from what its frames showed. A provider's own value wins. */
export declare function withTurnFrames<T extends ModelTurnResult>(result: T, frames: TurnFrameSummary): T;
//# sourceMappingURL=turn-frames.d.ts.map