/**
 * The request view's TOOL-TURN LAW — the structure every provider lane requires of a tool turn, restored on the
 * way to the brain (never in the transcript).
 *
 * For every assistant message that carries tool calls:
 *  (i)  the calls are a CONTIGUOUS TAIL of DISTINCT ids — every block that is not a call and stands after the first
 *       call (between two calls or after the last) moves ahead of the calls; blocks ahead of the first call, thinking
 *       first, keep their place (a stable partition: non-call blocks in their order, then the calls in theirs); a
 *       second call carrying an id the message already used is left out (every lane requires a request's call ids to
 *       be unique), so the message keeps the FIRST call per id and every result for that id answers it;
 *  (ii) the messages right after it are EXACTLY one result per call — a result recorded later in the transcript
 *       (behind a user message, a wake frame, another turn) is moved up into the batch, a second result for the
 *       same call is folded into the first (no recorded result is withheld), an interrupted close
 *       ({@link isInterruptedClose}) stands in only for a call with no other result (beside a recorded result it
 *       is void: it says only that none was recorded), and a call with no result at all is closed with the reconcile
 *       family's synthetic interrupted result ({@link interruptedResults}: the same text and `errorKind` a persisted
 *       reconcile writes);
 *  (iii) every result answers a call — a result with no EARLIER assistant message emitting its id (its call is gone,
 *       or it was recorded ahead of its call) answers nothing in this view and is left out. This is the one rule for
 *       that shape on every request builder (the harness's request lane and the side query alike).
 *
 * The three lanes carry the same requirement in three spellings — the Anthropic Messages API rejects a `tool_use`
 * followed by any non-`tool_use` block (between two calls as after the last), or whose `tool_result` is not in the
 * very next message; chat completions requires the `tool` messages right after the assistant's `tool_calls`; the
 * Responses API requires a `function_call_output` for every `function_call` — and each brain's own builder only ever
 * merged ADJACENT results. One transcript that
 * breaks the structure (a result recorded late, a note written after the calls) was therefore rejected on every
 * later request of its session. Holding the law here, once, at the provider boundary means the three brains read
 * the canonical form, and a session already carrying a broken turn is repaired on its next request.
 *
 * Attribution (some gateways number calls per request, so an id legitimately recurs across turns): a result belongs
 * to the NEAREST EARLIER assistant message that emitted its id — and to nothing else: its recorded tool name is not a
 * key. That is the persisted reconcile's positional reading (a call is answered by a result standing after it and
 * before the id's next use), so the two readers never disagree about which occurrence a result answers; a name-based
 * reading (7.37.1) reached back past turns the model had already answered.
 * An earlier occurrence of a reused id that has no result before the next use is therefore closed as
 * interrupted (outcome unknown), never handed a later occurrence's success; every result after the last use is that
 * use's (two or more are folded). A result with no earlier call carrying its id is left out (iii). Pure and
 * deterministic (a moved result keeps its object; a synthesized one takes its assistant's timestamp), so the same
 * transcript yields the same request bytes and the prefix cache holds.
 * The close the view synthesizes carries NO tool-effect refinement: the view holds no tool table and no record of
 * which calls started, so every call it closes reads the reconcile family's conservative "outcome unknown — verify"
 * wording, whatever the tool. (The persisted reconcile refines with the run's tool effects — a read-only or
 * idempotent call's close says it may simply be re-issued — and, on a live abort, with the calls it saw start.)
 * Returns the SAME array when nothing needed restoring.
 *
 * RUN OWNERSHIP. The caller may hand over the assistant messages that stood in its transcript before its run began
 * (`priorMessages`, by object). A `missing_result` repair on one of them is marked `beforeRun`: the call went
 * unanswered before this run started, so closing it on the wire is a fact about the transcript the run inherited, not
 * an event of the run. Membership is by message, never by position — a request projection that inserts, drops or
 * replaces other messages cannot move it. The mark says that and nothing else: the repair, the synthesized result and
 * the operator's account of them are the same with or without it. No `priorMessages` ⇒ no mark.
 */
import type { AssertAllKeysHandled } from "../../core/ask-origin.js";
import type { AssistantMessageDiagnostic } from "./diagnostics.js";
import type { Message } from "./types.js";
/** What the law restored — the `forms` of a `context.tool_turn_repaired` notice. */
export declare const TOOL_TURN_REPAIR_FORMS: readonly ["trailing_text", "late_result", "missing_result", "duplicate_result", "duplicate_call", "orphan_result"];
export type ToolTurnRepairForm = (typeof TOOL_TURN_REPAIR_FORMS)[number];
/** Does the form leave recorded content out of the request (a call, a result), rather than move, fold or add it?
 *  A request that did is a lossy projection of the session — the harness never seeds a fork summary from it. */
export declare const TOOL_TURN_REPAIR_DROPS: {
    readonly trailing_text: false;
    readonly late_result: false;
    readonly missing_result: false;
    readonly duplicate_result: false;
    readonly duplicate_call: true;
    readonly orphan_result: true;
};
export type DropsTableCoversEveryForm = AssertAllKeysHandled<Exclude<ToolTurnRepairForm, keyof typeof TOOL_TURN_REPAIR_DROPS>>;
/**
 * Why a tool turn reached the model incomplete — the `task.tool_turn_incomplete` notice's `detail.cause`, the person's
 * view of facts the model is already told in the turn itself. Closed:
 *  · `truncated` — calls whose argument bytes were cut before they parsed: dropped, the model asked to re-issue them;
 *  · `unnamed` — calls that arrived with no tool name: dropped the same way;
 *  · `bad_frame` — provider stream frames that were not valid JSON: dropped, so the response may be missing content;
 *  · `missing_result_synthesized` — a call with no recorded result, closed in the request view as interrupted with its
 *    outcome unknown (the `missing_result` repair).
 * The first three are a brain's stream facts ({@link StreamDropCause}), stamped on the turn's own message; the fourth is
 * the request view's.
 */
export declare const TOOL_TURN_INCOMPLETE_CAUSES: readonly ["truncated", "unnamed", "bad_frame", "missing_result_synthesized"];
export type ToolTurnIncompleteCause = (typeof TOOL_TURN_INCOMPLETE_CAUSES)[number];
/** The causes a brain's stream parse finds — what a turn's own message can report. */
export type StreamDropCause = Exclude<ToolTurnIncompleteCause, "missing_result_synthesized">;
/** One cause a turn's stream dropped content for, and how many calls (or frames) it dropped. */
export interface StreamDrop {
    readonly cause: StreamDropCause;
    readonly count: number;
}
/** Stamp a turn's stream drops on its message (`AssistantMessage.diagnostics`); nothing for a turn that dropped none. */
export declare function stampStreamDrops(message: {
    diagnostics?: AssistantMessageDiagnostic[];
}, drops: readonly StreamDrop[]): void;
/** The stream drops a message reports. A host brain's message is not trusted to be well-formed: an entry counts only
 *  with a closed-set cause and a positive integer count; anything else reads as no drop. */
export declare function streamDropsOf(message: {
    readonly diagnostics?: unknown;
}): StreamDrop[];
/** One restoration: on one assistant message, or — for `orphan_result` — on the view as a whole. */
export interface ToolTurnRepair {
    readonly form: ToolTurnRepairForm;
    /** The calls concerned, in call order — for `trailing_text` every call of the message; for `duplicate_call` the
     *  ids a later call of the message repeated; for `orphan_result` the ids of the results left out, once each, in
     *  transcript order; otherwise the calls whose result was moved up, synthesized, or folded with a second one. */
    readonly toolCallIds: readonly string[];
    /** `missing_result` only, and only when the caller handed over its run's prior messages
     *  ({@link ensureToolTurnInvariants}'s `priorMessages`): the message holding these calls is one of them. */
    readonly beforeRun?: true;
}
export interface ToolTurnView {
    /** The request view — the input array itself when {@link repairs} is empty. */
    readonly messages: Message[];
    readonly repairs: readonly ToolTurnRepair[];
}
/** The text standing between two results recorded for one call when the view folds them into one. */
export declare const SECOND_RESULT_SEPARATOR = "[another result was recorded for this same call:]";
/** Restore the tool-turn law on a provider-bound message list (see the module header). `priorMessages` = the calling
 *  run's inherited assistant messages (module header, RUN OWNERSHIP). */
export declare function ensureToolTurnInvariants(messages: Message[], priorMessages?: {
    has(message: object): boolean;
}): ToolTurnView;
