UNPKG

agentfootprint

Version:

The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.

1,817 lines • 102 kB
/**
 * Agent — ReAct primitive (LLM + tools + iteration loop).
 *
 * Pattern: Builder (GoF) → produces a Runner backed by a footprintjs FlowChart.
 * Role:    Layer-5 primitive (core/). Assembles the 3-slot context
 *          pipeline + callLLM + route decider + tool-calls subflow +
 *          loopTo. Composition nestable anywhere that accepts a Runner.
 * Emits:   Via internal recorders:
 *            agentfootprint.agent.turn_start / turn_end
 *            agentfootprint.agent.iteration_start / iteration_end
 *            agentfootprint.agent.route_decided
 *            agentfootprint.stream.llm_start / llm_end
 *            agentfootprint.stream.tool_start / tool_end
 *            agentfootprint.context.* (via ContextRecorder)
 */
import { type CombinedNarrativeEntry, type FlowchartCheckpoint, type ObserverDrainResult, type RedactionPolicy, type RuntimeSnapshot } from 'footprintjs';
import type { RunOptions } from './runner.js';
import type { CachePolicy, CacheStrategy } from '../cache/types.js';
import type { ReliabilityConfig } from '../reliability/types.js';
import { type RunnerPauseOutcome } from './pause.js';
import type { ArtifactStore } from '../artifacts/types.js';
import type { AgentfootprintEvent } from '../events/registry.js';
import type { SkillGraphDeclaredMap } from './agent/skillGraphDeclared.js';
import type { AppliedRecipe } from '../recipes/types.js';
import type { WindowStrategy } from './agent/window/strategy.js';
import type { AnswerAssessment, AssessmentDeclarations } from './agent/assessment/types.js';
import { type CheckInBuilderOptions } from './checkin.js';
import type { MemoryDefinition } from '../memory/define.types.js';
import type { MemoryIdentity } from '../memory/identity/types.js';
import type { SelfExplainBinding } from '../trace-toolpack/selfExplain.js';
import { type ChildOutcome } from './terminalVerdict.js';
import type { ResolvedEvidenceGate } from './agent/evidence/types.js';
import type { ResolvedScriptTravel } from './agent/scripts/types.js';
import type { Injection, InjectionContext } from '../injection-engine/types.js';
import type { CursorMove, EntryScoring, TurnRoutingPlan } from '../injection-engine/skillGraph.js';
import { type ResolvedOutputFallback } from './outputFallback.js';
import { type AgentRunCheckpoint } from './runCheckpoint.js';
import { type OutputSchemaParser } from '../answer-validation/outputSchema.js';
import { type RunTime } from '../time/clock.js';
import type { ResolvedOutputEnforcement } from './agent/outputEnforcement.js';
import { RunnerBase } from './RunnerBase.js';
import type { ToolRegistryEntry } from '../tools/tools.js';
import type { ToolProvider } from '../tools/toolProvider.js';
import type { AgentArtifactsOptions, AgentInput, AgentOptions, AgentOutput, AgentRecordingsOptions, AgentState, ObserverDeliveryOptions, RunConfig, RunConfigContext, RunConfigFn, WriteProvenanceMode } from './agent/types.js';
import type { ResolvedNegativeClaims } from './agent/negativeClaims/config.js';
import type { AnswerNegatives } from './agent/negativeClaims/delivery.js';
import type { AnswerCoverage } from '../semantics/coverage/answer.js';
import { type AnswerValidationReport, type ResolvedAnswerValidation } from '../answer-validation/index.js';
import type { MessageMiddleware, ToolMiddleware } from './agent/middleware/types.js';
import { AgentBuilder } from './agent/AgentBuilder.js';
export type { SkillGraphOptions } from './agent/AgentBuilder.js';
export type { ProviderChoice, EscalationPolicy } from './agent/skillBrains.js';
import type { ThinkingHandler } from '../thinking/types.js';
export { AgentBuilder };
export type { AgentArtifactsOptions, AgentInput, AgentOptions, AgentOutput, AgentRecordingsOptions, ObserverDeliveryOptions, RunConfig, RunConfigContext, RunConfigFn, WriteProvenanceMode, };
/**
 * `RunOptions` (footprintjs) + agentfootprint-domain correlation fields.
 *
 * `correlationId`/`traceId` are NOT footprintjs concepts — footprintjs's
 * `RunOptions.env` is an intentionally closed infra bag (signal/timeoutMs/
 * traceId only; see footprintjs's `ExecutionEnv`). These two ride separately
 * into `Agent.currentRunContext` and from there into every emitted event's
 * `EventMeta` via `buildEventMeta` (`RunContext` already declares both —
 * `../bridge/eventMeta.ts`), so a caller can join agentfootprint's event
 * stream against an external system (a upstream request id, an OTEL trace,
 * a cross-tier why() join key) without threading it through tool args.
 *
 * `traceId` here wins over `env.traceId` when both are set; `env.traceId`
 * remains a fallback since footprintjs already threads it to subflows.
 */
export interface AgentRunOptions extends RunOptions {
    /** Domain correlation id — forwarded onto every emitted event's `EventMeta.correlationId`. */
    correlationId?: string;
    /** OTEL-style trace id — forwarded onto every emitted event's `EventMeta.traceId`. Falls back to `options.env?.traceId` when unset. */
    traceId?: string;
    /**
     * The hosting CONVERSATION this run belongs to (9.4.0) — forwarded onto
     * every emitted event's `EventMeta.sessionId`, and from there into whatever
     * an observability strategy ships (the CloudWatch/AgentCore adapters
     * serialize the whole envelope, so it arrives without their knowing).
     *
     * `runId` is per run; a session spans many. Without this, a shipped event
     * stream can answer "what happened in this run?" and not "what happened in
     * this conversation?", which is the question a session-oriented host is
     * built around. `standingAgent` sets this for you from the request's own
     * session id, on both `run()` and `resume()`.
     *
     * **It also decides the memory namespace when you named no identity
     * (9.10.0):** a run with a session and no `identity` scopes its memory to
     * `{ conversationId: sessionId }`, because a hosting session IS a
     * conversation. An `identity` you pass always wins. See
     * {@link AgentInput.identity} for the full ladder.
     *
     * Omit it for an unhosted run. It is never derived, guessed, or defaulted to
     * the runId: an absent session and an invented one are different facts.
     */
    sessionId?: string;
    /**
     * Who this run is for — the same tuple as `run({ identity })`, reachable
     * from the doors whose input is a stored conversation rather than a
     * message bag: `resumeOnError(checkpoint, { identity })` and
     * `followUp(message, { identity })` (9.2.0).
     *
     * Before this existed, `resumeOnError` could not carry an identity at all,
     * so every continued turn silently re-namespaced its memory under a fresh
     * runId. Omitted, the conversation's own stored `identity` is used; given,
     * it wins. On `run()` this is a second spelling of `run({ identity })` and
     * the one on the input wins, since that is where the caller looked first.
     */
    identity?: MemoryIdentity;
    /**
     * THIS TURN'S CLOCK, on the doors whose input is not a message bag —
     * `followUp(message, { time })`, `resumeOnError(checkpoint, { time })` and
     * `resume(checkpoint, answer, { time })` — read only by an agent with
     * `.time()`, refused on one without. On `run()` it is a second spelling of
     * `run({ time })`, and the one on the input wins. On `resume()` the paused
     * turn's clock is KEPT (its words were resolved against it): a `time` that
     * differs is recorded as a `clock-on-resume` row, never applied.
     */
    time?: RunTime;
    /**
     * A redaction policy the CALLER adds for this run, joined with the agent's
     * own `redact` — it can only add names, never remove one. This is how a
     * policy reaches an agent run on someone else's behalf: a tool that runs
     * another agent hands it the policy its own run is covered by, exactly as it
     * hands `ctx.signal`:
     *
     * ```ts
     * execute: (args, ctx) => specialist.run({ message: args.text }, {
     *   ...(ctx.signal && { env: { signal: ctx.signal } }),
     *   ...(ctx.redact && { redact: ctx.redact }),
     * })
     * ```
     *
     * Validated like `Agent.create({ redact })`. A pause carries it: the run
     * commits it to its own state (`runRedaction`: its names, and each pattern
     * as a reference), so `resume()` covers the resumed leg by it without being
     * handed it again — except a pattern of your own, which is never compiled
     * from a checkpoint: pass the same `redact` to `resume()` (or declare it on
     * the agent), or the resume is refused (`ResumeRedactionError`,
     * `'unknown-pattern'`). A `redact` passed to `resume()` adds to it. A
     * conversation continued from the run (`followUp`, `continueFrom`) is a new
     * run, covered by what it is given.
     */
    redact?: RedactionPolicy;
}
export declare class Agent extends RunnerBase<AgentInput, AgentOutput> {
    readonly name: string;
    readonly id: string;
    private readonly provider;
    private readonly model;
    private readonly temperature?;
    private readonly maxTokens?;
    private readonly maxIterations;
    private readonly systemPromptValue;
    /**
     * Cache policy for the base system prompt (set via
     * `.system(text, { cache })`). Default `'always'` — base prompt is
     * stable per-turn, ideal cache anchor. CacheDecision subflow reads
     * this when computing the SystemPrompt slot's cache markers.
     */
    private readonly systemPromptCachePolicy;
    /**
     * Global cache kill switch from `Agent.create({ caching: 'off' })`.
     * Threaded into agent scope at seed-time as `scope.cachingDisabled`;
     * read by the CacheGate decider every iteration (highest-priority rule).
     */
    private readonly cachingDisabledValue;
    /**
     * The CacheStrategy this agent runs. Chosen at build time from the
     * provider's declared `promptCaching` (`cacheStrategyFor`) unless the
     * consumer passes one explicitly.
     */
    private readonly cacheStrategy;
    private readonly cacheStrategyIsOverride;
    private readonly cacheUnsupported;
    private readonly registry;
    /**
     * The Injection list — Skills, Steering, Instructions, Facts (and
     * RAG, Memory). Evaluated each iteration by the
     * InjectionEngine subflow; active set is filtered by slot subflows.
     */
    private readonly injections;
    /** Skill-graph cursor resolver (`graph.nextSkill`), set when built via
     *  `.skillGraph(graph)`. Plumbed into the Injection Engine so route triggers
     *  are `from`-gated against the persisted `currentSkillId`. */
    private readonly skillGraphNextSkill?;
    /** Skill-graph reachable-set resolver (`graph.reachableSkills`), set when built
     *  via `.skillGraph(graph)`. Plumbed into the tool-calls handler so `read_skill`
     *  is gated to in-graph jumps. Undefined → gate off. */
    private readonly skillGraphReachable?;
    /** Skill-graph relevance entry scorer (`graph.scoreEntries`), set when built via
     *  `.skillGraph(graph)` with `.entryByRelevance()`. Drives the PickEntry stage.
     *  Undefined → no relevance entry routing (cold-start entry as before). */
    private readonly skillGraphScoreEntries?;
    /** The `to` end of every edge the mounted graph declares — which skills the graph
     *  WIRES. Empty for a graph-less agent. Read only by `openSkillIds()`. */
    private readonly skillGraphEdgeTargets;
    /** Skill-graph cursor resolver that also reports WHICH CLAUSE won
     *  (`graph.explainNextSkill`, 8.5.0). Threaded to the Injection Engine, which
     *  stamps the result on `context.evaluated` as `cursorMove`. Optional — a graph
     *  built before it existed falls back to `nextSkill` and emits no `cursorMove`. */
    private readonly skillGraphExplainNextSkill?;
    /** Skill-graph suppression reporter (`graph.supersededEntries`, 8.15.0) — the
     *  conditional entries whose `when` matched while the cursor was elsewhere.
     *  Threaded to the Injection Engine, which stamps them on `context.evaluated` as
     *  `supersededIds`. Optional — a graph built before it existed routes identically
     *  and simply emits no `supersededIds`. */
    private readonly skillGraphSupersededEntries?;
    /** Is the mounted graph a decision `tree()`? Derived at build time from
     *  `graph.nodes` (a tree is the only shape with `predicate` nodes) — no new
     *  public field on `SkillGraph`. Read for ONE thing: the read_skill gate's
     *  refusal has to explain that a tree has no cursor to jump (8.5.0). */
    private readonly skillGraphIsTree;
    /** The turn-start cascade wiring (SG-C, 9.17.0) — the graph's routing plan,
     *  the mount's posture/continuity, and the node-id set droppedResume checks
     *  against. Absent (every graph without the new options) → RouteTurn never
     *  mounts, the gate never postures, seed never restores a cursor, and the
     *  checkpoint shape is byte-identical. */
    /** The folded per-skill brains + escalation + decider (9.19.0) —
     *  validated at `AgentBuilder.build()`. Undefined = no brain anywhere:
     *  callLLM, the gate, seed and RouteTurn wire nothing new. */
    private readonly skillBrains?;
    /**
     * The evidence gate (9.35.0) — `.namesAndNumbersFromEvidence()`, resolved by
     * the builder. Undefined for every agent that did not ask for it, and that
     * undefined is the whole zero-cost guarantee: no decider change, no branch,
     * no scope key, no event.
     */
    private readonly evidenceGate?;
    /**
     * `.limitsTravelWithTheAnswer()` — whether the run's declared coverage
     * travels with the final answer: appended as a block to a prose answer, or,
     * when an output schema makes the answer TYPED, committed beside it as data
     * (`answerCoverage()`), because JSON followed by prose is not JSON. False for
     * every agent that did not ask for it; the RECORDING half of the coverage
     * primitives does not consult it.
     */
    private readonly limitsTravelWithTheAnswerValue;
    /**
     * `.scriptTravelsWithTheAnswer()` — the resolved arm, or undefined for every
     * agent that did not ask. With `code: 'match'` on the gate it arms the
     * script record (`scriptRecordArmed`); alone it also picks the final stage.
     */
    private readonly scriptTravel?;
    private readonly skillGraphCascade?;
    /** Side channel for the conversation's inherited skill cursor (SG-C) —
     *  stashed by `applyContinuation`, consumed-and-cleared by seed. */
    private pendingResumeSkillCursor?;
    private readonly pricingTable?;
    /** Normalized at construction: a bare number is `{ usd, onExceed: 'warn' }`. */
    private readonly costBudget?;
    /** Per-slot character budgets (8.11.0). Absent keys keep the slot default. */
    private readonly contextBudget?;
    private readonly permissionChecker?;
    private readonly toolArgValidation?;
    /** See AgentOptions.findings (9.101.0). Set by `.findings()` and undefined
     *  on every other agent — the one value every findings gate below is
     *  conditioned on, so an unarmed agent hands each stage exactly the deps
     *  it always did. `serve` is threaded to seed (the run constant
     *  `findingsServe`) and to call-llm (`findingsServe` in its deps) on an
     *  armed agent only; `answerAsk` (9.103.0) rides the same two threads
     *  as `findingsAnswerAsk`, and only when it is `'quote-facts'` — the
     *  default `'none'` threads nothing. `keepLedgerFacts` is resolved once, here in the
     *  constructor (this door over `AgentOptions.keepLedgerFacts`), into the
     *  `keepLedgerFacts` field below and threaded to the window stage on an
     *  armed agent with a window, where `stages/window.ts · buildWindowStage`
     *  spends it as the `'ledger-fact'` pin ceiling. */
    private readonly findingsOptions?;
    /** `.inputsLayer()` (honesty layer 2): mount the inputs layer even when no
     *  registered tool declares `askOrAssume` — for ruled tools only a
     *  ToolProvider serves, which the build cannot see. */
    private readonly inputsLayerOption?;
    /** DECLARED SOURCES (honesty layer 2): `.findings({ argumentSources: true })`
     *  or `.inputsLayer({ argumentSources: true })` — resolved ONCE, in the
     *  constructor, from either door; every declared-sources gate below reads
     *  this one value, so the two doors can never arm different halves. The
     *  findings ledger's own serve stays `findingsOptions`'s: without
     *  `.findings()` the arm plants `_findings.from` on ruled tools only. */
    private readonly argumentSourcesArmed?;
    /** `AgentOptions.argumentAskContext` (honesty layer 2): the host's own
     *  context for the inputs layer's batch ask, handed to the dispatch stage
     *  only when the layer is mounted. */
    private readonly argumentAskContext?;
    /** Whether this agent's chart mounts the inputs layer (`sf-inputs`) —
     *  decided ONCE, in `buildChart`: a registered tool declares rules, or
     *  `.inputsLayer()` was set. Gates the findings event bridge and the
     *  widened ledger restore. */
    private inputsLayerArmed;
    /** `.resultsLayer()` (honesty layer 3, step 7b): mount the results layer
     *  even when no registered tool declares a `ToolPeriod` — for tools a
     *  ToolProvider serves, and for tools that declare a period only on their
     *  results. */
    private readonly resultsLayerOption?;
    /** Whether this agent's chart mounts the results layer (`sf-results`) —
     *  decided ONCE, in `buildChart`: a registered tool declares a `ToolPeriod`,
     *  or `.resultsLayer()` was set. Gates the findings event bridge and the
     *  widened ledger restore, as the inputs layer's flag does. */
    private resultsLayerArmed;
    /** `.answerLayer()` (honesty layer 4): the answer's standing folded at the
     *  head of the final branch and served as data; `standingLine` — also one
     *  line appended to a prose answer, for the standings its mode names
     *  (`'always'` for `standingLine: true`). Undefined on every agent that did not
     *  ask, and that undefined is the whole zero-cost guarantee: no stage, no
     *  witness row, no stamp, no event, no bridge. */
    private readonly answerLayerOption?;
    /** `.time()` (the time layer, `time/`): the fallback zone, as read.
     *  Undefined on every agent that did not ask — then no clock is read, no
     *  time row is filed and `time` on a run is refused. */
    private readonly timeOptions?;
    /** The clock the CURRENT `run()`'s seed stamps — set by `run()` (a run with
     *  no zone gets an unknown one, never the server's), read by seed through `SeedStageDeps.timeClock`, and
     *  cleared when `run()` ends, so a later turn this agent did not start (its
     *  chart mounted in a composition) never stamps a clock nobody declared for
     *  it (`seedClockDraft`). */
    private runClockDraft;
    /** The incoming request each of this agent's OWN scopes serves — recorded
     *  by the executor that made the scope (`createExecutor`), so a scope keeps
     *  ITS run's request for as long as it lives: a stage still running after
     *  its run was aborted can never be served the next run's request. A stage
     *  mounted in another runner's executor reads its run's request by link
     *  (`memberRun.ts`). Never written to scope. */
    private readonly scopeRequests;
    /** The `time` the CURRENT resume passed, as read — TAKEN once by the first
     *  ToolCalls pass of the resumed leg (`ToolCallsHandlerDeps.time`), and
     *  cleared when `run()` or `resume()` ends. */
    private resumePassedTime;
    /** Tool choice by classifier (9.105.0, `.toolChoice()`): the classifier,
     *  the serve dial and the app's own doors. Threaded to the tools slot (the
     *  pick and the narrowing), to call-llm (`toolChoice: true`, the outcome
     *  row) and to both chart builders (`hasToolChoice`, the mount args) on an
     *  armed agent only — an unarmed agent hands each stage exactly the deps it
     *  always did. */
    private readonly toolChoiceOptions?;
    /** The declared ontology (9.106.0, `.ontology()`): the frozen map. Threaded
     *  to seed (the whole map, written once as the run constant `ontology`),
     *  to call-llm (`ontology: true`, the gate on every read of that key) and
     *  to both chart builders (`hasOntology`, the grouped boundary's crossing)
     *  on an armed agent only — an unarmed agent hands each stage exactly the
     *  deps it always did. The tool names its `via` edges name are checked
     *  against the registry in `buildChart`, beside `buildToolRegistry`. */
    private readonly ontology?;
    /** The map's tool → declaring-skills join (9.108.0), read off the registry
     *  in `buildChart` beside the `via` check; `undefined` when no `via` name
     *  is a skill's. Seed reads it through a thunk (the stage is built first). */
    private ontologyTools?;
    /** The opt-in tool-result ceiling in characters (9.11.0). Absent → results
     *  are never measured. See {@link AgentOptions.maxToolResultChars}. */
    private readonly maxToolResultChars?;
    /** Resolved check-in config (evidence-carrying human consent). Always
     *  present — defaults to `standard` evidence + the lexical scorer, so a tool
     *  that declares `checkIn` works even without a `.checkIn()` builder call. */
    private readonly checkInConfig;
    /** Where answered consent requests are spent (`AgentOptions.decisionLedger`).
     *  Undefined → this process's ledger, shared by every agent that names none. */
    private readonly decisionLedger?;
    /** Per-run config resolver from `.configure()`. Undefined for every agent
     *  that never called it — and the chart is then built exactly as before,
     *  with no scope writes and no scope reads added. */
    private readonly runConfigFn?;
    /** The agent's one window strategy. Undefined = no window stage, loop
     *  target unchanged, run byte-identical to an agent without it. */
    private readonly windowStrategy?;
    /** The tool-dispatch chain (`.toolMiddleware()`), in declaration order.
     *  Empty for every agent that never called it — and then the dispatch loop
     *  never walks a chain, never writes the ledger key, and never emits. */
    private readonly toolMiddleware;
    /** The message chain (`.messageMiddleware()`), in declaration order. Empty
     *  keeps seed synchronous and prepare-final untouched. */
    private readonly messageMiddleware;
    /** The instrument the window stage reads mid-run (adapter-reported usage +
     *  per-message provenance). Only ever created alongside a strategy. */
    private readonly compactionMeterHandle?;
    /** The window stage's seam to the receipt (9.93.0): what left the window at
     *  this iteration's head, read by the call-llm mint in the same iteration.
     *  Only ever created alongside a strategy, like the meter. */
    private readonly evictedTurnsHandle?;
    /** Snapshot read-tracking policy (#18/#14) — forwarded to the internal
     *  executor. Agent default is `'summary'` (cheap markers), NOT
     *  footprintjs's `'full'`. See AgentOptions.readTracking. */
    private readonly readTracking;
    /** Commit-log value encoding (#13c-B) — forwarded to the internal
     *  executor. Agent default is `'delta'` (append/delete verbs; growing
     *  arrays like `history` record only their tails — lossless, linear
     *  retained memory), NOT footprintjs's `'full'`. See
     *  AgentOptions.commitValues. */
    private readonly commitValues;
    /** Per-write read provenance (#P1) — forwarded to the internal executor.
     *  Default `'off'` (footprintjs's own): recordings stay byte-identical
     *  unless a consumer opts in. See AgentOptions.writeProvenance. */
    private readonly writeProvenance;
    private readonly credentialProvider?;
    /** The claim-check store (9.21.0). When set, every tool's `ctx.artifacts`
     *  is this store bound to the run's scope. See AgentOptions.artifacts. */
    private readonly artifactStore?;
    /** The placement threshold (9.22.0) — the operator's ref-ing dial from the
     *  object form of AgentOptions.artifacts. Only ever set beside a store. */
    private readonly artifactPlacement?;
    /** Recordings-as-artifacts (9.26.0) — the operator's dial from the object
     *  form of AgentOptions.artifacts. Only ever set beside a store; absent
     *  means no recorder is ever attached and no run is ever recorded. */
    private readonly artifactRecordings?;
    /** The repeated-call nudge (9.26.0) — `false` only when the operator turned
     *  it off. See AgentOptions.repeatedCallNudge. */
    private readonly repeatedCallNudge?;
    /** The out-of-budget wrap-up (9.56.0) — `false` only when the operator
     *  turned it off. See AgentOptions.wrapUpAtMaxIterations. */
    private readonly wrapUpAtMaxIterations?;
    /** The last-tool-result pin (9.57.0) — set only when the operator named a
     *  value other than the default 2. See AgentOptions.keepLastToolResults. */
    private readonly keepLastToolResults?;
    /** The ledger-fact hold's ceiling (9.102.0), RESOLVED — set exactly when
     *  `.findings()` is on: `findings({ keepLedgerFacts })` over
     *  `AgentOptions.keepLedgerFacts`, `false` → `0`, nothing named →
     *  `DEFAULT_KEEP_LEDGER_FACTS`. Undefined on every unarmed agent, so the
     *  thread into the window stage reads as the decision it is. See
     *  AgentOptions.keepLedgerFacts. */
    private readonly keepLedgerFacts?;
    /** See AgentOptions.integrityPosture (9.60.0). Default 'observe'. */
    private readonly integrityPosture;
    /**
     * The per-run disposition ledger, shared with the check sites by
     * REFERENCE through build-time closures (the ProviderToolCache pattern —
     * plumbing, never scope state). `run()` resets it; the run boundary
     * files its report and clears it.
     */
    private readonly integrityLedgerHolder;
    /** Set at chart build: whether any tool in the FULL declared catalog
     *  (static registry + skill-carried tools) declared `argumentsFrom`. */
    private integrityDanglingPresent;
    /** See AgentOptions.noticeEmptyLookups (9.77.0). Default false — absent is
     *  byte-identical, save for the registered not-applicable ledger row. */
    private readonly noticeEmptyLookups;
    /** See AgentOptions.noticePriorTurnEvidence (9.83.0). Default false —
     *  absent is byte-identical, save for the registered not-applicable ledger
     *  row. */
    private readonly noticePriorTurnEvidence;
    /** Set at chart build: whether any tool in the FULL declared catalog
     *  declared `resultColumns` (9.78.0) — the other half of the column-type
     *  contract's arming. */
    private integrityColumnsPresent;
    /** See AgentOptions.checkColumnTypes (9.78.0). Default 'off' — absent is
     *  byte-identical, save for the registered not-applicable ledger rows. */
    private readonly checkColumnTypes;
    /** See AgentOptions.externalGrounds (9.72.0). Absent = door closed,
     *  byte-identical behavior. */
    private readonly externalGrounds?;
    /** What a run does when a declared credential needs 3LO consent (8.6.0).
     *  Default `'pause'`. See AgentOptions.onAuthorizationRequired. */
    private readonly onAuthorizationRequired;
    /**
     * Consent blocks outstanding in THIS run, keyed by service — the
     * `'tell-model'` honesty ledger, and the only place the authorization URL
     * lives between the block and the caller.
     *
     * It is a plain instance field rather than a scope key on purpose: tracked
     * state is the commit log, which is the snapshot, the narrative and every
     * recording, and this value is a bearer capability. Cleared at the top of
     * every `run()` / `resume()` so one run can never raise on another's block,
     * and cleared per service the moment that credential is issued.
     */
    private readonly consentOutstanding;
    /** Evidence bridge (#5) — present iff a CAUSAL memory is mounted. */
    private readonly causalEvidence?;
    /** Observer delivery tier (RFC-001 Block 10). `'inline'` (default) is
     *  byte-identical to pre-10 releases; `'deferred'` routes the bridge
     *  recorders + consumer attachments through footprintjs's bounded
     *  capture queue. See AgentOptions.observerDelivery. */
    private readonly observerDelivery;
    /** Queue dials forwarded on every deferred attach (first attach
     *  configures the executor's single dispatcher). */
    private readonly observerDeliveryOptions?;
    /**
     * Voice config — shared by viewers (Lens, ChatThinkKit, CLI tail).
     * `appName` is the active actor in narration ("Chatbot called…").
     * `commentaryTemplates` drives Lens's third-person panel.
     * `thinkingTemplates` drives chat-bubble first-person status.
     * Defaults to bundled English; consumer overrides via builder.
     */
    readonly appName: string;
    readonly commentaryTemplates: Readonly<Record<string, string>>;
    readonly thinkingTemplates: Readonly<Record<string, string>>;
    private currentRunContext;
    /**
     * The typed ask the CURRENT run's resume answered — set by
     * `resume()` when a person's answer completed an `awaitingInput`, cleared
     * by every other run start, so a pooled agent never marks one session's
     * ask as another's re-ask. Read by the dispatch door through
     * `ToolCallsHandlerDeps.answeredAsk`. The count crosses checkpoints on the
     * awaiting-input shape itself (`repeat.count`), not here.
     */
    private answeredAsk;
    /**
     * Memory subsystems registered via `.memory()`. Each definition mounts
     * its `read` subflow before the InjectionEngine on every turn; per-id
     * scope keys (`memoryInjectionKey(id)`) keep multi-memory layering
     * collision-free.
     */
    private readonly memories;
    /**
     * Optional terminal contract. Set via the builder's `.outputSchema()`.
     * When present, `agent.runTyped()` parses + validates the final
     * answer against this parser. `agent.run()` keeps returning the
     * raw string; consumers opt into typed mode explicitly.
     */
    private readonly outputSchemaParser?;
    /**
     * What the LOOP enforces about the output (7.26) — resolved by the builder
     * when `.outputSchema()` was given `retries` or a `'tool-forced'` strategy.
     * Undefined otherwise, and undefined is the whole of the byte-identical
     * path: no branch is mounted, the decider is the function it always was,
     * and the request is the one 7.25 sent.
     */
    private readonly outputEnforcement?;
    /**
     * Optional 3-tier degradation for output-schema validation
     * failures. Set via the builder's `.outputFallback({...})`. When
     * present, `parseOutput()` and `runTyped()` fall through:
     *   primary → fallback → canned (in order; canned guarantees no-throw).
     */
    private readonly outputFallbackCfg?;
    /** Side-channel for `run({ continueFrom })` and `resumeOnError(...)` —
     *  when set, the seed function restores `scope.history` from this
     *  instead of starting fresh, and appends this turn's user entry when
     *  `appendsUserTurn` says so. Cleared on first read so subsequent runs
     *  start clean. */
    private pendingResumeHistory?;
    /** Retried request's repair state; never inherited by a new human turn. */
    private pendingEvidenceRecovery?;
    /** Its sibling for the folded spans. A restored conversation that dropped
     *  them would carry summaries nobody could unpack — the evidence would be
     *  destroyed by the act of continuing, which is the one thing retention
     *  exists to prevent. Cleared on first read, exactly like the history. */
    private pendingResumeFolded?;
    /** Its sibling for the findings ledger (9.101.0) — the model's standings
     *  on results this process never saw, carried by the checkpoint and
     *  restored as a stored record. Cleared on first read, like the history. */
    private pendingResumeFindingsLedger?;
    /** The last completed run's final answer — see `checkpoint()` for why it is
     *  kept here rather than read back from the recording. Undefined after a run
     *  that failed or paused. */
    private lastRunAnswer?;
    /** Last run's checkpoint owner, including explicit replay edits from a failed child stage. */
    private checkpointTracker?;
    /** Whether any run on this instance got past input admission — so a
     *  refused FIRST turn is reported as 'never-run', never as "continue from
     *  your earlier accepted checkpoint" when there is none. */
    private hadAdmittedRun;
    /** The id the CONSUMER chose, or undefined when they took the default.
     *  `this.id` cannot answer that question — it is `'agent'` either way — and
     *  the stored-conversation fingerprint refuses only on ids somebody picked
     *  (see `AgentRunCheckpoint.agent`). */
    private readonly explicitId?;
    /** The identity the caller gave the last run, or undefined when they gave
     *  none. Only an EXPLICIT identity is carried onto `checkpoint()`: the
     *  default is derived from a runId, and storing that would pin a whole
     *  conversation to the id of the one run that started it.
     *
     *  Written by BOTH run doors, before the executor exists: `run()` from the
     *  call and the continued conversation, `resume()` from the call and the
     *  paused run's own record (`agent/callerIdentity.ts · callerIdentityOf`).
     *  A resume that inherited it instead stored another person's identity on
     *  a shared agent and none on a rebuilt pooled one. */
    private lastRunIdentity?;
    /** Run ids this instance minted, most recent last (bounded) — evidence that a
     *  checkpoint's `{ conversationId: '<runId>' }` is the per-run default
     *  (`agent/callerIdentity.ts`). */
    private readonly mintedRunIds;
    /** The self-explain evidence key of the run in flight (or served last):
     *  its session, else a host's per-request key, else undefined
     *  (`agent/servingConversation.ts`). */
    private servingConversation?;
    /** How long ONE tool teardown may take before the runner stops waiting.
     *  See `AgentOptions.toolTeardownTimeoutMs`. */
    private readonly toolTeardownTimeoutMs;
    /** The run in flight, by id — the whole of the one-turn-at-a-time guard.
     *  Set before the executor is built and cleared in `finally`, so a run that
     *  throws does not leave the agent permanently refusing. */
    private inFlightRunId?;
    /** The scopes this agent's OWN executors made — see the `isOwnRun` seed dep. */
    private readonly ownScopes;
    /** The question a person still owes this agent an answer to. Set when a run
     *  ends paused, cleared by `resume()`, `abandonPause()`, or a run that
     *  completes. Read by the `run()` guard — see `PendingQuestionError`. */
    private pendingQuestion?;
    /** The `.selfExplain()` binding, when the builder mounted one. Held so
     *  `canExplain()` can answer the same question the trace tools answer, from
     *  the same fact. Undefined on every agent that never called `.selfExplain()`. */
    private selfExplainBinding?;
    /**
     * Optional `ToolProvider` set via the builder's `.toolProvider()`.
     * When present, the Tools slot subflow consults it per iteration
     * (Block A5 follow-up) — the provider's tools land alongside any
     * tools registered statically via `.tool()` / `.tools()`. The
     * tool-call dispatcher also consults it for per-iteration execute
     * lookup so dynamic chains (`gatedTools`, `skillScopedTools`)
     * dispatch correctly when their visible-set changes mid-turn.
     */
    private readonly externalToolProvider?;
    /**
     * Optional rules-based reliability config (v2.11.5+). Set via the
     * builder's `.reliability({...})`. When present, every CallLLM
     * execution is wrapped in a retry/fallback/fail-fast loop driven
     * by `preCheck` and `postDecide` rules. Consumed by `buildCallLLMStage`.
     */
    private readonly reliabilityConfig?;
    /**
     * Resolved ThinkingHandler (v2.14+). The provider's DECLARED one
     * (`thinkingHandlerFor`) UNLESS the builder explicitly set one
     * (or `null` to opt out). When undefined, the NormalizeThinking
     * sub-subflow is NOT mounted at chart build time — zero overhead
     * for non-thinking agents.
     */
    private readonly thinkingHandler?;
    /**
     * v2.14+ — request-side thinking budget. When set, every LLMRequest
     * carries `thinking: { budget }`. AnthropicProvider translates to the
     * wire format. Undefined = no thinking activation (default behavior).
     */
    private readonly thinkingBudget?;
    /** Threaded to footprintjs `flowChart()` so every node the Agent
     *  builder creates is observed by these recorders at build time. Set
     *  from `opts.structureRecorders`; undefined when consumer didn't
     *  attach any. */
    private readonly structureRecorders?;
    /** Per-COMPOSITION translator (L1b). Set from `opts.groupTranslator`;
     *  undefined when consumer didn't attach one. */
    private readonly agentGroupTranslator?;
    /** ReAct loop mode — 'dynamic' (default, re-engineer all slots each turn,
     *  flat chart), 'classic' (engineer context once, loop→Messages only, flat
     *  chart), or 'dynamic-grouped' (dynamic semantics + LLM turn wrapped in an
     *  sf-llm-call subflow for richer Lens grouping). Set from `opts.reactMode`.
     *  See AgentOptions. */
    private readonly reactMode;
    /** The recipes `.recipe()` applied, in declaration order. Held for ONE
     *  purpose: the run manifest's `recipes` rows, so a recording can say which
     *  composition produced the agent that answered. Undefined — never `[]` — on
     *  every agent built without one, which is what keeps the manifest of an
     *  agent that uses no recipes byte-identical to the one it emitted before
     *  they existed. */
    private readonly appliedRecipes?;
    /** The DECLARED skill map (9.50.0) — nodes + edges verbatim, captured by
     *  `AgentBuilder.skillGraph()`. Filed once per run as
     *  `agentfootprint.skill.graph_declared`; undefined = no graph, or a graph
     *  that could not state its map (the event then never fires). */
    private readonly skillGraphDeclared?;
    /** The maps kernel's plan (9.58.0) — present only when built with `.maps()`. */
    private readonly mapsPlan?;
    /** `.claims()` (9.61.0) — the declared claim contract, or undefined. */
    private readonly claimContract?;
    /** `AgentOptions.recordSystemPrompt` (9.50.0) — OFF by default. When true,
     *  every `stream.llm_start` carries the assembled system prompt verbatim as
     *  `systemPromptText`. */
    private readonly recordSystemPromptValue;
    /** `AgentOptions.recordReceipt` (9.88.0) — ON by default. `false` declines
     *  the mint at `callLLM`; nothing else about the run changes. */
    private readonly recordReceiptValue;
    /** The receipt memo every call of a run mints through — one per agent,
     *  rebinding itself to each run id (`core/agent/receipt/receiptDigests.ts`). */
    private readonly receiptDigests;
    private readonly answerValidationConfig?;
    private readonly negativeClaimsConfig?;
    private readonly typedNegativeClaimsConfig?;
    private readonly applicationAnswerValidation;
    constructor(opts: AgentOptions, systemPromptValue: string, registry: readonly ToolRegistryEntry[], voice: {
        readonly appName: string;
        readonly commentaryTemplates: Readonly<Record<string, string>>;
        readonly thinkingTemplates: Readonly<Record<string, string>>;
    }, injections?: readonly Injection[], memories?: readonly MemoryDefinition[], outputSchemaParser?: OutputSchemaParser<unknown>, toolProvider?: ToolProvider, systemPromptCachePolicy?: CachePolicy, cachingDisabled?: boolean, cacheStrategy?: CacheStrategy, outputFallbackCfg?: ResolvedOutputFallback<unknown>, reliabilityConfig?: ReliabilityConfig, thinkingHandlerValue?: ThinkingHandler | null, thinkingBudgetValue?: number, skillGraphNextSkill?: (ctx: InjectionContext) => string | undefined, skillGraphReachable?: (currentSkillId?: string) => readonly string[], skillGraphScoreEntries?: (ctx: InjectionContext, signal?: AbortSignal) => Promise<EntryScoring>, checkInOptions?: CheckInBuilderOptions, runConfigFn?: RunConfigFn, windowStrategy?: WindowStrategy, toolMiddleware?: readonly ToolMiddleware[], messageMiddleware?: readonly MessageMiddleware[], outputEnforcement?: ResolvedOutputEnforcement, skillGraphEdgeTargets?: readonly string[], skillGraphExplainNextSkill?: (ctx: InjectionContext) => CursorMove, skillGraphIsTree?: boolean, skillGraphSupersededEntries?: (ctx: InjectionContext) => readonly string[], skillGraphCascade?: {
        readonly turnRouting?: TurnRoutingPlan;
        readonly strictness: 'assist' | 'guard' | 'rails';
        readonly continuity: 'turn' | 'conversation';
        readonly nodeIds: ReadonlySet<string>;
    }, skillBrains?: import('./agent/skillBrains.js').FoldedSkillBrains, evidenceGate?: ResolvedEvidenceGate, limitsTravelWithTheAnswer?: boolean, recipes?: readonly AppliedRecipe[], skillGraphDeclared?: SkillGraphDeclaredMap, mapsPlan?: import('../maps/engagement/types.js').EngagementPlan, claimContract?: readonly import('../integrity/unsupported-claim/check.js').DeclaredClaim[], answerValidationConfig?: ResolvedAnswerValidation, systemPromptCacheExplicit?: boolean, negativeClaimsConfig?: ResolvedNegativeClaims, scriptTravel?: ResolvedScriptTravel);
    static create(opts: AgentOptions): AgentBuilder;
    /**
     * Cache policy for the base system prompt. Read by the CacheDecision
     * subflow (v2.6 Phase 4) to know how to treat the SystemPrompt slot's
     * cache markers. Exposed as a method (not direct field access) so
     * the Agent's encapsulation boundary stays clean.
     */
    getSystemPromptCachePolicy(): CachePolicy;
    /**
     * The artifact store this agent was built with, or `undefined` when none
     * was attached (9.23.0).
     *
     * For COMPOSERS that resolve refs on the agent's behalf — the hosting
     * layer's `artifact-head` / `artifact-get` wire operations redeem a
     * screen's claim tickets against exactly this store. It is the store, not
     * a scope-bound capability: whoever calls it owns composing the resolution
     * scope (the hosting layer composes the requesting session's identity, the
     * same tuple the run's own tools resolved under). Tools never touch this —
     * `ctx.artifacts` is already bound to the run's scope, and that remains
     * their only door.
     */
    getArtifactStore(): ArtifactStore | undefined;
    /**
     * Start recording this run — or do nothing at all (9.26.0).
     *
     * Zero-cost when unused is not a claim here, it is the control flow: with
     * `recordings` unset this returns `undefined` before touching the agent, so
     * no listener is subscribed, no boundary recorder is attached, and the run
     * is byte-identical to every earlier release.
     *
     * It is deliberately the SAME recorder a consumer would call by hand
     * (`recordRun`'s own body, `recordRunWhere`). Nothing about this feature is a
     * second recording implementation — the three connections that a
     * hand-rolled version gets wrong (attach, subscribe, getCommitCount) are
     * wired in exactly one place in this package, and this is a caller of it.
     * The one difference is the timeline's filter: a recording filed FOR a
     * person keeps only the events of that person's run.
     */
    private startRunRecording;
    /**
     * Does `event` belong to the run this agent is serving (or served last)? The
     * run-membership rule (`bridge/eventMeta.ts · eventBelongsToRun`) against
     * this instance's run context — asked by the per-run recording and by the
     * self-explain evidence, the two collectors that keep one run's events.
     *
     * @internal
     */
    ownsEvent(event: AgentfootprintEvent): boolean;
    /**
     * File the finished recording into the artifact store.
     *
     * ── When ────────────────────────────────────────────────────────────────
     * After the answer is composed, and only for a run that COMPLETED. A pause
     * is not a finished run (the turn continues, and the resume mints its own);
     * a throw never reaches here at all.
     *
     * ── Why it is awaited ───────────────────────────────────────────────────
     * The answer is final before this begins and this cannot change it — but
     * `run()` does return after the write rather than before, and that is a
     * choice rather than an oversight. A fire-and-forget write is a recording
     * lost whenever the process exits with the reply, which is precisely the
     * serverless deployment that wants recordings most. The cost is one store
     * write per turn, stated on the option.
     *
     * ── Why it can never fail the run ───────────────────────────────────────
     * A full store, an unserializable snapshot, a bucket that 500s — none of
     * them are facts about the ANSWER, which is already correct and already
     * paid for. Turning "your recording was not filed" into "your request
     * failed" would be the library deciding that its observability matters more
     * than the user's turn. So every failure degrades to today's path: the
     * answer is returned unchanged and the reason lands on the record as
     * `agentfootprint.artifacts.refused`, where a sink can count it.
     *
     * The recording is FROZEN before the mint, so it can never contain the
     * `artifacts.minted` event describing itself.
     */
    private fileRunRecording;
    /** One refusal fact for a recording that could not be filed. The message is
     *  the store's own, which never carries a payload — only what went wrong. */
    private reportRecordingRefused;
    /**
     * The run's artifact scope, read from the finished run's own state.
     *
     * The SAME tuple `ctx.artifacts` bound during the run (`scope.runIdentity`,
     * composed by seed from the caller's identity or derived from the session).
     * Read rather than recomposed: a second derivation here could disagree with
     * the one the run's tools used, and a recording filed in a different scope
     * from the artifacts it describes is a recording nobody can find.
     */
    private runArtifactScope;
    /**
     * The footprintjs `RuntimeSnapshot` from the most recent `run()` /
     * `resume()`. Feeds Lens's Trace tab (ExplainableShell `runtimeSnapshot`
     * prop) so consumers can scrub the execution timeline post-run without
     * threading a recorder through the call site.
     *
     * `undefined` until a run has STARTED. After that it is the most recent
     * run's snapshot — including across multiple turns of the same instance.
     *
     * **It is LIVE during a run, not a completed-runs-only view.** The executor
     * is assigned at run start, so calling this from an event listener, a tool,
     * or any other mid-run vantage point returns the IN-FLIGHT run, partially
     * filled. That is deliberate (Lens scrubs a running agent through it), and
     * it is why `.selfExplain()` captures at the terminal flush instead of
     * resolving through this: evidence that is supposed to describe a FINISHED
     * turn cannot be read from a getter that also answers about an unfinished
     * one.
     *
     * **Under `redact` it is the SERVED snapshot** — footprintjs's redacted view
     * (`RunnerBase.getLastSnapshot`): the placeholder wherever the policy
     * selected a value, and no `initialState`. The agent's own logic never reads
     * this getter; `checkpoint()`, `followUp()` and the crash checkpoint read the
     * live run, so redaction never changes what the agent continues from.
     */
    getLastSnapshot(): RuntimeSnapshot | undefined;
    /**
     * Structured narrative entries from the most recent run. Pairs with
     * `getLastSnapshot()` for ExplainableShell's `narrativeEntries` prop.
     * Empty array (not `undefined`) when no run has completed — matches
     * the prop's expected shape so consumers can wire it directly without
     * a defensive guard.
     *
     * Under `redact`, footprintjs wrote these lines through the run's rule: a
     * read or write of a selected key reads `[REDACTED]`, and an `[emit]` line
     * shows the event's served payload (`src/redaction/runRedaction.ts`).
     */
    getLastNarrativeEntries(): readonly CombinedNarrativeEntry[];
    /**
     * The FlowChart compiled for the most recent run (or a freshly-built
     * one if no run has happened yet). Feeds ExplainableShell's `spec`
     * prop. Returning the cached chart matters: the spec must match what
     * `getLastSnapshot()` traced, otherwise the Trace view's stage tree
     * desyncs from the snapshot's runtime tree.
     */
    protected getGroupTranslator(): import('./translator.js').GroupTranslator | undefined;
    /** Agent has no nested-runner members (tools are function executors,
     *  not Runner instances). Slot ids + tool names live in `extra` so
     *  Lens can render an Agent card with slot rows + a tool list without
     *  inspecting `buildTimeStructure`.
     *
     *  Memories are NOT included as members — they're an internal
     *  mechanism, not a composition-level concept. Consumers who need
     *  memory visibility should listen for `agentfootprint.memory.*`
     *  events at runtime. */
    protected buildUIGroupMetadata(): import('./translator.js').GroupMetadata;
    /**
     * Parse + validate a raw agent answer against the agent's
     * `outputSchema` parser. Throws `OutputSchemaError` on JSON parse
     * or schema validation failure (the rawOutput is preserved on the
     * error for triage). Throws a plain `Error` if the agent has no
     * outputSchema set.
     *
     * Use this when you need to keep `agent.run()` returning the raw
     * string for logging/observability and validate at a different
     * layer; otherwise prefer `agent.runTyped()`.
     */
    parseOutput<T = unknown>(raw: string): T;
    /**
     * Async sister of `parseOutput()`. When the agent is configured
     * with `.outputFallback({...})`, this is the version that engages
     * the 3-tier degradation chain on validation failure (the sync
     * `parseOutput` always throws on failure for back-compat).
     *
     * Without `outputFallback`, behaves identically to `parseOutput`
     * — returns sync-style on the happy path, throws OutputSchemaError
     * on validation failure.
     */
    parseOutputAsync<T = unknown>(raw: string): Promise<T>;
    /**
     * A typed answer that failed: rethrow, or — with `.outputFallback()` and an
     * `OutputSchemaError` — hand it to the 3-tier fallback. The one settle for
     * `parseOutputAsync`'s parse failure and `runTyped`'s native stop failure.
     */
    private settleTypedFailure;
    /**
     * Corrective re-asks the agent's LAST run paid for, read off its own ledger.
     *
     * `undefined` when there is no last run to read — `parseOutputAsync` accepts
     * any string, including one that never came from this agent, and reporting
     * `0` for "I do not know" would be an invented fact in an event payload.
     */
    private lastRunRetriesSpent;
    /**
     * Run the agent and return the schema-validated typed output.
     * Convenience over `parseOutputAsync(await agent.run({...}))`.
     *
     * Throws `OutputSchemaError` on parse / validation failure UNLESS
     * `.outputFallback({...})` is configured, in which case the
     * 3-tier degradation chain (primary → fallback → canned) engages.
     *
     * Throws if the agent has no outputSchema set or if the run
     * pauses (use `run()` directly when pauses are expected).
     *
     * With `.limitsTravelWithTheAnswer()`, nothing is appended to a typed
     * answer: the limits its tools declared come back as data, from
     * `agent.answerCoverage()`.
     */
    runTyped<T = unknown>(input: AgentInput | string, options?: AgentRunOptions): Promise<T>;
    /**
     * Answer one turn.
     *
     * **`run()` is ONE turn, and it starts a new conversation every time.** The
     * chart seeds its history from this call's `message` alone, so a second
     * `run()` on the same agent does not continue the first: the model is shown
     * one user message and will honestly tell your user it has not spoken to
     * them before. That is deliberate — a primitive that quietly accumulated
     * state across calls could never be used for one-shot work, and a hidden
     * transcript is the most expensive thing an agent can carry.
     *
     * To continue a conversation, name it:
     *
     *   - `agent.followUp(message)` — continue THIS agent's own last completed
     *     run. The one-liner, and what most callers want.
     *   - `run({ message, continueFrom })` — continue a conversation you are
     *     holding: `agent.checkpoint()` from an earlier turn, persisted anywhere
     *     and handed back. Works across a restart, a deploy, or a different
     *     machine, and is what `standingAgent` uses per session.
     *
     * Passing the same `identity.conversationId` to two `run()` calls does NOT
     * continue anything — see {@link AgentInput.identity}. What a registered
     * memory adds is *recall* of prior turns into the system-prompt slot, which
     * is a different thing from the conversation itself.
     *
     * Two refusals guard the per-instance state this agent keeps; both replace
     * behavior that used to succeed while quietly being wrong (9.2.0):
     * {@link RunInFlightError} when a run is already in flight, and
     * {@link PendingQuestionError} when the last run paused to ask a person
     * something that nobody has answered.
     *
     * @example  One turn, then a follow-up
     * ```ts
     * await agent.run({ message: 'Book me a table for two.' });
     * await agent.followUp('Make it three.');       // remembers the table
     * ```
     */
    run(input: AgentInput | string, options?: AgentRunOptions): Promise<AgentOutput | RunnerPauseOutcome>;
    /**
     * Continue this agent's own last completed conversation.
     *
     * The one-liner for turn two and after. `run()` is one turn and starts a new
     * conversation each time (see {@link Agent.run}); this reads the
     * conversation off the last completed run, appends `message` as the next
     * user turn, and runs from there — so the model sees what was actually said.
     *
     * Sugar over `run({ message, continueFrom: this.checkpoint() })` and nothing
     * more: one restoration path, so the convenience cannot drift from the
     * mechanism. Reach for `run({ continueFrom })` directly when the
     * conversation comes from somewhere other than this instance's last run — a
     * store, another process, a different machine.
     *
     * Refuses rather than guessing: {@link NoConversationError} when this agent
     * has no completed run to continue (a "follow-up" that quietly became a
     * first turn would be exactly the confusion this door exists to remove),
     * and — through `run()` — {@link PendingQuestionError} when the last run
     * paused to ask a person something, because a pause has its own door:
     * `resume(checkpoint, decision)`.
     *
     * The conversation grows every turn and nothing here trims it; bounding what
     * the model is shown is `.window()` / `.compaction()` / `.memory()`, not a
     * silent cap on the way through.
     *
     * @example
     * ```ts
     * await agent.run({ message: 'Book me a table for two.' });
     * await agent.followUp('Make it three.');
     * await agent.followUp('And move it to 8pm.');
     * ```
     */
    followUp(message: string, options?: AgentRunOptions): Promise<AgentOutput | RunnerPauseOutcome>;
    /**
     * Drop the question this agent's last run paused to ask, on the record.
     *
     * A paused run is waiting on a person. Sending a different message while one
     * is outstanding is refused ({@link PendingQuestionError}) because silently
     * discarding a pending question makes a consent gate something any later
     * message can walk around. When the question really is being dropped —
     * the user changed the subject, the session timed out, the approval is no
     * longer wanted — say so with this, and the next `run()` proceeds.
     *
     * Returns what was dropped (`undefined` when nothing was pending), so a
     * caller can log or audit the abandonment rather than perform it blind. It
     * does not touch the paused run's checkpoint: if you still hold that, it
     * remains resumable.
     */
    abandonPause(): {
        readonly toolName?: string;
        readonly toolCallId?: string;
        readonly question?: string;
    } | undefined;
    /**
     * Whether {@link Agent.selfExplain}'s why-questions have a run to answer
     * from right now.
     *
     * `false` for two different reasons, both honest: this agent was not built
     * with `.selfExplain()`, or it was and no turn has completed yet (evidence
     * binds at the END of a run, never to the one in flight). Either way there
     * is nothing to explain, which is what a caller routing a why-question needs
     * to know before it routes.
     *
     * The model is told the same thing by the same fact — the trace tools answer
     * "No completed run is available yet" and the skill body says to say so
     * plainly. This is that answer, for the program.
     *
     * Evidence is kept per conversation, so on an agent serving several sessions
     * this answers for the session of the run in flight — or, between runs, of
     * the run served last.
     */
    canExplain(): boolean;
    /**
     * Resume an agent run from a checkpoint produced by a prior
     * `RunCheckpointError`. Unlike `agent.resume()` (which takes a
     * `FlowchartCheckpoint` from an intentional pause), this takes
     * an `AgentRunCheckpoint` (conversation-history snapshot) and
     * replays the agent run with that history restored.
     *
     * The next iteration retries the call that originally failed —
     * with the latest provider state (circuit breaker may have
     * closed, vendor may have recovered, etc.).
     *
     * **Resume = REPLAY from the last completed iteration boundary,
     * not exact-state restore.** Only the conversation history is
     * restored; everything else re-seeds fresh:
     *
     *   - **Tool re-execution / idempotency**: tool side effects from
     *     the FAILED iteration are not in the checkpoint. The model
     *     re-decides from the restored history and may re-issue those
     *     tool calls — they WILL execute again (there is no built-in
     *     toolCallId dedup). Mutating tools (payments, emails, DB
     *     writes) must be idempotent — key on stable call content, not
     *     `ctx.toolCallId` (a re-issued call gets a new id).
     *   - **Fresh `runId`**: the resumed run's events carry a new
     *     `runId`; use `checkpoint.runId` to correlate back to the
     *     failing run.
     *   - **Iteration counter + budget reset**: the resumed run starts
     *     at iteration 1 with a full `maxIterations` budget
     *     (`checkpoint.lastCompletedIteration` is diagnostic only).
     *     Token/cost accumulators also restart at zero.
     *
     * @example
     * ```ts
     * try {
     *   const result = await agent.run({ message: 'long task' });
     * } catch (err) {
     *   if (err instanceof RunCheckpointError) {
     *     await checkpointStore.put(sessionId, err.checkpoint);
     *     // hours / restart later:
     *     const checkpoint = await checkpointStore.get(sessionId);
     *     const result = await agent.resumeOnError(checkpoint);
     *   }
     * }
     * ```
     */
    resumeOnError(checkpoint: AgentRunCheckpoint | unknown, options?: AgentRunOptions): Promise<AgentOutput | RunnerPauseOutcome>;
    /**
     * Which identity a continued turn runs under: the caller's if they named
     * one, otherwise the conversation's own.
     *
     * @internal
     */
    private identityFor;
    /**
     * A run's `time`, read into the turn's clock draft (the time layer) — or
     * refused, before the turn starts: `time` on an agent without `.time()` or
     * a malformed value. No zone anywhere (the run's, else the builder's) is no
     * refusal: the zone is UNKNOWN (`zoneSource: 'unknown'`, G15) — never the
     * server's, never guessed; the person is asked it before any time they
     * wrote is read. `undefined` on an agent without the layer.
     *
     * @internal
     */
    private clockDraftFor;
    /**
     * The clock draft seed stamps (the time layer): the one `run()` read — or,
     * for a turn this agent's `run()` did not start (its chart mounted in a
     * composition, which passes no `time`), the builder's fallback zone with
     * the turn's start as `now` (`zoneSource: 'builder'`, `nowSource:
     * 'default'` — the same record a `run()` with no `time` files). With no
     * fallback zone that turn's zone is unknown, as a `run()`'s is (G15): the
     * server's zone is never used.
     *
     * @internal
     */
    private seedClockDraft;
    /**
     * A `time` passed to a run or a resume, read — or refused by name: passed to
     * an agent without `.time()` (a door that ignored it would look configured
     * and do nothing), or malformed.
     *
     * @internal
     */
    private passedTimeFor;
    /**
     * Install a per-run checkpoint tracker. Listens for the agent's own
     * iteration and stream brackets and snapshots the conversation history into
     * the tracker. Returns a stop function.
     *
     * It listens on the REAL-value path (`EventDispatcher · onRealEvent`), never
     * on the served one: the crash checkpoint it builds is what
     * `resumeOnError` replays to the model, and a resume checkpoint keeps real
     * values — a redaction policy that names `history` must not turn the
     * conversation a crash resumes into placeholders (`src/redaction/`).
     *
     * @internal
     */
    private installCheckpointTracker;
    /**
     * Continue a run that paused to ask a person something, with their answer.
     *
     * WHO the resumed run is for is the paused run's caller, read off the
     * checkpoint (`agent/callerIdentity.ts`) — never whatever this instance ran
     * last; which SESSION, the call's `sessionId`, else the paused run's. A
     * checkpoint names who it is for; it is not proof: a host that lets
     * checkpoints leave its trust boundary signs them or keeps them
     * server-side, and passes the identity it verified as `options.identity`.
     *
     * @throws ResumeIdentityConflictError when `options.identity` is not the
     *   paused run's caller identity — before anything runs.
     * @throws DecisionRequiredError when a consent gate is answered with
     *   something other than a decision.
     * @throws ResumeDecisionError when the decision does not answer the request
     *   this run is paused on: it names no request, another request, a call the
     *   checkpoint no longer holds (refused before anything runs), or a request
     *   a resume already answered (refused before the tool runs). The tool never
     *   runs on a refusal.
     * @throws RunInFlightError when a run is already in flight.
     *
     * @example
     * ```ts
     * const outcome = await agent.run({ message: 'refund me', identity }, { sessionId });
     * if (isPaused(outcome)) await agent.resume(outcome.checkpoint, 'yes', { identity, sessionId });
     * ```
     */
    resume(checkpoint: FlowchartCheckpoint, input?: unknown, options?: AgentRunOptions): Promise<AgentOutput | RunnerPauseOutcome>;
    /**
     * Fire `'run'`-scoped tool teardown — IF this run really ended.
     *
     * **Not on `finally`, and that is the whole point.** `finally` runs on every
     * exit including a pause, and a pause exits TWO ways: a returned
     * `RunnerPauseOutcome` and a thrown `PauseSignal`. A check-in on a
     * code-interpreter call pauses the run so a person can approve the code —
     * tearing the sandbox down there destroys the exact state the resume needs,
     * and it fails QUIETLY, as a resumed run that "just re-ran everything".
     * Both shapes are discriminated here and both are skipped.
     *
     * An error IS a terminal: the run is over, nobody is coming back, and a
     * sandbox held by a run that crashed is the clearest kind of leak. Only a
     * pause survives.
     *
     * Fired for the TURN, not for `currentRunContext.runId` — `resume()` mints a
     * fresh run id, so a pause and its resume are one turn across two runs, and
     * filtering on the id would leave everything a paused turn opened alive
     * forever. Hosted turns are scoped to their session, preserving other pauses. See `ToolSessionTier.fireRun`.
     *
     * @param outcome what `run()`/`resume()` is about to return, or about to throw.
     */
    private endRunToolSessions;
    /**
     * The conversation this agent's LAST completed run leaves behind, packed as
     * the same `AgentRunCheckpoint` that `resumeOnError(...)` accepts. Store it,
     * hand it back next turn, and the agent continues where it left off — across
     * a restart, a deploy, or a different machine.
     *
     * Returns `undefined` before any run has completed or when the latest run
     * was refused by input middleware. A refused input is not an admitted
     * conversation. Keep an earlier accepted checkpoint to continue explicitly;
     * `followUp()` after input denial raises `NoConversationError`.
     *
     * **Read from the run's own committed state, not from a second copy.** The
     * history comes from the LIVE snapshot's `sharedState.history` — the state
     * the run actually committed, never the served record (an agent's `redact`
     * keeps the conversation out of `getLastSnapshot()`, never out of the
     * conversation it continues) — cloned on the way out so a persistence layer
     * can never mutate the live heap. The final assistant turn is appended from the answer
     * `run()` returned, because nothing ever writes it back into `history`: the
     * loop appends assistant turns only when they carry tool calls, and the turn
     * that ends the run carries none. An agent that stored this conversation
     * without that append would drop its own reply every turn and answer the next
     * one having forgotten what it just said.
     * Provider replay evidence and its normalized thinking travel with that
     * accepted answer, including a terminal proof with empty text. The answer
     * remains the delivered text, including output-policy edits; raw provider
     * text is never substituted back. Evidence comes from live state, not the
     * redacted observation. Denied, failed and paused runs append no final turn.
     *
     * Explicit thinking retirements recorded before transport also apply here:
     * a failed grouped call cannot restore reasoning omitted from its request.
     * This copies no other failed-stage state or tool effects into the history.
     * Adds no events, no scope writes and no capture: every recording is
     * byte-identical to an agent that never calls this.
     *
     * After a run that **paused**, this is the conversation as of the pause, with
     * no answer appended — a pause is unfinished work, and pause/resume has its
     * own carrier (`FlowchartCheckpoint`) that holds engine state this shape
     * cannot.
     *
     * The conversation grows every turn and nothing here trims it. Bounding what
     * the model is shown is the memory subsystem's job (`.memory(...)`), not a
     * silent cap applied on the way to storage.
     *
     * @example
     * ```ts
     * await agent.run({ message: 'Book me a table for two.' });
     * const conversation = agent.checkpoint();          // persist anywhere
     * // …a restart later, on a fresh Agent:
     * await agent.run({ message: 'Make it three.', continueFrom: conversation });
     * // `continueFrom` admits the new turn through the 'input' middleware chain.
     * // `resumeOnError` rechecks originalInput but replays stored history as-is;
     * // it does not rewrite entries manually appended to that history.
     * ```
     */
    checkpoint(): AgentRunCheckpoint | undefined;
    /** Called as each run/resume ends: remember a run that got past input admission. */
    private noteAdmittedRun;
    /**
     * Whether the evidence gate's revision calls no tools: a posture that can
     * revise (`'guard'`, `'rails'`) under an ENFORCING answer validation. There
     * the answer may yet be withheld, so a revision must not run a tool that
     * writes or sends again — and the library cannot tell one that only reads.
     */
    private revisionWithholdsTools;
    /** Whether input middleware refused the last run's message — the one reading both doors ask. */
    private lastInputRefused;
    /** Both checkpoint doors keep the repair budget separately from conversation text. */
    private evidenceRecoveryOf;
    /**
     * The graph cursor a conversation carrier stores — the run's final
     * committed `currentSkillId`, read from the SNAPSHOT (the state the run
     * actually committed; both chart shapes map the advanced cursor onto it
     * every iteration), and only when the mounted graph declared
     * `continuity: 'conversation'`.
     *
     * ONE reader for BOTH carriers — `checkpoint()` (the conversation door
     * `followUp()` walks through) and the crash checkpoint
     * `RunCheckpointError` carries — the `foldedSpansOf`/`conversationOwner`
     * rule: a conversation must not keep its place on one path and silently
     * lose it on the other.
     *
     * @internal
     */
    private continuityCursorOf;
    /**
     * The folded spans this run has committed, cloned on the way out.
     *
     * One reader for both carriers — `checkpoint()` and the crash checkpoint
     * `RunCheckpointError` carries — so a conversation cannot keep its spans on
     * one path and silently lose them on the other. The clone is the same
     * promise `checkpoint()` makes about history: a persistence layer never gets
     * a reference into the live heap.
     *
     * @internal
     */
    private foldedSpansOf;
    /**
     * What the resume door checks a time field's answer with (the time design
     * § 6.2, step T4): the paused turn's clock zone — the kept `clock` row, so
     * a resume that passes another `time` changes nothing — and the app's
     * catalog overrides. `undefined` without `.time()`: a `format` field is
     * then judged for shape, order and offset only, in the default words.
     *
     * @internal
     */
    private timeAnswerContextOf;
    /**
     * The findings ledger for a checkpoint (9.101.0) — `foldedSpansOf`'s twin:
     * one reader for `checkpoint()` and the crash carrier, `undefined` when the
     * run recorded no rows (so the key stays absent), and a detached copy
     * otherwise, never a reference into the live heap.
     *
     * @internal
     */
    private findingsLedgerOf;
    /**
     * The turn a checkpoint's history ends on — `findingsLedgerOf`'s twin, one
     * reader for `checkpoint()` and the crash carrier. Only while an honesty
     * layer is armed (the run constant `honestyLayers`, read from the same
     * snapshot): that is when every ledger row carries its `turn` and the next
     * run's stamp must continue from it (`AgentRunCheckpoint.turnNumber`).
     * `undefined` otherwise, so the key stays absent.
     *
     * @internal
     */
    private turnNumberOf;
    /**
     * The two owner facts every conversation carrier stamps — who the run was
     * for, and which agent ran it (9.2.0).
     *
     * One reader for `checkpoint()` and the crash checkpoint, the same rule
     * `foldedSpansOf` follows: a fact kept on one carrier and lost on the other
     * is worse than a fact kept on neither. Both are absent unless the caller
     * chose them, which is what keeps the fingerprint refusal narrow and the
     * default `conversationId` out of storage.
     *
     * @internal
     */
    private conversationOwner;
    /**
     * Restore a stored conversation onto the side channel `seed` reads.
     *
     * THE one restoration path — `run({ continueFrom })` and `resumeOnError()`
     * both come through here, so the conversation door and the error door cannot
     * disagree about what continuing means. It checks the agent fingerprint,
     * restores history + folded spans, and adopts the conversation's identity so
     * the continued turn writes its memory where the earlier turns are.
     *
     * `appendsUserTurn` is the difference between the two callers, and it is the
     * whole difference. Continuing a conversation ADDS this turn's user message
     * to the stored history; resuming after an error does NOT, because there the
     * message is already the last user turn in that history and appending it
     * would ask the same question twice.
     *
     * Only the FLAG is stashed, never the entry (9.112.2). The entry is written
     * by `seed.ts · historyForTurn` from the message the `'input'` middleware
     * chain let through; an entry built here, before that chain has run, is the
     * caller's raw text — which is what a continued turn served the model
     * through 9.112.1, while the record said the rewrite had happened.
     *
     * @internal
     */
    private applyContinuation;
    /** One turn at a time — see `RunInFlightError`. @internal */
    private assertNotRunning;
    /** A person's unanswered question outranks a new message — see
     *  `PendingQuestionError`. @internal */
    private assertNoPendingQuestion;
    /**
     * Remember (or forget) the question this run ended on.
     *
     * A paused outcome sets it; anything else clears it, because a run that
     * reached an answer has no outstanding question by definition. Reads the
     * same `pauseData` fields `standingAgent.describePause` reads — the tool
     * name and question the dispatch loop stamped — and invents nothing.
     *
     * @internal
     */
    private recordPendingQuestion;
    /**
     * Hand the `.selfExplain()` binding to the agent that owns it.
     *
     * Called once by `AgentBuilder.build()`, immediately after `bindTo`. The
     * binding stays the tool provider's to read; the Agent holds it only so
     * `canExplain()` answers from the same fact the trace tools answer from,
     * rather than from a second guess about whether a run has completed.
     *
     * @internal
     */
    bindSelfExplain(binding: SelfExplainBinding): void;
    /**
     * Refuse, at run start, any declared messages-slot role this provider
     * cannot carry inside its message list (7.21, D2).
     *
     * Run start rather than build time because the answer depends on the
     * provider — and a decorated provider (`withFallback`, `withRetry`) is only
     * the thing it is once composed. Run start rather than delivery time
     * because a declaration that can never work should fail on the first call,
     * not three iterations into a paid run. The delivery stage re-checks each
     * message anyway, which is what catches roles that only exist at run time
     * (a hand-built memory-recall subflow's formatted output).
     *
     * Called from the ONE place `run()` and `resume()` share, so no entry point
     * can slip past it.
     */
    /**
     * The OPEN skills — the ones `read_skill` may reach from anywhere, whatever the
     * graph's cursor says (8.4.0). Two clauses, both load-bearing:
     *
     *   • `trigger.kind === 'llm-activated'` — the trigger that reads
     *     `activatedInjectionIds`, which is the ONLY thing a `read_skill` call writes.
     *     It is exactly "read_skill can really activate this", so admitting anything
     *     else (a hand-built `rule` injection, say) would replace one lie with another:
     *     the tool would answer "activated" and nothing would activate.
     *   • the graph declares no incoming edge to it — a bare model edge `.route(a, m)`
     *     is a declared, drawn, `from`-gated affordance ("from a, the model may hop to
     *     m"), and opening every such target would silently globalize it. What is left
     *     is skills the graph never mentions at all.
     *
     * That covers three shapes that were all dead before: `.selfExplain()`'s debug
     * skill under a graph, a `.skill()`/`.skills()` registration beside a graph, and a
     * skill listed in `skills[]` and wired to nothing (whose own check-up warning says
     * "it can only be reached by the model via read_skill" — true again now).
     *
     * An open pick ACTIVATES but never moves the cursor — see the tool-calls gate.
     * Computed once per chart build; the injection list is fixed at construction.
     */
    /**
     * The identity facts this run hands `tool.execute` (9.7.0).
     *
     * Read through an ACCESSOR from the chart (see `ToolCallsHandlerDeps.currentRun`)
     * because the chart is built once and this changes every run.
     *
     * `identity` is `lastRunIdentity` — what the CALLER passed — and deliberately
     * NOT `scope.runIdentity`, which is always populated and defaults to
     * `{ conversationId: '<runId>' }` (or, on a session-bound run since 9.10.0,
     * to `{ conversationId: sessionId }`). Handing a tool a synthesized
     * conversation as "the identity" would let it key an isolated session on a
     * fiction, and would make "absent" unrepresentable at exactly the layer that
     * most needs to see it. The session-derived namespace is synthesized too, and
     * is withheld here for that reason — `sessionId` beside it is the fact the
     * transport really delivered.
     */
    private toolRunFacts;
    /**
     * The teardown tier, built on FIRST registration.
     *
     * An agent whose tools never hold a session never allocates one, and its
     * terminals stay a single `undefined` check.
     */
    private toolSessions;
    /**
     * Turn one TEARDOWN report into a typed `agentfootprint.tools.session_*` event.
     *
     * Only the two closing events come through here. A start and a reuse happen
     * inside `tool.execute`, where the dispatch loop still holds the scope, so
     * those ride the ordinary emit channel and carry the stage they really
     * happened in. These two fire after the run's last stage committed, and this
     * is the one place that has to answer "from where?" without a stage to point
     * at.
     *
     * **Built with `buildEventMeta`, never `minimalMeta()`.** `minimalMeta()`
     * hardcodes `runId: 'consumer-scope'`, and a teardown event stamped that way
     * cannot be joined to the run that OPENED the session — the exact
     * unjoinability 9.4.0 spent a release fixing for credential events. So the
     * meta comes from the registration-time run context, with a STATED pseudo-stage, the same
     * move as the `'<stageId>#paused'` stamp at the pause boundary.
     */
    private emitLateFact;
    private emitToolSessionReport;
    private openSkillIds;
    /**
     * The per-iteration `read_skill` offer builder — or `undefined` to leave the tool
     * exactly as it has always been (8.5.0).
     *
     * `read_skill` enumerated every registered skill while the gate admitted only
     * `reachableSkills(cursor) ∪ open`, so under a graph the model was handed ids it
     * would be refused, every iteration, and could spend a whole run re-asking. The
     * OFFER is rebuilt here from the same two functions the gate itself calls — one
     * source of truth, so the menu cannot drift from the verdict.
     *
     * Two guards:
     *
     *   • no graph AND no per-role skill visibility → `undefined`. A plain
     *     `read_skill` agent has no cursor and no gate; every registered skill
     *     really is reachable, and the tool keeps its byte-identical description.
     *   • `reactMode: 'classic'` → `undefined` for the GRAPH menu, plus a dev-mode
     *     warning. Classic composes the tools slot on turn 1 ONLY (see the Context
     *     selector's `includeStatic`), so a cursor-scoped menu would freeze at the
     *     cold-start cursor and keep advertising it for the rest of the run — a
     *     worse lie than the honest full catalog. `.selfExplain()` refuses under
     *     classic for exactly this caching reason; here the full catalog is a
     *     correct fallback, so this warns instead of refusing.
     *
     * Per-role VISIBILITY (9.11.0) survives classic, and that is not an
     * inconsistency: a cursor moves every iteration, but who is asking does not
     * change inside one run. A filter computed on turn 1 is still exactly right
     * on turn 9.
     */
    private readSkillOfferFor;
    /**
     * Does the configured checker ask to decide which skills this caller sees?
     * (9.11.0)
     *
     * Absence is NO — see `PermissionChecker.governs`. This is the ONE switch:
     * false and the menu, the resolver and the activation gate are all inert, so
     * an agent with a checker that predates 9.11.0 composes the same prompt it
     * always did.
     */
    private governsSkillVisibility;
    /**
     * Which skills the caller's role may NOT see, asked once per iteration
     * (9.11.0).
     *
     * Per iteration rather than per run because the checker is a port: a
     * hub-backed one can legitimately answer differently as a grant is revoked
     * mid-conversation, and caching the first answer would keep a withdrawn skill
     * on the menu for the rest of the run. The cost is one `check()` per skill per
     * iteration, paid only by agents that opted in.
     *
     * A skill is hidden when the checker returns anything other than `'allow'` /
     * `'gate_open'` — and when the checker THROWS, which is the fail-closed half:
     * a policy that did not answer did not say yes, and the same sentence governs
     * the tool gate.
     */
    private hiddenSkillIdsNow;
    private assertDeliverableRoles;
    /**
     * Refuse, at run start, a `'tool-forced'` output strategy on a provider
     * that does not put a forced tool choice on its wire (7.26).
     *
     * Run start rather than build time for the reason `assertDeliverableRoles`
     * gives one method up: a decorated provider (`withFallback`, `withRetry`,
     * a breaker) is only the thing it is once composed, and `withFallback`
     * publishes the AND of its pair.
     *
     * Refusal rather than a quiet fall back to `'instruct'`, because the two
     * are not interchangeable: one constrains the shape at generation, the
     * other asks for it in prose. An agent that silently got the second while
     * its config said the first would be a promise the recording could not
     * even show was broken.
     */
    private assertForcedToolChoiceSupported;
    /**
     * Refuse, at run start, a `'native'` output strategy on a provider that
     * does not put a structured-output format on its wire, or on a model that
     * does not take one — the `assertForcedToolChoiceSupported` twin, for the
     * same reasons: run start because a decorated provider is only what it is
     * once composed; a refusal because `'instruct'` asks in prose for what this
     * strategy constrains at decoding, and a quiet swap would be config that
     * lies.
     */
    private assertNativeOutputSchemaSupported;
    private createExecutor;
    /**
     * File the run-configuration manifest (9.41.0) — which adapters and
     * strategies this run is about to use, stamped with the runId every other
     * event of the run already carries.
     *
     * **Why it lives in `createExecutor` and not in `run()`.** `run()` and
     * `resume()` both come through here, and both mint a fresh runId (a resumed
     * run is a new run to every consumer joining on `meta.runId`, so a resume
     * with no manifest would be a run whose arm nobody can name). One funnel is
     * also how the next entry point cannot forget — the `beginIngress` lesson.
     *
     * **Why a direct dispatch rather than `typedEmit`.** There is no stage: the
     * chart has not started. So it is built with `buildEventMeta` and a STATED
     * pseudo-stage, exactly like the tool-teardown reports at the other end of
     * the run — never `minimalMeta()`, whose hardcoded `runId: 'consumer-scope'`
     * would make the one event whose whole job is to BE joinable the one event
     * that cannot be joined.
     *
     * **Why it is gated on a listener.** Every typed event in this library is:
     * the dispatcher drops what nobody subscribed to, and `EmitBridge` does the
     * same upstream. The gate is what keeps an unwatched agent at one map
     * lookup per run. It also means the manifest is not "always on" but "always
     * there when anything is watching" — including `recordRun`, which subscribes
     * with `'*'` before the run starts, so every recording carries one.
     */
    /** Fresh per-run ledger — see AgentOptions.integrityPosture (9.60.0). */
    private beginIntegrityLedger;
    /**
     * Dev posture only: throw {@link CheckerDeadError} on a run whose
     * registered checkers demonstrably never ran, or whose canary went
     * uncaught. Called on the SUCCESS path before the recording files, so the
     * failure is the run's result, never a masked afterthought.
     */
    private assertIntegrityAlive;
    /**
     * Did this run reach work a registered check should have seen?
     *
     * MEASURED, not asserted — and measured from a signal the integrity code
     * does not write. `llmLatestContent` is committed by the LLM stage's own
     * core path on every completed call, so its presence proves a call
     * happened; its absence proves the run died or paused before one, and a
     * checker that filed nothing THERE is not rot, it is a run that never got
     * started. Deriving this from the checks' own encounter counts would be
     * circular: an unhooked check would report "no work existed" and silence
     * the very alarm it should be tripping.
     */
    private integrityWorkExisted;
    /**
     * File the run's disposition rows as ONE `integrity.disposition` event and
     * clear the ledger. On the finally path of both run doors — every exit,
     * before the recording stops. Listener-gated like every typed event, and
     * deliberately throw-proof: accounting must never change a run's outcome.
     */
    private fileIntegrityDisposition;
    private emitRunManifest;
    /**
     * File the DECLARED skill map (9.50.0) — `agentfootprint.skill.graph_declared`,
     * once per run, right after the run-configuration manifest.
     *
     * Same funnel, same dispatch discipline, same listener gate as the manifest
     * (see `emitRunManifest` above): `run()` and `resume()` both come through
     * `createExecutor`, both mint a fresh runId, and a resumed run's consumers
     * deserve the topology under the runId they are joining on. The payload is
     * the map `AgentBuilder.skillGraph()` projected at mount — the author's
     * nodes and edges VERBATIM, never inferred from runtime hops — so a
     * recording carries the complete declared topology rather than the
     * fired-edges lower bound that `context.evaluated.routing[]` names.
     *
     * No graph, or a graph that could not state its map ⇒ no event — absent,
     * never guessed.
     */
    private emitSkillGraphDeclared;
    /**
     * Flush the deferred-observer backlog of the most recent run's executor,
     * then await async listener completions under a deadline (RFC-001 §11 —
     * the serverless / graceful-shutdown pattern). Resolves immediately with
     * zeros before the first run or when `observerDelivery` is `'inline'`
     * and no recorder opted into `'deferred'` itself.
     *
     * `pending === 0` means a full drain; non-zero honestly reports
     * continuations still outstanding at the deadline — never silent loss.
     *
     * @example Lambda-style handler
     * ```ts
     * export const handler = async (event) => {
     *   const reply = await agent.run({ message: event.message });
     *   // settle "one beat behind" observer work BEFORE the freeze:
     *   await agent.drainObservers({ timeoutMs: 5_000 });
     *   return reply;
     * };
     * ```
     */
    drainObservers(opts?: {
        timeoutMs?: number;
    }): Promise<ObserverDrainResult>;
    /**
     * Did the last turn stop because a LIMIT cut it short — and if so, which?
     *
     * `undefined` on every normal finish, including a turn that used its whole
     * `maxIterations` budget and then genuinely finished. It is set only when
     * the model was still asking for tools and the run refused to run them:
     * `maxIterations` was reached, or a `costBudget: { onExceed: 'halt' }` was
     * crossed.
     *
     * ## Why this is a method and not part of the answer
     *
     * `run()` resolves to a bare string. There is nowhere in a string to write
     * "…and three tool calls never ran", which is the same wall 8.6.0 hit with
     * an outstanding credential consent — and there the turn raises, because
     * handing back a plausible answer for work a tool never did is a silent
     * success. This is not that. A limit you configured firing is the limit
     * working, and the answer is sometimes real (a model can return content AND
     * tool calls). So it does not raise; it records, in committed state, where
     * it is provable after the fact — `getLastSnapshot().sharedState.stoppedEarly`
     * is the same value (unless the agent's `redact` names it: this accessor
     * reads the live run), and this is the short way to it.
     *
     * When the answer came back EMPTY the library also warns once on the
     * console, because an empty string reaching a user is indistinguishable
     * from a bug.
     *
     * @example
     * ```ts
     * const answer = await agent.run({ message: 'audit every log file' });
     * const cut = agent.stoppedEarly();
     * if (cut) {
     *   console.log(`stopped at iteration ${cut.iteration}: ${cut.reason}`);
     *   console.log(`${cut.pendingToolCalls} tool call(s) never ran`);
     * }
     * ```
     */
    stoppedEarly(): AgentState['stoppedEarly'];
    /**
     * Did the last turn's answer FAIL this agent's `outputSchema` — and how (8.18.0)?
     *
     * `undefined` when the answer satisfied the contract, and on any agent with
     * no `.outputSchema()`. Set on every run whose final answer was judged and
     * rejected, including the default `retries: 0` case where the first answer is
     * the only one there was.
     *
     * ## Why a method, when `runTyped()` already throws
     *
     * Because `run()` does not, and `run()` is what a server, a queue worker and
     * `standingAgent` call. Before this existed, that caller received a string
     * that violated a contract they had declared, with nothing anywhere saying
     * so: the retries were billed, the ledger row was written under `retries > 0`
     * and absent under `retries: 0`, and the answer looked exactly like a good
     * one. `runTyped()` still throws `OutputSchemaError` — that is the caller
     * ASKING to be raised at, and it is unchanged.
     *
     * `brokenBy` is the case worth a dashboard: the model's answer PASSED and one
     * of your own `act({ output })` rules rewrote it into one that fails. The run
     * stops re-asking when that happens — a deterministic rule breaks the next
     * answer identically, so the retries would be bought for nothing.
     *
     * @example
     * ```ts
     * const answer = await agent.run({ message: 'summarise ticket 91' });
     * const unmet = agent.outputContractUnmet();
     * if (unmet) {
     *   log.warn({ stage: unmet.stage, error: unmet.error, brokenBy: unmet.brokenBy });
     *   return safeDefault;               // …rather than shipping `answer` as typed data
     * }
     * ```
     */
    outputContractUnmet(): AgentState['outputContractUnmet'];
    /**
     * Did the last turn's answer state names or numbers that appear in NO tool
     * result (9.35.0)?
     *
     * `undefined` when every value was grounded — and on any agent without
     * `.namesAndNumbersFromEvidence()`. Set on a turn that shipped flagged
     * (`'assist'` / `'guard'`) and on one that was refused (`'rails'`, where
     * `run()` also raised `UnsupportedValuesError`, so this is what a caller
     * reads in the `catch`).
     *
     * `revised: true` means the model was asked once to correct the values and
     * they survived that turn — the fact worth alerting on, because it is a
     * model that cannot ground its own claims rather than one that slipped.
     *
     * Remember what the verdict does NOT say: values were invented. It cannot
     * tell you whether a claim built from real values is true.
     *
     * @example
     * ```ts
     * const answer = await agent.run({ message: 'which port is down?' });
     * const bad = agent.unsupportedValues();
     * if (bad) log.warn({ values: bad.values.map((v) => v.value), revised: bad.revised });
     * ```
     */
    unsupportedValues(): AgentState['unsupportedValues'];
    /**
     * The last run's findings ledger (9.101.0) — the model's OWN standings on
     * its tool results, as `.findings()` recorded them: `basis` rows (what a
     * call was for, declared before it ran), `standing` rows (`fact` with the
     * assertions stood on, `open`, `ruled-out`, `noise` — the LAST row per
     * `toolCallId` is the current reading; earlier ones are quotable history)
     * and `conflict` rows (two stood-on readings that disagree, witnesses by
     * identity). Undefined when nothing filed a row — never an empty array
     * standing in for "no findings", and an id with no standing row is
     * undeclared, never `open`.
     *
     * THE INPUTS LAYER files here too (honesty layer 2): an agent whose tools
     * declare `askOrAssume` gets `argument` rows — the library's verdict on each
     * ruled argument of each call (`source: 'default'` when a tool's rule
     * assumed the value, `'model'` when the model sent one the record does not
     * trace), each stamped with its conversation `turn` — WITHOUT `.findings()`.
     * A reader that switches over every row kind must skip one it does not know.
     *
     * THE RESULTS LAYER files here too (honesty layer 3, step 7b): `period` rows
     * — one per call whose result declared the period its read covered, or whose
     * tool declares a period argument: `covered`, `partly-held`, `not-held`,
     * `unknown`, or `undeclared` (the result said nothing about its period).
     *
     * Detached from the execution record (`structuredClone`), so a caller may
     * keep or mutate it without touching the run's state.
     *
     * @example
     * ```ts
     * await agent.run({ message: 'which port is down?' });
     * const current = new Map<string, string>();
     * for (const row of agent.findings() ?? []) {
     *   if (row.kind === 'standing') current.set(row.toolCallId, row.standing);
     * }
     * ```
     */
    findings(): AgentState['findingsLedger'];
    /** The library-composed negative statements and their recorded limits.
     * Detached, in-process data for the caller. Record redaction applies to the
     * snapshots and emitted events, not this caller-owned value. */
    answerNegatives(): AnswerNegatives | undefined;
    /** The last run's answer checks, detached from its execution record.
     * Undefined means no terminal validation ran, never an implicit pass. */
    answerValidation(): AnswerValidationReport | undefined;
    /**
     * The limits of the last run's TYPED answer, as data — what its tools
     * declared they `checked`, did not check (`notChecked`) and can never see
     * (`cannotCover`), folded across the run: duplicates said once, every entry
     * kept.
     *
     * Set when the agent has an output schema AND `.limitsTravelWithTheAnswer()`:
     * a typed answer is JSON, and the limits block that option appends to a
     * prose answer would stop it being JSON, so for a typed answer the limits
     * travel beside it instead — here, on `turn_end.answerCoverage`, and in
     * `getLastSnapshot().sharedState.answerCoverage` (served, under the agent's
     * `redact`), one value three ways. The
     * answer string, and so `runTyped()`, is exactly the model's.
     *
     * On an agent whose inputs layer is armed (a tool declares `askOrAssume`),
     * `assumed` lists the values a tool's rule filled this turn — the same rows,
     * read the same way, that a prose answer's "Assumed" block prints — each in
     * the tool's own argument view (`'REDACTED'` with `hidden` when that view
     * hides it).
     *
     * `undefined` when the run's tools declared no limits and nothing was
     * assumed, on a prose answer (the block is in the answer string there;
     * `sharedState.coverageDeclared` holds the raw rows either way), and before
     * the first run. Detached from the execution record, so a caller may keep
     * or mutate it.
     *
     * `periods` (honesty step 7b) — present only when a call's result declared
     * the period its read covered: one entry per declaring call, `{ toolName,
     * toolCallId, queried, held, readAt? }`, the period as the tool declared it
     * — the data twin of the prose block's `Period:` lines.
     *
     * @example
     * ```ts
     * const agent = Agent.create({ provider, model })
     *   .tool(replicationHealth) // returns coverage(verdict, { … })
     *   .outputSchema(Verdict)
     *   .limitsTravelWithTheAnswer()
     *   .build();
     *
     * const verdict = await agent.runTyped({ message: 'is replication healthy?' });
     * const limits = agent.answerCoverage();
     * for (const item of limits?.cannotCover ?? []) {
     *   console.log(`never covered: ${item.what} (${item.why})`);
     * }
     * ```
     */
    answerCoverage(): AnswerCoverage | undefined;
    /**
     * How far the last run's answer stands — folded from its COMMITTED record,
     * never from how sure the model sounded: `known` · `consistent` (checks ran,
     * none fired — never "verified") · `not-sure` (with the reasons) · `ask` (the
     * run paused on a question still waiting for a person) · `not-assessed`
     * (nothing on the record could be checked).
     *
     * The same pure fold as `assessAnswer` on `agentfootprint/observe`, over this
     * agent's last snapshot; it reads committed state, never events, so a later
     * reader of the same recording folds the same standing. (This call folds the
     * LIVE run. Under `redact` a recording holds the placeholder wherever the
     * policy selected a value, and a fold of it stands only on what the policy
     * left — the same standing unless a selected key is one the fold reads.) It resolves
     * asynchronously because the fold is loaded through `import()` on first use —
     * an agent that never asks does not carry it.
     *
     * Resolves to `undefined` when there is no answer to assess: before the first
     * run, while a run is in flight, and after a run that threw or whose answer a
     * rule refused (the typed error carries that verdict).
     *
     * `declarations` is the answer account's object, accepted as it is: the fold
     * reads `tools[name].rowsAt`, where an object result keeps its rows.
     *
     * @example
     * ```ts
     * await agent.run({ message: 'Which ports on switch A are down?' });
     * const a = await agent.assessment();
     * if (a?.standing === 'not-sure') {
     *   for (const r of a.reasons) console.log(r.reason); // e.g. 'empty-undeclared'
     * }
     * ```
     */
    assessment(declarations?: AssessmentDeclarations): Promise<AnswerAssessment | undefined>;
    /**
     * @internal What a mount of this agent's chart handed back
     * (`core/terminalVerdict.ts` · `ReadsItsOwnOutcome`, read by every
     * composition): the ANSWER, or the terminal verdict the chart ended on. A
     * string, or the validated answer's `{ finalContent, answerValidationCommitted }`,
     * is the answer; a verdict is read ONLY from the chart's state — handed over
     * when the chart returned no result — with the one translation this agent's
     * own run boundary (`finalizeResult`) uses. The `'tell-model'` consent record
     * travels off tracked state, so it is raised by the run boundary only.
     */
    outcomeOf(sfOutput: unknown): ChildOutcome;
    /** The records a run ends on in place of an answer, in the order the boundary raises them. */
    private refusalVerdictOf;
    /** Answer validation's verdict on a run that reached the end (7.24): blocked, or never committed. */
    private validationVerdictOf;
    private finalizeResult;
    private buildChart;
}