/**
 * What every row reader shares: the view, the declarations, the per-sentence
 * catch, and the small pointer / var builders.
 *
 * `say` is THE way a reader writes a line. It fills the template and, when the
 * fill throws (a programming error — a var the reader forgot), writes
 * `unreadable.line@1` instead and counts it in `unread`. One bad line never
 * crashes the account.
 */
import { parseMaybeJson, readEmptiness, type EmptinessReading } from '../../core/agent/emptiness.js';
import { type SentenceSpec } from '../render.js';
import type { TemplateId } from '../templates.js';
import type { AccountSource, AnswerAccountDeclarations, RecordPointer, Sentence, SentenceVar } from '../types.js';
import { type RecordingView, type ViewEvent } from '../view.js';
export interface ReadContext {
    readonly view: RecordingView;
    readonly declarations: AnswerAccountDeclarations;
    /** A resumed leg: a `pause.resume`, or a `turn_end` with no `turn_start`. */
    readonly resumedLeg: boolean;
    /** The iteration of the last `stream.llm_start` before `turn_end` (the answering iteration). */
    readonly answeringIteration?: number;
    /** Write one line through the per-sentence catch. */
    say(id: TemplateId, spec?: SentenceSpec): Sentence;
    /** Count one row the account passed over because its shape did not fit. */
    noteUnread(): void;
    /** Items (and their characters) already printed — the readability budget. */
    readonly budget: {
        itemChars: number;
        items: number;
    };
}
/**
 * The bulleted items the account prints IN TOTAL — declared coverage items and
 * flagged values. Each item rides a sentence (its text three times: `text`,
 * `parts`, `vars`, plus pointers, about 1 KB of structure), so both the count
 * and the characters are bounded; past either, items fold into `items.more@1`
 * for readability. `size.ts` separately enforces the serialized-byte bound.
 */
export declare const ITEM_BUDGET: {
    readonly items: 12;
    readonly chars: 3000;
};
/** Take one item of `chars` characters from the budget; `false` = fold it. */
export declare function takeItem(ctx: ReadContext, chars: number): boolean;
/** @internal — a test hook: force the fill of one template id to throw. */
export interface AccountInternals {
    readonly failTemplate?: string;
}
/**
 * Long text the account prints in TOTAL, past the first `SHORT_TEXT_CHARS` of
 * each value: once spent, every later value is cut at `SHORT_TEXT_CHARS` (marked
 * `clipped`, followed by `part.clipped@1`). This keeps ordinary accounts
 * readable; `size.ts` separately enforces the serialized-byte bound.
 */
export declare const LONG_TEXT_BUDGET = 3000;
export declare const SHORT_TEXT_CHARS = 300;
/**
 * A text value a call's FACT carries is cut here (the sentence that prints it
 * carries up to 2,000). A cut that keeps an ordinary account readable; the
 * account's size bound itself is measured in bytes (`../size.ts`).
 */
export declare const FACT_TEXT_CHARS = 200;
export declare function makeSay(internals: AccountInternals | undefined, onUnread: () => void, budget?: {
    longChars: number;
}): (id: TemplateId, spec?: SentenceSpec) => Sentence;
export declare const jsonPointer: (...keys: readonly (string | number)[]) => string;
/**
 * A pointer the account did not build itself — the standing fold's witnesses
 * (`core/agent/assessment/assess.ts`) — with its identity cut as the
 * builders below cut theirs.
 */
export declare function boundedPointer(p: RecordPointer): RecordPointer;
export declare function at(event: ViewEvent, ...keys: readonly (string | number)[]): RecordPointer;
/** A derived leaf on an event (`#emptiness`, `#meta/runId`). */
export declare function derived(event: ViewEvent, path: string): RecordPointer;
export declare const stateAt: (key: string, ...keys: readonly (string | number)[]) => RecordPointer;
export declare const historyAt: (index: number, path: string, toolCallId?: string) => RecordPointer;
export declare function declarationAt(declarations: AnswerAccountDeclarations, field: string): RecordPointer;
/** A tool name the LIBRARY recorded (its claims are vouched by the template). */
export declare const toolVar: (name: string, from?: RecordPointer) => SentenceVar;
/**
 * The `{{name:skill}}` pair: the id (library) and, when there is one, its plain
 * label — the recorded `title` (library) or the app's declared label (app).
 */
export declare function skillVars(ctx: ReadContext, name: string, id: string, from?: RecordPointer): Record<string, SentenceVar>;
export { parseMaybeJson, readEmptiness, type EmptinessReading };
/** The app's declared rows key for one tool, when it declared one. */
export declare const rowsAtOf: (declarations: AnswerAccountDeclarations, toolName: string) => string | undefined;
/** The source a sentence's emptiness claim rests on. */
export declare const emptinessSource: (reading: {
    readonly source?: 'library' | 'app';
}) => AccountSource;
/**
 * The count a fact carries from one reading — ONE owner for the three fact
 * kinds (this run's calls, the calls before a pause, the earlier answers in
 * view): how many rows, who counted them, and where in the value read the
 * count was taken (a JSON pointer; "show me" points there — `shown.ts`).
 */
export declare const countedFields: (reading: EmptinessReading) => {
    readonly rows?: number;
    readonly emptinessSource?: 'library' | 'app';
    readonly countedAt?: string;
};
/**
 * `sharedState.history`, when it is an array — and EMPTY when the record keeps
 * it out (a redaction policy's placeholder). It asks the view first, so the
 * view's guard counts the kept-out history as handled; a reader that would
 * otherwise say something about what the history lacks asks
 * `view.isStateKeptOut('history')` itself (`inView.ts`, `checked.ts`).
 */
export declare function historyOf(view: RecordingView): readonly unknown[];
/**
 * True when this recorded history entry is a message a PERSON wrote — the
 * one rule (`lib/saidByPerson.ts` · `isSaidByPerson`), read off a record. A
 * `role: 'user'` entry is not enough: the library writes frames in that role
 * (an evidence correction, a budget wrap-up, a drop notice), and one that
 * lands after a turn's results would move "the current request" past them.
 */
export declare function isPersonEntry(entry: unknown): boolean;
//# sourceMappingURL=common.d.ts.map