/**
 * hosting/answeredPause — a stored pause whose resume failed and may have used
 * its decision: answered, with the outcome not known.
 *
 * Role:   the one owner of that state, for EVERY door that keeps a paused run
 *         (`standingAgent`, `streamHandler`). Once a resume's decision may have
 *         reached the ledger the call may have run, so a failure — in the run,
 *         or in storing its result — must stop the pause being offered for an
 *         answer: a retry, a rebuilt instance, a restart or another host on the
 *         same store would answer it again. The conversation must still be able
 *         to go on.
 *
 *           readStoredSession   the one reading of a stored session: an
 *                               answered pause is a conversation to
 *                               continue, never a pause to answer
 *           listedFormatOf      the same reading for a session listing
 *           answeredRefusal     what an answer to it is refused with
 *           watchAnswer         opened before a door hands an answer over
 *           afterFailedAnswer   the one step after that answer's resume failed
 *           unanswerablePause   a pause no answer can reach any more, and
 *           closedConversation  the conversation it goes on from
 *
 * ── MARKED WHEN ITS DECISION MAY HAVE BEEN USED ─────────────────────────────
 * The call may have run only if the decision reached a ledger, and
 * `spendDecision` is the one place it does — so a door asks the watch it
 * opened before handing the answer over (`core/consentRequest.ts` ·
 * `watchDecisionUse`). Spent, refused as spent already, still unanswered, or a
 * failed spend its ledger cannot say never landed: marked. Taken up by this
 * library and never taken to a ledger — refused, or aborted before the spend:
 * the pause stays answerable. Never taken up at all: marked, because that
 * cannot be told apart from a use. What an error calls itself proves nothing,
 * and nothing is read from the decision object for it, which a door may copy
 * or wrap on its way to the resume.
 *
 * ── A PAUSE NO ANSWER CAN REACH IS CLOSED, NOT HELD ─────────────────────────
 * A consent pause that recorded no request (stored before requests were
 * named), whose call changed after the ask, or an ask made under rules the
 * resuming agent no longer runs (a redeploy) can never be answered — every
 * decision is refused. Held, it would hold the session for good. So a door
 * closes it: the next message continues the conversation with the calls it
 * left open settled, and a decision refused for one of those reasons — having
 * used nothing — closes it too, when its question names the request it asked
 * (one stored before requests were named names none: the next message closes
 * that one).
 *
 * ── "DID NOT RUN" ONLY ON PROOF ─────────────────────────────────────────────
 * A pause that still says it is waiting is no proof its call never ran: a
 * resume can spend the decision, run the call, fail, and fail again to mark
 * the pause answered — and a redeploy can then make it a pause no answer can
 * reach. So a closed pause's open calls are settled as not run
 * ({@link NOT_RUN_UNANSWERABLE}) only when the ledger the request was minted
 * under — the serving agent's, and only that one — spends the request itself
 * (`consentRequest.ts` · `proveNeverRan`): atomic, and it consumes the request
 * so no later resume can run the call. Otherwise, and whenever that proof
 * cannot be had, as possibly run ({@link OUTCOME_UNKNOWN_UNANSWERABLE}: do not
 * run it again, ask the person). A false "may have run" is the safe
 * direction: a model told a refund did not run may issue it again.
 *
 * Reads:  the stored session — never the runner's own state, which on a
 *         shared agent may be another session's run, or a run that never
 *         started.
 * Writes: the marked pause, through the door's session store.
 *
 * ── WHY THE OPEN CALLS ARE SETTLED ─────────────────────────────────────────
 * A conversation whose last assistant turn holds a tool call with no result
 * cannot be continued: a provider refuses the next request. So every call left
 * open gets the host's notice ({@link OUTCOME_NOT_RECORDED}) — never a result,
 * because the host kept none and whether the call ran is not known. When the
 * run kept this session's conversation while it ran (a durable writer), that
 * is what goes on, its recorded results included.
 */
import { type DecisionUseWatch, type UnanswerableReason } from '../core/consentRequest.js';
import { ResumeDecisionError } from '../core/pause.js';
import type { AgentRunCheckpoint } from '../core/runCheckpoint.js';
import type { LLMMessage } from '../provider-contract/types.js';
import type { CheckpointEnvelope, PausedRun, SessionLifecycle } from './types.js';
/** What a stored session holds, for a door that continues it ({@link readStoredSession}). */
export interface StoredSession {
    /** The conversation the next message continues — a stored one, or an answered pause's. */
    readonly prior?: AgentRunCheckpoint;
    /** The pause still waiting on a person: the only one a door may offer for an answer. */
    readonly waiting?: PausedRun;
    /** A pause whose decision a resume already used — an answer to it is refused. */
    readonly answered?: PausedRun;
}
/**
 * Read a stored session the way every door must: a pause still waiting is
 * offered for an answer; an ANSWERED pause is the conversation the next
 * message continues and is never offered again; a conversation is a
 * conversation. Throws as the envelope readers do on a format this runtime
 * cannot read.
 */
export declare function readStoredSession(stored: CheckpointEnvelope): StoredSession;
/**
 * The format a session LISTING reports for a stored envelope
 * (`SessionSummary.format`): `'flowchart-v1'` only for a pause still waiting
 * on somebody's answer — the one a door would offer for an answer — and
 * `'conversation-v1'` for a conversation, an answered pause
 * (`PausedRun.answered`) and a pause no answer can reach any more
 * ({@link unanswerablePause}, as far as the stored checkpoint can tell).
 *
 * The one reading for every store that lists, so a sidebar never badges a
 * pause the doors would not offer for an answer as "awaiting you". A store
 * that keeps the format in a column or a field writes this when it persists,
 * and reads a row that still says `'flowchart-v1'` again when it lists
 * ({@link listedFormatOfRow}); one that reads its envelopes at list time calls
 * it there. The envelope itself is unchanged: `hydrate` hands back what was
 * stored.
 *
 * Lenient, as a listing must be — it never throws. A value that is not an
 * envelope lists as `'unknown'`, and a pause the readers would refuse lists
 * as stored, so `hydrate` refuses it by name. An ask whose later rules a
 * redeploy changed is told by the serving agent, not by the stored pause: it
 * lists as waiting until a door closes it.
 *
 * @example
 *   // A store's listByUser — or its persist, when the format is a column:
 *   const format = listedFormatOf(envelope);
 */
export declare function listedFormatOf(envelope: unknown): string;
/**
 * The listed format of a row that KEEPS one beside its envelope (a SQLite
 * column, a Firestore field): what the row says — except a stored
 * `'flowchart-v1'`, which is read again from the envelope ({@link listedFormatOf}).
 *
 * A row written before the kept format was the listed one (an earlier
 * release, or an older replica still writing) holds the envelope's own
 * format, so a pause stored then says `'flowchart-v1'` whether or not anyone
 * can still answer it. Only that value can be stale: a row that says
 * anything else is not a pause still waiting, and nothing makes it one
 * without a write. Never throws — text this runtime cannot read keeps what
 * the row says (`hydrate` refuses it by name).
 *
 * @param stored       the format the row keeps.
 * @param envelopeJson the envelope stored beside it, as JSON text.
 */
export declare function listedFormatOfRow(stored: string, envelopeJson: unknown): string;
/**
 * What an answer to an answered pause is refused with: `'already-answered'`,
 * whose message says the earlier resume's outcome is not known here.
 */
export declare function answeredRefusal(answered: PausedRun): ResumeDecisionError;
/**
 * The watch a door opens BEFORE it hands an answer to its runner, and releases
 * once {@link afterFailedAnswer} has decided — `undefined` for a pause no
 * decision answers. Keyed by the pause's request, never by the answer object.
 */
export declare function watchAnswer(paused: PausedRun): DecisionUseWatch | undefined;
/**
 * What {@link afterFailedAnswer} did to the stored pause: marked it answered,
 * closed it (no answer could ever reach it), or kept it as it was.
 */
export type FailedAnswerOutcome = 'marked' | 'closed' | 'kept';
/**
 * After a resume of a consent gate — or what followed it, storing its result
 * included — FAILED, at any door that keeps the pause: when the watch says
 * its decision may have been used (`DecisionUseWatch.mayHaveBeenUsed`),
 * persist the pause marked answered; otherwise nothing of it was used and the
 * pause stays answerable.
 *
 * Read first, to leave alone what must not be overwritten — but only when the
 * read SUCCEEDS: a newer pause the run stored before the failure (this pause
 * is gone, and a decision for it is refused as another request's) or a mark
 * already there. A store that cannot be read, or holds what this runtime
 * cannot read, is marked anyway: failing to read is no proof the decision was
 * unused. A store that holds NOTHING is left so — the session expired or was
 * forgotten while the answer ran, and a mark would bring it back. The
 * conversation the mark goes on from is what the run kept for this session (a
 * durable writer's conversation) when the read shows one, else the
 * conversation as of the pause — never the runner's own state, which on a
 * shared agent may be another session's run.
 *
 * A declined decision never runs its call — but a decline is recorded only
 * when it is what the ledger spent: when the answer that failed was a decline
 * AND the watch saw the request spent for a decline, with no approval taken
 * to a ledger (`DecisionUseWatch.spentAsDecline`), the paused call is
 * settled as declined. A decline refused because the request was already
 * spent — an approval, here or in another process, may have run the call —
 * is settled as unknown, like any other.
 *
 * Unused, and refused for a reason no decision can change (`error` is a
 * `'request-not-recorded'`, `'call-changed'`, `'chain-changed'` or
 * `'ledger-changed'` refusal):
 * the pause is CLOSED instead — it could only ever hold the session. Read
 * from the refusal's own code, which is safe only because THIS resume used
 * nothing. An earlier one may have — a resume that ran the call and then
 * could not mark the pause answered — so the calls it leaves open are
 * recorded as not run only on proof ({@link closedConversation}, asked of
 * `runner`'s ledger), else as not known.
 *
 * Only a failure of the WRITE itself is swallowed — the run's failure is the
 * one the caller is told, and the ledger still refuses the decision in this
 * process — and it is reported on the console, never silent.
 *
 * @param watch  the door's {@link watchAnswer}, opened before the resume.
 * @param answer the answer as the door handed it over — read only to tell a
 *   decline, and only from its own data properties.
 * @param settle writes still in flight for this session (a durable writer),
 *   drained first so none lands on top of the mark.
 * @param runner the runner the answer was handed to — whose ledger can prove
 *   that a closed pause's calls never ran.
 */
export declare function afterFailedAnswer(input: {
    readonly store: SessionLifecycle;
    readonly sessionId: string;
    readonly paused: PausedRun;
    readonly watch: DecisionUseWatch | undefined;
    readonly answer?: unknown;
    /** What the resume — or what followed it — threw. */
    readonly error?: unknown;
    readonly settle?: () => Promise<void> | undefined;
    readonly runner?: unknown;
}): Promise<FailedAnswerOutcome>;
/**
 * What the model reads for a call whose question no answer can reach any more
 * — its pause was closed, and the call PROVABLY did not run: the ledger its
 * request was minted under spent the request itself, so no decision for it
 * had been handed over and none ever can be (`consentRequest.ts` ·
 * `proveNeverRan`).
 */
export declare const NOT_RUN_UNANSWERABLE = "That call did not run: the question it waited on could no longer be answered.";
/**
 * What the model reads for each call a pause no answer can reach left open,
 * when it cannot be proven that the call never ran: a decision for the pause
 * may have been used — by a resume whose failure the host could not record —
 * so the call may have run. Never "did not run" without proof, and never an
 * invitation to try again: a model told a refund did not run may issue it
 * again. The same words for every open call — the paused one and a sibling
 * that never needed an approval alike — so none of them names an approval.
 */
export declare const OUTCOME_UNKNOWN_UNANSWERABLE = "This call may have run; no result was kept. Do not run it again. Tell the person it may already have happened and ask them to check.";
/**
 * Why the stored pause can never be answered by `runner` — `undefined` when it
 * can, or when that cannot be told (`core/consentRequest.ts` ·
 * `unanswerableReason`). Without a runner, or with one whose rules and
 * ledger a host cannot see (a composition, an app's own), an ask's chain and
 * the ledger binding (`'ledger-changed'`) are not checked.
 */
export declare function unanswerablePause(paused: PausedRun, runner?: unknown): UnanswerableReason | undefined;
/** The door closing a pause: who serves the session, and where it keeps its pauses. */
export interface ClosingDoor {
    /** The runner serving the session — an agent this library built names its ledger. */
    readonly runner?: unknown;
    /** The door's session store — this process's memory or not (`processLocalStore.ts`). */
    readonly store?: unknown;
}
/**
 * The conversation a pause no answer can reach goes on from: every call it
 * left open settled by the host's notice — none of them can run from here.
 *
 * "Did not run" ({@link NOT_RUN_UNANSWERABLE}) ONLY when non-execution is
 * proven: the ledger the request was minted under — the serving agent's,
 * and only when it is the same one — spends the request itself, atomically
 * (`consentRequest.ts` · `proveNeverRan`). That both proves no decision had
 * reached it and makes sure none ever will: closing CONSUMES the request. The
 * record alone cannot say it — a resume may have run the call and then failed
 * to mark the stored pause answered, before a redeploy made the pause one no
 * answer can reach. Otherwise, and whenever the proof cannot be had, every
 * open call is recorded as possibly run ({@link OUTCOME_UNKNOWN_UNANSWERABLE}).
 * Every notice is marked as the library's (`toolResultOrigin`).
 */
export declare function closedConversation(paused: PausedRun, door?: ClosingDoor): Promise<AgentRunCheckpoint>;
/** The paused call a person declined — that call never ran. */
export interface DeclinedCall {
    readonly toolCallId: string;
    /** The person's note, when the decline carried one. */
    readonly note?: string;
}
/**
 * What the model reads for a call the run left open: a past fact about that
 * call, and a notice rather than its result.
 */
export declare const OUTCOME_NOT_RECORDED: string;
/**
 * The stored pause, marked answered: a decision for it is refused from here
 * on, and the conversation it goes on from has every call left open settled
 * as unknown — the call a person declined, as declined: it did not run.
 *
 * @param progressed this session's conversation as the run kept it, or
 *   `undefined` to go on from the conversation as of the pause.
 * @param declined the paused call, when the answer declined it.
 */
export declare function markAnswered(paused: PausedRun, progressed: AgentRunCheckpoint | undefined, now?: number, declined?: DeclinedCall): PausedRun;
/**
 * The tool calls in `history` that no tool message answered, in the order the
 * model made them.
 */
export declare function openToolCalls(history: readonly LLMMessage[]): readonly {
    readonly id: string;
    readonly name: string;
}[];
/**
 * `history` with every open tool call settled by the host's notice — the same
 * history when none is open. Each notice is marked as the library's
 * (`toolResultOrigin`: `'outcome-unknown'`, or `'not-entered'` for a declined
 * call), whether or not the run served findings.
 *
 * @param declined the call a person declined, settled as declined — the
 *   result the dispatch loop records for a decline — instead of as unknown.
 */
export declare function settleOpenCalls(history: readonly LLMMessage[], declined?: DeclinedCall): LLMMessage[];
