@dudousxd/nestjs-agent-core 0.43.0 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tokens.ts","../src/spi/model-catalog.ts","../src/spi/token-stream-sink.ts","../src/stream-events.ts","../src/turn-frames.ts","../src/tool-ui.ts","../src/tool-presentation.ts","../src/spi/chat-queue.ts","../src/spi/quota-provider.ts","../src/spi/pricing-store.ts","../src/spi/processors.ts","../src/spi/governance-queries.ts","../src/spi/approval-policy.ts","../src/governance/compute.ts","../src/tool-filters.ts","../src/personas.ts","../src/history.ts","../src/processors.ts","../src/structured-output.ts","../src/elicitation-input.ts","../src/elicitation.ts","../src/skills.ts","../src/memory.ts","../src/agent-registry.ts","../src/replay-integrity.ts","../src/control-flow.ts","../src/dangling-tool-calls.ts","../src/dead-run.ts","../src/delegation.ts","../src/action-proposal-discovery.ts","../src/action-proposal-outcome.ts","../src/genui/schema.ts","../src/genui/catalog.ts","../src/genui/tree.ts","../src/genui/text.ts","../src/genui/capabilities.ts","../src/action-proposal-transitions.ts","../src/genui/builtins.ts","../src/genui/registry.ts","../src/tool-presentations.ts","../src/tool-registry.ts","../src/agent-loop.ts","../src/action-proposal-approval.ts","../src/action-proposal-preparation.ts","../src/action-proposal-receipt.ts","../src/diagnostics.ts","../src/negotiated-tool-ui.ts","../src/tool-retry.ts","../src/in-memory-action-proposal-store.ts","../src/in-memory-store.ts","../src/confirm-token.ts","../src/channel-store.ts","../src/confirmed-tool.ts","../src/sql-token-stream-sink.ts","../src/action-proposal-text.ts","../src/action-proposal-view.ts","../src/action-proposal-executor.ts","../src/action-proposal-worker.ts","../src/action-proposal-capabilities.ts","../src/functional-tool.ts"],"sourcesContent":["/**\n * Public, cross-lib-discoverable DI tokens.\n *\n * These use `Symbol.for(...)` (the global symbol registry) on purpose: pnpm peer\n * multiplexing + dual ESM/CJS can load `core` more than once, and a plain `Symbol()`\n * would mint a distinct token per copy and break DI across package boundaries. A\n * registered symbol collapses every copy onto the same token, and lets a sibling lib\n * resolve our injectables by name without importing our internals.\n *\n * Naming convention (ecosystem-wide): `@dudousxd/nestjs-<lib>:<name>`.\n */\nexport const AGENT_OPTIONS = Symbol.for('@dudousxd/nestjs-agent:options');\nexport const AGENT_STORE = Symbol.for('@dudousxd/nestjs-agent:store');\nexport const AGENT_RUNNER = Symbol.for('@dudousxd/nestjs-agent:runner');\n/**\n * The durable runner, provided ONLY by `AgentDurableModule`. When `durable: true`, the module\n * binds `AGENT_RUNNER` to this via an optional injection, so a missing `AgentDurableModule`\n * fails with a clear error instead of a cryptic unresolved-dependency one.\n */\nexport const AGENT_DURABLE_RUNNER = Symbol.for('@dudousxd/nestjs-agent:durable-runner');\nexport const AGENT_SINK = Symbol.for('@dudousxd/nestjs-agent:sink');\nexport const AGENT_MODEL = Symbol.for('@dudousxd/nestjs-agent:model');\nexport const AGENT_ROLES_POLICY = Symbol.for('@dudousxd/nestjs-agent:roles-policy');\n/**\n * @deprecated Nothing binds or injects this token since the quota rework (#230): `AgentModule`\n * enforces and reports the budget through {@link AGENT_QUOTA_PROVIDER}, configured with\n * `AgentModule.forRoot({ quota })`. Inject `AGENT_QUOTA_PROVIDER` instead. Removed in the next major.\n */\nexport const AGENT_QUOTA_STORE = Symbol.for('@dudousxd/nestjs-agent:quota-store');\nexport const AGENT_TOOL_REGISTRY = Symbol.for('@dudousxd/nestjs-agent:tool-registry');\nexport const AGENT_REGISTRY = Symbol.for('@dudousxd/nestjs-agent:agent-registry');\nexport const AGENT_ACTOR_RESOLVER = Symbol.for('@dudousxd/nestjs-agent:actor-resolver');\n/** The governance read-model (usage/spend/threads), consumed by the dashboard + telescope surfaces. */\nexport const AGENT_GOVERNANCE_QUERIES = Symbol.for('@dudousxd/nestjs-agent:governance-queries');\n/** The `QuotaProvider` behind `GET <base>/quota` (and, when the host binds one, the send gate). */\nexport const AGENT_QUOTA_PROVIDER = Symbol.for('@dudousxd/nestjs-agent:quota-provider');\n/** The `ModelCatalog` behind `GET <base>/models` and the model a send may name. Optional. */\nexport const AGENT_MODEL_CATALOG = Symbol.for('@dudousxd/nestjs-agent:model-catalog');\n/** The pricing WRITE side (`AgentPricingStore`) — seeds/updates the per-model rates cost is priced against. */\nexport const AGENT_PRICING_STORE = Symbol.for('@dudousxd/nestjs-agent:pricing-store');\n/** The RAG retrieval seam (`Retriever`) — vector/keyword search behind the agentic tool or inject mode. */\nexport const AGENT_RETRIEVER = Symbol.for('@dudousxd/nestjs-agent:retriever');\n/** The embedding provider (`EmbeddingProvider`) — text→vector for retrieval + ingestion. */\nexport const AGENT_EMBEDDING_PROVIDER = Symbol.for('@dudousxd/nestjs-agent:embedding-provider');\n// Per-agent deps factory. A Symbol.for token (not the class) so DI survives tsup's dual\n// index/durable bundles, which each get their own copy of the AgentDepsFactory class.\nexport const AGENT_DEPS_FACTORY = Symbol.for('@dudousxd/nestjs-agent:deps-factory');\n/** App-wide, ordered `@SystemPromptContributor()` functions the loop appends after the agent base. */\nexport const AGENT_PROMPT_CONTRIBUTORS = Symbol.for('@dudousxd/nestjs-agent:prompt-contributors');\n/**\n * Resolves opaque store `actorRef`s to human display labels for governance/dashboard read surfaces.\n * Optional — see {@link import('./spi/actor-directory.js').ActorDirectory}.\n */\nexport const AGENT_ACTOR_DIRECTORY = Symbol.for('@dudousxd/nestjs-agent:actor-directory');\n/**\n * Persists an uploaded attachment somewhere the model can fetch it from and returns a\n * `MessageAttachment`. Optional — see\n * {@link import('./spi/attachment-staging.js').AttachmentStagingStore}.\n */\nexport const AGENT_ATTACHMENT_STAGING = Symbol.for('@dudousxd/nestjs-agent:attachment-staging');\n/**\n * Console-side HITL approve/reject for the cross-thread approvals inbox. Optional — see\n * {@link import('./spi/approval-port.js').AgentApprovalPort}.\n */\nexport const AGENT_APPROVAL_PORT = Symbol.for('@dudousxd/nestjs-agent:approval-port');\n/**\n * The resolved `SkillsConfig` (provider + scope resolver + ceiling), or `undefined` where the host\n * configured no skills. Bound once and read by BOTH the loop's deps and the listing endpoint, so\n * what a user can invoke and what the model can reach are the same resolution.\n */\nexport const AGENT_SKILLS = Symbol.for('@dudousxd/nestjs-agent:skills');\n/**\n * The resolved `MemoryConfig` (provider + scope resolver + ceilings), or `undefined` where the host\n * configured no memory. Bound once and read by BOTH the loop's deps and the read-back endpoint, so\n * what a person is shown and what the model was shown are the same resolution.\n */\nexport const AGENT_MEMORY = Symbol.for('@dudousxd/nestjs-agent:memory');\n/**\n * A shared, mutable list `SkillDiscoveryService` fills with `@Skill`-decorated providers. Read\n * lazily by the bound {@link AGENT_SKILLS} provider — discovery runs after DI has built it.\n */\nexport const AGENT_SKILL_SOURCES = Symbol.for('@dudousxd/nestjs-agent:skill-sources');\n/**\n * The `ConfirmTokenStore` that makes a `defineConfirmedTool` confirmation single use. Bound by the\n * store modules (`DrizzleAgentStoreModule`, `MikroOrmAgentStoreModule`); inject it into the factory\n * that builds the tool (`provideAgentTool(factory, [AGENT_CONFIRM_TOKEN_STORE])`).\n */\nexport const AGENT_CONFIRM_TOKEN_STORE = Symbol.for('@dudousxd/nestjs-agent:confirm-token-store');\n/**\n * The `ChannelStore` text channels (`@dudousxd/nestjs-agent-channels`) keep their short-lived state\n * in: message ids already answered, questions waiting for an answer, outcomes already relayed. Bound\n * by the store modules (`DrizzleAgentStoreModule`, `MikroOrmAgentStoreModule`) on the\n * `agent_channel_state` table; unbound, `AgentChannelsModule` keeps it in memory.\n */\nexport const AGENT_CHANNEL_STORE = Symbol.for('@dudousxd/nestjs-agent:channel-store');\n","import type { Actor } from '../types.js';\nimport type { ModelProvider, ModelTurnArgs } from './model-provider.js';\n\n/** One model a caller may pick. */\nexport interface ModelCatalogEntry {\n /** What a client sends as `model` — and what the {@link ModelProvider} receives as `args.model`. */\n id: string;\n label: string;\n description?: string;\n /** Short tags a picker can render as chips — `'fast'`, `'reasoning'`, `'vision'`, `'new'`, … */\n badges?: string[];\n /** `false` → listed but not selectable right now (plan, quota, outage); a send naming it is refused. */\n available: boolean;\n /** Why it is unavailable, in words a picker can show. */\n unavailableReason?: string;\n /** Context window, in tokens, when the host knows it. */\n contextWindow?: number;\n}\n\n/** Models grouped under the provider that serves them. */\nexport interface ModelCatalogProviderGroup {\n id: string;\n label: string;\n models: ModelCatalogEntry[];\n}\n\n/** The agent always runs on one model: the picker shows it and offers no choice. */\nexport interface ModelCatalogLock {\n /** The catalog id every turn runs on. */\n model: string;\n /** Why, in words a picker can show (\"This assistant always uses GPT-5\"). */\n reason?: string;\n}\n\n/** What `GET <base>/models` answers. */\nexport interface ModelCatalogView {\n providers: ModelCatalogProviderGroup[];\n /**\n * Present when the agent is locked to one model. Every turn runs on `locked.model` — a send's own\n * `model` and a thread's pin included — and a send naming another model is refused (`400`). List\n * the other models as unavailable too, so an older client that ignores the lock cannot pick them.\n */\n locked?: ModelCatalogLock;\n /** The model a turn runs on when nobody picked one; `null` when the provider decides. */\n default: string | null;\n}\n\nexport interface ModelCatalogQuery {\n actor: Actor;\n /** The agent the picker is for; omitted → the default agent. */\n agent?: string;\n}\n\n/**\n * Which models a caller may run a turn on — the picker's data and the send's gate. The server\n * refuses a `model` (on a send, or pinned on a thread) that this does not list as `available` for\n * the actor and agent, so a client cannot pick a model the host did not offer it.\n *\n * Bind with `AgentModule.forRoot({ models })`. Without one, `GET <base>/models` answers an empty\n * catalog and a request naming a model is refused.\n */\nexport interface ModelCatalog {\n list(query: ModelCatalogQuery): ModelCatalogView | Promise<ModelCatalogView>;\n}\n\n/** A catalog that answers the same view to everyone — for a fixed list of models. */\nexport function staticModelCatalog(view: ModelCatalogView): ModelCatalog {\n return { list: () => view };\n}\n\n/** The entry `id` names in `view`, or `undefined`. */\nexport function findCatalogModel(\n view: ModelCatalogView,\n id: string,\n): ModelCatalogEntry | undefined {\n for (const group of view.providers) {\n const found = group.models.find((model) => model.id === id);\n if (found !== undefined) return found;\n }\n return undefined;\n}\n\n/**\n * A provider that runs every turn on `model` — what the loop wraps the bound provider in when a\n * turn has a selected model, so every call it makes (the answer, a structured-output pass, the\n * follow-up suggestions) goes to the same one. A provider that does not read `args.model` runs its\n * own default, unchanged.\n */\nexport function withSelectedModel(provider: ModelProvider, model: string): ModelProvider {\n return {\n runTurn: (args: ModelTurnArgs) => provider.runTurn({ ...args, model }),\n };\n}\n","/**\n * The \"data plane\": live token transport, decoupled from the durable control plane.\n *\n * The model turn writes deltas to a `SinkWriter` keyed by runId; the HTTP layer\n * `subscribe`s by runId and pipes the chunks to the browser as SSE. A late subscriber\n * (reconnect/resume) replays buffered chunks first, then follows live — which is what\n * makes streaming survive a dropped connection or a pod restart.\n */\nexport interface SinkWriter {\n write(chunk: Uint8Array): void | Promise<void>;\n /** Mark the run's stream finished (no more chunks). */\n end(): void | Promise<void>;\n /**\n * Terminate the run's stream with an error instead of a normal end. Subscribers replay any\n * buffered chunks first, then throw an {@link AgentStreamError} carrying this `code`/`message`\n * — so the transport can surface a typed failure frame instead of leaking it as assistant text.\n */\n fail(error: StreamError): void | Promise<void>;\n /**\n * OPTIONAL: write out anything this writer is still holding back, without ending the stream. Only\n * a sink that gathers frames before writing them (the SQL sink coalesces text) has anything to do\n * here; a delegated run's child writer calls it where it would have ended the stream, so nothing\n * of the delegate's is still held back when its parent — possibly on another replica — writes next.\n */\n flush?(): void | Promise<void>;\n}\n\n/** A machine-readable stream failure. `code` is a stable slug; `message` is human-facing. */\nexport interface StreamError {\n code: string;\n message: string;\n}\n\n/**\n * Thrown out of {@link TokenStreamSink.subscribe} when a run ended via {@link SinkWriter.fail}.\n * Carries the structured {@link StreamError} so the HTTP layer can emit an `event: error` frame.\n */\nexport class AgentStreamError extends Error {\n readonly code: string;\n constructor(error: StreamError) {\n super(error.message);\n this.name = 'AgentStreamError';\n this.code = error.code;\n }\n}\n\nexport interface TokenStreamSink {\n /** Open (or reopen) the writer for a run. */\n open(runId: string): SinkWriter | Promise<SinkWriter>;\n /**\n * Replay buffered chunks for the run, then yield live ones until `end()`. Throws\n * {@link AgentStreamError} if the run was terminated with {@link SinkWriter.fail}.\n */\n subscribe(runId: string): AsyncIterable<Uint8Array>;\n /** Drop any buffer/resources for the run. */\n close(runId: string): void | Promise<void>;\n}\n","/**\n * The structured live-stream vocabulary carried over the {@link SinkWriter} byte channel.\n *\n * The model turn (via the AI-SDK adapter) and the agent loop write these events as NDJSON — one\n * `JSON.stringify(event)\\n` per {@link SinkWriter.write}. The HTTP layer forwards each line as an\n * SSE `data:` frame, and the client transport maps them back to the AI SDK UI-message chunk\n * protocol so the browser renders text, reasoning, and tool cards (input + output) LIVE — the same\n * rich rendering a raw `streamText().toUIMessageStream()` would give, but reconstructed on the\n * client so the sink stays a format-agnostic byte buffer (durable buffering/replay is untouched).\n *\n * Keeping this vocabulary neutral (not AI-SDK `UIMessageChunk`) means core never depends on `ai`:\n * the adapter owns model-parts → event, the transport owns event → UI-chunk.\n *\n * The vocabulary is also a CONTRACT for runners that are not this library's loop: anything that\n * writes these frames (one JSON object per SSE `data:` line) gets the React transport, transcript\n * model and hooks for free. Two rules keep it evolvable:\n * - every frame is a JSON object with a string `kind`; a reader MUST tolerate kinds it does not\n * know (the React transport forwards them as `data-<kind>` parts rather than dropping them);\n * - fields are only ever added, and new fields are optional.\n */\nimport type { ElicitationRequest } from './elicitation.js';\nimport type { ChatQueueState } from './spi/chat-queue.js';\nimport type { ToolConfirmation } from './tool-presentation.js';\nimport type { MessageUsage } from './types.js';\n\n/**\n * A component the server pushed into the conversation: generative UI that is NOT a tool call's\n * rendering. It is addressed by `component` (a key in the client's own component registry), never\n * by a tool name, so a runner can emit one from anywhere — a tool body, a post-processing step, a\n * sandboxed agent that renders through its own protocol.\n *\n * `id` is the component's identity within the message: a second frame with the same `id` REPLACES\n * the first (streaming props into a chart, flipping a card from \"loading\" to \"ready\"), it never\n * adds a second component.\n */\nexport interface AgentUiComponent {\n id: string;\n /** Registry key the client resolves to its own renderer, e.g. `data-table`. */\n component: string;\n props: Record<string, unknown>;\n /** Schema version of `props`, so a client can keep rendering components persisted by an older server. */\n version?: number;\n /** Validated readable fallback retained for clients without this renderer. */\n fallbackText?: string;\n /** Trusted schema versions for every component in a persisted tree. */\n componentVersions?: Record<string, number>;\n /**\n * The tool call that pushed the component (`ctx.emitUi`), when one did. Lets a client place it\n * with that call — a reloaded message puts it right after the call's tool part, where the live\n * stream showed it. Absent for a component pushed outside a tool.\n */\n toolCallId?: string;\n}\n\n/**\n * Who has to settle an action tool call, and until when. Metadata only: the call itself is still\n * settled through the tool-call approve/reject routes, by its `toolCallId`.\n */\nexport interface AgentApprovalRequest {\n target?: { kind: 'proposal'; proposalId: string };\n /** Resolved confirmation from the action preflight; overrides presentation templates. */\n confirmation?: ToolConfirmation;\n /** The tool call awaiting the decision — the `id` of a call already announced on this stream. */\n id: string;\n /**\n * Who may decide. Open vocabulary the host defines — `'requester'` (the person chatting),\n * `'admin'`, a role name, a team. A client uses it to say \"waiting on an admin\" instead of\n * offering buttons the viewer cannot use.\n */\n approver: string;\n /** ISO-8601 instant after which the request lapses. Absent → it never expires. */\n expiresAt?: string;\n /** Why this call needs a person, in words for that person. */\n reason?: string;\n}\n\n/**\n * How an approval settled — the other half of {@link AgentApprovalRequest}, under the same `id`.\n * Metadata again: the call's own outcome still arrives as `tool-output` (approved and ran),\n * `tool-output-error` (approved and failed) or `tool-output-denied` (rejected or expired).\n */\nexport interface AgentApprovalSettlement {\n id: string;\n status: 'approved' | 'rejected' | 'expired';\n /** Repeated from the request, for a call approved without one being streamed (a remembered approval). */\n approver?: string;\n /** Opaque ref of who decided. Absent on an expiry. */\n decidedBy?: string;\n /** The surface the decision came through: `'web'`, `'slack'`, `'remembered'`, … */\n decidedVia?: string;\n /** The approval also covers later calls of this tool in this thread. */\n remember?: boolean;\n /** What the person said when declining. */\n reason?: string;\n}\n\nexport type AgentStreamEvent =\n | { kind: 'step-start' }\n /**\n * Closes the step opened by the matching `step-start`. Carries the model call's token usage and\n * `costUsd` (an estimate from the bound pricing store, or `null` when unpriced/unbound — never a\n * fabricated `0`) so a live client can render running cost without waiting for a thread re-fetch.\n */\n | {\n kind: 'step-finish';\n usage?: MessageUsage;\n costUsd?: number | null;\n /**\n * How long the model spent thinking in this step, in ms — the same number persisted as\n * `StoredMessage.reasoningMs`, so a live thread and a reloaded one read the same duration.\n * Absent when the step had no reasoning.\n */\n reasoningMs?: number;\n /**\n * The model the step ran on: the one the provider reported, else the configured `modelId`.\n * What a per-model usage report keys on (the AG-UI producer's `RUN_FINISHED.usage`). Absent\n * when neither is known; a reader that does not know the field ignores it.\n */\n model?: string;\n }\n | { kind: 'text'; text: string }\n | { kind: 'reasoning'; text: string }\n /**\n * `toolKind` collapses `ToolKind`'s `'agent'` into `'read'` — delegation tools auto-execute like a read tool.\n *\n * `parentId` nests this call under another call on the same stream: the inner calls a code-mode\n * `execute` makes, the tools a delegated sub-agent runs. The parent must be announced first. A\n * call's parent is fixed by its first frame that names one; later frames may omit it.\n */\n | {\n kind: 'tool-input-start';\n id: string;\n name: string;\n toolKind: 'read' | 'action';\n parentId?: string;\n }\n | { kind: 'tool-input-delta'; id: string; delta: string }\n | {\n kind: 'tool-input-available';\n id: string;\n name: string;\n input: unknown;\n toolKind: 'read' | 'action';\n /** Same as on `tool-input-start`, for a runner that announces a call without streaming its input. */\n parentId?: string;\n }\n | { kind: 'tool-output'; id: string; output: unknown }\n | { kind: 'tool-output-error'; id: string; error: string }\n /**\n * A person was asked to approve an action tool and declined it. Its own frame, NOT\n * `tool-output-error`: a refusal is a decision with a known outcome — nothing ran — while a\n * failure is an outcome nobody chose and whose effects are unknown. Rendering them the same way\n * tells an operator their own \"no\" was a malfunction. Maps onto the SDK's `output-denied` tool\n * part state, which a client reads without knowing any tool's name.\n */\n | { kind: 'tool-output-denied'; id: string; reason?: string }\n /**\n * The run has put a question set to the user and is parked until someone answers it (or skips).\n * Written by the LOOP for both elicitation surfaces — the configured intake and the model's `ask`\n * tool — so a client renders one form either way rather than learning to recognise a tool name.\n * The matching `tool-output` frame, under the same `id`, carries the settled answers.\n */\n | { kind: 'elicitation'; id: string; request: ElicitationRequest }\n /**\n * An action tool call (already announced by `tool-input-start`/`tool-input-available` under the\n * same `id`) is parked on a person. Optional: a client still treats an `action` call stuck at\n * its input as pending — this frame adds WHO has to decide and UNTIL WHEN, and moves the call\n * into the AI SDK's native `approval-requested` state.\n */\n | ({ kind: 'approval-requested' } & AgentApprovalRequest)\n /**\n * A parked action call was decided (or lapsed). Optional, like `approval-requested`: it adds WHO\n * decided, THROUGH WHAT and whether the approval is REMEMBERED; the outcome itself rides the\n * call's own output frame. See {@link AgentApprovalSettlement}.\n */\n | ({ kind: 'approval-settled' } & AgentApprovalSettlement)\n /**\n * Server-pushed generative UI, positioned in the message where it arrives. Not tied to a tool\n * call. See {@link AgentUiComponent}.\n */\n | ({ kind: 'ui' } & AgentUiComponent)\n /**\n * The thread's title was set or changed while this run streamed (typically derived from the\n * first exchange). Thread-level, not message content: a client updates its header/sidebar and\n * does not render it in the transcript.\n */\n | { kind: 'title'; title: string }\n /**\n * Host-defined facts about the message being streamed (the model that answered, how long it took,\n * the error it ended with), merged into the client message's `metadata`. The persisted\n * counterpart is `StoredMessage.metadata`, so a reload reads the same values. The library's own\n * loop never writes it; a runner that is not this library's loop uses it for what its store keeps\n * per message.\n */\n | { kind: 'message-metadata'; metadata: Record<string, unknown> }\n /**\n * Someone stopped this run. The stream's LAST frame, written by the runner that settled the\n * cancel, immediately before a normal `end()` — never a `fail()`, because a cancel is not an\n * error and a client that retries on a failed stream must not retry this.\n *\n * A run that simply ends wrote everything it had; one that ends after this frame did not, and the\n * difference is the whole point: without it a reader cannot tell a truncated answer from a\n * complete one. Consumers that predate the frame ignore it and see the `end()` they always saw.\n */\n | { kind: 'cancelled' }\n /**\n * The thread's message queue changed — a snapshot of the whole queue, never a delta, so a client\n * that missed one frame is corrected by the next. Written into the stream of the run that is\n * holding the thread: when someone queues, edits, reorders or removes a waiting message, and, just\n * before this run's own terminal frame, with what happens next — `started` names the queued\n * message that became the next turn and that turn's run id (attach to it with\n * `GET <base>/chat/:runId/stream`), `queue.paused` says why nothing starts.\n */\n | { kind: 'queue'; queue: ChatQueueState; started?: { messageId: string; runId: string } };\n\nconst encoder = new TextEncoder();\n\n/** Encode one event as an NDJSON line (`{...}\\n`) for {@link SinkWriter.write}. */\nexport function encodeStreamEvent(event: AgentStreamEvent): Uint8Array {\n return encoder.encode(`${JSON.stringify(event)}\\n`);\n}\n\n/**\n * Read one NDJSON line back, or `null` when the line is not a stream event at all.\n *\n * `null` covers a genuinely opaque chunk, not just malformed JSON: the sink is a byte channel, so a\n * model provider is free to write anything into it and some write bare text. A caller that has to\n * CLASSIFY a chunk — the output gate, which may only forward what it can prove is not the answer —\n * treats an unreadable frame as unclassifiable rather than guessing.\n */\nexport function decodeStreamEvent(line: string): AgentStreamEvent | null {\n try {\n const parsed: unknown = JSON.parse(line);\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n typeof (parsed as AgentStreamEvent).kind === 'string'\n ) {\n return parsed as AgentStreamEvent;\n }\n } catch {\n /* not a stream event — the caller decides what an opaque chunk means */\n }\n return null;\n}\n\n/**\n * The `code` of a failed run's `event: error` frame — what a client branches on, and translates.\n * `quota_exceeded`, `output_rejected` and `structured_output_invalid` are outcomes the library words\n * itself (their `message` is safe to show as it is); the rest are crashes, whose `message` is a\n * generic sentence in production. Open-ended on purpose: a host's own runner may send other codes.\n */\nexport type AgentStreamErrorCode =\n | 'quota_exceeded'\n | 'output_rejected'\n | 'structured_output_invalid'\n /** The durable runtime refused a checkpoint position: the run's journal and its code disagree. */\n | 'replay_diverged'\n /** A model call ended without producing anything. */\n | 'model_no_output'\n | 'run_failed';\n","import type { ModelTurnResult } from './spi/model-provider.js';\nimport type { SinkWriter } from './spi/token-stream-sink.js';\nimport { type AgentUiComponent, decodeStreamEvent } from './stream-events.js';\n\n/** What a model turn streamed that the persisted message keeps, beyond its text and tool calls. */\nexport interface TurnFrameSummary {\n reasoning?: string;\n reasoningMs?: number;\n ui?: AgentUiComponent[];\n}\n\nexport interface ObservedTurnFrames {\n /** Hand THIS to the provider: every write passes through to the wrapped writer unchanged. */\n writer: SinkWriter;\n /** What was seen so far. Closes an open thinking burst at the moment it is called. */\n summary(): TurnFrameSummary;\n}\n\n/**\n * Watch the frames a model turn writes, to learn what the stream showed that the provider's result\n * does not carry: the model's thinking (text and how long it took) and any pushed UI components.\n *\n * Derived from the FRAMES rather than asked of each provider, so every provider that streams the\n * vocabulary gets reasoning persisted without implementing anything. Thinking time is the sum of\n * each burst of consecutive `reasoning` frames — from the first one to the next frame that is not\n * reasoning (or the end of the turn) — which is what a reader watched as \"thinking\".\n *\n * Call it inside the step that runs the model, so the summary rides that step's journaled result\n * and a replay reads the same numbers back instead of re-measuring a turn that is not happening.\n */\nexport function observeTurnFrames(\n writer: SinkWriter,\n now: () => number = Date.now,\n): ObservedTurnFrames {\n const decoder = new TextDecoder();\n let pending = '';\n let reasoning = '';\n let reasoningMs = 0;\n let burstStartedAt: number | undefined;\n const ui = new Map<string, AgentUiComponent>();\n\n function closeBurst(): void {\n if (burstStartedAt !== undefined) {\n reasoningMs += Math.max(0, now() - burstStartedAt);\n burstStartedAt = undefined;\n }\n }\n\n function observeLine(line: string): void {\n if (line.trim().length === 0) {\n return;\n }\n const event = decodeStreamEvent(line);\n if (event === null) {\n return;\n }\n if (event.kind === 'reasoning') {\n burstStartedAt ??= now();\n reasoning += event.text;\n return;\n }\n closeBurst();\n if (event.kind === 'ui') {\n // A repeat id replaces the props but keeps the component where it first appeared, exactly as\n // the client's data part does.\n ui.set(event.id, {\n id: event.id,\n component: event.component,\n props: event.props,\n ...(event.version !== undefined ? { version: event.version } : {}),\n });\n }\n }\n\n function observe(chunk: Uint8Array): void {\n pending += decoder.decode(chunk, { stream: true });\n let newline = pending.indexOf('\\n');\n while (newline !== -1) {\n observeLine(pending.slice(0, newline));\n pending = pending.slice(newline + 1);\n newline = pending.indexOf('\\n');\n }\n }\n\n return {\n writer: {\n write(chunk) {\n // Observed before it is forwarded, so a burst closes at the moment the next frame was\n // produced rather than whenever a slow sink got round to accepting it.\n observe(chunk);\n return writer.write(chunk);\n },\n end: () => writer.end(),\n fail: (error) => writer.fail(error),\n },\n summary() {\n if (pending.length > 0) {\n observeLine(pending);\n pending = '';\n }\n closeBurst();\n return {\n ...(reasoning.length > 0 ? { reasoning, reasoningMs: Math.round(reasoningMs) } : {}),\n ...(ui.size > 0 ? { ui: [...ui.values()] } : {}),\n };\n },\n };\n}\n\n/** Fill what a provider did not report from what its frames showed. A provider's own value wins. */\nexport function withTurnFrames<T extends ModelTurnResult>(result: T, frames: TurnFrameSummary): T {\n return {\n ...result,\n ...(result.reasoning === undefined && frames.reasoning !== undefined\n ? { reasoning: frames.reasoning }\n : {}),\n ...(result.reasoningMs === undefined && frames.reasoningMs !== undefined\n ? { reasoningMs: frames.reasoningMs }\n : {}),\n ...(result.ui === undefined && frames.ui !== undefined ? { ui: frames.ui } : {}),\n };\n}\n","import type { AiToolCtx } from './spi/tool.js';\nimport { type AgentStreamEvent, type AgentUiComponent } from './stream-events.js';\n\n/**\n * Components a tool pushes through `ctx.emitUi` have to survive a durable replay without being\n * streamed or persisted twice. They do it by riding the tool step's RESULT: the step that ran the\n * tool (`tool:<callId>` in-process, or the dispatched `AgentRunSteps.tool`) returns its output\n * wrapped together with the components, the runtime journals that, and a replay reads both back\n * without running anything. The loop then persists them once, from the step that already persists\n * the step's tool results.\n *\n * The wrapper is used ONLY when a tool pushed something, so every other tool journals exactly the\n * bytes it always did, and a run recorded before this existed replays unchanged.\n */\nconst TOOL_STEP_UI = '@@nestjs-agent/tool-step-ui';\n\ninterface ToolStepOutputWithUi {\n [TOOL_STEP_UI]: 1;\n output: unknown;\n ui: AgentUiComponent[];\n preflightDenied?: string;\n text?: string;\n}\n\n/** The tool step's journaled result: the bare output, or the output plus the components it pushed. */\nexport function wrapToolStepOutput(\n output: unknown,\n ui: readonly AgentUiComponent[],\n text?: string,\n): unknown {\n // Escape ordinary output that happens to match our envelope: unwrap exactly one layer.\n const reserved = typeof output === 'object' && output !== null && TOOL_STEP_UI in output;\n if (ui.length === 0 && !reserved && !text) {\n return output;\n }\n const wrapped: ToolStepOutputWithUi = {\n [TOOL_STEP_UI]: 1,\n output,\n ui: [...ui],\n ...(text ? { text } : {}),\n };\n return wrapped;\n}\n\n/** Carry domain refusal across a remote step without losing its type in error serialization. */\nexport function wrapToolPreflightDenied(reason: string): unknown {\n const wrapped: ToolStepOutputWithUi = {\n [TOOL_STEP_UI]: 1,\n output: null,\n ui: [],\n preflightDenied: reason,\n };\n return wrapped;\n}\n\n/** Read a tool step's result back — either shape. */\nexport function unwrapToolStepOutput(raw: unknown): {\n output: unknown;\n ui: AgentUiComponent[];\n preflightDenied?: string;\n text?: string;\n} {\n if (\n typeof raw === 'object' &&\n raw !== null &&\n (raw as Partial<ToolStepOutputWithUi>)[TOOL_STEP_UI] === 1\n ) {\n const wrapped = raw as ToolStepOutputWithUi;\n return {\n output: wrapped.output,\n ui: Array.isArray(wrapped.ui) ? wrapped.ui : [],\n ...(typeof wrapped.text === 'string' ? { text: wrapped.text } : {}),\n ...(typeof wrapped.preflightDenied === 'string'\n ? { preflightDenied: wrapped.preflightDenied }\n : {}),\n };\n }\n return { output: raw, ui: [] };\n}\n\nexport type EmitUi = AiToolCtx['emitUi'];\n\n/**\n * `ctx.emitUi` where there is no conversation to push into (the MCP server, a direct\n * `registry.invoke`): nothing is streamed or persisted, but the call resolves to an id — the one it\n * was given, else `<scope>:ui:<n>` — so a tool never has to test for the capability.\n */\nexport function createNoopEmitUi(scope = 'noop'): EmitUi {\n let next = 0;\n return async (_component, _props, options = {}) => {\n if (options.id !== undefined) {\n return { id: options.id };\n }\n const id = `${scope}:ui:${next}`;\n next += 1;\n return { id };\n };\n}\n\n/** Collects what one tool invocation pushes, streaming each push as it happens. */\nexport interface UiCollector {\n emit: EmitUi;\n /** Everything pushed so far: first-seen order, last props per id. */\n components(): AgentUiComponent[];\n /**\n * A new ATTEMPT of the same call (a transient retry): numbering restarts, so the retry's pushes\n * reuse — and replace — the ids the failed attempt used.\n */\n restart(): void;\n}\n\n/**\n * `write` streams one frame; omit it where there is no live stream (the component is still\n * collected and persisted).\n */\nexport function createUiCollector(\n toolCallId: string,\n write?: (event: AgentStreamEvent) => void | Promise<void>,\n): UiCollector {\n const pushed = new Map<string, AgentUiComponent>();\n let next = 0;\n const emit: EmitUi = async (component, props, options = {}) => {\n if (typeof component !== 'string' || component.length === 0) {\n throw new Error('emitUi: component must be a non-empty string');\n }\n if (typeof props !== 'object' || props === null || Array.isArray(props)) {\n throw new Error('emitUi: props must be a JSON object');\n }\n let id = options.id;\n if (id === undefined) {\n id = `${toolCallId}:ui:${next}`;\n next += 1;\n }\n const entry: AgentUiComponent = {\n id,\n component,\n // Snapshot: the frame and the persisted value are what the tool pushed at THIS moment, not\n // whatever the object it handed over looks like when the step settles.\n props: JSON.parse(JSON.stringify(props)) as Record<string, unknown>,\n ...(options.version !== undefined ? { version: options.version } : {}),\n ...(options.fallbackText !== undefined ? { fallbackText: options.fallbackText } : {}),\n ...(options.componentVersions !== undefined\n ? { componentVersions: { ...options.componentVersions } }\n : {}),\n toolCallId,\n };\n // Delete-then-set would move it; a repeat id keeps its first position, like the client's part.\n pushed.set(id, entry);\n await write?.({ kind: 'ui', ...entry });\n return { id };\n };\n return {\n emit,\n components: () => [...pushed.values()],\n restart: () => {\n next = 0;\n },\n };\n}\n\n/** Merge component lists: first-seen order, the last props for each id. */\nexport function mergeUi(\n ...lists: readonly (readonly AgentUiComponent[] | undefined)[]\n): AgentUiComponent[] {\n const merged = new Map<string, AgentUiComponent>();\n for (const list of lists) {\n for (const component of list ?? []) {\n merged.set(component.id, component);\n }\n }\n return [...merged.values()];\n}\n\n/** Escape code units native PostgreSQL/MySQL TEXT cannot store; retain ordinary prose and emoji. */\nexport function escapeUnsafeToolUiText(text: string): string {\n return text\n .replaceAll('\\u0000', '\\\\u0000')\n .replace(\n /[\\uD800-\\uDFFF]/gu,\n (unit) => `\\\\u${unit.charCodeAt(0).toString(16).padStart(4, '0')}`,\n );\n}\n","import type { ToolKind } from './types.js';\n\n/**\n * How a person-facing surface talks about a tool WITHOUT ever naming it. Declared on the server,\n * beside the tool's input schema, because whoever changes the input is the one who has to re-word\n * the sentence that mentions it — and a client that shipped its own name-to-sentence map would go\n * stale the moment a tool was renamed. A tool name is an identifier, never copy.\n *\n * `running` / `done` (and `confirm.title`, `confirm.detail`, `result.text`) are templates:\n * `{dotted.path}` placeholders are filled from the call's INPUT (or, for `result`, its OUTPUT), so one\n * declaration covers every call the tool will ever receive and replays identically from history.\n * A placeholder with nothing behind it collapses along with the space before it.\n */\nexport interface ToolPresentation {\n /** Noun phrase, for counts and headings: \"Database query\", \"Knowledge base\". */\n label: string;\n /** Present progressive, while the call is in flight: \"Reading {bucket}\". */\n running: string;\n /** Settled, once the output is in: \"Read {bucket}\". */\n done: string;\n /** A key into the client's own glyph map (`database`, `search`, …). Unknown keys fall back to a generic glyph there. */\n icon?: string;\n /** One line naming what the tool reaches, for when the activity line is opened. */\n detail?: string;\n /** `destructive` earns the warning treatment on an approval prompt. */\n tone?: ToolPresentationTone;\n /** What a person is being asked to allow when an `action` call parks for approval. */\n confirm?: ToolConfirmation;\n /** How the call's OUTPUT reads as content. */\n result?: ToolResultView;\n}\n\nexport type ToolPresentationTone = 'neutral' | 'destructive';\n\nexport interface ToolConfirmation {\n /** \"Delete {count} files?\" */\n title: string;\n /** The button: \"Delete\". */\n verb: string;\n /** A sentence under the title, when the title alone does not say what changes. */\n detail?: string;\n}\n\n/** A value read out of a tool's output by dotted path, with the words to put next to it. */\nexport interface ToolResultField {\n path: string;\n label: string;\n unit?: string;\n}\n\n/**\n * How a tool's output reads as content. Every variant names dotted paths into the output rather\n * than shapes, so a renderer never has to recognise which tool it is drawing: it receives\n * `{ view, output }` and draws it.\n */\nexport type ToolResultView =\n /** A row of labelled readings — one result, several facets. */\n | { kind: 'metrics'; fields: ToolResultField[] }\n /** `rows` is a path to an array; each column's `path` is read WITHIN a row. */\n | { kind: 'table'; columns: ToolResultField[]; rows: string; empty?: string }\n /** `lines` is a path to an array of strings, drawn as a log tail. */\n | { kind: 'log'; lines: string }\n /** One sentence, templated over the output. */\n | { kind: 'note'; text: string }\n /** The output is drawn somewhere else on the screen already (a pushed component, a side panel). */\n | { kind: 'elsewhere' };\n\n/**\n * `GET <base>/tools?agent=*` (and `useToolCatalog({ agent: ALL_AGENTS })`): every tool the actor\n * reaches through ANY agent, each once — for a surface that shows several agents' conversations.\n */\nexport const ALL_AGENTS = '*';\n\n/**\n * One tool as `GET <base>/tools` reports it: the tools THIS actor may be offered by the chosen agent,\n * with how each is spoken about. `presentation` is absent for a tool that declared none — a client\n * then narrates it generically rather than falling back to its name.\n */\nexport interface ToolCatalogEntry {\n /** The wire name tool parts carry (`tool-<name>`) — the key a client looks a call up by. */\n name: string;\n kind: ToolKind;\n presentation?: ToolPresentation;\n}\n","import type { UiCapabilities } from '../genui/capabilities.js';\nimport type { Actor, AgentHostContext, MessageAttachment, PageContext } from '../types.js';\nimport type { AgentStore } from './agent-store.js';\n\n/**\n * Why a thread's queue stopped draining. A paused queue keeps its messages; nothing starts until\n * someone resumes it (`POST <base>/threads/:id/queue/resume`, `chat.queue.resume()`).\n *\n * - `run_failed` the turn before it failed — the next message would likely fail the same way,\n * and the person should see the error before more of their messages are spent.\n * - `cancelled` someone pressed Stop. Stop means stop: the queue does not start behind it.\n * An interrupt (`mode: 'interrupt'`) is the exception — its message starts.\n * - `quota_exceeded` the next message's actor is over budget; resuming later retries the check.\n * - `start_failed` the next message could not be started (the runner refused it).\n */\nexport type QueuePauseReason = 'run_failed' | 'cancelled' | 'quota_exceeded' | 'start_failed';\n\nexport interface QueuePause {\n reason: QueuePauseReason;\n /** Human-facing detail (the failure, the quota window), when there is one. */\n message?: string;\n /** ISO-8601 instant the queue paused. */\n at: string;\n}\n\n/**\n * A message a person sent while a turn was still running on the thread, waiting its turn. It is not\n * part of the transcript until it starts: the loop appends it as the turn's user message, exactly as\n * if it had been sent then. Everything a send carries is captured at enqueue time, resolved and\n * checked there (agent, model, attachments), so a queued message starts with no request around it.\n */\nexport interface QueuedMessage {\n id: string;\n threadId: string;\n /** Who queued it. The turn it starts runs as this actor. */\n actor: Actor;\n content: string;\n attachments?: MessageAttachment[];\n agentName?: string;\n /** The persona the send resolved (explicit, the thread's, or the agent's default) — what it starts under. */\n persona?: string;\n model?: string;\n pageContext?: PageContext;\n uiCapabilities?: UiCapabilities;\n /** The send's {@link AgentRunInput.hostContext}, carried to the turn it starts. Never on the wire view. */\n hostContext?: AgentHostContext;\n /**\n * Queued by an interrupt (`POST chat { mode: 'interrupt' }`): the running turn was cancelled to\n * make room for it, so the cancel starts it instead of pausing the queue.\n */\n interrupt?: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\n/** A queued message as the wire shows it — {@link QueuedMessage} without the actor or thread. */\nexport interface QueuedMessageView {\n id: string;\n content: string;\n attachments?: MessageAttachment[];\n agentName?: string;\n persona?: string;\n model?: string;\n interrupt?: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\n/**\n * A thread's queue: its waiting messages in the order they will run, and whether it is draining.\n * What `GET <base>/threads/:id/queue` answers, what `ThreadDetail.queue` carries, and what every\n * `queue` stream frame snapshots.\n */\nexport interface ChatQueueState {\n items: QueuedMessageView[];\n paused: QueuePause | null;\n}\n\nexport interface EnqueueMessageInput {\n threadId: string;\n actor: Actor;\n content: string;\n attachments?: MessageAttachment[];\n agentName?: string;\n persona?: string;\n model?: string;\n pageContext?: PageContext;\n uiCapabilities?: UiCapabilities;\n hostContext?: AgentHostContext;\n interrupt?: boolean;\n /** `'tail'` (default) runs it after everything already waiting; `'head'` runs it next. */\n at?: 'tail' | 'head';\n}\n\n/**\n * What a store may change on a waiting message (`PATCH <base>/queue/:messageId` sets the text and\n * attachments). An omitted key leaves the field as it is.\n */\nexport interface QueuedMessagePatch {\n content?: string;\n /** `null` drops every attachment. */\n attachments?: MessageAttachment[] | null;\n /**\n * Mark (or unmark) the message as an interrupt — what `POST <base>/queue/:messageId/interrupt`\n * does to a message that is already waiting, before it cancels the running turn for it.\n */\n interrupt?: boolean;\n}\n\n/**\n * A store that can hold a thread's queue of waiting messages, and admit ONE run per thread at a time.\n *\n * Probed STRUCTURALLY ({@link isChatQueueStore}), like `ThreadTurnReader`: a store that predates it\n * keeps the old behaviour (a send on a busy thread starts a second, concurrent run). All members or\n * none — a queue without the admission primitives cannot be drained safely across processes.\n *\n * Admission is the thread's `activeStreamId`, compare-and-set:\n * - {@link claimActiveStream} sets it to `runId` only when it is free, already `runId` (a retried\n * claim is idempotent), or held by `replacing` (a handoff from the run that is settling, or a\n * takeover from a holder the runner reports dead). Exactly one of two racing claims wins.\n * - {@link releaseActiveStream} clears it only when `runId` still holds it — so a run that settles\n * after it handed the thread to the next one cannot clear the next one's claim.\n */\nexport interface ChatQueueStore {\n enqueueMessage(input: EnqueueMessageInput): Promise<QueuedMessage>;\n /** The thread's waiting messages, in run order (the head first). */\n listQueue(threadId: string): Promise<QueuedMessage[]>;\n getQueuedMessage(id: string): Promise<QueuedMessage | null>;\n /** `null` when there is no such message (it started, or was removed). */\n updateQueuedMessage(id: string, patch: QueuedMessagePatch): Promise<QueuedMessage | null>;\n /** Move a message to `index` (clamped) in its thread's run order. `false` when it is gone. */\n moveQueuedMessage(id: string, index: number): Promise<boolean>;\n /**\n * Remove a message. `false` when it was already gone — which is also how a drain learns that the\n * head it was about to start was deleted under it, so it must be a real conditional delete.\n */\n removeQueuedMessage(id: string): Promise<boolean>;\n /** Remove every waiting message on the thread; answers how many there were. */\n clearQueue(threadId: string): Promise<number>;\n queuePause(threadId: string): Promise<QueuePause | null>;\n setQueuePause(threadId: string, pause: QueuePause | null): Promise<void>;\n /** The run currently holding the thread, or `null`. */\n activeRunForThread(threadId: string): Promise<string | null>;\n claimActiveStream(\n threadId: string,\n runId: string,\n options?: { replacing?: string },\n ): Promise<boolean>;\n releaseActiveStream(threadId: string, runId: string): Promise<boolean>;\n}\n\nconst CHAT_QUEUE_METHODS = [\n 'enqueueMessage',\n 'listQueue',\n 'getQueuedMessage',\n 'updateQueuedMessage',\n 'moveQueuedMessage',\n 'removeQueuedMessage',\n 'clearQueue',\n 'queuePause',\n 'setQueuePause',\n 'activeRunForThread',\n 'claimActiveStream',\n 'releaseActiveStream',\n] as const satisfies readonly (keyof ChatQueueStore)[];\n\n/** Whether `store` implements every {@link ChatQueueStore} member. */\nexport function isChatQueueStore(store: AgentStore): store is AgentStore & ChatQueueStore {\n const candidate = store as unknown as Record<string, unknown>;\n return CHAT_QUEUE_METHODS.every((method) => typeof candidate[method] === 'function');\n}\n\n/**\n * Release the thread `runId` was streaming — conditionally when the store can compare, so a run\n * that already handed the thread to the next queued turn does not clear that turn's claim; the old\n * unconditional clear on a store that cannot.\n */\nexport async function releaseThreadRun(\n store: AgentStore,\n threadId: string,\n runId: string,\n): Promise<void> {\n if (isChatQueueStore(store)) {\n await store.releaseActiveStream(threadId, runId);\n return;\n }\n await store.setActiveStream(threadId, null);\n}\n\n/** The wire view of a queued message. */\nexport function queuedMessageView(message: QueuedMessage): QueuedMessageView {\n return {\n id: message.id,\n content: message.content,\n ...(message.attachments !== undefined && message.attachments.length > 0\n ? { attachments: message.attachments }\n : {}),\n ...(message.agentName !== undefined ? { agentName: message.agentName } : {}),\n ...(message.persona !== undefined ? { persona: message.persona } : {}),\n ...(message.model !== undefined ? { model: message.model } : {}),\n ...(message.interrupt === true ? { interrupt: true } : {}),\n createdAt: message.createdAt,\n updatedAt: message.updatedAt,\n };\n}\n","import type { Actor } from '../types.js';\n\n/** The span a quota window counts over, in UTC. */\nexport type QuotaPeriod = 'day' | 'month';\n\n/** One budget window: what was spent in it, and the ceiling when there is one. */\nexport interface QuotaWindow {\n period: QuotaPeriod;\n /**\n * Tokens used in the window. Absent → the budget does not count tokens (a USD-only spend cap, such\n * as an AI gateway's) — never a fabricated `0`.\n */\n usedTokens?: number;\n /** Absent → no token ceiling on this window. */\n limitTokens?: number;\n usedUsd: number;\n /** Absent → no spend ceiling on this window. */\n limitUsd?: number;\n /** ISO-8601 instant the window starts over (next UTC midnight, first of next month). */\n resetsAt?: string;\n /**\n * The soft limit: the share of a ceiling (`0..1`, e.g. `0.8`) past which a client should warn\n * that the budget is running out. Absent → no warning for this window.\n */\n warnAt?: number;\n}\n\n/** Which window stopped the actor, when one did. */\nexport interface QuotaBlock {\n period: QuotaPeriod;\n /** Words a client can show (\"Monthly AI budget reached\"). */\n reason?: string;\n}\n\n/** A window past its soft limit ({@link QuotaWindow.warnAt}) but not exhausted. */\nexport interface QuotaWarning {\n period: QuotaPeriod;\n /** How much of the window's ceiling is used, `0..1` (the larger of spend and tokens). */\n ratio: number;\n /** Words a client can show (\"80% of your monthly AI budget used\"). */\n reason?: string;\n}\n\n/** What `GET <base>/quota` answers. */\nexport interface QuotaReport {\n windows: QuotaWindow[];\n /** Present when a window is exhausted — a send will be refused until it resets. */\n blocked?: QuotaBlock;\n /**\n * Present when a window crossed its `warnAt` and none is exhausted — the fullest one. A client\n * may also derive it from the windows ({@link quotaWarning}); the server's wins.\n */\n warning?: QuotaWarning;\n}\n\nexport interface QuotaQuery {\n actor: Actor;\n /** The instant to report for; defaults to now. */\n now?: Date;\n}\n\n/**\n * The actor's budget across windows — the read behind `GET <base>/quota` and, when the host binds\n * one (`AgentModule.forRoot({ quota })`), the gate a send passes: a report with `blocked`\n * refuses the turn with `429` before it starts.\n *\n * The default reads the usage ledger (`LedgerQuotaProvider` in `@dudousxd/nestjs-agent`); a host\n * with its own budget (an AI-gateway spend cap, a plan's monthly allowance) implements this.\n */\nexport interface QuotaProvider {\n report(query: QuotaQuery): Promise<QuotaReport>;\n}\n\n/** The first window whose token or spend ceiling is reached, as a {@link QuotaBlock}. */\nexport function exhaustedWindow(windows: readonly QuotaWindow[]): QuotaBlock | undefined {\n for (const window of windows) {\n const tokensOut =\n window.limitTokens !== undefined && (window.usedTokens ?? 0) >= window.limitTokens;\n const spendOut = window.limitUsd !== undefined && window.usedUsd >= window.limitUsd;\n if (tokensOut || spendOut) {\n return {\n period: window.period,\n reason: `${window.period === 'day' ? 'Daily' : 'Monthly'} ${spendOut ? 'spend' : 'token'} limit reached`,\n };\n }\n }\n return undefined;\n}\n\n/** How much of `window`'s ceilings is used, `0..1+` (the larger of spend and tokens), or `null`. */\nexport function quotaUsedRatio(window: QuotaWindow): number | null {\n const ratios: number[] = [];\n if (window.limitUsd !== undefined && window.limitUsd > 0) {\n ratios.push(window.usedUsd / window.limitUsd);\n }\n if (\n window.limitTokens !== undefined &&\n window.limitTokens > 0 &&\n window.usedTokens !== undefined\n ) {\n ratios.push(window.usedTokens / window.limitTokens);\n }\n return ratios.length === 0 ? null : Math.max(...ratios);\n}\n\n/**\n * The fullest window past its `warnAt`, as a {@link QuotaWarning} — `undefined` when none is, or\n * when one is exhausted (that is `blocked`, not a warning).\n */\nexport function quotaWarning(windows: readonly QuotaWindow[]): QuotaWarning | undefined {\n if (exhaustedWindow(windows) !== undefined) return undefined;\n let fullest: QuotaWarning | undefined;\n for (const window of windows) {\n if (window.warnAt === undefined) continue;\n const ratio = quotaUsedRatio(window);\n if (ratio === null || ratio < window.warnAt) continue;\n if (fullest === undefined || ratio > fullest.ratio) {\n fullest = { period: window.period, ratio };\n }\n }\n return fullest;\n}\n\n/** The UTC day range (`YYYY-MM-DD`, inclusive) and reset instant of `period` around `now`. */\nexport function quotaPeriodRange(\n period: QuotaPeriod,\n now: Date,\n): { fromDay: string; toDay: string; resetsAt: string } {\n const year = now.getUTCFullYear();\n const month = now.getUTCMonth();\n const day = now.toISOString().slice(0, 10);\n if (period === 'day') {\n const next = new Date(Date.UTC(year, month, now.getUTCDate() + 1));\n return { fromDay: day, toDay: day, resetsAt: next.toISOString() };\n }\n const first = new Date(Date.UTC(year, month, 1));\n const last = new Date(Date.UTC(year, month + 1, 0));\n return {\n fromDay: first.toISOString().slice(0, 10),\n toDay: last.toISOString().slice(0, 10),\n resetsAt: new Date(Date.UTC(year, month + 1, 1)).toISOString(),\n };\n}\n","/**\n * The WRITE side of the pricing table the {@link import('./governance-queries.js').AgentGovernanceQueries}\n * read-model prices usage against. Cost is $0 for an unpriced model, so an app seeds its models'\n * per-1M rates once (and re-`upsert`s when a provider changes prices). A store adapter implements\n * this; consumers inject via `AGENT_PRICING_STORE`. Use `seedModelPrices` for a one-shot batch.\n */\n\n/** A per-1M-token price for one model. Cache rates fall back to the input rate when omitted. */\nexport interface ModelPriceInput {\n modelId: string;\n inputPricePer1m: number;\n outputPricePer1m: number;\n /** Per-1M price for cache-write (prompt-cache) input tokens. Omit → priced at the input rate. */\n cacheWritePricePer1m?: number;\n /** Per-1M price for cache-read (prompt-cache) input tokens. Omit → priced at the input rate. */\n cacheReadPricePer1m?: number;\n}\n\n/** A current price row as read back, with the timestamp it took effect. */\nexport interface CurrentModelPrice extends ModelPriceInput {\n effectiveFrom: string;\n}\n\nexport interface AgentPricingStore {\n /**\n * Set the current price for a model. Atomic supersede: the model's prior `isCurrent` row (if any)\n * is retired and this one is inserted as current, effective now — so the read-model always joins\n * to exactly one live price per model, with no window where two rows race for `isCurrent`.\n */\n upsertModelPrice(input: ModelPriceInput): Promise<void>;\n /** The current price row per model (`isCurrent`), for a pricing admin view. */\n listCurrentPrices(): Promise<CurrentModelPrice[]>;\n}\n\n/** Seed (or refresh) a batch of model prices — one `upsertModelPrice` per row, in order. */\nexport async function seedModelPrices(\n store: AgentPricingStore,\n prices: ModelPriceInput[],\n): Promise<void> {\n for (const price of prices) {\n await store.upsertModelPrice(price);\n }\n}\n","/**\n * The two seams that see a turn's traffic to and from the model: an {@link InputProcessor} rewrites\n * the prompt on its way out, an {@link OutputProcessor} inspects the answer on its way back and may\n * redact, replace or refuse it. Wire them as `AgentLoopDeps.inputProcessors` /\n * `outputProcessors`, or via `AgentModule.forRoot({ inputProcessors, outputProcessors })`.\n *\n * WHAT THESE ARE NOT: a second way to decide what enters the context. `HistoryPolicy` owns\n * SELECTION — which of the thread's messages ride into the turn, and what stands in for the rest.\n * Processors run on whatever selection produced and own TRANSFORMATION — what those messages say.\n * The distinction is load-bearing rather than stylistic: selection is contractually pure and is what\n * the `load:thread` checkpoint records, so it bounds the journal as well as the prompt, while a\n * processor is allowed to call a model, runs in a checkpoint of its own per step, and rewrites a\n * DERIVED prompt that never becomes the thread's own memory of what was said. Splitting the same\n * decision across both means neither can be reasoned about alone, and the cheap one stops being the\n * whole answer to \"why did this turn cost that much\".\n */\n\nimport type { Actor, ModelMessage, ToolCallRequest } from '../types.js';\n\n/** Which turn, and which model step of it, a processor is looking at. */\nexport interface ProcessorContext {\n threadId: string;\n actor: Actor;\n /** The agent running this turn. Undefined → the default agent. */\n agentName?: string;\n /** The persona the turn runs under, when it runs under one. */\n persona?: string;\n /** 0-based model step within the run — the same index the `llm:<step>` checkpoint carries. */\n step: number;\n}\n\n/** Everything the model is about to be sent, as the previous processor in the chain left it. */\nexport interface ProcessedPrompt {\n /** The composed system prompt (agent base + contributors + any injected retrieval block). */\n system: string;\n /** The turn's messages, oldest-first, already through the history ceiling. */\n messages: ModelMessage[];\n}\n\n/**\n * Rewrites the prompt before each model call of a turn — masking identifiers, stamping a policy\n * preamble, collapsing an oversized tool result. Runs on EVERY step, not once per run, because the\n * transcript grows between steps: a redactor that only saw the opening prompt would wave through\n * whatever a tool result carried back.\n *\n * Runs inside the loop's `process:input:<step>` checkpoint and its result is journaled, so a\n * processor may call a model or hit the network — a resumed run reads back the prompt the suspended\n * attempt built rather than composing a different one.\n */\nexport interface InputProcessor {\n /** Identifies this processor in a failure. Keep it stable — it is user-visible on an error. */\n readonly name: string;\n process(\n prompt: ProcessedPrompt,\n ctx: ProcessorContext,\n ): ProcessedPrompt | Promise<ProcessedPrompt>;\n}\n\n/** One model step's answer, as the previous processor in the chain left it. */\nexport interface ModelAnswer {\n /** The assembled assistant text for this step. */\n text: string;\n /** The tool calls the same step asked for. Read-only context — a processor cannot change them. */\n toolCalls: readonly ToolCallRequest[];\n}\n\n/**\n * What an {@link OutputProcessor} decided. `pass` hands the text to the next processor unchanged;\n * `replace` hands it on rewritten (a redaction is a replacement); `reject` ends the chain AND the\n * run — the text is never streamed, never persisted, and the caller gets an\n * {@link OutputRejectedError} rather than an answer.\n */\nexport type OutputVerdict =\n | { action: 'pass' }\n | { action: 'replace'; text: string }\n | { action: 'reject'; reason: string };\n\n/**\n * Characters an incremental gate keeps holding at the end of the transformed answer, when a\n * processor declares {@link IncrementalGating} without naming its own window. Wide enough for the\n * patterns a redactor is usually written against — an SSN, an email address, a card number — and\n * deliberately not wider: the window IS the answer's minimum latency tail, since those characters\n * are only released once the whole-answer pass runs.\n */\nexport const DEFAULT_INCREMENTAL_LOOKBACK_CHARS = 64;\n\n/**\n * A processor's statement that its verdict on a PREFIX of an answer is worth acting on, which is\n * what lets the loop release that prefix to the reader instead of holding the whole answer.\n *\n * Declaring it is a promise about every prefix `P` of the final answer, and the loop takes it at\n * face value on the streaming path:\n *\n * 1. REJECTION IS PREFIX-DECIDABLE. The refusal this processor would return for the whole answer is\n * already returned for the first prefix that contains the reason. A refusal that only emerges\n * from the complete answer still fails the run, but by then the reader has seen a prefix — there\n * is no un-sending bytes, and that is the cost of opting in.\n * 2. REPLACEMENT IS PREFIX-STABLE UP TO THE WINDOW. Once a character of `process(P)`'s output is\n * more than {@link lookbackChars} from the end of that output, it never changes as `P` grows.\n *\n * A broken second promise is caught, not tolerated: the whole-answer pass stays authoritative, and\n * the loop raises a `ProcessorFailedError` when its result is not an extension of what the chain\n * already released. So a window too short for a pattern fails loudly rather than streaming the text\n * it was supposed to redact.\n */\nexport interface IncrementalGating {\n /**\n * How many characters of this processor's own output stay held back. Undefined →\n * {@link DEFAULT_INCREMENTAL_LOOKBACK_CHARS}. Set it to the length of the longest pattern the\n * processor can act on — anything shorter is a run that fails on the pattern it was written for.\n */\n readonly lookbackChars?: number;\n}\n\n/**\n * Inspects each model step's answer before anything downstream sees it — before it reaches the live\n * stream, before it is persisted, before it becomes the next step's context.\n *\n * Gating an answer and streaming it as it is generated are mutually exclusive, so registering ANY\n * output processor switches the turn's model call off the run's sink: nothing reaches the\n * subscriber until this chain has ruled on it — see `AgentLoopDeps.outputProcessors`. How much of\n * that costs the reader is what {@link incremental} decides.\n *\n * Runs inside the loop's `process:output:<step>` checkpoint (which also performs the release), so a\n * processor may call a model — a moderation pass is the motivating case — and a replay reads the\n * verdict back instead of re-deciding it.\n */\nexport interface OutputProcessor {\n /** Identifies this processor in a rejection or a failure. User-visible; keep it stable. */\n readonly name: string;\n /**\n * Opt this processor into gating a PREFIX, so the turn keeps streaming — see\n * {@link IncrementalGating} for what declaring it promises. Undefined means the whole answer,\n * which is what a processor written against the complete text needs and therefore the only safe\n * default; a chain is incremental only when EVERY member of it declares this, so a neighbour can\n * never downgrade what another author was given.\n */\n readonly incremental?: IncrementalGating;\n process(answer: ModelAnswer, ctx: ProcessorContext): OutputVerdict | Promise<OutputVerdict>;\n}\n\n/**\n * The run ended because an output processor refused the answer — NOT because the model failed. The\n * two must stay distinguishable: a model failure is worth retrying and worth paging someone about,\n * a refusal is the control doing its job. Both runners map this to the `output_rejected` stream\n * error code.\n */\nexport class OutputRejectedError extends Error {\n /** {@link OutputProcessor.name} of the processor that refused. */\n readonly processor: string;\n /** The reason it gave, verbatim. */\n readonly reason: string;\n\n constructor(processor: string, reason: string) {\n super(`Output rejected by \"${processor}\": ${reason}`);\n this.name = 'OutputRejectedError';\n this.processor = processor;\n this.reason = reason;\n }\n}\n\n/**\n * A processor threw. Wrapped so it can never be mistaken for the model call failing — the loop's\n * only other source of failure at that point in the turn — and so the failure names the processor\n * that produced it instead of surfacing a bare `TypeError` from someone else's code.\n */\nexport class ProcessorFailedError extends Error {\n /** Which seam it was on, so a reader knows whether the prompt or the answer was in flight. */\n readonly phase: 'input' | 'output';\n /** The processor's `name`. */\n readonly processor: string;\n\n constructor(phase: 'input' | 'output', processor: string, cause: unknown) {\n super(\n `${phase} processor \"${processor}\" failed: ${cause instanceof Error ? cause.message : String(cause)}`,\n );\n this.name = 'ProcessorFailedError';\n this.phase = phase;\n this.processor = processor;\n this.cause = cause;\n }\n}\n","/**\n * A read-model over the persisted agent data (usage ⋈ pricing, tool calls, threads) for the\n * governance surfaces — the standalone `-dashboard` SPA and the `-telescope` \"Agent\" tab both\n * consume this ONE interface, so cost/usage aggregation lives in a single place.\n *\n * Separate from {@link AgentStore} on purpose: that SPI owns the write/thread path, this owns the\n * read/analytics path. A store adapter implements both. Consumers inject via\n * `AGENT_GOVERNANCE_QUERIES`.\n *\n * Live activity (in-flight runs, streaming tool calls, delegations, forbidden attempts) is NOT here\n * — that comes off the `aviary:agent:*` diagnostics channel. This interface is the durable, restart-\n * surviving history.\n */\n\n/** Inclusive UTC day range, each `YYYY-MM-DD`. */\nexport interface GovernanceRange {\n fromDay: string;\n toDay: string;\n}\n\n/** Spend + token totals for one model over a range. */\nexport interface ModelSpendRow {\n modelId: string;\n requests: number;\n inputTokens: number;\n outputTokens: number;\n costUsd: number;\n}\n\n/** Spend + token totals for one acting ref (user/tenant) over a range. */\nexport interface ActorSpendRow {\n actorRef: string;\n requests: number;\n totalTokens: number;\n costUsd: number;\n /** Distinct threads the actor used in the range. */\n threadCount: number;\n}\n\n/** Spend + token totals for one thread over a range. */\nexport interface ThreadSpendRow {\n threadId: string;\n title: string;\n actorRef: string;\n requests: number;\n totalTokens: number;\n costUsd: number;\n}\n\n/** One point on the daily usage/cost trend. */\nexport interface UsageTrendPoint {\n day: string;\n totalTokens: number;\n costUsd: number;\n}\n\n/** A recent tool-call for the activity feed. */\nexport interface ToolCallActivityRow {\n toolCallId: string;\n toolName: string;\n toolType: string;\n status: string;\n threadId: string;\n createdAt: string;\n /** The run this call belongs to, for a trace deep-link; `null` for a call recorded before this shipped. */\n runId: string | null;\n}\n\n/** A recent thread with rolled-up activity. */\nexport interface ThreadActivityRow {\n threadId: string;\n title: string;\n actorRef: string;\n messageCount: number;\n totalTokens: number;\n lastActivityAt: string;\n}\n\n/** Aggregated run reliability over a range. */\nexport interface RunMetrics {\n runs: number;\n completed: number;\n failed: number;\n /** completed / runs, 0 when runs = 0. */\n successRate: number;\n /** Total llm-step retries across the range's runs. */\n retries: number;\n durationP50Ms: number | null;\n durationP95Ms: number | null;\n}\n\n/** Run/failure/retry rollup for one agent over a range. */\nexport interface RunAgentBreakdownRow {\n /** '(default)' when the run had none. */\n agentName: string;\n runs: number;\n failed: number;\n retries: number;\n}\n\n/** Failed-run count for one error code over a range. */\nexport interface RunErrorBreakdownRow {\n errorCode: string;\n count: number;\n}\n\n/** One point on the daily run/failure trend. */\nexport interface RunTrendPoint {\n day: string;\n runs: number;\n failed: number;\n}\n\n/** A recent run for the reliability feed. */\nexport interface RecentRunRow {\n runId: string;\n threadId: string;\n actorRef: string;\n agentName: string | null;\n /**\n * `'running'` | `'completed'` | `'failed'` | `'cancelled'`. `cancelled` is a terminal of its own —\n * someone asked the run to stop and it did — so a consumer computing a failure rate over these\n * rows has to be able to leave it out rather than fold it into `failed`.\n */\n status: string;\n durationMs: number | null;\n errorCode: string | null;\n errorMessage: string | null;\n retries: number;\n /** ISO timestamp. */\n startedAt: string;\n /** sha256 hex of the run's resolved (pre-RAG) system prompt; `null` for a run recorded before this shipped. */\n promptHash: string | null;\n /**\n * The run that delegated this one; `null` for a turn nobody delegated, and for any run recorded\n * before the column existed. Pairing a child with its parent is what lets a console draw the\n * delegation tree and roll a child's cost up to the turn that asked for it — and for a DETACHED\n * child it is the only pairing there is, since it outlives its parent's turn and the transcript\n * holds no other link.\n */\n parentRunId: string | null;\n}\n\n/** One tool call awaiting a HITL decision, for the cross-thread approvals inbox. */\nexport interface PendingApprovalRow {\n toolCallId: string;\n toolName: string;\n input: unknown;\n threadId: string;\n threadTitle: string;\n /** Who asked — the run's actor. */\n actorRef: string;\n agentName: string | null;\n /** ISO timestamp. */\n requestedAt: string;\n /** The run this call belongs to, for a trace deep-link; `null` for a call recorded before this shipped. */\n runId: string | null;\n}\n\n/** Governance rollup for one tool over a range. */\nexport interface ToolStatRow {\n toolName: string;\n toolType: string;\n calls: number;\n failed: number;\n rejected: number;\n /**\n * p50 (median) of executionMs across calls that recorded one; null when none carry it. Reported\n * alongside p95 rather than a mean: tool latency is long-tailed (a retry or a slow upstream drags\n * an average somewhere no single call ever was), so the pair \"typical / tail\" is what an operator\n * can actually act on.\n */\n p50ExecutionMs: number | null;\n /** p95 of executionMs across executed calls; null when none carry it. */\n p95ExecutionMs: number | null;\n}\n\n/**\n * Neutral paged query for the governance list reads (`toolCallsPage`/`threadsPage`/`runsPage`). The\n * WIRE format a host exposes over HTTP mirrors `@dudousxd/nestjs-filter`'s conventions (`page`,\n * `limit`, `where[field][op]`) so consumers see one grammar across the ecosystem, but this SPI stays\n * neutral/typed — no filter-builder or ORM coupling here.\n */\nexport interface GovernancePageQuery<TWhere> {\n /** 1-based. */\n page: number;\n /** Rows per page, already clamped by the caller (the dashboard clamps to 200). */\n pageSize: number;\n /** Equality/range filters; absent field = no constraint. */\n where?: TWhere;\n}\n\n/** One page of a governance list read, with the total row count for prev/next + \"page X of Y\" UI. */\nexport interface GovernancePage<TRow> {\n rows: TRow[];\n total: number;\n page: number;\n pageSize: number;\n}\n\n/** Filters for {@link AgentGovernanceQueries.toolCallsPage}. */\nexport interface ToolCallWhere {\n toolName?: string;\n toolType?: string;\n status?: string;\n threadId?: string;\n /** Inclusive UTC day bounds, `YYYY-MM-DD`. */\n fromDay?: string;\n toDay?: string;\n}\n\n/** Filters for {@link AgentGovernanceQueries.threadsPage}. */\nexport interface ThreadWhere {\n actorRef?: string;\n /** Substring match on the title (case-insensitive). */\n title?: string;\n fromDay?: string;\n toDay?: string;\n}\n\n/** Filters for {@link AgentGovernanceQueries.runsPage}. */\nexport interface RunWhere {\n agentName?: string;\n status?: string;\n errorCode?: string;\n threadId?: string;\n fromDay?: string;\n toDay?: string;\n}\n\n/** Filters for {@link AgentGovernanceQueries.approvalsPage}. */\nexport interface ApprovalWhere {\n toolName?: string;\n threadId?: string;\n /** The requesting thread's owner. */\n actorRef?: string;\n agentName?: string;\n /** Inclusive UTC day bounds on when the approval was requested, `YYYY-MM-DD`. */\n fromDay?: string;\n toDay?: string;\n}\n\n// ─── Drill-down details ──────────────────────────────────────────────────────\n//\n// The list reads above answer \"what happened\"; these two answer \"what happened HERE\". Each is ONE\n// call returning everything the corresponding drill-down renders, so a console never fans out a\n// query per row it just drew. Both return `null` for an id that doesn't exist — the caller decides\n// whether that's a 404 or an empty panel.\n\n/** One tool call inside a {@link GovernanceRunDetail}, with the execution outcome a list row can't afford to carry. */\nexport interface RunToolCallRow {\n toolCallId: string;\n toolName: string;\n toolType: string;\n status: string;\n /** Wall time of the execution; null for a call that never executed (rejected/still pending). */\n executionMs: number | null;\n /** Who executed/decided it, when the store recorded an attribution. */\n executedByRef: string | null;\n /** The failure text for a `failed` call; null otherwise. */\n error: string | null;\n /** ISO timestamp. */\n createdAt: string;\n}\n\n/** The owning thread's headline, carried on a drill-down so it can be named without a second read. */\nexport interface DetailThreadRef {\n threadId: string;\n title: string;\n actorRef: string;\n /** True when the thread is soft-deleted — its history is still readable, the thread is not. */\n deleted: boolean;\n}\n\n/**\n * Everything a run drill-down renders: the run row itself, its owning thread's headline, and the\n * tool calls attributed to it.\n *\n * `toolCalls` is empty for a run recorded before tool calls carried a `runId` (the column is\n * nullable and pre-rollout rows have none) — indistinguishable, from here, from a run that called\n * no tools. There is deliberately no cost figure: the token ledger has no run column, so per-run\n * spend is not attributable without a store migration.\n */\nexport interface GovernanceRunDetail {\n run: RecentRunRow;\n thread: DetailThreadRef;\n /** The run's tool calls, oldest first — the order they were requested in. */\n toolCalls: RunToolCallRow[];\n}\n\n/** One message inside a {@link GovernanceThreadDetail}. `content` is capped server-side. */\nexport interface ThreadMessageRow {\n messageId: string;\n role: string;\n /** Message text, cut to {@link THREAD_DETAIL_CONTENT_CHARS}; see `truncated`. */\n content: string;\n /** True when `content` was cut — the console shows an explicit \"…\" rather than implying the tail. */\n truncated: boolean;\n agentName: string | null;\n /** How many tool calls this message requested. */\n toolCallCount: number;\n /** ISO timestamp. */\n createdAt: string;\n}\n\n/** Token/cost rollup across a thread's whole ledger (not range-scoped — a thread's lifetime). */\nexport interface ThreadUsageRollup {\n /** Ledger rows, i.e. billed turns. */\n requests: number;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n costUsd: number;\n}\n\n/** Everything a thread drill-down renders, in one call. */\nexport interface GovernanceThreadDetail {\n /** The thread's own activity row (`messageCount` is the thread total, not the page below). */\n thread: ThreadActivityRow;\n /** True when the thread is soft-deleted. */\n deleted: boolean;\n usage: ThreadUsageRollup;\n /** The thread's runs, newest first, capped at the query's `runLimit`. */\n runs: RecentRunRow[];\n /** Runs on this thread in total — `runs.length < runTotal` means the cap bit. */\n runTotal: number;\n /** The thread's messages, newest first, capped at the query's `messageLimit`. */\n messages: ThreadMessageRow[];\n}\n\n/** Row caps for {@link AgentGovernanceQueries.threadDetail}, already clamped by the caller. */\nexport interface GovernanceThreadDetailQuery {\n threadId: string;\n /** Max messages returned, newest first. */\n messageLimit: number;\n /** Max runs returned, newest first. */\n runLimit: number;\n}\n\n/**\n * Per-message content cap for {@link ThreadMessageRow.content}. A drill-down is a triage view, not a\n * transcript reader: capping here keeps one response bounded regardless of how long an assistant\n * turn ran. Shared by every adapter so the cut is identical wherever the console is served from.\n */\nexport const THREAD_DETAIL_CONTENT_CHARS = 2000;\n\n/**\n * Cut a message body to {@link THREAD_DETAIL_CONTENT_CHARS}, reporting whether it was cut. Lives\n * next to the cap so every adapter truncates at the same boundary — a console comparing two stores\n * must not see two different \"…\".\n */\nexport function truncateDetailContent(content: string): {\n content: string;\n truncated: boolean;\n} {\n if (content.length <= THREAD_DETAIL_CONTENT_CHARS) {\n return { content, truncated: false };\n }\n return { content: content.slice(0, THREAD_DETAIL_CONTENT_CHARS), truncated: true };\n}\n\n/**\n * The governance read-model. Cost is `inputTokens/1e6 * inputPricePer1m + outputTokens/1e6 *\n * outputPricePer1m` against the current pricing row per model; an unpriced model contributes 0 cost\n * (its tokens still count).\n */\nexport interface AgentGovernanceQueries {\n spendByModel(range: GovernanceRange): Promise<ModelSpendRow[]>;\n spendByActor(range: GovernanceRange): Promise<ActorSpendRow[]>;\n /** Top threads by spend within the range, highest cost first, capped at `limit`. */\n spendByThread(range: GovernanceRange, limit: number): Promise<ThreadSpendRow[]>;\n usageTrend(range: GovernanceRange): Promise<UsageTrendPoint[]>;\n recentToolCalls(limit: number): Promise<ToolCallActivityRow[]>;\n recentThreads(limit: number): Promise<ThreadActivityRow[]>;\n // Run reliability. An adapter backed by a store without run recording (no `recordRunStart`)\n // returns zeros/empty from all five (plus `runsPage`, below) — the dashboard renders an empty\n // reliability surface.\n runMetrics(range: GovernanceRange): Promise<RunMetrics>;\n runsByAgent(range: GovernanceRange): Promise<RunAgentBreakdownRow[]>;\n runErrors(range: GovernanceRange): Promise<RunErrorBreakdownRow[]>;\n runTrend(range: GovernanceRange): Promise<RunTrendPoint[]>;\n recentRuns(limit: number): Promise<RecentRunRow[]>;\n /**\n * Tool calls sitting `pending_approval`, oldest first — an inbox drains from the back. Capped at\n * `limit`, with NO total: a caller that needs to know whether the cap hid anything wants\n * {@link approvalsPage} instead.\n */\n pendingApprovals(limit: number): Promise<PendingApprovalRow[]>;\n /**\n * Paged, filterable approvals inbox, oldest first (same ordering as `pendingApprovals`). Unlike\n * that method this reports `total`, so a console can page a backlog and say how much of it is\n * off-screen — the one failure this surface cannot afford is a pending approval nobody sees.\n * An adapter without the backing data returns an empty page (`total: 0`) rather than throwing.\n */\n approvalsPage(\n query: GovernancePageQuery<ApprovalWhere>,\n ): Promise<GovernancePage<PendingApprovalRow>>;\n /** Per-tool call/failure/rejection/latency rollup over the range, highest call count first. */\n toolStats(range: GovernanceRange): Promise<ToolStatRow[]>;\n /**\n * Paged, filterable tool-call activity, newest-first (same ordering as `recentToolCalls`). An\n * adapter without the backing data returns an empty page (`total: 0`) rather than throwing.\n */\n toolCallsPage(\n query: GovernancePageQuery<ToolCallWhere>,\n ): Promise<GovernancePage<ToolCallActivityRow>>;\n /**\n * Paged, filterable thread activity, newest-first (same ordering as `recentThreads`). An adapter\n * without the backing data returns an empty page (`total: 0`) rather than throwing.\n */\n threadsPage(query: GovernancePageQuery<ThreadWhere>): Promise<GovernancePage<ThreadActivityRow>>;\n /**\n * Paged, filterable run activity, newest-first (same ordering as `recentRuns`). An adapter backed\n * by a store without run recording (no `recordRunStart`) returns an empty page (`total: 0`).\n */\n runsPage(query: GovernancePageQuery<RunWhere>): Promise<GovernancePage<RecentRunRow>>;\n /**\n * One run with its owning thread and its tool calls — the drill-down behind a row in the runs\n * table. `null` when no run has that id. ONE call, not one per tool call: a failed run is the\n * thing an operator opens first and it should not cost a query per step.\n *\n * An adapter backed by a store without run recording returns `null` for every id.\n */\n runDetail(runId: string): Promise<GovernanceRunDetail | null>;\n /**\n * One thread with its lifetime usage rollup, its recent runs and its recent messages — the\n * drill-down behind a row in the threads table. `null` when no thread has that id; a soft-deleted\n * thread IS returned (with `deleted: true`), because \"what did the thread we just deleted do\" is\n * exactly the question an audit asks.\n */\n threadDetail(query: GovernanceThreadDetailQuery): Promise<GovernanceThreadDetail | null>;\n}\n","import type { ToolConfirmation } from '../tool-presentation.js';\nimport type {\n Actor,\n ToolCallApproval,\n ToolCallApprovalStatus,\n ToolCallStatus,\n ToolKind,\n ToolSpec,\n} from '../types.js';\n\n/** The approver that means \"the person the run is acting for\" — the thread's own actor. */\nexport const REQUESTER_APPROVER = 'requester';\n\n/** The tool a requirement is asked about. `spec` is absent where this process cannot resolve it. */\nexport interface ApprovalToolRef {\n name: string;\n kind: ToolKind;\n spec?: ToolSpec;\n}\n\n/** Where the call is being made. */\nexport interface ApprovalThreadRef {\n threadId: string;\n runId: string;\n agentName?: string;\n}\n\n/**\n * What an action tool call needs before it runs.\n *\n * - `required: false` → the call runs without asking anyone (it is still recorded as an action).\n * - `approver` → who may decide: {@link REQUESTER_APPROVER} (the thread's own actor — the default)\n * or any other string, which the default {@link ApprovalPolicy.canDecide} reads as a ROLE the\n * decider must hold. Streamed on `approval-requested` and persisted on the call.\n * - `ttlMs` → how long the request stays open. When it lapses the call settles `expired` and the\n * model is told nobody approved it. Absent → it waits indefinitely.\n */\nexport interface ApprovalRequirement {\n required: boolean;\n approver: string;\n ttlMs?: number;\n}\n\n/** A decision about to be taken on a call, as {@link ApprovalPolicy.canDecide} sees it. */\nexport interface ApprovalDecisionRef {\n toolCallId: string;\n /** The approver recorded on the call when it was put to a person. */\n approver: string;\n /** The actorRef the run is acting for — the owner of the call's thread. */\n requesterRef: string;\n}\n\n/**\n * Who has to approve an action tool call, and for how long the request stays open.\n *\n * Consulted by the LOOP once per `action` call, inside the call's `persist:toolcall` checkpoint — so\n * a durable run reads the answer back on every replay instead of re-deciding it against a policy\n * that may have changed while it was parked. Only `action` calls are asked about: a policy cannot\n * put a `read` behind an approval, and an `ask` (a question set) is always the requester's.\n */\nexport interface ApprovalPolicy {\n requirementFor(\n tool: ApprovalToolRef,\n actor: Actor,\n thread: ApprovalThreadRef,\n ): ApprovalRequirement | Promise<ApprovalRequirement>;\n /**\n * May `actor` settle this call? Checked by the approve/reject routes before a decision is\n * signalled. Absent → {@link defaultCanDecide}: the requester approver means the thread's own\n * actor, anything else is a role the actor must hold. Plug an authz Gate here for abilities.\n */\n canDecide?(actor: Actor, decision: ApprovalDecisionRef): boolean | Promise<boolean>;\n}\n\n/**\n * The behaviour the lib always had: every `action` call waits on the person who asked, with no\n * expiry.\n */\nexport class DefaultApprovalPolicy implements ApprovalPolicy {\n requirementFor(tool: ApprovalToolRef): ApprovalRequirement {\n return { required: tool.kind === 'action', approver: REQUESTER_APPROVER };\n }\n}\n\n/** The default decider rule — see {@link ApprovalPolicy.canDecide}. */\nexport function defaultCanDecide(actor: Actor, decision: ApprovalDecisionRef): boolean {\n if (decision.approver === REQUESTER_APPROVER) {\n return actor.id === decision.requesterRef;\n }\n return actor.roles?.includes(decision.approver) === true;\n}\n\n/** Resolve whether `actor` may decide, through the policy's own rule when it has one. */\nexport async function mayDecideApproval(\n policy: ApprovalPolicy | undefined,\n actor: Actor,\n decision: ApprovalDecisionRef,\n): Promise<boolean> {\n if (policy?.canDecide !== undefined) {\n return policy.canDecide(actor, decision);\n }\n return defaultCanDecide(actor, decision);\n}\n\n/** The columns a store keeps for one call's approval, however it names them. */\nexport interface ToolCallApprovalColumns {\n proposalId?: string | null;\n confirmation?: ToolConfirmation | null | undefined;\n toolCallId: string;\n status: ToolCallStatus;\n approver: string | null | undefined;\n expiresAt: string | Date | null | undefined;\n remember: boolean | null | undefined;\n executedByRef: string | null | undefined;\n decidedVia: string | null | undefined;\n error: string | null | undefined;\n}\n\n/**\n * Read a tool-call row back as the {@link ToolCallApproval} a thread carries, or `null` for a call\n * no policy put to anyone (no approver recorded). Shared by every store so they agree on the\n * status mapping: a call that ran — or ran and failed — after a decision was APPROVED.\n */\nexport function toolCallApprovalFromRow(row: ToolCallApprovalColumns): ToolCallApproval | null {\n if (row.approver === null || row.approver === undefined) {\n return null;\n }\n const status: ToolCallApprovalStatus =\n row.status === 'pending_approval' || row.status === 'proposed'\n ? 'pending'\n : row.status === 'rejected'\n ? 'rejected'\n : row.status === 'expired'\n ? 'expired'\n : 'approved';\n const expiresAt =\n row.expiresAt instanceof Date\n ? row.expiresAt.toISOString()\n : typeof row.expiresAt === 'string'\n ? row.expiresAt\n : undefined;\n const decided = status === 'approved' || status === 'rejected';\n return {\n toolCallId: row.toolCallId,\n ...(row.proposalId != null ? { proposalId: row.proposalId } : {}),\n approver: row.approver,\n ...(row.confirmation != null ? { confirmation: row.confirmation } : {}),\n status,\n ...(expiresAt !== undefined ? { expiresAt } : {}),\n ...(row.remember === true ? { remember: true } : {}),\n ...(decided && typeof row.executedByRef === 'string' ? { decidedBy: row.executedByRef } : {}),\n ...(decided && typeof row.decidedVia === 'string' ? { decidedVia: row.decidedVia } : {}),\n ...(status === 'rejected' && typeof row.error === 'string' ? { reason: row.error } : {}),\n };\n}\n","import type {\n ActorSpendRow,\n GovernanceRange,\n ModelSpendRow,\n ThreadSpendRow,\n ThreadUsageRollup,\n UsageTrendPoint,\n} from '../spi/governance-queries.js';\n\n/**\n * The pure aggregation core shared by every {@link import('../spi/governance-queries.js').AgentGovernanceQueries}\n * adapter (MikroORM, Drizzle, in-memory). An adapter's only job is the DB-specific row fetch; the\n * cost formula, the group→sort bucketing, and the day-bounds math live here so all three surfaces\n * report identical numbers.\n */\n\n/** The current per-1M token prices for one model; cache rates fall back to the input rate. */\nexport interface ModelPrice {\n inputPricePer1m: number;\n outputPricePer1m: number;\n cacheWritePricePer1m?: number | null;\n cacheReadPricePer1m?: number | null;\n}\n\n/** The token split of one turn needed to estimate its cost. */\nexport interface CostUsage {\n inputTokens: number;\n outputTokens: number;\n cacheWriteTokens?: number | null | undefined;\n cacheReadTokens?: number | null | undefined;\n}\n\n/**\n * A normalized usage row the bucketers consume. Each adapter maps its raw DB row into this shape\n * (MikroORM reads `thread.id` + `createdAt`, Drizzle/in-memory read the flat `threadId` + `day`).\n */\nexport interface GovernanceUsageInput extends CostUsage {\n modelId: string;\n actorRef: string;\n threadId: string;\n /** The `YYYY-MM-DD` UTC day the row belongs to (its trend bucket). */\n day: string;\n /** Provider-reported spend for the row; wins over the token estimate when present. */\n costUsd?: number | null | undefined;\n}\n\n/** Thread metadata joined onto a spend bucket. */\nexport interface ThreadMeta {\n title: string;\n actorRef: string;\n}\n\n/**\n * Token-ledger estimate for one turn against a pricing row: the uncached input at the input rate,\n * cache-write/cache-read tokens at their own rates (falling back to the input rate when unpriced),\n * plus output at the output rate. An unpriced model (`price === undefined`) contributes 0 — its\n * tokens still count. Cache token counts are subsets of `inputTokens`, so the uncached remainder is\n * the difference.\n */\nexport function estimateCost(usage: CostUsage, price: ModelPrice | undefined): number {\n if (price === undefined) {\n return 0;\n }\n const cacheWriteTokens = usage.cacheWriteTokens ?? 0;\n const cacheReadTokens = usage.cacheReadTokens ?? 0;\n const uncachedInputTokens = usage.inputTokens - cacheWriteTokens - cacheReadTokens;\n return (\n (uncachedInputTokens / 1_000_000) * price.inputPricePer1m +\n (cacheWriteTokens / 1_000_000) * (price.cacheWritePricePer1m ?? price.inputPricePer1m) +\n (cacheReadTokens / 1_000_000) * (price.cacheReadPricePer1m ?? price.inputPricePer1m) +\n (usage.outputTokens / 1_000_000) * price.outputPricePer1m\n );\n}\n\n/** Provider-reported cost wins per row; otherwise the cache-aware token estimate. */\nfunction rowCost(row: GovernanceUsageInput, prices: ReadonlyMap<string, ModelPrice>): number {\n return row.costUsd ?? estimateCost(row, prices.get(row.modelId));\n}\n\n/** Aggregate usage rows into per-model spend, highest cost first then modelId ascending. */\nexport function bucketByModel(\n rows: GovernanceUsageInput[],\n prices: ReadonlyMap<string, ModelPrice>,\n): ModelSpendRow[] {\n const byModel = new Map<\n string,\n { requests: number; inputTokens: number; outputTokens: number; costUsd: number }\n >();\n for (const row of rows) {\n const bucket = byModel.get(row.modelId) ?? {\n requests: 0,\n inputTokens: 0,\n outputTokens: 0,\n costUsd: 0,\n };\n bucket.requests += 1;\n bucket.inputTokens += row.inputTokens;\n bucket.outputTokens += row.outputTokens;\n bucket.costUsd += rowCost(row, prices);\n byModel.set(row.modelId, bucket);\n }\n const result: ModelSpendRow[] = [];\n for (const [modelId, bucket] of byModel) {\n result.push({\n modelId,\n requests: bucket.requests,\n inputTokens: bucket.inputTokens,\n outputTokens: bucket.outputTokens,\n costUsd: bucket.costUsd,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.modelId.localeCompare(right.modelId),\n );\n return result;\n}\n\n/** Aggregate usage rows into per-actor spend (with distinct thread counts), highest cost first. */\nexport function bucketByActor(\n rows: GovernanceUsageInput[],\n prices: ReadonlyMap<string, ModelPrice>,\n): ActorSpendRow[] {\n const byActor = new Map<\n string,\n { requests: number; totalTokens: number; costUsd: number; threadIds: Set<string> }\n >();\n for (const row of rows) {\n const bucket = byActor.get(row.actorRef) ?? {\n requests: 0,\n totalTokens: 0,\n costUsd: 0,\n threadIds: new Set<string>(),\n };\n bucket.requests += 1;\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(row, prices);\n bucket.threadIds.add(row.threadId);\n byActor.set(row.actorRef, bucket);\n }\n const result: ActorSpendRow[] = [];\n for (const [actorRef, bucket] of byActor) {\n result.push({\n actorRef,\n requests: bucket.requests,\n totalTokens: bucket.totalTokens,\n costUsd: bucket.costUsd,\n threadCount: bucket.threadIds.size,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.actorRef.localeCompare(right.actorRef),\n );\n return result;\n}\n\n/**\n * Aggregate usage rows into per-thread spend, highest cost first then threadId ascending, capped at\n * `limit`. A thread absent from `threads` is dropped when `includeUnknownThreads` is false (the SQL\n * adapters fetch only non-deleted threads, so a soft-deleted thread's rows vanish from the ranking);\n * when true it is kept with blank title/actor (the in-memory adapter's semantics).\n */\nexport function bucketByThread(\n rows: GovernanceUsageInput[],\n prices: ReadonlyMap<string, ModelPrice>,\n threads: ReadonlyMap<string, ThreadMeta>,\n options: { limit: number; includeUnknownThreads: boolean },\n): ThreadSpendRow[] {\n const byThread = new Map<string, { requests: number; totalTokens: number; costUsd: number }>();\n for (const row of rows) {\n const bucket = byThread.get(row.threadId) ?? { requests: 0, totalTokens: 0, costUsd: 0 };\n bucket.requests += 1;\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(row, prices);\n byThread.set(row.threadId, bucket);\n }\n const result: ThreadSpendRow[] = [];\n for (const [threadId, bucket] of byThread) {\n const thread = threads.get(threadId);\n if (thread === undefined && !options.includeUnknownThreads) {\n continue;\n }\n result.push({\n threadId,\n title: thread?.title ?? '',\n actorRef: thread?.actorRef ?? '',\n requests: bucket.requests,\n totalTokens: bucket.totalTokens,\n costUsd: bucket.costUsd,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.threadId.localeCompare(right.threadId),\n );\n return result.slice(0, options.limit);\n}\n\n/**\n * Sum an already-scoped set of usage rows into one rollup — the thread drill-down's headline. Same\n * `rowCost` as every bucketer above (provider-reported cost wins, else the cache-aware estimate), so\n * a thread's detail cost and its row in the by-thread ranking can never disagree.\n */\nexport function rollupThreadUsage(\n rows: GovernanceUsageInput[],\n prices: ReadonlyMap<string, ModelPrice>,\n): ThreadUsageRollup {\n const rollup: ThreadUsageRollup = {\n requests: 0,\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n costUsd: 0,\n };\n for (const row of rows) {\n rollup.requests += 1;\n rollup.inputTokens += row.inputTokens;\n rollup.outputTokens += row.outputTokens;\n rollup.totalTokens += row.inputTokens + row.outputTokens;\n rollup.costUsd += rowCost(row, prices);\n }\n return rollup;\n}\n\n/** Aggregate usage rows into a daily token/cost trend, ascending by day. */\nexport function bucketUsageTrend(\n rows: GovernanceUsageInput[],\n prices: ReadonlyMap<string, ModelPrice>,\n): UsageTrendPoint[] {\n const byDay = new Map<string, { totalTokens: number; costUsd: number }>();\n for (const row of rows) {\n const bucket = byDay.get(row.day) ?? { totalTokens: 0, costUsd: 0 };\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(row, prices);\n byDay.set(row.day, bucket);\n }\n const result: UsageTrendPoint[] = [];\n for (const [day, bucket] of byDay) {\n result.push({ day, totalTokens: bucket.totalTokens, costUsd: bucket.costUsd });\n }\n result.sort((left, right) => left.day.localeCompare(right.day));\n return result;\n}\n\n/** Turn an inclusive `YYYY-MM-DD` day range into the UTC datetime bounds used to filter usage rows. */\nexport function dayBoundsUtc(range: GovernanceRange): { start: Date; end: Date } {\n return {\n start: new Date(`${range.fromDay}T00:00:00.000Z`),\n end: new Date(`${range.toDay}T23:59:59.999Z`),\n };\n}\n","import type { RolesPolicy } from './spi/roles-policy.js';\nimport type { ToolHandler } from './spi/tool.js';\nimport type { Actor, ToolSpec } from './types.js';\n\n/**\n * Is this tool part of this deployment right now? `ToolSpec.enabled` and the handler's\n * `isEnabled()` are ANDed — either one saying no is enough — and both default to yes.\n *\n * Resolved per turn rather than at registration, so the answer can come from configuration that\n * did not exist when the module was built.\n */\nexport async function isToolEnabled(spec: ToolSpec, handler?: ToolHandler): Promise<boolean> {\n const declared =\n typeof spec.enabled === 'function' ? await spec.enabled() : (spec.enabled ?? true);\n if (!declared) {\n return false;\n }\n return handler?.isEnabled === undefined ? true : await handler.isEnabled();\n}\n\n/**\n * Second filter layer: drop tools this deployment has turned off, before anyone asks who may call\n * them. A disabled tool is absent, not forbidden — the difference matters, because \"forbidden\"\n * tells the model (and the user reading a refusal) that the capability exists.\n */\nexport async function filterToolsByEnabled<T extends { spec: ToolSpec; handler?: ToolHandler }>(\n entries: T[],\n): Promise<T[]> {\n const checked = await Promise.all(\n entries.map(async (entry) => ({\n entry,\n enabled: await isToolEnabled(entry.spec, entry.handler),\n })),\n );\n return checked.filter((row) => row.enabled).map((row) => row.entry);\n}\n\n/**\n * May this actor use this tool, per the tool's OWN gate? Tools without a `canUse` say yes and are\n * governed by the `RolesPolicy` alone.\n */\nexport async function canActorUseTool(actor: Actor, handler?: ToolHandler): Promise<boolean> {\n return handler?.canUse === undefined ? true : await handler.canUse(actor);\n}\n\n/**\n * Fourth filter layer: drop tools whose own `canUse` refuses this actor. Runs after the app-wide\n * `RolesPolicy`, and is additive to it — a tool can narrow who reaches it, never widen.\n */\nexport async function filterToolsByCanUse<T extends { spec: ToolSpec; handler?: ToolHandler }>(\n entries: T[],\n actor: Actor,\n): Promise<T[]> {\n const checked = await Promise.all(\n entries.map(async (entry) => ({\n entry,\n allowed: await canActorUseTool(actor, entry.handler),\n })),\n );\n return checked.filter((row) => row.allowed).map((row) => row.entry);\n}\n\n/** Third filter layer: drop tools the actor's role may not invoke. `can` may be async (authz). */\nexport async function filterToolsByRole(\n tools: ToolSpec[],\n actor: Actor,\n policy: RolesPolicy,\n): Promise<ToolSpec[]> {\n const checked = await Promise.all(\n tools.map(async (tool) => ({ tool, allowed: await policy.can(actor, tool) })),\n );\n return checked.filter((entry) => entry.allowed).map((entry) => entry.tool);\n}\n\n/**\n * First filter layer: if the agent pins an allow-list, keep only those tool names. Pure and\n * synchronous, which is why it runs ahead of the three gates that may do I/O — see\n * `ToolRegistry.definitionsFor`.\n */\nexport function filterToolsByAllowList(\n tools: ToolSpec[],\n allowedTools: string[] | undefined,\n): ToolSpec[] {\n if (allowedTools === undefined) {\n return tools;\n }\n const allowed = new Set(allowedTools);\n return tools.filter((tool) => allowed.has(tool.name));\n}\n","import type { AgentDefinition, Persona, PersonaCatalogEntry } from './types.js';\n\n/**\n * The narrower of two tool allow-lists. `undefined` is \"no restriction\", so it yields the other;\n * two lists yield the names on both, in the order of the first.\n */\nexport function intersectAllowLists(\n first: readonly string[] | undefined,\n second: readonly string[] | undefined,\n): string[] | undefined {\n if (first === undefined) {\n return second === undefined ? undefined : [...second];\n }\n if (second === undefined) {\n return [...first];\n }\n const allowed = new Set(second);\n return first.filter((name) => allowed.has(name));\n}\n\n/** The persona `id` of `definition`, or `undefined` when it declares none by that id. */\nexport function findPersona(\n definition: Pick<AgentDefinition, 'personas'> | undefined,\n id: string | undefined,\n): Persona | undefined {\n if (id === undefined) {\n return undefined;\n }\n return definition?.personas?.find((persona) => persona.id === id);\n}\n\n/** A persona as a picker reads it — never its prompt or its allow-list. */\nexport function personaCatalogEntry(persona: Persona): PersonaCatalogEntry {\n return {\n id: persona.id,\n label: persona.label,\n ...(persona.description !== undefined ? { description: persona.description } : {}),\n };\n}\n\n/** Where a former agent name now lives: an agent, and the persona of it the name stands for. */\nexport interface PersonaAlias {\n agent: string;\n persona: string;\n}\n\n/**\n * Resolve `name` through the {@link Persona.aliases} of `definitions`: the agent and persona that\n * answer for it, or `undefined` when no persona claims it. A name that IS a registered agent is\n * never an alias — the caller checks that first, so a real agent always wins.\n */\nexport function resolvePersonaAlias(\n definitions: readonly AgentDefinition[],\n name: string,\n): PersonaAlias | undefined {\n for (const definition of definitions) {\n for (const persona of definition.personas ?? []) {\n if (persona.aliases?.includes(name) === true) {\n return { agent: definition.name, persona: persona.id };\n }\n }\n }\n return undefined;\n}\n","/**\n * The built-in {@link HistoryPolicy}: keep the newest messages that fit a count and/or a token\n * budget, and (optionally) fold the rest into a summary. See `./spi/history-policy.ts` for the seam\n * itself and the determinism contract `select` has to hold to.\n */\n\nimport type { HistoryPolicy, HistorySelection, HistorySummary } from './spi/history-policy.js';\nimport type { ModelProvider } from './spi/model-provider.js';\nimport type { SinkWriter } from './spi/token-stream-sink.js';\nimport type { ModelMessage } from './types.js';\n\n/**\n * Rough token count for one message: ~4 characters per token over its content and its serialized\n * tool calls/results, plus a small per-message envelope allowance for the role and part framing.\n *\n * A heuristic on purpose. A real tokenizer is model-specific and would drag a provider dependency\n * into core, while a budget only has to be approximately right to keep a thread clear of the\n * provider's hard limit — and it must be a pure function, because it runs inside `select`. Pass\n * `estimate` to {@link windowHistory} to substitute a real one.\n */\nexport function estimateMessageTokens(message: ModelMessage): number {\n const extras =\n (message.toolCalls !== undefined ? JSON.stringify(message.toolCalls).length : 0) +\n (message.toolResults !== undefined ? JSON.stringify(message.toolResults).length : 0);\n return Math.ceil((message.content.length + extras) / 4) + 4;\n}\n\nexport interface WindowHistoryOptions {\n /** Keep at most this many of the newest messages. Omit → no count limit. */\n maxMessages?: number;\n /** Keep the newest messages whose estimated tokens fit this budget. Omit → no token limit. */\n maxTokens?: number;\n /** Substitute for {@link estimateMessageTokens}. Must be pure — it runs inside `select`. */\n estimate?: (message: ModelMessage) => number;\n /** Folds the dropped messages into a leading summary. Omit → they are simply gone. */\n summarize?: HistoryPolicy['summarize'];\n}\n\n/**\n * Keep the newest messages that fit. Both limits apply when both are set — whichever cuts more wins.\n * Neither set is a policy that keeps everything, which is what an unconfigured loop already does.\n *\n * A naive slice is safe here because a tool exchange is ONE message: the loop persists a call's\n * results onto the same assistant message that made them (`toolCalls` + `toolResults`), and each\n * model adapter expands that into the assistant/tool pair the provider wants. So a cut can't orphan\n * a tool result from its call, the way it could against a provider-shaped transcript.\n */\nexport function windowHistory(options: WindowHistoryOptions): HistoryPolicy {\n const estimate = options.estimate ?? estimateMessageTokens;\n const policy: HistoryPolicy = {\n // A suffix selection of at most `maxMessages` rows, which is exactly what `HistoryPolicy`'s row\n // hint promises — so the store can bound its read to that many of the thread's newest messages.\n // A token-only window declares nothing: its budget names no row count.\n ...(options.maxMessages !== undefined ? { maxMessages: options.maxMessages } : {}),\n select(messages: ModelMessage[]): HistorySelection {\n let cut = 0;\n if (options.maxMessages !== undefined) {\n cut = Math.max(cut, messages.length - options.maxMessages);\n }\n if (options.maxTokens !== undefined) {\n cut = Math.max(cut, tokenCut(messages, options.maxTokens, estimate));\n }\n // The newest message always rides, whatever the limits say — a turn with nothing to answer is\n // worse than a turn slightly over budget.\n cut = Math.min(cut, Math.max(0, messages.length - 1));\n return { keep: messages.slice(cut), drop: messages.slice(0, cut) };\n },\n };\n return options.summarize !== undefined ? { ...policy, summarize: options.summarize } : policy;\n}\n\n/** Index of the oldest message that still fits `maxTokens`, walking newest-first. */\nfunction tokenCut(\n messages: ModelMessage[],\n maxTokens: number,\n estimate: (message: ModelMessage) => number,\n): number {\n let index = messages.length;\n let total = 0;\n while (index > 0) {\n const message = messages[index - 1];\n if (message === undefined) {\n break;\n }\n const cost = estimate(message);\n if (index < messages.length && total + cost > maxTokens) {\n break;\n }\n total += cost;\n index -= 1;\n }\n return index;\n}\n\n/**\n * What a summarizer is told to produce when none is supplied. Written for a reader who will continue\n * the conversation without seeing the messages themselves, so it asks for the parts a later turn\n * still has to act on rather than a readable recap.\n */\nexport const DEFAULT_HISTORY_SUMMARY_INSTRUCTION =\n 'Summarize this conversation for an assistant that will continue it without seeing these messages. Preserve decisions made, facts and constraints the user stated, identifiers and names mentioned, and anything left unresolved. Omit pleasantries. Reply with the summary only — no preamble, no headings.';\n\n/**\n * A {@link HistoryPolicy.summarize} backed by one extra, non-streamed model call — what\n * `AgentModule.forRoot({ history: { summarize: true } })` binds. Writes to a discarding sink so the\n * summary's tokens never reach the user's live stream, and reports its usage so the call lands in\n * the spend read-model like any other.\n */\nexport function summarizeWithModel(\n model: ModelProvider,\n instruction: string = DEFAULT_HISTORY_SUMMARY_INSTRUCTION,\n): NonNullable<HistoryPolicy['summarize']> {\n return async (dropped: ModelMessage[]): Promise<HistorySummary> => {\n const discard: SinkWriter = { write: () => {}, end: () => {}, fail: () => {} };\n const turn = await model.runTurn({\n system: instruction,\n messages: dropped,\n tools: [],\n sink: discard,\n });\n return {\n text: turn.text,\n usage: turn.usage,\n ...(turn.modelId !== undefined ? { modelId: turn.modelId } : {}),\n };\n };\n}\n","/**\n * Running the processor chains, and the stream buffering an output gate requires. See\n * `./spi/processors.ts` for the seams themselves and the boundary against `HistoryPolicy`.\n */\n\nimport {\n DEFAULT_INCREMENTAL_LOOKBACK_CHARS,\n type InputProcessor,\n type ModelAnswer,\n type OutputProcessor,\n type OutputVerdict,\n type ProcessedPrompt,\n type ProcessorContext,\n ProcessorFailedError,\n} from './spi/processors.js';\nimport type { SinkWriter } from './spi/token-stream-sink.js';\nimport { decodeStreamEvent, encodeStreamEvent } from './stream-events.js';\nimport type { ToolCallRequest } from './types.js';\n\n/**\n * Holds a model call's stream frames instead of letting them reach the subscriber. `end`/`fail` are\n * swallowed for the same reason `childSinkWriter` swallows them: the loop owns the run's stream\n * lifecycle across however many steps the turn takes, and the model call is one step of it.\n *\n * Frames are kept as the decoded NDJSON LINES rather than the raw `Uint8Array`s so the buffer can\n * ride a durable checkpoint — the gate has to survive a suspend between the model call and the\n * verdict, and bytes do not round-trip through JSON.\n */\nexport interface FrameBuffer {\n writer: SinkWriter;\n /** Everything written so far, one entry per NDJSON line, in write order. */\n frames(): string[];\n}\n\nconst decoder = new TextDecoder();\n\nexport function createFrameBuffer(): FrameBuffer {\n const frames: string[] = [];\n return {\n writer: {\n write: (chunk) => {\n for (const line of decoder.decode(chunk).split('\\n')) {\n if (line.length > 0) {\n frames.push(line);\n }\n }\n },\n end: () => {},\n fail: () => {},\n },\n frames: () => frames,\n };\n}\n\n/**\n * The chunks a passed gate releases to the live stream: the held frames, with every text frame\n * collapsed into ONE carrying `text` — the answer as the chain left it, which is the only version\n * anything downstream is allowed to see.\n *\n * A frame that does not decode is dropped along with them. It cannot be forwarded, because a gate\n * that forwards bytes it cannot classify is not a gate: a provider writing bare text into the sink\n * (rather than the `AgentStreamEvent` vocabulary) would otherwise stream the ungated answer past\n * the processor that was supposed to hold it. That is the cost of an output gate for a provider\n * outside the encoded vocabulary, and it is stated in `AgentLoopDeps.outputProcessors`.\n */\nexport function releaseGatedFrames(frames: readonly string[], text: string): Uint8Array[] {\n const released: Uint8Array[] = [];\n let emitted = false;\n for (const frame of frames) {\n const event = decodeStreamEvent(frame);\n if (event === null || event.kind === 'text') {\n // Substituted in place, so the answer keeps its position relative to the tool-call frames a\n // model interleaves with it.\n if (!emitted && text.length > 0) {\n released.push(encodeStreamEvent({ kind: 'text', text }));\n emitted = true;\n }\n continue;\n }\n released.push(encodeStreamEvent(event));\n }\n if (!emitted && text.length > 0) {\n released.push(encodeStreamEvent({ kind: 'text', text }));\n }\n return released;\n}\n\n/**\n * Fold the prompt through each processor in order, every one seeing what the previous one produced.\n * A throw is wrapped so it cannot read as the model call failing — see {@link ProcessorFailedError}.\n */\nexport async function runInputProcessors(\n processors: readonly InputProcessor[],\n prompt: ProcessedPrompt,\n ctx: ProcessorContext,\n): Promise<ProcessedPrompt> {\n let current = prompt;\n for (const processor of processors) {\n try {\n current = await processor.process(current, ctx);\n } catch (error) {\n throw new ProcessorFailedError('input', processor.name, error);\n }\n }\n return current;\n}\n\n/** A settled output chain: the answer as the chain left it, plus who refused it if anyone did. */\nexport interface OutputGateResult {\n /** The text every downstream consumer sees — the stream, the persisted message, the next step. */\n text: string;\n /** Set only on a refusal; the run ends with an `OutputRejectedError` naming these. */\n rejection?: { processor: string; reason: string };\n}\n\n/**\n * Fold the answer through each processor in order. The FIRST rejection ends the chain: a later\n * processor has nothing to add about text that is never going anywhere, and running it would bill\n * a moderation call for a turn already refused.\n */\nexport async function runOutputProcessors(\n processors: readonly OutputProcessor[],\n answer: ModelAnswer,\n ctx: ProcessorContext,\n): Promise<OutputGateResult> {\n let text = answer.text;\n for (const processor of processors) {\n let verdict: OutputVerdict;\n try {\n verdict = await processor.process({ text, toolCalls: answer.toolCalls }, ctx);\n } catch (error) {\n throw new ProcessorFailedError('output', processor.name, error);\n }\n if (verdict.action === 'reject') {\n return { text, rejection: { processor: processor.name, reason: verdict.reason } };\n }\n if (verdict.action === 'replace') {\n text = verdict.text;\n }\n }\n return { text };\n}\n\n/**\n * Put each suggestion through the output chain on its own, and keep what survives.\n *\n * A follow-up is model-generated text that gets persisted and rendered, so the gate has to see it.\n * What it does NOT get is the chain's usual answer to a refusal — ending the run. The suggestions\n * are produced AFTER the turn's answer has already cleared the same chain, and retracting a cleared\n * answer because a question nobody asked for was refused would make a run's outcome depend on a\n * by-product. Dropping the suggestion removes it just as completely, which is what the refusal was\n * for. A `replace` is honoured; a processor that empties one drops it too, since an empty suggestion\n * is nothing to render.\n *\n * One suggestion at a time rather than the joined list, so a refusal is confined to the one that\n * earned it and a `replace` cannot smear across a neighbour.\n */\nexport async function gateFollowUps(\n processors: readonly OutputProcessor[],\n followUps: readonly string[],\n ctx: ProcessorContext,\n): Promise<string[]> {\n const kept: string[] = [];\n for (const followUp of followUps) {\n const settled = await runOutputProcessors(processors, { text: followUp, toolCalls: [] }, ctx);\n if (settled.rejection === undefined && settled.text.length > 0) {\n kept.push(settled.text);\n }\n }\n return kept;\n}\n\n/**\n * How much of a turn's stream an output chain costs the reader.\n *\n * `off` — nothing registered, the model writes straight to the run's sink.\n * `whole` — at least one processor needs the complete answer, so every frame is held until the\n * chain has passed and the answer arrives as one `text` frame.\n * `incremental` — every processor declared {@link IncrementalGating}, so a lookback-bounded prefix\n * is released while the call streams.\n */\nexport type OutputGateMode = 'off' | 'whole' | 'incremental';\n\n/**\n * ALL or nothing: one undeclared processor puts the whole chain on the whole-answer path. Its\n * author wrote `process` against the complete text, and a chain that ran it on a prefix because a\n * neighbour opted in would be handing it an input it never agreed to read.\n */\nexport function resolveOutputGateMode(processors: readonly OutputProcessor[]): OutputGateMode {\n if (processors.length === 0) {\n return 'off';\n }\n return processors.every((processor) => processor.incremental !== undefined)\n ? 'incremental'\n : 'whole';\n}\n\n/**\n * The chain's window is the WIDEST any member asked for: a release safe for the shortest-sighted\n * processor is not safe for the one that matches longer patterns, and the gate makes one release\n * decision for all of them.\n *\n * An undeclared processor contributes nothing rather than the default — it has no window, because a\n * chain containing one never reaches the incremental path at all.\n */\nexport function resolveGateLookback(processors: readonly OutputProcessor[]): number {\n let lookback = 0;\n for (const processor of processors) {\n if (processor.incremental !== undefined) {\n lookback = Math.max(\n lookback,\n processor.incremental.lookbackChars ?? DEFAULT_INCREMENTAL_LOOKBACK_CHARS,\n );\n }\n }\n return lookback;\n}\n\n/** A live gate over one model call: the sink the model writes to, plus what it let through. */\nexport interface IncrementalGate {\n /** Hand this to the model instead of the run's writer. */\n writer: SinkWriter;\n /** Resolves once every chunk handed to {@link writer} has been ruled on. */\n settled(): Promise<void>;\n /** The transformed prefix already written to the run's sink. */\n released(): string;\n /** Set once a prefix was refused; nothing further was released after that. */\n rejection(): OutputGateResult['rejection'];\n}\n\n/**\n * Releases a model call's answer to `writer` as it arrives, holding back the last `lookbackChars`\n * characters of what the chain produces so a processor can still change them.\n *\n * The chain runs over the whole PREFIX accumulated so far rather than over each new chunk, so a\n * processor always sees well-formed text and never has to reassemble a pattern split across\n * frames — which is what makes {@link IncrementalGating}'s promise a claim about prefixes. It runs\n * once per streamed `text` frame.\n *\n * Only an EXTENSION of what the reader already has is ever written: a chain whose output stops\n * agreeing with its earlier output has broken its promise, and the loop's whole-answer pass reports\n * that rather than this gate papering over it by re-sending a different answer.\n *\n * Frames that are not text are forwarded live, in arrival order. They are not the answer, so the\n * gate does not own them — but it does drop any frame it cannot decode, for the same reason\n * {@link releaseGatedFrames} does: a gate that forwards bytes it cannot classify is not a gate.\n */\nexport function createIncrementalGate(options: {\n processors: readonly OutputProcessor[];\n ctx: ProcessorContext;\n lookbackChars: number;\n writer: SinkWriter;\n}): IncrementalGate {\n const { processors, ctx, lookbackChars, writer } = options;\n let raw = '';\n let released = '';\n let rejection: OutputGateResult['rejection'];\n /** A prefix the chain could not rule on. Text stops flowing; the whole-answer pass decides. */\n let stalled = false;\n const toolCalls: ToolCallRequest[] = [];\n // The model is free to write without awaiting, and a verdict is asynchronous — serialize, or two\n // prefixes race and the reader gets the answer out of order.\n let queue: Promise<void> = Promise.resolve();\n\n async function advance(): Promise<void> {\n if (raw.length === 0) {\n return;\n }\n let settled: OutputGateResult;\n try {\n settled = await runOutputProcessors(processors, { text: raw, toolCalls }, ctx);\n } catch {\n // Swallowed HERE only: a prefix pass is an early release, not the verdict. The whole-answer\n // pass runs the same chain and surfaces the failure with the processor's name on it.\n stalled = true;\n return;\n }\n if (settled.rejection !== undefined) {\n rejection = settled.rejection;\n return;\n }\n // The window is trimmed off the chain's OUTPUT, not off the text fed to it: a processor that\n // only saw `raw` minus a tail could not match a pattern straddling that cut, and would release\n // the very text it exists to rewrite.\n const candidate = settled.text.slice(0, Math.max(0, settled.text.length - lookbackChars));\n if (candidate.length <= released.length || !candidate.startsWith(released)) {\n return;\n }\n const delta = candidate.slice(released.length);\n released = candidate;\n await writer.write(encodeStreamEvent({ kind: 'text', text: delta }));\n }\n\n async function handle(chunk: Uint8Array): Promise<void> {\n for (const line of decoder.decode(chunk).split('\\n')) {\n if (line.length === 0) {\n continue;\n }\n const event = decodeStreamEvent(line);\n if (event === null || rejection !== undefined) {\n continue;\n }\n if (event.kind === 'text') {\n raw += event.text;\n if (!stalled) {\n await advance();\n }\n continue;\n }\n if (event.kind === 'tool-input-available') {\n toolCalls.push({ id: event.id, name: event.name, input: event.input });\n }\n await writer.write(encodeStreamEvent(event));\n }\n }\n\n return {\n writer: {\n write: (chunk) => {\n queue = queue.then(() => handle(chunk));\n return queue;\n },\n end: () => {},\n fail: () => {},\n },\n settled: () => queue,\n released: () => released,\n rejection: () => rejection,\n };\n}\n\n/**\n * The tail an incremental gate still owes the reader once the whole-answer pass has settled: the\n * authoritative text minus the prefix already released.\n *\n * Throws when the settled answer is not an extension of that prefix. That check is the reason the\n * final pass stays authoritative for both the stream and the store rather than the stream being\n * stitched together from per-prefix results: agreement between what was streamed and what was\n * stored becomes structural instead of assumed.\n */\nexport function gateTail(\n processors: readonly OutputProcessor[],\n released: string,\n text: string,\n): string {\n if (!text.startsWith(released)) {\n throw new ProcessorFailedError(\n 'output',\n processors.map((processor) => processor.name).join(' → '),\n new Error(\n `the gated answer is not an extension of the ${released.length} characters this chain already released — a processor that declares \"incremental\" promises its result on a prefix stays a prefix of its result on the whole answer, outside the last lookbackChars`,\n ),\n );\n }\n return text.slice(released.length);\n}\n","/**\n * Constraining a turn's ANSWER to a schema. See `AgentLoopDeps.outputSchema` for where this sits in\n * the loop and why it is a separate model call rather than a constraint on the turn's own calls.\n */\n\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\n\n/**\n * The turn produced an answer that does not satisfy `outputSchema`, and the bounded repair attempts\n * did not fix it. A DEFINED outcome of asking for structured output, not a crash: it carries the\n * validation issues and the text that failed them, so a caller can log what the model actually said\n * instead of guessing from a parse error. Both runners map it to the `structured_output_invalid`\n * stream error code.\n */\nexport class StructuredOutputError extends Error {\n /** Why it failed the schema. Empty only when the text was not JSON at all. */\n readonly issues: readonly StandardSchemaV1.Issue[];\n /** The last text the model produced, verbatim. */\n readonly text: string;\n /** How many model calls were spent trying (1 = the formatting pass, no repairs). */\n readonly attempts: number;\n\n constructor(issues: readonly StandardSchemaV1.Issue[], text: string, attempts: number) {\n const detail =\n issues.length > 0\n ? issues.map((issue) => issue.message).join('; ')\n : 'the model did not reply with JSON';\n super(`Structured output invalid after ${attempts} attempt(s): ${detail}`);\n this.name = 'StructuredOutputError';\n this.issues = issues;\n this.text = text;\n this.attempts = attempts;\n }\n}\n\n/** A validated answer, or the issues that stopped it being one. */\nexport type StructuredOutcome<T> =\n | { ok: true; value: T }\n | { ok: false; issues: readonly StandardSchemaV1.Issue[] };\n\n/**\n * Pull a JSON value out of a model reply, tolerating the code fences and lead-in prose a provider\n * that cannot constrain its own generation still emits. `undefined` when there is no JSON in there\n * at all — distinct from a JSON `null`, which is a value the schema may well accept.\n */\nexport function extractJson(text: string): unknown {\n const candidates = [text, text.match(/\\{[\\s\\S]*\\}/)?.[0], text.match(/\\[[\\s\\S]*\\]/)?.[0]];\n for (const candidate of candidates) {\n if (candidate === undefined) {\n continue;\n }\n try {\n return JSON.parse(candidate) as unknown;\n } catch {\n /* try the next shape */\n }\n }\n return undefined;\n}\n\n/**\n * Validate one attempt. The provider's own parsed `object` is preferred when it reported one (a\n * provider that constrained generation already did the parse), but it is validated all the same —\n * \"the provider says it matched\" is not the same claim as \"it matches\", and a provider that ignored\n * `outputSchema` entirely must fail here rather than downstream.\n */\nexport async function validateStructured<T>(\n schema: StandardSchemaV1<unknown, T>,\n text: string,\n reported: unknown,\n): Promise<StructuredOutcome<T>> {\n const candidate = reported !== undefined ? reported : extractJson(text);\n if (candidate === undefined) {\n return { ok: false, issues: [] };\n }\n const result = await schema['~standard'].validate(candidate);\n return result.issues !== undefined\n ? { ok: false, issues: result.issues }\n : { ok: true, value: result.value };\n}\n\n/**\n * What the formatting pass is told to do. Written for a model that is being shown a finished answer\n * and asked to restate it — never to extend or improve it, which would make the structured result\n * disagree with the prose the user already read.\n */\nexport const DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION =\n \"Restate the assistant's final answer as a single JSON value matching the required schema. Use only information already present in the conversation — add nothing, and answer nothing that was not asked. Reply with ONLY the JSON: no prose, no explanation, no code fences.\";\n\n/** Appends the previous attempt's validation issues, so a repair call knows what to fix. */\nexport function repairInstruction(\n instruction: string,\n issues: readonly StandardSchemaV1.Issue[],\n): string {\n const detail =\n issues.length > 0\n ? issues\n .map((issue) => `${(issue.path ?? []).join('.') || '(root)'}: ${issue.message}`)\n .join('\\n')\n : 'the previous reply was not valid JSON';\n return `${instruction}\\n\\nYour previous reply was rejected:\\n${detail}`;\n}\n","/**\n * Typed answers for a question set: a question that asks for a number, a date, an email or a\n * sentence instead of offering options to pick.\n *\n * Answers stay `string[]` on the wire whatever the type — the signal that carries them, the row that\n * records them and the model that reads them back all see strings — so this module fixes ONE\n * canonical string per type and validates against it:\n *\n * | `type` | canonical value |\n * |------------|----------------------------------------------|\n * | `text` | the text |\n * | `textarea` | the text (newlines kept) |\n * | `number` | a finite decimal, e.g. `\"42\"`, `\"-1.5\"` |\n * | `boolean` | `\"true\"` or `\"false\"` |\n * | `date` | `YYYY-MM-DD` |\n * | `email` | an address with one `@` and a dotted domain |\n * | `url` | an absolute `http:`/`https:` URL |\n * | `select` | one of the question's `options[].value` |\n *\n * Pure and dependency-free, so the loop (which filters what it settles on), the HTTP surface (which\n * refuses what it cannot settle) and a client (which says so before sending) all agree.\n */\nimport type { ElicitationOption, ElicitationQuestion } from './elicitation.js';\n\nexport const ELICITATION_INPUT_TYPES = [\n 'text',\n 'textarea',\n 'number',\n 'boolean',\n 'date',\n 'email',\n 'url',\n 'select',\n] as const;\n\nexport type ElicitationInputType = (typeof ELICITATION_INPUT_TYPES)[number];\n\n/** How a question takes its answer when it is not (only) a pick from `options`. */\nexport interface ElicitationInput {\n type: ElicitationInputType;\n /** Hint shown in an empty field. Advisory. */\n placeholder?: string;\n /** Submitting without a value is refused. Skipping the whole set is still allowed. */\n required?: boolean;\n /**\n * Lower bound: the smallest number for `number`, the shortest length for `text`/`textarea`, the\n * earliest `YYYY-MM-DD` for `date`. Ignored for the other types.\n */\n min?: number | string;\n /** Upper bound, read like {@link min}. */\n max?: number | string;\n /** A regular expression the WHOLE value must match (`text`, `textarea`, `email`, `url`). */\n pattern?: string;\n}\n\n/** The question's options, or none — `options` may be omitted on a typed question. */\nexport function questionOptions(question: ElicitationQuestion): ElicitationOption[] {\n return question.options ?? [];\n}\n\n/** A question answered by a typed value rather than by picking one of its options. */\nexport function isTypedQuestion(question: ElicitationQuestion): boolean {\n return question.input !== undefined && question.input.type !== 'select';\n}\n\nconst DATE_PATTERN = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\nconst EMAIL_PATTERN = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst NUMBER_PATTERN = /^-?(\\d+\\.?\\d*|\\.\\d+)(e[+-]?\\d+)?$/i;\n\nfunction isDate(value: string): boolean {\n const match = DATE_PATTERN.exec(value);\n if (match === null) {\n return false;\n }\n const [, year, month, day] = match;\n const date = new Date(Date.UTC(Number(year), Number(month) - 1, Number(day)));\n return (\n date.getUTCFullYear() === Number(year) &&\n date.getUTCMonth() === Number(month) - 1 &&\n date.getUTCDate() === Number(day)\n );\n}\n\nfunction isHttpUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\nfunction fullMatch(pattern: string, value: string): boolean | undefined {\n try {\n return new RegExp(`^(?:${pattern})$`, 'u').test(value);\n } catch {\n // An author's unreadable pattern constrains nothing rather than refusing every answer.\n return undefined;\n }\n}\n\nfunction asNumber(bound: number | string | undefined): number | undefined {\n if (typeof bound === 'number' && Number.isFinite(bound)) {\n return bound;\n }\n if (typeof bound === 'string' && NUMBER_PATTERN.test(bound.trim())) {\n return Number(bound);\n }\n return undefined;\n}\n\n/**\n * Why `value` is not an acceptable answer to `question`, or `null` when it is. Checks ONE value;\n * {@link validateElicitationAnswer} checks the list (required, single choice).\n */\nexport function validateElicitationValue(\n question: ElicitationQuestion,\n value: string,\n): string | null {\n const input = question.input;\n if (input === undefined || input.type === 'select') {\n if (question.allowFreeText === true) {\n return null;\n }\n return questionOptions(question).some((option) => option.value === value)\n ? null\n : 'must be one of the offered options';\n }\n switch (input.type) {\n case 'number': {\n if (!NUMBER_PATTERN.test(value.trim()) || !Number.isFinite(Number(value))) {\n return 'must be a number';\n }\n const number = Number(value);\n const min = asNumber(input.min);\n const max = asNumber(input.max);\n if (min !== undefined && number < min) {\n return `must be at least ${min}`;\n }\n if (max !== undefined && number > max) {\n return `must be at most ${max}`;\n }\n return null;\n }\n case 'boolean':\n return value === 'true' || value === 'false' ? null : 'must be \"true\" or \"false\"';\n case 'date': {\n if (!isDate(value)) {\n return 'must be a date as YYYY-MM-DD';\n }\n if (typeof input.min === 'string' && isDate(input.min) && value < input.min) {\n return `must be on or after ${input.min}`;\n }\n if (typeof input.max === 'string' && isDate(input.max) && value > input.max) {\n return `must be on or before ${input.max}`;\n }\n return null;\n }\n case 'email':\n if (!EMAIL_PATTERN.test(value)) {\n return 'must be an email address';\n }\n break;\n case 'url':\n if (!isHttpUrl(value)) {\n return 'must be an http(s) URL';\n }\n break;\n case 'text':\n case 'textarea': {\n const min = asNumber(input.min);\n const max = asNumber(input.max);\n if (min !== undefined && value.length < min) {\n return `must be at least ${min} characters`;\n }\n if (max !== undefined && value.length > max) {\n return `must be at most ${max} characters`;\n }\n break;\n }\n }\n if (input.pattern !== undefined && fullMatch(input.pattern, value) === false) {\n return 'does not match the expected format';\n }\n return null;\n}\n\n/**\n * Why `values` is not an acceptable answer to `question`, or `null` when it is: a `required`\n * question left empty, more than one value for a single-choice question, or any value\n * {@link validateElicitationValue} refuses. An empty string counts as no value.\n */\nexport function validateElicitationAnswer(\n question: ElicitationQuestion,\n values: readonly string[],\n): string | null {\n const present = values.filter((value) => value !== '');\n if (present.length === 0) {\n return question.input?.required === true ? 'requires an answer' : null;\n }\n if (question.multiple !== true && present.length > 1) {\n return 'takes a single value';\n }\n for (const value of present) {\n const problem = validateElicitationValue(question, value);\n if (problem !== null) {\n return problem;\n }\n }\n return null;\n}\n\n/**\n * Read an {@link ElicitationInput} from untrusted JSON, or `undefined` when it is not one. Unknown\n * keys are dropped; a malformed optional field is dropped rather than failing the input.\n */\nexport function readElicitationInput(raw: unknown): ElicitationInput | undefined {\n if (typeof raw !== 'object' || raw === null) {\n return undefined;\n }\n const candidate = raw as Record<string, unknown>;\n const type = candidate.type;\n if (typeof type !== 'string' || !(ELICITATION_INPUT_TYPES as readonly string[]).includes(type)) {\n return undefined;\n }\n const bound = (value: unknown) =>\n (typeof value === 'number' && Number.isFinite(value)) || typeof value === 'string'\n ? (value as number | string)\n : undefined;\n const min = bound(candidate.min);\n const max = bound(candidate.max);\n return {\n type: type as ElicitationInputType,\n ...(typeof candidate.placeholder === 'string' ? { placeholder: candidate.placeholder } : {}),\n ...(candidate.required === true ? { required: true } : {}),\n ...(min !== undefined ? { min } : {}),\n ...(max !== undefined ? { max } : {}),\n ...(typeof candidate.pattern === 'string' ? { pattern: candidate.pattern } : {}),\n };\n}\n\n/**\n * The questions a parked call carries, read leniently from its recorded input (`{ questions }` —\n * what both an intake and an `ask` persist). Used where a reply is checked against the questions it\n * answers; a question that cannot be read is left out rather than failing the rest.\n */\nexport function readElicitationQuestions(input: unknown): ElicitationQuestion[] {\n if (typeof input !== 'object' || input === null) {\n return [];\n }\n const raw = (input as { questions?: unknown }).questions;\n if (!Array.isArray(raw)) {\n return [];\n }\n const questions: ElicitationQuestion[] = [];\n for (const item of raw) {\n if (typeof item !== 'object' || item === null) {\n continue;\n }\n const candidate = item as Record<string, unknown>;\n if (typeof candidate.id !== 'string' || typeof candidate.prompt !== 'string') {\n continue;\n }\n const options: ElicitationOption[] = Array.isArray(candidate.options)\n ? candidate.options.flatMap((option: unknown) => {\n if (typeof option !== 'object' || option === null) {\n return [];\n }\n const { value, label } = option as Record<string, unknown>;\n return typeof value === 'string' && typeof label === 'string' ? [{ value, label }] : [];\n })\n : [];\n const typed = readElicitationInput(candidate.input);\n const defaults = Array.isArray(candidate.defaults)\n ? candidate.defaults.filter((value): value is string => typeof value === 'string')\n : [];\n questions.push({\n id: candidate.id,\n prompt: candidate.prompt,\n options,\n ...(typed !== undefined ? { input: typed } : {}),\n ...(defaults.length > 0 ? { defaults } : {}),\n ...(candidate.multiple === true ? { multiple: true } : {}),\n ...(candidate.allowFreeText === true ? { allowFreeText: true } : {}),\n });\n }\n return questions;\n}\n","/**\n * Asking the USER a structured question, and waiting for the answer.\n *\n * `awaitApproval` collects a yes/no about work already proposed; this collects the scope BEFORE the\n * work. Two surfaces produce it — a configured intake (`AgentLoopDeps.intake`) and the model-callable\n * `ask` tool (`AgentLoopDeps.ask`) — and they deliberately produce the SAME {@link\n * ElicitationRequest}, persist through the same tool-call row, and resume through the same\n * `tool:<runId>:<callId>` signal. A consumer cannot tell which one asked, and should not have to.\n */\n\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport {\n ELICITATION_INPUT_TYPES,\n type ElicitationInput,\n isTypedQuestion,\n questionOptions,\n readElicitationInput,\n validateElicitationValue,\n} from './elicitation-input.js';\nimport type { Decision, ToolDefinition } from './types.js';\n\n/** One choice a question offers. */\nexport interface ElicitationOption {\n /** Stable identifier submitted back. Never shown to the user. */\n value: string;\n /** What the user reads. */\n label: string;\n /**\n * A single character a UI may bind as a keyboard shortcut for this option. Advisory — nothing in\n * the library reads it, and a client is free to render its own.\n */\n hotkey?: string;\n}\n\n/** One question in a set. */\nexport interface ElicitationQuestion {\n /** Unique within its request; the key answers come back under. */\n id: string;\n prompt: string;\n /** A line of help under the prompt. */\n description?: string;\n /**\n * The choices. Required unless {@link input} asks for a typed value — then optional, and a UI may\n * offer them as suggestions. An `input` of type `select` still picks from these.\n */\n options?: ElicitationOption[];\n /**\n * Ask for a typed value (a number, a date, a sentence…) instead of — or, for `select`, on top of —\n * a pick from `options`. The answer is still a `string[]`, in the type's canonical form; see\n * `elicitation-input.ts`.\n */\n input?: ElicitationInput;\n /** More than one option may be chosen. Omit → single choice. */\n multiple?: boolean;\n /**\n * The options already picked for the user. The claim this whole surface makes is that confirming\n * is enough, so a question with no defaults is a question the user must stop and think about —\n * which is the case the design is trying to avoid. Empty/omitted is allowed and means exactly\n * that: submitting without answering leaves this question unanswered.\n */\n defaults?: string[];\n /** Accept values that are not among `options` (a typed-in answer). Omit → options only. */\n allowFreeText?: boolean;\n}\n\n/**\n * A question set awaiting a human. Identical in shape whether an `@Agent`'s configured intake or\n * the model's `ask` tool authored it — `source` records which, for audit, not for control flow.\n *\n * `questions.length` is known when the request is written, which is what lets a client render\n * \"Question 1 of 3\" without guessing whether a fourth is coming.\n */\nexport interface ElicitationRequest {\n /** The tool-call id this request is persisted under, and the signal it is answered through. */\n id: string;\n source: 'intake' | 'ask';\n /** What the assistant says above the form. */\n preamble?: string;\n questions: ElicitationQuestion[];\n}\n\n/** What a human sent back for an {@link ElicitationRequest}. */\nexport interface ElicitationReply {\n /**\n * questionId → chosen values. A question whose id is ABSENT takes the request's own `defaults` —\n * that is what makes \"just submit\" mean \"yes, your pre-picked answers\". A present-but-empty array\n * is an explicit \"none of these\" and does NOT fall back.\n */\n answers: Record<string, string[]>;\n /**\n * The user declined to answer and told the agent to proceed on its own assumptions. Distinct from\n * confirming the defaults even though the resulting values are the same: one is a decision the\n * user made, the other is one they refused to make, and only the first is evidence of intent.\n */\n skipped?: boolean;\n /** Opaque ref of WHO answered, when it wasn't the run's own actor. */\n answeredByRef?: string;\n /**\n * The surface the answer came through — `'web'`, `'slack'`, `'console'`, … — the counterpart of\n * an approval's `decidedVia`.\n */\n answeredVia?: string;\n}\n\n/** A settled elicitation: what the agent proceeds on, and how it got there. */\nexport interface ElicitationOutcome {\n /** One entry per question, in request order — always present, so a caller never re-applies defaults. */\n answers: Record<string, string[]>;\n skipped: boolean;\n /** Question ids filled from the request's `defaults` rather than by the human. */\n defaulted: string[];\n /**\n * Who answered (or skipped) — the reply's `answeredByRef`, which a host may make a display name.\n * The counterpart of an approval's `decidedBy`. Absent when the reply did not say.\n */\n answeredBy?: string;\n /** The surface it came through (`'web'`, `'slack'`, …) — an approval's `decidedVia`. */\n answeredVia?: string;\n}\n\n/**\n * Read whatever the human channel delivered as an {@link ElicitationReply}.\n *\n * A question set is persisted as an `action` tool call in `pending_approval` — that is what puts it\n * in the approvals inbox a deployment already has, instead of needing one of its own. The cost of\n * that choice is that the thing which comes back may be a {@link Decision} someone pressed\n * Approve/Reject on rather than a set of answers, and a `Decision` carries no `answers` at all.\n *\n * Approve means every question keeps its own pre-picked `defaults`, which is exactly what \"just\n * submit\" already means on this surface; Reject is the same declining-to-answer a skip is. Neither\n * reading is a guess — a yes/no channel cannot say more than that, and saying it here is what lets\n * one inbox settle both kinds of pending work.\n *\n * Returns the reply UNCHANGED when it already carries answers, so the common path allocates nothing\n * and a caller can identity-compare.\n */\nexport function normalizeElicitationReply(reply: ElicitationReply | Decision): ElicitationReply {\n if (typeof reply !== 'object' || reply === null) {\n return { answers: {} };\n }\n const candidate = reply as Partial<ElicitationReply> & Partial<Decision>;\n if (typeof candidate.answers === 'object' && candidate.answers !== null) {\n return reply as ElicitationReply;\n }\n const answeredByRef = candidate.answeredByRef ?? candidate.executedByRef;\n const answeredVia = candidate.answeredVia ?? candidate.decidedVia;\n return {\n answers: {},\n ...(candidate.approved === false || candidate.skipped === true ? { skipped: true } : {}),\n ...(answeredByRef !== undefined ? { answeredByRef } : {}),\n ...(answeredVia !== undefined ? { answeredVia } : {}),\n };\n}\n\n/**\n * Settle a reply against the request it answers: fill every unanswered question from its own\n * `defaults`, drop submitted values that aren't on offer, and collapse a single-choice question to\n * one value.\n *\n * PURE, and deliberately so. Both of its inputs are already journaled by the time the loop calls it\n * — the request came from module config or from an `llm:<i>` checkpoint, the reply from the signal\n * checkpoint — so every process replaying the turn reaches the same values without a checkpoint of\n * its own. Resolving defaults in the HTTP layer instead would put them behind a store read that a\n * replay would have to repeat.\n */\nexport function resolveElicitation(\n request: ElicitationRequest,\n raw: ElicitationReply | Decision,\n): ElicitationOutcome {\n const reply = normalizeElicitationReply(raw);\n const answers: Record<string, string[]> = {};\n const defaulted: string[] = [];\n for (const question of request.questions) {\n const submitted = reply.skipped === true ? undefined : reply.answers[question.id];\n if (submitted === undefined) {\n answers[question.id] = [...(question.defaults ?? [])];\n defaulted.push(question.id);\n continue;\n }\n // What cannot be settled is dropped, never guessed at: a value off the offered options, or one a\n // typed question's own rules refuse. The HTTP surface refuses both before they are signalled; this\n // is the same rule applied where the loop settles, so a reply from anywhere reads the same.\n const valid = submitted.filter(\n (value) => value !== '' && validateElicitationValue(question, value) === null,\n );\n answers[question.id] = question.multiple === true ? valid : valid.slice(0, 1);\n }\n return {\n answers,\n skipped: reply.skipped === true,\n defaulted,\n ...(reply.answeredByRef !== undefined ? { answeredBy: reply.answeredByRef } : {}),\n ...(reply.answeredVia !== undefined ? { answeredVia: reply.answeredVia } : {}),\n };\n}\n\n/**\n * What a settled elicitation looks like to everyone downstream: the model reading it back as a tool\n * result, the thread reader rendering it, the auditor asking what the agent was told to do. One\n * shape for both surfaces — nothing here records which of them asked.\n */\nexport interface ElicitationResult extends ElicitationOutcome {\n /** The questions against the chosen LABELS, so a reader (and a model) can act on it. */\n summary: string;\n}\n\n/** {@link resolveElicitation} plus its human-readable rendering. Pure, for the same reason. */\nexport function settleElicitation(\n request: ElicitationRequest,\n reply: ElicitationReply | Decision,\n): ElicitationResult {\n const outcome = resolveElicitation(request, reply);\n return { ...outcome, summary: renderElicitationAnswers(request, outcome) };\n}\n\n/**\n * The answers as the model reads them: the question's own prompt against the chosen options' LABELS,\n * not their opaque `value`s — a model shown `{\"scope\":[\"b\"]}` has been told nothing.\n */\nexport function renderElicitationAnswers(\n request: ElicitationRequest,\n outcome: ElicitationOutcome,\n): string {\n const lines = request.questions.map((question) => {\n const chosen = outcome.answers[question.id] ?? [];\n const labels = chosen.map(\n (value) => questionOptions(question).find((option) => option.value === value)?.label ?? value,\n );\n return `${question.prompt} → ${labels.length > 0 ? labels.join(', ') : '(no answer)'}`;\n });\n const preface = outcome.skipped\n ? 'The user declined to answer and asked you to proceed on these assumptions:'\n : 'The user answered:';\n return `${preface}\\n${lines.join('\\n')}`;\n}\n\n/** The reserved tool name the model calls to ask the user something. */\nexport const ASK_TOOL_NAME = 'ask';\n\n/** What the model must supply when it calls `ask`. */\nexport interface AskToolInput {\n preamble?: string;\n questions: ElicitationQuestion[];\n}\n\n/** How many questions one `ask` may carry. A form the user has to scroll is a form they skip. */\nexport const MAX_ASK_QUESTIONS = 5;\n\nfunction issue(path: (string | number)[], message: string): StandardSchemaV1.Issue {\n return { message, path };\n}\n\nfunction parseOption(\n raw: unknown,\n path: (string | number)[],\n issues: StandardSchemaV1.Issue[],\n): ElicitationOption | undefined {\n if (typeof raw !== 'object' || raw === null) {\n issues.push(issue(path, 'must be an object'));\n return undefined;\n }\n const candidate = raw as Partial<ElicitationOption>;\n if (typeof candidate.value !== 'string' || candidate.value.length === 0) {\n issues.push(issue([...path, 'value'], 'must be a non-empty string'));\n return undefined;\n }\n if (typeof candidate.label !== 'string' || candidate.label.length === 0) {\n issues.push(issue([...path, 'label'], 'must be a non-empty string'));\n return undefined;\n }\n return {\n value: candidate.value,\n label: candidate.label,\n ...(typeof candidate.hotkey === 'string' ? { hotkey: candidate.hotkey } : {}),\n };\n}\n\nfunction parseQuestion(\n raw: unknown,\n path: (string | number)[],\n issues: StandardSchemaV1.Issue[],\n): ElicitationQuestion | undefined {\n if (typeof raw !== 'object' || raw === null) {\n issues.push(issue(path, 'must be an object'));\n return undefined;\n }\n const candidate = raw as Partial<ElicitationQuestion>;\n if (typeof candidate.id !== 'string' || candidate.id.length === 0) {\n issues.push(issue([...path, 'id'], 'must be a non-empty string'));\n return undefined;\n }\n if (typeof candidate.prompt !== 'string' || candidate.prompt.length === 0) {\n issues.push(issue([...path, 'prompt'], 'must be a non-empty string'));\n return undefined;\n }\n let input: ElicitationInput | undefined;\n if (candidate.input !== undefined) {\n input = readElicitationInput(candidate.input);\n if (input === undefined) {\n issues.push(\n issue([...path, 'input', 'type'], `must be one of ${ELICITATION_INPUT_TYPES.join(', ')}`),\n );\n return undefined;\n }\n }\n const described =\n typeof candidate.description === 'string' && candidate.description.length > 0\n ? { description: candidate.description }\n : {};\n const typed = input !== undefined && input.type !== 'select';\n if (!typed && (!Array.isArray(candidate.options) || candidate.options.length === 0)) {\n issues.push(issue([...path, 'options'], 'must be a non-empty array'));\n return undefined;\n }\n const options: ElicitationOption[] = [];\n for (const [index, rawOption] of (Array.isArray(candidate.options)\n ? candidate.options\n : []\n ).entries()) {\n const option = parseOption(rawOption, [...path, 'options', index], issues);\n if (option !== undefined) {\n options.push(option);\n }\n }\n if (typed) {\n // A typed question pre-picks when it can (a sensible date, a default count) but need not: there\n // is no honest default for \"what is your email\". What it does pre-pick has to be an answer its\n // own rules accept, or confirming would submit something the form would refuse.\n const question: ElicitationQuestion = {\n id: candidate.id,\n prompt: candidate.prompt,\n ...described,\n ...(options.length > 0 ? { options } : {}),\n input: input as ElicitationInput,\n ...(candidate.multiple === true ? { multiple: true } : {}),\n };\n const offered = Array.isArray(candidate.defaults)\n ? candidate.defaults.filter((value): value is string => typeof value === 'string')\n : [];\n const defaults = offered.filter((value) => validateElicitationValue(question, value) === null);\n if (offered.length > 0 && defaults.length === 0) {\n issues.push(\n issue([...path, 'defaults'], `must be valid ${(input as ElicitationInput).type} values`),\n );\n return undefined;\n }\n return defaults.length > 0 ? { ...question, defaults } : question;\n }\n // The one rule that carries the design: a question with no pre-picked answer is a question the\n // user has to stop and think about, and this surface exists to avoid that.\n if (!Array.isArray(candidate.defaults) || candidate.defaults.length === 0) {\n issues.push(\n issue(\n [...path, 'defaults'],\n 'must pre-pick at least one option — say what you would choose so the user can just confirm',\n ),\n );\n return undefined;\n }\n const offered = new Set(options.map((option) => option.value));\n const defaults = candidate.defaults.filter(\n (value): value is string => typeof value === 'string' && offered.has(value),\n );\n if (defaults.length === 0) {\n issues.push(\n issue([...path, 'defaults'], \"must name values that appear in this question's options\"),\n );\n return undefined;\n }\n return {\n id: candidate.id,\n prompt: candidate.prompt,\n ...described,\n options,\n ...(input !== undefined ? { input } : {}),\n defaults,\n ...(candidate.multiple === true ? { multiple: true } : {}),\n ...(candidate.allowFreeText === true ? { allowFreeText: true } : {}),\n };\n}\n\nconst ASK_JSON_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n properties: {\n preamble: {\n type: 'string',\n description:\n 'One sentence shown above the form, e.g. \"Three questions before I start. I have pre-picked what I would choose, so confirming is enough.\"',\n },\n questions: {\n type: 'array',\n minItems: 1,\n maxItems: MAX_ASK_QUESTIONS,\n items: {\n type: 'object',\n additionalProperties: false,\n required: ['id', 'prompt'],\n properties: {\n id: {\n type: 'string',\n description: 'Unique within this call; answers come back under it.',\n },\n prompt: { type: 'string' },\n description: { type: 'string', description: 'A line of help under the prompt.' },\n input: {\n type: 'object',\n additionalProperties: false,\n required: ['type'],\n description:\n 'Ask for a typed value instead of offering options. Omit for a pick from options. Answers come back as strings: numbers as decimals, booleans as \"true\"/\"false\", dates as YYYY-MM-DD.',\n properties: {\n type: { type: 'string', enum: [...ELICITATION_INPUT_TYPES] },\n placeholder: { type: 'string' },\n required: { type: 'boolean' },\n min: {\n type: ['number', 'string'],\n description: 'number: minimum; text: minimum length; date: earliest YYYY-MM-DD.',\n },\n max: {\n type: ['number', 'string'],\n description: 'number: maximum; text: maximum length; date: latest YYYY-MM-DD.',\n },\n pattern: { type: 'string', description: 'A regex the whole value must match.' },\n },\n },\n multiple: { type: 'boolean', description: 'Allow more than one option to be chosen.' },\n allowFreeText: {\n type: 'boolean',\n description: 'Accept an answer that is not an option.',\n },\n defaults: {\n type: 'array',\n minItems: 1,\n items: { type: 'string' },\n description:\n 'REQUIRED for a pick from options: the option values you would pick yourself, so the user can confirm rather than decide. For a typed input, the value you would enter, when there is a sensible one.',\n },\n options: {\n type: 'array',\n minItems: 2,\n items: {\n type: 'object',\n additionalProperties: false,\n required: ['value', 'label'],\n properties: {\n value: { type: 'string' },\n label: { type: 'string' },\n hotkey: { type: 'string', maxLength: 1 },\n },\n },\n },\n },\n },\n },\n },\n required: ['questions'],\n} as const;\n\n/**\n * The `ask` tool's input schema, hand-written rather than borrowed from a validation library: core\n * depends on no validator, and the schema has to carry a JSON Schema a provider can constrain\n * generation against. It publishes one through the Standard JSON Schema extension\n * (`~standard.jsonSchema.input`), which is the path the AI SDK adapter already recognises for\n * Valibot / ArkType / Zod 4.\n */\nexport const askInputSchema: StandardSchemaV1<unknown, AskToolInput> = {\n '~standard': {\n version: 1,\n vendor: 'nestjs-agent',\n validate: (value: unknown) => {\n const issues: StandardSchemaV1.Issue[] = [];\n if (typeof value !== 'object' || value === null) {\n return { issues: [issue([], 'must be an object')] };\n }\n const candidate = value as Partial<AskToolInput>;\n if (!Array.isArray(candidate.questions) || candidate.questions.length === 0) {\n return { issues: [issue(['questions'], 'must be a non-empty array')] };\n }\n if (candidate.questions.length > MAX_ASK_QUESTIONS) {\n return {\n issues: [issue(['questions'], `must hold at most ${MAX_ASK_QUESTIONS} questions`)],\n };\n }\n const questions: ElicitationQuestion[] = [];\n for (const [index, raw] of candidate.questions.entries()) {\n const question = parseQuestion(raw, ['questions', index], issues);\n if (question !== undefined) {\n questions.push(question);\n }\n }\n if (issues.length > 0) {\n return { issues };\n }\n return {\n value: {\n questions,\n ...(typeof candidate.preamble === 'string' ? { preamble: candidate.preamble } : {}),\n },\n };\n },\n jsonSchema: { input: () => ASK_JSON_SCHEMA },\n },\n} as StandardSchemaV1<unknown, AskToolInput>;\n\n/**\n * What the model is told the `ask` tool is for. Written to discourage the two failure modes that\n * make a clarifying question worse than a guess: asking about something the conversation already\n * settled, and asking without saying what you would have done.\n */\nexport const ASK_TOOL_DESCRIPTION =\n 'Ask the user to settle the scope of the work before you do it. Use it when a reasonable person would produce a materially different result depending on the answer — not to confirm something the conversation already says. Every question must pre-pick the answer you would choose, so the user can confirm instead of deciding. The user may decline, in which case you proceed on those pre-picked answers.';\n\n/**\n * The `ask` tool as the model sees it. NOT a `ToolSpec` and never registered: `ask` has no handler,\n * because the loop settles it against a human instead of invoking anything. Keeping it out of the\n * `ToolRegistry` is also what keeps the kind decision off a process-local lookup — see\n * `claimToolCall`.\n */\nexport function askToolDefinition(): ToolDefinition {\n return {\n name: ASK_TOOL_NAME,\n kind: 'ask',\n description: ASK_TOOL_DESCRIPTION,\n inputSchema: askInputSchema,\n };\n}\n\n/** A question set an `@Agent` asks before it starts working. See `AgentLoopDeps.intake`. */\nexport interface AgentIntake {\n questions: ElicitationQuestion[];\n /** What the assistant says above the form. Omit → {@link DEFAULT_INTAKE_PREAMBLE}. */\n preamble?: string;\n /**\n * `'thread-start'` (default) asks once, on the first turn of a thread; `'every-turn'` asks before\n * every turn. Both are decided from what `load:thread` recorded about the thread when the turn\n * began, never from anything this process happens to know — by the time a replay reaches the\n * question, the thread already holds the assistant message the first attempt wrote.\n */\n when?: 'thread-start' | 'every-turn';\n}\n\nexport const DEFAULT_INTAKE_PREAMBLE =\n 'A few questions before I start. I have pre-picked what I would choose, so confirming is enough.';\n","/**\n * Skills: an authored procedure the model pulls in when a task calls for it, instead of every\n * instruction living in the system prompt.\n *\n * WHAT A SKILL IS NOT: an agent. An `@Agent` is WHO is answering — its persona, its tools, its\n * history ceiling, its output schema. A skill is HOW one particular task is done, and any agent may\n * pull one in. That is why a skill carries no model, no tool list and no schema: the moment it did,\n * the two would be the same thing wearing different names, and a consumer would have to choose\n * between them for reasons nobody could state.\n *\n * WHAT IT COSTS THE PROMPT: one line per skill. The catalog block below carries names, scopes and\n * descriptions only; a BODY reaches the model as a tool result, on the transcript, where the\n * `HistoryPolicy` ceiling already governs it. So skills are not a fourth thing competing for the\n * system block with the agent's own prompt, its contributors and injected retrieval — see\n * `AgentLoopDeps.skills` for how the four compose.\n */\n\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport type { Actor, PageContext, ToolDefinition } from './types.js';\n\n/** How a skill is identified in the catalog, to the model and to a `/`-autocomplete alike. */\nexport interface SkillSummary {\n /** Unique within a scope. The handle the model passes to the `skill` tool. */\n name: string;\n /** One line: what task this covers, and therefore when to load it. Read by the MODEL to choose. */\n description: string;\n /** The opaque scope token this skill is published at — see {@link ScopeResolver}. */\n scope: string;\n}\n\n/** A skill with the instructions themselves. Only ever materialized when something loads it. */\nexport interface Skill extends SkillSummary {\n body: string;\n}\n\n/** Whose turn is asking, and therefore which scopes apply. */\nexport interface ScopeContext {\n actor: Actor;\n threadId: string;\n /** The agent running this turn. Undefined → the default agent. */\n agentName?: string;\n pageContext?: PageContext;\n}\n\n/**\n * The skills-facing name for {@link ScopeContext}, so a `SkillProvider`'s signature reads in its own\n * vocabulary. Deliberately the SAME type rather than a parallel one: skills and memory resolve\n * scopes through one `ScopeResolver`, and a deployment that could answer \"which scopes does this\n * actor have\" twice would eventually answer it differently.\n */\nexport type SkillContext = ScopeContext;\n\n/** The scope token every deployment has: skills nobody narrowed. */\nexport const GLOBAL_SCOPE = 'global';\n\n/** The token for one actor's own skills. */\nexport function actorScope(actor: Actor): string {\n return `actor:${actor.id}`;\n}\n\n/** The token for a tenant's skills — `Actor.tenantRef` is the only tenant key this library knows. */\nexport function tenantScope(tenantRef: string): string {\n return `tenant:${tenantRef}`;\n}\n\n/**\n * Which scopes a turn may draw skills from, MOST SPECIFIC FIRST. Precedence is the order: a skill\n * from an earlier token outranks a same-named one from a later token, and the model is shown which\n * of them won.\n *\n * A HOST-SUPPLIED FUNCTION rather than an enum this library owns, because the axes a deployment\n * scopes by are the deployment's own. `Actor` gives an id and a tenant; it does not give a sector, a\n * region, a warehouse, a shift — and every one of those is a real axis in some consumer. An enum here\n * would make each of them a schema change in a library that has no business knowing they exist,\n * while a token is a string a host mints for itself. Return `['sector:logistics', 'tenant:berlin',\n * 'global']` and precedence follows, with nothing in this package edited.\n *\n * MUST be a pure function of its context. It runs inside the `skills:catalog` checkpoint and its\n * result is journaled, so a resumed run reads back the scopes the first attempt resolved rather than\n * asking a membership table that may have changed since — which would otherwise let a run's prompt\n * differ from the one its journal records. Read a database here at your peril; read it in the\n * provider, whose answer is journaled at the same position.\n */\nexport interface ScopeResolver {\n resolve(ctx: SkillContext): string[] | Promise<string[]>;\n}\n\n/**\n * The scopes derivable from an {@link Actor} alone — the common case, so a consumer wiring skills\n * for the first time supplies no resolver at all: the actor's own, their tenant's (when they have\n * one), and the deployment's. A host adding an axis of its own replaces this rather than extending\n * it, since the ORDER is the precedence and only the host knows where its axis belongs.\n */\nexport const defaultScopeResolver: ScopeResolver = {\n resolve: ({ actor }: SkillContext): string[] => [\n actorScope(actor),\n ...(actor.tenantRef !== undefined ? [tenantScope(actor.tenantRef)] : []),\n GLOBAL_SCOPE,\n ],\n};\n\n/**\n * Where skills come from. Deliberately two calls rather than one: `list` is asked on EVERY turn and\n * must stay cheap, while a body is read only when the model decides it needs that procedure — the\n * whole point of the surface. A provider over a table selects name/description/scope for the first\n * and one row for the second.\n *\n * This library owns no skill table. A skill's real scoping axes, its authoring UI and its audit\n * trail are all the host's, and a host that related its own `Sector` entity into a table this\n * package created at boot would be writing migrations against a schema the boot-time heal also\n * edits. Tokens split it the other way round: the library owns the contract (what a scope means, how\n * precedence works, what is journaled), the host owns the rows.\n */\n/** Arguments to {@link SkillProvider.list}. */\nexport interface ListSkillsInput {\n scopes: readonly string[];\n ctx: SkillContext;\n}\n\n/**\n * Arguments to {@link SkillProvider.load}. An object rather than positional arguments because\n * `name` and `scope` are both strings: transposed, a positional call compiles clean, returns `null`,\n * and the skill silently fails to load.\n */\nexport interface LoadSkillInput {\n name: string;\n scope: string;\n ctx: SkillContext;\n}\n\nexport interface SkillProvider {\n /**\n * Every skill visible at `scopes`, in any order — this library sorts and resolves precedence. A\n * provider MAY return skills outside `scopes`; they are dropped rather than trusted, so a filter\n * bug in a host cannot widen what an actor is offered.\n */\n list(input: ListSkillsInput): SkillSummary[] | Promise<SkillSummary[]>;\n /**\n * The instructions for one skill, or `null` when it is gone. Called only from inside the loading\n * checkpoint, so the body it returns is journaled and every replay reads THAT text back — an\n * edited skill never rewrites the prompt of a run already in flight.\n */\n load(input: LoadSkillInput): string | null | Promise<string | null>;\n}\n\n/** A source of skills that is a fixed list — `@Skill()`-decorated classes, or plain config. */\nexport function staticSkillProvider(skills: readonly Skill[]): SkillProvider {\n return {\n list: ({ scopes }) => skills.filter((skill) => scopes.includes(skill.scope)),\n load: ({ name, scope }) =>\n skills.find((skill) => skill.name === name && skill.scope === scope)?.body ?? null,\n };\n}\n\n/**\n * Read several sources as one. The order is the tie-break and nothing else: precedence between\n * skills is by SCOPE, so two sources only ever compete when they publish the same name at the same\n * scope, and then the earlier source wins. Wire the host's own provider first — a row it can edit is\n * a better answer than a body that needs a deploy to change.\n */\nexport function compositeSkillProvider(providers: readonly SkillProvider[]): SkillProvider {\n return {\n list: async ({ scopes, ctx }) => {\n const seen = new Set<string>();\n const merged: SkillSummary[] = [];\n for (const provider of providers) {\n for (const summary of await provider.list({ scopes, ctx })) {\n const key = `${summary.scope}\\u0000${summary.name}`;\n if (!seen.has(key)) {\n seen.add(key);\n merged.push(summary);\n }\n }\n }\n return merged;\n },\n load: async ({ name, scope, ctx }) => {\n for (const provider of providers) {\n const body = await provider.load({ name, scope, ctx });\n if (body !== null) {\n return body;\n }\n }\n return null;\n },\n };\n}\n\n/**\n * One skill as it is offered — to the model in the catalog block, and to a client over\n * `GET /agent/skills`. Both read the same list, built by the same call, so what a user can type\n * after a `/` and what the model can reach cannot drift apart.\n */\nexport interface SkillCatalogEntry {\n name: string;\n description: string;\n /** The scope token it resolved from — the provenance a user is entitled to see. */\n scope: string;\n /**\n * Scope tokens of same-named skills this one outranks, widest last. Present ONLY when something\n * was shadowed, so a reader can tell \"there is no org default\" from \"there is one and yours wins\".\n * The model is shown it for the same reason: a silent override is indistinguishable from an\n * instruction nobody wrote, and the user can only be told \"your setting differs from the org\n * default\" by something that knows both existed.\n */\n shadows?: string[];\n}\n\n/** What a turn resolved — journaled whole, so the prompt is reconstructible from the journal alone. */\nexport interface SkillOffer {\n /** The scope tokens this turn drew from, most specific first. */\n scopes: string[];\n /** The skills offered, most specific first then by name. */\n entries: SkillCatalogEntry[];\n /** Applicable skills `maxSkills` left out. Non-zero means the catalog is not the whole truth. */\n omitted: number;\n}\n\n/**\n * How many skills a catalog offers before it starts leaving some out. A ceiling on the SYSTEM\n * PROMPT's share, not on how many a deployment may have: the block costs one line each, and a\n * hundred lines of \"here is something you could load\" crowds out the agent's own instructions while\n * making the choice harder rather than easier.\n */\nexport const DEFAULT_MAX_SKILLS = 20;\n\n/** How a turn reaches its skills. See `AgentLoopDeps.skills`. */\nexport interface SkillsConfig {\n provider: SkillProvider;\n /** Undefined → {@link defaultScopeResolver}: the actor's own, their tenant's, the deployment's. */\n scopes?: ScopeResolver;\n /** Undefined → {@link DEFAULT_MAX_SKILLS}. */\n maxSkills?: number;\n}\n\n/**\n * Resolve a provider's skills against an ordered scope list: most specific wins, and the loser's\n * scope is recorded rather than discarded.\n *\n * Pure, and separately exported, because two callers must reach the identical answer — the loop, so\n * the model is offered it, and the listing endpoint, so a user is. A second implementation of\n * \"which skills apply\" is a second answer, and the two diverge the first time either is edited.\n */\nexport function resolveSkillCatalog(\n summaries: readonly SkillSummary[],\n scopes: readonly string[],\n maxSkills: number = DEFAULT_MAX_SKILLS,\n): Omit<SkillOffer, 'scopes'> {\n const rank = new Map(scopes.map((scope, index) => [scope, index]));\n const byName = new Map<string, SkillSummary[]>();\n for (const summary of summaries) {\n // A scope the resolver did not return is one this actor has no claim on, whatever the provider\n // thinks. Dropping it here is what makes over-returning a performance mistake instead of a leak.\n if (!rank.has(summary.scope)) {\n continue;\n }\n const existing = byName.get(summary.name);\n if (existing === undefined) {\n byName.set(summary.name, [summary]);\n } else {\n existing.push(summary);\n }\n }\n const resolved: SkillCatalogEntry[] = [];\n for (const candidates of byName.values()) {\n const ordered = [...candidates].sort(\n (a, b) => (rank.get(a.scope) ?? 0) - (rank.get(b.scope) ?? 0),\n );\n const winner = ordered[0];\n if (winner === undefined) {\n continue;\n }\n const shadows = ordered.slice(1).map((candidate) => candidate.scope);\n resolved.push({\n name: winner.name,\n description: winner.description,\n scope: winner.scope,\n ...(shadows.length > 0 ? { shadows } : {}),\n });\n }\n // Most specific first, then alphabetical: an order a reader can predict, and one where trimming\n // the tail to `maxSkills` drops the WIDEST skills — an org default is the one a deployment can\n // best afford to lose, and the actor's own is the one it can least.\n resolved.sort((a, b) => {\n const byScope = (rank.get(a.scope) ?? 0) - (rank.get(b.scope) ?? 0);\n return byScope !== 0 ? byScope : compare(a.name, b.name);\n });\n return {\n entries: resolved.slice(0, maxSkills),\n omitted: Math.max(0, resolved.length - maxSkills),\n };\n}\n\nfunction compare(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/** Resolve the scopes and the catalog for one turn. Called INSIDE the loop's `skills:catalog` step. */\nexport async function offerSkills(config: SkillsConfig, ctx: SkillContext): Promise<SkillOffer> {\n const scopes = await (config.scopes ?? defaultScopeResolver).resolve(ctx);\n const summaries = await config.provider.list({ scopes, ctx });\n return { scopes, ...resolveSkillCatalog(summaries, scopes, config.maxSkills) };\n}\n\n/**\n * The catalog as the model reads it. One line per skill — name, scope, description, and what it\n * overrides — because the entire claim of progressive disclosure is that choosing what to read costs\n * far less than reading everything.\n */\nexport function buildSkillsBlock(entries: readonly SkillCatalogEntry[]): string {\n const lines = entries.map((entry) => {\n const shadows =\n entry.shadows === undefined ? '' : ` (overrides the one from ${entry.shadows.join(', ')})`;\n return `- ${entry.name} [${entry.scope}] — ${entry.description}${shadows}`;\n });\n return `<skills>\nProcedures available to you. Each line is a name, the scope it came from, and what it covers — not the procedure itself.\nCall the \\`${SKILL_TOOL_NAME}\\` tool with a name from this list to read one BEFORE doing the task it covers, and follow what it says; never guess its contents from the description.\nA skill from a narrower scope overrides a same-named one from a wider scope. When you follow one that overrides another, say which scope it came from, so the user knows their setting differs from the wider default.\n${lines.join('\\n')}\n</skills>`;\n}\n\n/** The reserved name of the built-in skill-loading tool. */\nexport const SKILL_TOOL_NAME = 'skill';\n\n/** What the model passes to the `skill` tool. */\nexport interface SkillToolInput {\n name: string;\n}\n\nconst SKILL_JSON_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['name'],\n properties: {\n name: {\n type: 'string',\n description: 'The name of a skill from the <skills> list, exactly as written there.',\n },\n },\n} as const;\n\nfunction issue(path: (string | number)[], message: string) {\n return { message, path };\n}\n\n/**\n * The `skill` tool's input schema. Hand-written for the same reason `askInputSchema` is: core\n * depends on no validator and the schema has to publish a JSON Schema a provider can constrain\n * generation against.\n *\n * The available names are deliberately NOT an enum here. A per-turn enum would make the tool's\n * definition depend on the catalog — and the dispatched llm step re-derives the tool list on\n * whichever worker serves it, from ITS OWN provider, which is exactly the process-local lookup this\n * design keeps off the turn's decisions. The names live in the prompt, where the journal holds them;\n * a name that is not in the catalog comes back as an ordinary tool failure listing the ones that are.\n */\nexport const skillInputSchema = {\n '~standard': {\n version: 1,\n vendor: 'nestjs-agent',\n validate: (value: unknown) => {\n if (typeof value !== 'object' || value === null) {\n return { issues: [issue([], 'must be an object')] };\n }\n const candidate = value as Partial<SkillToolInput>;\n if (typeof candidate.name !== 'string' || candidate.name.length === 0) {\n return { issues: [issue(['name'], 'must be a non-empty string')] };\n }\n return { value: { name: candidate.name } };\n },\n jsonSchema: { input: () => SKILL_JSON_SCHEMA },\n },\n} as unknown as StandardSchemaV1<unknown, SkillToolInput>;\n\nexport const SKILL_TOOL_DESCRIPTION =\n 'Read one of the procedures listed in <skills>. Call it before doing a task a listed skill covers, and follow what it returns. It performs nothing and changes nothing — it only gives you instructions you do not yet have.';\n\n/**\n * The `skill` tool as the model sees it. NOT a `ToolSpec` and never registered, exactly like `ask`:\n * it has no handler, because the loop serves it from the catalog the journal holds. Keeping it out\n * of the `ToolRegistry` is also what keeps its kind off a process-local lookup — see `claimToolCall`.\n */\nexport function skillToolDefinition(): ToolDefinition {\n return {\n name: SKILL_TOOL_NAME,\n kind: 'skill',\n description: SKILL_TOOL_DESCRIPTION,\n inputSchema: skillInputSchema,\n };\n}\n\n/**\n * Append the built-in `skill` definition to a turn's tool list. Exported because the dispatched llm\n * step re-derives the tool list on a worker and has to reach the same list the loop would have.\n */\nexport function withSkillTool({\n tools,\n enabled,\n}: { tools: ToolDefinition[]; enabled: boolean }): ToolDefinition[] {\n return enabled ? [...tools, skillToolDefinition()] : tools;\n}\n\n/** What a `skill` call resolved to — the body, or why it did not. */\nexport type SkillLoadOutcome =\n | { ok: true; skill: Skill; shadows?: string[] }\n | { ok: false; error: string };\n\n/**\n * Serve one `skill` call against the catalog THIS TURN was offered.\n *\n * The catalog is the authorization boundary, not just a menu: a name the turn was never offered is\n * refused here, so a model that invents one (or repeats one it saw in another actor's thread) cannot\n * reach a body through a provider that would happily serve it. Because the catalog came out of the\n * `skills:catalog` checkpoint, that boundary is the one the journal records rather than the one this\n * process's provider currently believes in.\n */\nexport async function loadSkill(\n config: SkillsConfig,\n offer: SkillOffer,\n name: string,\n ctx: SkillContext,\n): Promise<SkillLoadOutcome> {\n const entry = offer.entries.find((candidate) => candidate.name === name);\n if (entry === undefined) {\n const available = offer.entries.map((candidate) => candidate.name).join(', ');\n return {\n ok: false,\n error:\n available.length === 0\n ? `No skill named \"${name}\" is available to you, and no others are either.`\n : `No skill named \"${name}\" is available to you. Available: ${available}.`,\n };\n }\n const body = await config.provider.load({ name: entry.name, scope: entry.scope, ctx });\n if (body === null) {\n return { ok: false, error: `Skill \"${name}\" is listed but its body could not be read.` };\n }\n return {\n ok: true,\n skill: { name: entry.name, description: entry.description, scope: entry.scope, body },\n ...(entry.shadows !== undefined ? { shadows: entry.shadows } : {}),\n };\n}\n\n/** Who is trying to write a skill. */\nexport interface SkillAuthor {\n /**\n * `'human'` is a person acting through a UI; `'agent'` is anything else — a tool, a turn, a\n * batch job. The distinction is the whole of the rule below, so it is not inferable and has to\n * be stated by the caller.\n */\n kind: 'human' | 'agent';\n actorRef?: string;\n}\n\n/** A request to author a skill at a scope. */\nexport interface SkillWriteRequest {\n /** The scope token the skill would be published at. */\n scope: string;\n actor: Actor;\n /** The actor's resolved scopes, most specific first — the same list a turn draws from. */\n scopes: readonly string[];\n author: SkillAuthor;\n /**\n * The host's own answer to \"may this person administer that scope\" — a sector lead editing their\n * sector's skills, an operator editing the deployment's. This library cannot know it: it has no\n * notion of who administers `sector:logistics`, and inventing one would be a second, weaker\n * authorization model next to the host's real one. Undefined/false → a wider scope is refused.\n */\n elevated?: boolean;\n}\n\nexport type SkillWriteVerdict = { allowed: true } | { allowed: false; reason: string };\n\n/**\n * May this author publish a skill at this scope?\n *\n * A skill's body is instructions the model follows, which makes writing one at a scope an edit to\n * everyone in that scope's system prompt. The rules follow from that, and only the third is\n * interesting:\n *\n * 1. You may only write into a scope you are yourself in. Writing into a scope you are not in is\n * authoring for people you have no relationship with.\n * 2. Your OWN scope is yours. A per-actor skill affects exactly one prompt — the author's.\n * 3. NOTHING BUT A HUMAN MAY WRITE ABOVE ITS OWN SCOPE, whatever `elevated` says. An agent that can\n * write a `tenant:` skill is an agent whose prompt anyone in the tenant can edit by talking to\n * it: the user asks for something, the turn writes the instruction, and every later turn for\n * every other user follows it. That is prompt injection with persistence, and no elevation a\n * host could grant makes it a different shape. An agent that has genuinely learned something\n * worth sharing proposes it; a person publishes it.\n * 4. A human writing above their own scope needs the host to say so (`elevated`).\n */\nexport function skillWriteVerdict(request: SkillWriteRequest): SkillWriteVerdict {\n const { scope, scopes, author, actor } = request;\n if (!scopes.includes(scope)) {\n return { allowed: false, reason: `\"${scope}\" is not a scope this actor belongs to` };\n }\n const own = actorScope(actor);\n if (scope === own) {\n return { allowed: true };\n }\n if (author.kind !== 'human') {\n return {\n allowed: false,\n reason: `only a human may author a skill at \"${scope}\"; an agent may write only at \"${own}\"`,\n };\n }\n return request.elevated === true\n ? { allowed: true }\n : { allowed: false, reason: `authoring at \"${scope}\" requires an elevated human author` };\n}\n","/**\n * Memory: what the assistant has concluded about a person or an organisation, carried across turns\n * and across threads.\n *\n * HOW A READER TELLS IT FROM RAG. Retrieval answers \"what do the documents say\"; memory answers\n * \"what did I decide about you\". A passage is content a person authored and can correct at its\n * source, and it is cited. A memory has no source to go and fix: it is the agent's own inference,\n * which is why every record carries an {@link MemoryOrigin} (who wrote it, in which conversation),\n * why the block tells the model to treat it as fallible, and why `forget` is a REQUIRED method on\n * the provider rather than an optional one. A wrong document is a content problem. A wrong memory is\n * the assistant being confidently wrong about someone with nobody aware it is there, so the whole\n * design is arranged around making it visible and removable.\n *\n * WHAT IT COSTS THE PROMPT. One line per memory, capped by `maxMemories`, and each line capped by\n * `maxFactChars` at WRITE time — so the block a turn can carry is the product of two numbers an\n * operator sets, rather than however much the model felt like writing down. Unlike a skill, a memory\n * has no body/catalog split: a fact that cannot be stated in a line is not a memory, it is a\n * document, and documents are retrieval's job.\n *\n * WHAT IT IS NOT: recall over a TRANSCRIPT. Searching what was said earlier is retrieval, and this\n * library already has `Retriever`/`Reranker` for that.\n *\n * RECALL OVER THE MEMORIES THEMSELVES IS A DIFFERENT QUESTION, and it is answered here. The prompt\n * budget must be bounded; the store has no reason to be. A person accumulates preferences over\n * months and an organisation publishes facts for everyone in it, so the applicable set outgrows\n * `maxMemories` quickly — and once it does, WHICH of them the block carries is a decision somebody\n * has to make. Making it by scope starves the widest scopes first, which is precisely backwards: the\n * facts that apply to the most people are the ones nobody sees. So a provider MAY supply\n * {@link MemoryProvider.search}, and where it does, the block is filled by relevance to the turn\n * (see {@link resolveMemoryDigest}) with scope still a hard filter and never a ranking signal.\n * `maxMemories` then means \"how many matter right now\" rather than \"how many a person may have\".\n */\n\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport {\n type ScopeContext,\n type ScopeResolver,\n actorScope,\n defaultScopeResolver,\n} from './skills.js';\nimport type { Actor, ToolDefinition } from './types.js';\n\n/** Who wrote a memory, and out of what. Kept so a person reading it back can ask \"says who?\". */\nexport interface MemoryOrigin {\n /** `'agent'` — a turn concluded it. `'human'` — a person wrote it in the host's own console. */\n author: 'agent' | 'human';\n /**\n * The conversation the conclusion was drawn in. MAY name a thread whose messages the history\n * ceiling has since dropped: a memory deliberately outlives its source, so this is a pointer that\n * is allowed to dangle, and a read-back that cannot resolve it says so rather than hiding the row.\n */\n threadId?: string;\n runId?: string;\n actorRef?: string;\n}\n\n/** One thing the assistant believes, at one scope. */\nexport interface MemoryRecord {\n /** The host's row id — what `forget` takes and what a read-back offers a delete button for. */\n id: string;\n /**\n * What the fact is ABOUT. The handle that makes a conflict mechanically detectable: two memories\n * sharing a key at different scopes are one question answered twice, and the narrower wins. A\n * keyless store could only ever hope its facts did not contradict each other.\n */\n key: string;\n /** The fact itself, as the model reads it. */\n text: string;\n /** The opaque scope token it is held at — see `ScopeResolver` in `skills.ts`. */\n scope: string;\n origin: MemoryOrigin;\n /** ISO-8601, so the ceiling can keep the newest with a string comparison it can do purely. */\n updatedAt: string;\n /**\n * Always-on: this fact is in the block whether or not the turn is about it. The difference between\n * working memory and recall, drawn per record — \"they report on the calendar year\" must not depend\n * on the turn mentioning dates, while \"they prefer the kerbside dock\" can wait until it comes up.\n *\n * A PROPERTY OF THE ROW, NOT OF A WRITE. This library reads it and never sets it, the same way it\n * never mints an `id`: an agent deciding its own conclusions are always-on is an agent deciding\n * how much of every future prompt it gets, so pinning is an operator's act in the host's console.\n * That is also why {@link StoreMemoryInput} carries no `pinned` — the `remember` tool has no\n * parameter to refuse. A host whose upsert drops the flag has silently unpinned the row; preserve\n * it across an upsert on (`scope`, `key`).\n */\n pinned?: boolean;\n}\n\n/** A same-key memory a narrower scope outranked, with the value it holds. */\nexport interface OverriddenMemory {\n scope: string;\n text: string;\n /**\n * Who asserted the beaten value. Travels because precedence is blind to it: an agent's own\n * inference at `actor:` outranks an administrator's published policy at `global`, and an agent\n * that knew only that a wider value existed could not tell the two apart — one is a stale guess,\n * the other is what the organisation decided.\n */\n author: MemoryOrigin['author'];\n}\n\n/** One memory as the model and a read-back both meet it. */\nexport interface MemoryDigestEntry extends MemoryRecord {\n /**\n * Same-key memories this one outranks, widest last. Present ONLY where something was outranked.\n *\n * Carries the beaten TEXT, which is where memory departs from a skill's `shadows`. A skill only\n * has to say which scope it beat — the agent follows one procedure either way. A memory is a\n * VALUE, and an agent that knows only that a wider value existed cannot tell the user what the\n * difference is; it can only choose, silently, which is the thing this is meant to prevent.\n */\n overrides?: OverriddenMemory[];\n}\n\n/** What a turn resolved — journaled whole, so its prompt is reconstructible from its journal alone. */\nexport interface MemoryDigest {\n /** The scope tokens this turn drew from, most specific first. */\n scopes: string[];\n /** The memories in the block, most specific first then by key. */\n entries: MemoryDigestEntry[];\n /**\n * Applicable memories `maxMemories` left out. Non-zero means the block is not the whole truth —\n * and under {@link recalled} it counts what the SEARCH offered and the ceiling dropped, not what\n * the store holds, because nothing asked the store for a total.\n */\n omitted: number;\n /**\n * Of {@link omitted}, how many were ALWAYS-ON. Reported separately because it means something else\n * entirely: ordinary omission is the budget doing its job, while an always-on memory the ceiling\n * dropped is a deployment's own standing policies having silently stopped reaching any prompt.\n * Non-zero is a misconfiguration — more was pinned than the block holds — and the fix is to unpin\n * something or raise `maxMemories`, not to wait for it to come back.\n */\n pinnedOmitted: number;\n /**\n * Whether the entries were selected by relevance to this turn rather than read whole. The model is\n * told (see {@link buildMemoryBlock}), because a partial set read as a whole one turns an absence\n * into evidence: \"you never told me that\" about a fact it simply was not shown.\n *\n * Optional so a digest journaled before recall existed reads back as the plain scoped read it was.\n */\n recalled?: boolean;\n}\n\n/** What a write asks the host to store. `id` and `updatedAt` are the host's to mint. */\nexport interface MemoryFact {\n key: string;\n text: string;\n scope: string;\n origin: MemoryOrigin;\n}\n\n/** Arguments to {@link MemoryProvider.list}. */\nexport interface ListMemoriesInput {\n /** The scope tokens that apply to this turn, most specific first. */\n scopes: readonly string[];\n ctx: ScopeContext;\n}\n\n/**\n * Arguments to {@link MemoryProvider.search}.\n *\n * `scopes` GATES, AND IT GATES FIRST. A search that ranks before it filters is a cross-tenant leak\n * wearing a relevance score: the nearest neighbour to \"what is our rollback policy\" is another\n * tenant's rollback policy. Filter in the query, not after it. Records returned outside `scopes` are\n * dropped rather than trusted, so a mistake here costs throughput rather than privacy — but the\n * drop is a backstop, not the boundary.\n */\nexport interface SearchMemoriesInput {\n /** The scope tokens that apply to this turn, most specific first. A HARD FILTER. */\n scopes: readonly string[];\n /** What this turn is about. Never blank — a blank query is served by `list` instead. */\n query: string;\n /**\n * At most this many distinct KEYS may be ranked in, which is the block's own unit: precedence\n * resolves a key to one line, so `limit` keys is `limit` lines. Pinned records are returned in\n * addition and do not count against it.\n */\n limit: number;\n ctx: ScopeContext;\n}\n\n/** Arguments to {@link MemoryProvider.forget}. */\nexport interface ForgetMemoryInput {\n id: string;\n ctx: ScopeContext;\n}\n\n/**\n * Arguments to {@link MemoryProvider.write}. An object rather than positional arguments because\n * `key`, `text` and `scope` are all strings: transposed, a positional call compiles clean and writes\n * a fact whose key is its value, at a scope nobody meant.\n */\nexport interface StoreMemoryInput extends MemoryFact {\n ctx: ScopeContext;\n}\n\n/**\n * Where memories live. The host owns the rows, for the same reason it owns skill rows: the axes a\n * deployment scopes by, the console that edits them and the audit trail are all the host's, and a\n * table this package created at boot would put a consumer's migrations in the path of the schema\n * heal that manages the `agent_*` tables.\n *\n * `forget` is REQUIRED, unlike `write`. A deployment may reasonably populate memory from its own\n * pipeline and offer the agent no write tool; no deployment may reasonably hold conclusions about a\n * person that the person cannot have deleted. Making it optional would make forgetting a wiring\n * choice, and it is not one.\n */\nexport interface MemoryProvider {\n /**\n * Every memory visible at `scopes`, in any order — this library resolves precedence and the\n * ceiling. Asked on EVERY turn, so keep it cheap. A provider MAY return records outside `scopes`;\n * they are dropped rather than trusted, so a filter bug in a host cannot widen what an actor sees.\n */\n list(input: ListMemoriesInput): MemoryRecord[] | Promise<MemoryRecord[]>;\n /** Delete one record by id. `false` where there was nothing by that id to delete. */\n forget(input: ForgetMemoryInput): boolean | Promise<boolean>;\n /**\n * Upsert on (`scope`, `key`) and return the stored record. Omit to serve memory read-only — the\n * `remember` tool is then never offered, and a turn's tool list is the same on every pod.\n */\n write?(input: StoreMemoryInput): MemoryRecord | Promise<MemoryRecord>;\n /**\n * The memories worth putting in front of a turn about `query`, MOST RELEVANT FIRST. Omit and every\n * turn is served by {@link list} — a deployment with twenty memories must not have to stand up an\n * index to keep working, and one with two thousand uses whatever it already runs (pgvector, a\n * full-text index, a hybrid service). The host owns the index for the same reason it owns the\n * rows.\n *\n * THREE CLAUSES, and the third is the one that is easy to miss:\n *\n * 1. Filter to `scopes` before ranking — see {@link SearchMemoriesInput}.\n * 2. Rank the KEYS visible at those scopes and take the best `limit` of them.\n * 3. Return EVERY record sharing a returned key, plus every `pinned` record at those scopes.\n *\n * Clause three is what keeps precedence intact. Precedence resolves a conflict between two records\n * at one key, narrower winning and the beaten value riding along; a search that returned the\n * `global` half of a conflict and not the `actor:` half would render the org default as the answer\n * — the exact failure memory exists to prevent, and one nothing downstream can detect. It is one\n * query either way:\n *\n * ```sql\n * SELECT * FROM agent_memory\n * WHERE scope IN (:scopes)\n * AND (pinned OR key IN (SELECT key FROM agent_memory\n * WHERE scope IN (:scopes)\n * ORDER BY embedding <=> :queryVector\n * LIMIT :limit))\n * ```\n */\n search?(input: SearchMemoriesInput): MemoryRecord[] | Promise<MemoryRecord[]>;\n}\n\n/**\n * How many memories the block carries. The same ceiling shape as `maxSkills`, and for the same\n * reason: a prompt that grows with how much the agent has written down is a prompt whose cost nobody\n * set. A budget on the PROMPT and never on the store — with a provider that can\n * {@link MemoryProvider.search}, it is how many matter right now rather than how many a person may\n * have.\n */\nexport const DEFAULT_MAX_MEMORIES = 20;\n\n/**\n * How long one memory may be, enforced when it is WRITTEN rather than when it is rendered. Enforcing\n * it at render time would make the prompt disagree with the store; enforcing it at write time makes\n * the block's whole ceiling a multiplication an operator can do — `maxMemories × maxFactChars` — and\n * pushes back on the model at the moment it is writing an essay instead of a fact.\n */\nexport const DEFAULT_MAX_FACT_CHARS = 240;\n\n/** How a turn reaches its memory. See `AgentLoopDeps.memory`. */\nexport interface MemoryConfig {\n provider: MemoryProvider;\n /** Undefined → `defaultScopeResolver`: the actor's own, their tenant's, the deployment's. */\n scopes?: ScopeResolver;\n /** Undefined → {@link DEFAULT_MAX_MEMORIES}. Always-on memories are taken from it first. */\n maxMemories?: number;\n /** Undefined → {@link DEFAULT_MAX_FACT_CHARS}. */\n maxFactChars?: number;\n}\n\n/**\n * Resolve a provider's records against an ordered scope list: most specific wins a key, and the\n * losers' values are carried rather than discarded.\n *\n * Pure, and separately exported, because the loop and the read-back endpoint must reach the same\n * answer — a person has to be shown what the model was shown, or \"see what it believes about you\"\n * means nothing.\n */\n/** Arguments to {@link resolveMemoryDigest}. */\nexport interface ResolveMemoryDigestInput {\n records: readonly MemoryRecord[];\n /** The scope tokens that apply, most specific first — the precedence order. */\n scopes: readonly string[];\n /** Undefined → {@link DEFAULT_MAX_MEMORIES}. */\n maxMemories?: number;\n /**\n * Whether `records` arrived most-relevant-first, from {@link MemoryProvider.search}. A key's rank\n * is its best-placed record's. Undefined/false → the ceiling selects by scope and recency, which\n * is the right order only while nothing is being starved.\n */\n ranked?: boolean;\n}\n\nexport function resolveMemoryDigest({\n records,\n scopes,\n maxMemories = DEFAULT_MAX_MEMORIES,\n ranked = false,\n}: ResolveMemoryDigestInput): Omit<MemoryDigest, 'scopes' | 'recalled'> {\n const rank = new Map(scopes.map((scope, index) => [scope, index]));\n const byKey = new Map<string, MemoryRecord[]>();\n for (const entry of records) {\n // A scope the resolver did not return is one this actor has no claim on, whatever the provider\n // thinks. Dropping it here is what makes over-returning a performance mistake, not a leak.\n if (!rank.has(entry.scope)) {\n continue;\n }\n const existing = byKey.get(entry.key);\n if (existing === undefined) {\n byKey.set(entry.key, [entry]);\n } else {\n existing.push(entry);\n }\n }\n const resolved: MemoryDigestEntry[] = [];\n for (const candidates of byKey.values()) {\n const ordered = [...candidates].sort(\n (a, b) => (rank.get(a.scope) ?? 0) - (rank.get(b.scope) ?? 0),\n );\n const winner = ordered[0];\n if (winner === undefined) {\n continue;\n }\n const overrides = ordered.slice(1).map((beaten) => ({\n scope: beaten.scope,\n text: beaten.text,\n author: beaten.origin.author,\n }));\n // A pin belongs to the QUESTION, not to the record that currently answers it: pinning \"which\n // fiscal year\" and then letting a personal override of it fall out of the block would make\n // always-on mean \"always-on until someone disagrees with it\".\n const pinned = ordered.some((candidate) => candidate.pinned === true);\n resolved.push({\n ...winner,\n ...(pinned ? { pinned: true } : {}),\n ...(overrides.length > 0 ? { overrides } : {}),\n });\n }\n // Three orders, answering three different questions.\n //\n // ALWAYS-ON FIRST, whatever else is true: a pinned fact is in the block whether or not the turn is\n // about it. It spends the same budget as everything else, so the ceiling stays a product of two\n // numbers an operator set rather than growing with how much got pinned.\n //\n // Then SELECTION among the rest — by relevance where the candidates were ranked, else by narrowest\n // scope and newest within it. That second rule is right only while nothing is being starved, which\n // is the case a host running no index is in: `list` returns the whole applicable set, so a ceiling\n // that bites is dropping what the deployment can best afford to lose. Once the set outgrows the\n // block it is exactly wrong, because the scopes it drops first are the ones shared by the most\n // people — one person's twentieth note would end every chance their organisation's facts had.\n //\n // RENDERING is by scope then key, stable between turns: ordering the block by recency or by score\n // would reshuffle it on every write and throw away the provider's prompt cache. Pinned entries\n // lead, because they are the part of the block that does not move from turn to turn.\n const byPrecedence = (a: MemoryDigestEntry, b: MemoryDigestEntry): number =>\n (rank.get(a.scope) ?? 0) - (rank.get(b.scope) ?? 0) ||\n compare(b.updatedAt, a.updatedAt) ||\n compare(a.key, b.key);\n const selected = resolved\n .map((entry, index) => ({ entry, index }))\n .sort(\n (a, b) =>\n pinRank(a.entry) - pinRank(b.entry) ||\n (ranked && a.entry.pinned !== true ? a.index - b.index : byPrecedence(a.entry, b.entry)),\n )\n .slice(0, maxMemories)\n .map((candidate) => candidate.entry);\n const pinnedOmitted =\n resolved.filter((entry) => entry.pinned === true).length -\n selected.filter((entry) => entry.pinned === true).length;\n selected.sort(\n (a, b) =>\n pinRank(a) - pinRank(b) ||\n (rank.get(a.scope) ?? 0) - (rank.get(b.scope) ?? 0) ||\n compare(a.key, b.key),\n );\n return {\n entries: selected,\n omitted: Math.max(0, resolved.length - maxMemories),\n pinnedOmitted,\n };\n}\n\nfunction pinRank(entry: MemoryDigestEntry): number {\n return entry.pinned === true ? 0 : 1;\n}\n\nfunction compare(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/** Arguments to {@link offerMemories}. */\nexport interface OfferMemoriesInput {\n config: MemoryConfig;\n ctx: ScopeContext;\n /**\n * What this turn is about — the loop passes the user's own message, and nothing else. Given, and\n * with a provider that has an index, the block is filled by relevance to it. Absent, the scope is\n * read whole: that is what the read-back endpoint wants, since a person must be shown every belief\n * held about them rather than the slice one turn happened to need.\n */\n query?: string;\n}\n\n/**\n * Resolve the scopes and the digest for one turn. Called INSIDE the loop's `memory:digest` step, and\n * that placement is the whole of its determinism: a search is the most re-derivable thing in this\n * library — the index moves, a neighbour is written, embeddings are recomputed — so its result has\n * to be part of the checkpoint every replay reads back, never something a replaying process asks\n * again.\n */\nexport async function offerMemories({\n config,\n ctx,\n query,\n}: OfferMemoriesInput): Promise<MemoryDigest> {\n const scopes = await (config.scopes ?? defaultScopeResolver).resolve(ctx);\n const maxMemories = config.maxMemories ?? DEFAULT_MAX_MEMORIES;\n // A search keyed on nothing ranks on noise, so a turn with no text to search with reads the scope\n // plainly rather than making a worse selection out of it. What carries a fact through a turn like\n // that is `pinned`, not a cleverer query.\n const trimmed = query?.trim() ?? '';\n // Bound for the same reason `writeMemory` binds its own: a provider is normally a class, and a\n // method read off it has lost the receiver its body needs.\n const search = trimmed.length > 0 ? config.provider.search?.bind(config.provider) : undefined;\n const records =\n search !== undefined\n ? await search({ scopes, query: trimmed, limit: maxMemories, ctx })\n : await config.provider.list({ scopes, ctx });\n return {\n scopes,\n recalled: search !== undefined,\n ...resolveMemoryDigest({ records, scopes, maxMemories, ranked: search !== undefined }),\n };\n}\n\n/**\n * The block as the model reads it.\n *\n * THREE THINGS IT HAS TO DO THAT A SKILLS CATALOG DOES NOT.\n *\n * It must frame each note by WHO ASSERTED IT, which is why there are two sections rather than one\n * sentence over the whole list. An unlabelled fact in a system prompt reads with the authority of an\n * instruction, and the hazard of an agent's own inference is exactly that authority — so those are\n * hedged. But a memory an administrator published for a whole organisation is not the agent's guess,\n * and telling the model to \"prefer what the user says now\" about it hands any user an override of\n * their organisation's policy by asserting the opposite. `MemoryOrigin.author` is the axis, and it\n * is the only one that matters here: scope says who a fact applies to, not who decided it.\n *\n * Where a narrower scope won, it must print the value it beat, so the model can tell the user their\n * setting differs from the org's instead of quietly applying one of them.\n *\n * And a block that is a SELECTION must say so. A model reading a partial set as a whole one turns an\n * absence into evidence — \"you never told me that\" about a fact it simply was not shown.\n */\n/** Arguments to {@link buildMemoryBlock}. */\nexport interface BuildMemoryBlockInput {\n entries: readonly MemoryDigestEntry[];\n /** Whether this deployment offers `remember` — the block names the tool only where it exists. */\n writable: boolean;\n /** Whether applicable memories are missing from `entries` — the ceiling bit, or recall selected. */\n partial: boolean;\n}\n\nconst ASSERTED_FRAMING =\n 'Stated by people. A person wrote each of these deliberately — the user about themselves, or someone administering their organisation. Treat them as you would any other instruction you were given. If the user says something that contradicts one, say which note it conflicts with and at what scope it is held, rather than quietly setting it aside.';\n\nconst CONCLUDED_FRAMING =\n 'Concluded by you. These are your own notes from earlier turns, not documents anyone wrote: they may be wrong or out of date, so prefer what the user says now, and say where a note came from if you act on it.';\n\nconst PARTIAL_FRAMING =\n 'You are being shown a selection, not everything on file. Other notes exist that are not in this list, so never read something’s absence from it as evidence that it was never recorded.';\n\nfunction memorySection(framing: string, entries: readonly MemoryDigestEntry[]): string[] {\n if (entries.length === 0) {\n return [];\n }\n return [\n framing,\n ...entries.flatMap((entry) => [\n `- [${entry.scope}] ${entry.key}: ${entry.text}`,\n ...(entry.overrides ?? []).map(\n (beaten) =>\n ` ↳ [${beaten.scope}] ${beaten.author === 'human' ? 'a person stated' : 'instead has'}: ${beaten.text}`,\n ),\n ]),\n ];\n}\n\nexport function buildMemoryBlock({ entries, writable, partial }: BuildMemoryBlockInput): string {\n const writeLine = writable\n ? [\n `When you learn something durable about this user, record it with the \\`${REMEMBER_TOOL_NAME}\\` tool; when one of these turns out to be wrong, record the corrected fact under the same key. What you record that way is one of your own notes, not something stated by a person.`,\n ]\n : [];\n const body = [\n 'What is on file about this user and their organisation, carried over from earlier conversations. Each line is a scope, a key and the fact. A narrower scope overrides a wider one; where the wider value is shown underneath, tell the user their setting differs from it rather than silently choosing one.',\n ...(partial ? [PARTIAL_FRAMING] : []),\n ...writeLine,\n // People before inferences: the model meets what it was told before what it worked out.\n ...memorySection(\n ASSERTED_FRAMING,\n entries.filter((entry) => entry.origin.author === 'human'),\n ),\n ...memorySection(\n CONCLUDED_FRAMING,\n entries.filter((entry) => entry.origin.author !== 'human'),\n ),\n ];\n return `<memory>\\n${body.join('\\n')}\\n</memory>`;\n}\n\n/** The reserved name of the built-in memory-writing tool. */\nexport const REMEMBER_TOOL_NAME = 'remember';\n\n/** What the model passes to the `remember` tool. */\nexport interface RememberToolInput {\n key: string;\n fact: string;\n}\n\nconst REMEMBER_JSON_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['key', 'fact'],\n properties: {\n key: {\n type: 'string',\n description:\n 'A short, stable handle for what this fact is ABOUT (e.g. \"fiscal-year\", \"preferred-units\"). Reusing an existing key replaces that fact rather than adding a second one.',\n },\n fact: {\n type: 'string',\n description:\n 'The fact itself, in one sentence, stated so it still makes sense in a conversation months from now.',\n },\n },\n} as const;\n\nfunction issue(path: (string | number)[], message: string) {\n return { message, path };\n}\n\n/**\n * The `remember` tool's input schema. Hand-written for the same reason `askInputSchema` and\n * `skillInputSchema` are: core depends on no validator and has to publish a JSON Schema a provider\n * can constrain generation against.\n *\n * THERE IS NO SCOPE PARAMETER, and that is the enforcement rather than a simplification. An agent\n * may only ever write the actor it is running for (see {@link memoryWriteVerdict}), so a scope\n * argument could only ever be a request that gets refused — and a refusable request is one a model\n * will keep making, and one a future reader will be tempted to make grantable.\n */\nexport const rememberInputSchema = {\n '~standard': {\n version: 1,\n vendor: 'nestjs-agent',\n validate: (value: unknown) => {\n if (typeof value !== 'object' || value === null) {\n return { issues: [issue([], 'must be an object')] };\n }\n const candidate = value as Partial<RememberToolInput>;\n if (typeof candidate.key !== 'string' || candidate.key.length === 0) {\n return { issues: [issue(['key'], 'must be a non-empty string')] };\n }\n if (typeof candidate.fact !== 'string' || candidate.fact.length === 0) {\n return { issues: [issue(['fact'], 'must be a non-empty string')] };\n }\n return { value: { key: candidate.key, fact: candidate.fact } };\n },\n jsonSchema: { input: () => REMEMBER_JSON_SCHEMA },\n },\n} as unknown as StandardSchemaV1<unknown, RememberToolInput>;\n\nexport const REMEMBER_TOOL_DESCRIPTION =\n 'Record one durable fact about this user under a key, so later conversations start knowing it. For things that will still be true another day — how they work, what their organisation requires, a correction they made. Not for what this conversation is about, and not for anything you were not told or could not reasonably infer. The user can read and delete everything you record here.';\n\n/**\n * The `remember` tool as the model sees it. NOT a `ToolSpec` and never registered, exactly like\n * `ask` and `skill`: it has no handler, because the loop serves it against the digest the journal\n * holds. Keeping it out of the `ToolRegistry` is also what keeps its kind off a process-local\n * lookup — see `claimToolCall`.\n */\nexport function rememberToolDefinition(): ToolDefinition {\n return {\n name: REMEMBER_TOOL_NAME,\n kind: 'memory',\n description: REMEMBER_TOOL_DESCRIPTION,\n inputSchema: rememberInputSchema,\n };\n}\n\n/**\n * Append the built-in `remember` definition to a turn's tool list. Exported because the dispatched\n * llm step re-derives the tool list on a worker and has to reach the same list the loop would have.\n */\n/** Arguments to {@link withMemoryTool}. */\nexport interface WithMemoryToolInput {\n tools: ToolDefinition[];\n /** Whether this deployment's provider can write at all — module config, uniform across its pods. */\n enabled: boolean;\n}\n\nexport function withMemoryTool({ tools, enabled }: WithMemoryToolInput): ToolDefinition[] {\n return enabled ? [...tools, rememberToolDefinition()] : tools;\n}\n\n/** Who is trying to write a memory. */\nexport interface MemoryAuthor {\n /**\n * `'human'` is a person acting through a UI; `'agent'` is anything else — a turn, a tool, a batch\n * job. The distinction is the whole of rule three below, so it is not inferable and has to be\n * stated by the caller.\n */\n kind: 'human' | 'agent';\n actorRef?: string;\n}\n\n/** A request to write a memory at a scope. */\nexport interface MemoryWriteRequest {\n scope: string;\n actor: Actor;\n /** The actor's resolved scopes, most specific first — the same list the turn drew its digest from. */\n scopes: readonly string[];\n author: MemoryAuthor;\n /**\n * The host's own answer to \"may this person administer that scope\". This library cannot know it,\n * and inventing an answer would be a second, weaker authorization model next to the host's real\n * one. Undefined/false → a wider scope is refused.\n */\n elevated?: boolean;\n}\n\nexport type MemoryVerdict = { allowed: true } | { allowed: false; reason: string };\n\n/**\n * May this author write a memory at this scope?\n *\n * The same four rules as `skillWriteVerdict`, deliberately duplicated rather than shared: they are\n * the same rules about two different things, and folding them into one function would mean a future\n * change to how skills are authored silently changing who may edit what the assistant believes about\n * a person. Rule three is the one that matters, and it bites harder here than it does for skills:\n *\n * 1. You may only write into a scope you are yourself in.\n * 2. Your OWN scope is yours. A memory at `actor:<you>` affects exactly one prompt — your own.\n * 3. NOTHING BUT A HUMAN MAY WRITE ABOVE ITS OWN SCOPE, whatever `elevated` says. A skill an agent\n * could publish at `tenant:` is a procedure anyone in the tenant can edit by talking to the\n * assistant; a MEMORY it could publish there is a fact everyone in the tenant is then answered\n * from, with no document to inspect and nobody aware it was written. An agent that has genuinely\n * learned something the organisation should know proposes it; a person publishes it.\n * 4. A human writing above their own scope needs the host to say so (`elevated`).\n */\nexport function memoryWriteVerdict(request: MemoryWriteRequest): MemoryVerdict {\n const { scope, scopes, author, actor } = request;\n if (!scopes.includes(scope)) {\n return { allowed: false, reason: `\"${scope}\" is not a scope this actor belongs to` };\n }\n const own = actorScope(actor);\n if (scope === own) {\n return { allowed: true };\n }\n if (author.kind !== 'human') {\n return {\n allowed: false,\n reason: `only a human may write a memory at \"${scope}\"; an agent may write only at \"${own}\"`,\n };\n }\n return request.elevated === true\n ? { allowed: true }\n : { allowed: false, reason: `writing at \"${scope}\" requires an elevated human author` };\n}\n\n/**\n * May this actor delete this memory?\n *\n * Narrower than the write rule on purpose, and it takes no `elevated` flag. Deleting what the\n * assistant believes about YOU needs no permission from anyone — that is the point of the read-back\n * — so the endpoint that serves it must not be able to ask a host a question it might answer no to.\n * Deleting what it believes about a tenant is an administrative act on shared state, which belongs\n * in the host's console with the same elevation a write there needs.\n */\n/** A request to delete one memory. */\nexport interface MemoryForgetRequest {\n record: Pick<MemoryRecord, 'scope'>;\n actor: Actor;\n}\n\nexport function memoryForgetVerdict({ record, actor }: MemoryForgetRequest): MemoryVerdict {\n return record.scope === actorScope(actor)\n ? { allowed: true }\n : {\n allowed: false,\n reason: `\"${record.scope}\" is not this actor's own scope; deleting it is an administrative action`,\n };\n}\n\n/** What a `remember` call resolved to — the stored record, or why nothing was stored. */\nexport type MemoryWriteOutcome = { ok: true; record: MemoryRecord } | { ok: false; error: string };\n\n/**\n * Serve one `remember` call against the digest THIS TURN resolved.\n *\n * The digest's `scopes` are the authorization boundary, not the resolver: they came out of the\n * `memory:digest` checkpoint, so a write is checked against the scopes the run recorded rather than\n * the ones a replaying process's resolver would produce now. A membership table edited mid-run\n * cannot retroactively widen — or narrow — what a turn already in flight is allowed to write.\n */\n/** Arguments to {@link writeMemory}. */\nexport interface WriteMemoryInput {\n config: MemoryConfig;\n /** The digest THIS TURN journaled — the authorization boundary, never a fresh resolution. */\n digest: MemoryDigest;\n /** The `remember` call as the model made it. */\n call: RememberToolInput;\n ctx: ScopeContext;\n runId: string;\n}\n\nexport async function writeMemory({\n config,\n digest,\n call,\n ctx,\n runId,\n}: WriteMemoryInput): Promise<MemoryWriteOutcome> {\n // Bound, not detached. A provider is normally a CLASS — a Nest `@Injectable()` holding a\n // repository on `this` — and `const write = provider.write` hands back a function that has lost\n // its receiver, so the first `this.` inside it throws a TypeError the tool reports as a failed\n // call. Every provider in this repo's own tests is an object literal of arrow functions, which is\n // why that went unseen: they never need a receiver.\n const write = config.provider.write?.bind(config.provider);\n if (write === undefined) {\n return { ok: false, error: 'Memory is read-only in this deployment.' };\n }\n const key = call.key.trim();\n const text = call.fact.trim();\n if (key.length === 0 || text.length === 0) {\n return { ok: false, error: 'A memory needs both a key and a fact.' };\n }\n const maxFactChars = config.maxFactChars ?? DEFAULT_MAX_FACT_CHARS;\n if (text.length > maxFactChars) {\n return {\n ok: false,\n error: `A memory must be at most ${maxFactChars} characters; that was ${text.length}. State the fact more briefly.`,\n };\n }\n const scope = actorScope(ctx.actor);\n const verdict = memoryWriteVerdict({\n scope,\n actor: ctx.actor,\n scopes: digest.scopes,\n author: { kind: 'agent', actorRef: ctx.actor.id },\n });\n if (!verdict.allowed) {\n return { ok: false, error: verdict.reason };\n }\n const record = await write({\n key,\n text,\n scope,\n origin: { author: 'agent', threadId: ctx.threadId, runId, actorRef: ctx.actor.id },\n ctx,\n });\n return { ok: true, record };\n}\n","import type { AgentDefinition } from './types.js';\n\n/** Holds the named agent definitions registered via `AgentModule.forFeature([...])`. */\nexport class AgentRegistry {\n private readonly definitions = new Map<string, AgentDefinition>();\n\n register(definition: AgentDefinition): void {\n this.definitions.set(definition.name, definition);\n }\n\n get(name: string): AgentDefinition | undefined {\n return this.definitions.get(name);\n }\n\n has(name: string): boolean {\n return this.definitions.has(name);\n }\n\n list(): AgentDefinition[] {\n return [...this.definitions.values()];\n }\n}\n","/**\n * Is this the durable runtime refusing a checkpoint position, rather than anything the agent did?\n *\n * Matched by NAME because this package cannot import either class: the in-process engine throws\n * `@dudousxd/nestjs-durable-core`'s `NonDeterminismError` and the thin BullMQ worker throws\n * `@dudousxd/nestjs-durable-worker`'s `NondeterminismError` — the same contract under two spellings\n * in two packages, neither of which core depends on. Same cross-runtime reasoning as the\n * `isControlFlowError` hook, which exists for exactly this reason on the suspend path.\n *\n * Suffix rather than equality, because a runtime is free to qualify the name: the sibling Adonis\n * stack raises a `WorkflowNondeterminismError` from its remote-replay path, which an equality check\n * would wave through as an ordinary tool failure. `replay-integrity.contract.spec.ts` pins this\n * against the real exported classes, so a rename upstream fails a test instead of quietly\n * disarming the guard.\n *\n * Callers must let these through untouched. Every `catch` in a workflow body reacts by writing more\n * checkpoints (a toolfail, a run-end, a deactivate), and on a journal that has already diverged each\n * of those asks for a position the history cannot supply — so the recovery attempt raises its own\n * refusal, and THAT is the error the operator reads: a message pointing at the wrong seq, naming\n * checkpoints from the recovery path rather than the two that actually disagreed.\n */\nexport function isReplayIntegrityError(error: unknown): boolean {\n return error instanceof Error && error.name.toLowerCase().endsWith('nondeterminismerror');\n}\n","/**\n * The durable runtime's marker for a CONTROL-FLOW signal — a suspend or a continue-as-new, thrown to\n * unwind the current turn, never a failure. Declared here as a bare `Symbol.for` rather than\n * imported, for the same reason `replay-integrity.ts` matches by name: core depends on neither\n * durable package and must not, since the inline runner has to work with neither installed. The\n * duplication is safe precisely because the key is in the GLOBAL registry — the string IS the\n * contract, and a locally-declared copy collapses onto the identical symbol across duplicate module\n * copies, dual ESM/CJS loads, and the two packages that raise these signals under different class\n * names (`@dudousxd/nestjs-durable-core`'s `WorkflowSuspended`/`ContinueAsNew`, the BullMQ thin\n * worker's `Suspend`).\n */\nconst CONTROL_FLOW_SIGNAL = Symbol.for('aviary:durable:control-flow');\n\n/**\n * Is this the runner unwinding the turn (a durable suspend / continue-as-new) rather than something\n * the agent did? Callers must rethrow it untouched: every `catch` in the loop reacts by writing more\n * checkpoints, and a suspend recorded as a tool failure leaves a journal the resumed replay cannot\n * line up with.\n *\n * Detected from the error itself so a host that never wired `AgentLoopHooks.isControlFlowError` still\n * gets its suspends through — that hook is an override for a runner whose signals carry no marker,\n * not the only line of defence. Checked as a stamped property, NOT `instanceof`: the classes differ\n * per runtime, which is why the marker exists.\n */\nexport function isControlFlowSignal(error: unknown): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n (error as { [CONTROL_FLOW_SIGNAL]?: unknown })[CONTROL_FLOW_SIGNAL] === true\n );\n}\n","import type { ModelMessage, ToolCallStatus, ToolResult } from './types.js';\n\n/**\n * What a store knows about a tool call, read back when its message carries no result for it — see\n * {@link import('./spi/agent-store.js').AgentStore.toolCallOutcomes}.\n */\nexport interface ToolCallOutcome {\n id: string;\n status: ToolCallStatus;\n output?: unknown;\n error?: string;\n}\n\n/** What the model is told about a call whose turn died before the call was settled. */\nexport const UNFINISHED_TOOL_CALL =\n 'This tool call was never completed: the turn it belonged to ended unexpectedly before it was ' +\n 'settled. Do not assume it ran, and do not assume it did not — check the current state with a ' +\n 'read tool if one exists, tell the person plainly what is and is not confirmed, and do it again ' +\n 'only if they still want it.';\n\n/** What is written on the row of a call whose run ended without settling it. */\nexport const RUN_ENDED_BEFORE_TOOL_CALL = 'the run ended before this tool call was settled';\n\nconst DECLINED =\n 'The person was asked to approve this action and declined it. Nothing ran and nothing changed.';\nconst EXPIRED =\n 'This action needed approval, and the request expired before anyone decided. Nothing ran.';\n\n/** The ids of every tool call in `messages` that the message asking for it holds no result for. */\nexport function danglingToolCallIds(messages: readonly ModelMessage[]): string[] {\n const ids: string[] = [];\n for (const message of messages) {\n const calls = message.toolCalls ?? [];\n if (message.role !== 'assistant' || calls.length === 0) {\n continue;\n }\n const settled = new Set((message.toolResults ?? []).map((result) => result.id));\n for (const call of calls) {\n if (!settled.has(call.id)) {\n ids.push(call.id);\n }\n }\n }\n return ids;\n}\n\nfunction resultFor(\n call: { id: string; name: string },\n outcome: ToolCallOutcome | undefined,\n): ToolResult {\n const base = { id: call.id, name: call.name };\n switch (outcome?.status) {\n case 'executed':\n case 'auto_executed':\n return { ...base, output: outcome.output ?? null };\n case 'failed':\n return { ...base, output: null, error: outcome.error ?? UNFINISHED_TOOL_CALL };\n case 'rejected':\n return { ...base, output: { rejected: true }, denied: true, error: DECLINED };\n case 'expired':\n return {\n ...base,\n output: { rejected: true, expired: true },\n denied: true,\n expired: true,\n error: EXPIRED,\n };\n default:\n return { ...base, output: null, error: UNFINISHED_TOOL_CALL };\n }\n}\n\n/**\n * Give every tool call in a thread's history a result.\n *\n * A turn writes its results onto the assistant message once the step's LAST tool has settled. A turn\n * that dies before that — its run failed, its worker was killed, an approval was never answered and\n * the run was abandoned — leaves an assistant message that asks for tools and is answered by\n * nothing. A provider refuses a prompt shaped like that (a tool call must be followed by its\n * result), so every LATER turn on the thread fails too, with an error about the stream rather than\n * about the history: one dead turn makes the whole conversation unusable.\n *\n * Here each such call is settled from what is actually known: the call's own row where the store\n * can read it (`outcomes` — a tool that DID run hands the model its real output, so it is not run a\n * second time), and otherwise a result saying the call was never completed. Pure: the same messages\n * and outcomes always produce the same prompt, so a replay composes what the first attempt did.\n * Messages with nothing dangling are returned as they are.\n */\nexport function settleDanglingToolCalls(\n messages: ModelMessage[],\n outcomes: readonly ToolCallOutcome[] = [],\n): ModelMessage[] {\n const known = new Map(outcomes.map((outcome) => [outcome.id, outcome]));\n return messages.map((message) => {\n const calls = message.toolCalls ?? [];\n if (message.role !== 'assistant' || calls.length === 0) {\n return message;\n }\n const results = message.toolResults ?? [];\n const settled = new Set(results.map((result) => result.id));\n const missing = calls.filter((call) => !settled.has(call.id));\n if (missing.length === 0) {\n return message;\n }\n return {\n ...message,\n toolResults: [...results, ...missing.map((call) => resultFor(call, known.get(call.id)))],\n };\n });\n}\n","import { RUN_ENDED_BEFORE_TOOL_CALL } from './dangling-tool-calls.js';\nimport type { AgentStore } from './spi/agent-store.js';\nimport { releaseThreadRun } from './spi/chat-queue.js';\n\n/** The `code` a decision answers with when the run it was for is over (`409`). */\nexport const RUN_NOT_ACTIVE_CODE = 'run_not_active';\n\n/** What a person is told when they decide on a request whose run is over. */\nexport const RUN_NOT_ACTIVE_MESSAGE =\n 'This request is no longer waiting for an answer: the turn it belonged to has ended. Send the message again.';\n\n/** What is written on the row of a run that was found over without having said so itself. */\nexport const RUN_NO_LONGER_RUNNING = 'the run is no longer running';\n\nexport interface SettleDeadRunInput {\n runId: string;\n /** Set for a thread's own turn: the thread is released if this run still holds it. */\n threadId?: string;\n /**\n * Settle the run ROW as `failed` with this. Pass it only where the caller KNOWS the run failed\n * (the run's own body, unwinding). `recordRunEnd` is last-write-wins, so a caller that only knows\n * the run is no longer running — it may have completed — must leave the row alone.\n */\n failure?: { code: string; message: string };\n}\n\n/**\n * Leave nothing waiting on a run that is over and did not say so itself.\n *\n * A run normally settles its own row, its calls and its thread from inside its body. One that is\n * refused a checkpoint position, or whose worker died, never gets there: a call it had put to a\n * person stays `pending_approval` — an approval card that takes a \"yes\" and then does nothing, for\n * ever — and its thread stays pointed at it. Everything here is written straight to the store,\n * outside any checkpoint, because the callers are exactly the paths that have no journal left to\n * write to; each write is idempotent (only still-pending calls, a release conditional on the\n * holder), so doing it twice changes nothing.\n *\n * Best-effort on purpose: this runs while something else is already failing, and must not replace\n * that failure with one of its own.\n */\nexport async function settleDeadRun(store: AgentStore, input: SettleDeadRunInput): Promise<void> {\n const failure = input.failure;\n if (failure !== undefined) {\n await Promise.resolve(\n store.recordRunEnd?.({\n runId: input.runId,\n status: 'failed',\n errorCode: failure.code,\n errorMessage: failure.message,\n }),\n ).catch(() => undefined);\n }\n await Promise.resolve(\n store.failUnsettledToolCalls?.(input.runId, RUN_ENDED_BEFORE_TOOL_CALL),\n ).catch(() => 0);\n if (input.threadId !== undefined) {\n await releaseThreadRun(store, input.threadId, input.runId).catch(() => undefined);\n }\n}\n","import type { AgentStore } from './spi/agent-store.js';\nimport type { AgentDelegation, DetachedDelivery } from './types.js';\n\n/** An agent->agent edge with its awaited-or-not resolved, whichever form it was authored in. */\nexport interface ResolvedDelegation {\n agent: string;\n detached: boolean;\n}\n\n/** Read one {@link AgentDelegation} entry in either of its forms. */\nexport function normalizeDelegation(entry: AgentDelegation): ResolvedDelegation {\n return typeof entry === 'string'\n ? { agent: entry, detached: false }\n : { agent: entry.agent, detached: entry.detached === true };\n}\n\n/**\n * What a detached delegation hands the model in place of an answer. Its `status` is the whole point:\n * a model that is given an object shaped like a result will report one, and this run has none yet.\n */\nexport interface DetachedDelegationReceipt {\n detached: true;\n status: 'started';\n /** The agent now working on it. */\n agent: string;\n /** The run doing the work — what a client subscribes to, and what stamps the delivered message. */\n runId: string;\n /**\n * The same fact in the only vocabulary the model reliably acts on: prose in a tool result. The\n * structured fields above are for a client; this is for the turn that has to explain itself to a\n * user without claiming a result it does not hold.\n */\n note: string;\n}\n\n/** How a detached delegation ended, written back onto its tool-call row once the run settles. */\nexport interface DetachedDelegationOutcome {\n detached: true;\n status: 'delivered' | 'failed' | 'cancelled';\n agent: string;\n runId: string;\n /** The delivered answer. Present on `delivered` only. */\n text?: string;\n /** Why it did not deliver. Present on `failed` only. */\n error?: string;\n}\n\n/** The receipt an `agent`-kind call returns the moment its delegate is under way. */\nexport function detachedStarted(args: { agent: string; runId: string }): DetachedDelegationReceipt {\n return {\n detached: true,\n status: 'started',\n agent: args.agent,\n runId: args.runId,\n note: `The \"${args.agent}\" agent is now working on this in the background. Its answer is NOT part of this turn and will arrive in this conversation as a separate message when it is ready. Tell the user the work has started; do not state or guess what it will find.`,\n };\n}\n\n/** The outcome written onto the delegating tool call when a detached run finishes its answer. */\nexport function detachedDelivered(args: {\n agent: string;\n runId: string;\n text: string;\n}): DetachedDelegationOutcome {\n return {\n detached: true,\n status: 'delivered',\n agent: args.agent,\n runId: args.runId,\n text: args.text,\n };\n}\n\n/**\n * The outcome written onto the delegating tool call when a detached run never produced an answer.\n * Written by the RUNNER, not the loop: a run that crashed or was stopped cannot record its own\n * ending, and a delegation card that stays \"started\" for ever is the one state a reader cannot act\n * on.\n */\nexport function detachedUnsettled(args: {\n agent: string;\n runId: string;\n status: 'failed' | 'cancelled';\n error?: string;\n}): DetachedDelegationOutcome {\n return {\n detached: true,\n status: args.status,\n agent: args.agent,\n runId: args.runId,\n ...(args.error !== undefined ? { error: args.error } : {}),\n };\n}\n\n/**\n * Settle the delegation a detached run was started for when that run ends with no answer.\n *\n * Two writes, because a reader needs both: the tool-call row so a governance surface stops counting\n * it as in flight, and a MESSAGE in the delegating thread so the person who asked finds out. A\n * delivered answer already arrives as a message; without this, the failure is the one outcome that\n * silently never does, and the conversation shows \"started\" for ever.\n *\n * Called by the RUNNER, never the loop — a run that crashed or was stopped cannot record its own\n * ending. Skipped entirely when the thread is gone, for the same reason delivery is.\n *\n * Settles ONCE: a thread that already holds a message from this run (its answer, or an earlier\n * settlement) is left alone. A Stop can be settled from two places — the run's own body when it\n * observes the cancel, and the runner for a run parked where its body never runs again — and a\n * Stop on a run that already answered must not write \"stopped\" under its answer.\n */\nexport async function settleUnsettledDelegation(args: {\n store: AgentStore;\n delivery: DetachedDelivery;\n agent: string;\n runId: string;\n status: 'failed' | 'cancelled';\n error?: string;\n}): Promise<void> {\n const { store, delivery, agent, runId, status } = args;\n const thread = await store.getThread(delivery.threadId);\n if (thread === null || thread.messages.some((message) => message.runId === runId)) {\n return;\n }\n await store.appendMessage({\n threadId: delivery.threadId,\n role: 'assistant',\n content:\n status === 'cancelled'\n ? `The \"${agent}\" agent was stopped before it could answer.`\n : `The \"${agent}\" agent stopped before it could answer: ${args.error ?? 'unknown error'}`,\n agentName: agent,\n runId,\n });\n await store.updateToolCall({\n toolCallId: delivery.toolCallId,\n status: 'executed',\n output: detachedUnsettled({\n agent,\n runId,\n status,\n ...(args.error !== undefined ? { error: args.error } : {}),\n }),\n });\n}\n","import type { ClaimActionProposal } from './spi/action-proposal-store.js';\n\nexport function validateActionProposalWorkerClaim(command: ClaimActionProposal, now: number): void {\n if (!Number.isSafeInteger(now)) throw new RangeError('Invalid action proposal clock');\n if (typeof command.workerId !== 'string' || command.workerId.length === 0)\n throw new TypeError('workerId must be a nonempty string');\n if (\n !Number.isSafeInteger(command.leaseMs) ||\n command.leaseMs <= 0 ||\n !Number.isSafeInteger(now + command.leaseMs)\n )\n throw new RangeError('leaseMs must be positive safe integer milliseconds');\n}\n\nexport function validateActionProposalExpiryBatch(command: { limit: number }, now: number): void {\n if (!Number.isSafeInteger(now)) throw new RangeError('Invalid action proposal clock');\n validateActionProposalDiscoveryIndexBatch(command);\n}\n\nexport function validateActionProposalDiscoveryIndexBatch(command: { limit: number }): void {\n if (!Number.isInteger(command.limit) || command.limit < 1 || command.limit > 1000)\n throw new RangeError('limit must be an integer from 1 to 1000');\n}\n","import { validateActionProposalWorkerClaim } from './action-proposal-discovery.js';\nimport { snapshotActionProposal } from './action-proposal-transitions.js';\nimport type {\n ActionProposalOutcome,\n ActionProposalOutcomeLease,\n} from './spi/action-proposal-outcome-store.js';\nimport type { ActionProposal, ActionProposalScope } from './spi/action-proposal-store.js';\nimport type { AgentUiComponent } from './stream-events.js';\n\nexport function attachActionProposalOutcome(\n row: ActionProposal,\n now: number,\n ui: AgentUiComponent[] = [],\n text?: string,\n): ActionProposal {\n if (row.outcome) return row;\n const execution = row.execution;\n const outcome: ActionProposalOutcome = {\n id: `${row.id}:outcome:1`,\n proposalId: row.id,\n outcomeVersion: 1,\n tenantRef: row.tenantRef,\n actorRef: row.actorRef,\n threadId: row.threadId,\n originRunId: row.originRunId,\n originToolCallId: row.originToolCallId,\n toolName: row.toolName,\n decision: row.decision,\n ui,\n createdAt: now,\n ...(text !== undefined ? { text } : {}),\n ...(execution?.status === 'succeeded' || execution?.status === 'failed'\n ? { executionStatus: execution.status }\n : {}),\n ...(execution && Object.hasOwn(execution, 'result') ? { result: execution.result } : {}),\n ...(execution?.error !== undefined\n ? { error: execution.error }\n : row.decisionAudit?.reason !== undefined\n ? { error: row.decisionAudit.reason }\n : {}),\n };\n return snapshotActionProposal({\n ...row,\n outcome,\n outcomeDelivery: { status: 'pending', generation: 0, lease: null },\n });\n}\nexport function claimActionProposalOutcome(\n row: ActionProposal,\n command: { workerId: string; leaseMs: number },\n now: number,\n token: string,\n): ActionProposal | null {\n validateActionProposalWorkerClaim(command, now);\n const delivery = row.outcomeDelivery;\n if (\n !row.outcome ||\n !delivery ||\n delivery.status !== 'pending' ||\n (delivery.lease && now < delivery.lease.expiresAt)\n )\n return null;\n const generation = delivery.generation + 1;\n return snapshotActionProposal({\n ...row,\n outcomeDelivery: {\n ...delivery,\n generation,\n lease: { token, generation, workerId: command.workerId, expiresAt: now + command.leaseMs },\n },\n });\n}\nexport function actionProposalOutcomeFenceValid(\n row: ActionProposal,\n command: ActionProposalOutcomeLease,\n now: number,\n): boolean {\n if (!Number.isSafeInteger(now)) throw new RangeError('Invalid server clock');\n if (\n typeof command.token !== 'string' ||\n !command.token ||\n !Number.isSafeInteger(command.generation) ||\n command.generation < 1 ||\n typeof command.outcomeId !== 'string' ||\n !command.outcomeId\n )\n throw new TypeError('Invalid outcome fence');\n const delivery = row.outcomeDelivery;\n return (\n row.outcome?.id === command.outcomeId &&\n delivery?.status === 'pending' &&\n delivery.generation === command.generation &&\n delivery.lease?.token === command.token &&\n delivery.lease.generation === command.generation &&\n now < delivery.lease.expiresAt\n );\n}\nfunction outcomeSummary(outcome: ActionProposalOutcome): string {\n if (outcome.executionStatus === 'succeeded')\n return `Action ${JSON.stringify(outcome.toolName)} completed (proposal ${JSON.stringify(outcome.proposalId)}).${Object.hasOwn(outcome, 'result') ? ` Result: ${JSON.stringify(outcome.result)}` : ''}`;\n if (outcome.executionStatus === 'failed')\n return `Action ${JSON.stringify(outcome.toolName)} failed (proposal ${JSON.stringify(outcome.proposalId)}): ${JSON.stringify(outcome.error ?? 'Execution failed')}`;\n return `Action ${JSON.stringify(outcome.toolName)} was ${outcome.decision} (proposal ${JSON.stringify(outcome.proposalId)}) and was not executed.${outcome.error ? ` Reason: ${JSON.stringify(outcome.error)}` : ''}`;\n}\nexport function actionProposalOutcomeScope(outcome: ActionProposalOutcome): ActionProposalScope {\n return { tenantRef: outcome.tenantRef, actorRef: outcome.actorRef, threadId: outcome.threadId };\n}\n\nexport function actionProposalOutcomeText(outcome: ActionProposalOutcome): string {\n return outcomeSummary(outcome) + (outcome.text ? ` UI: ${JSON.stringify(outcome.text)}` : '');\n}\n","import type { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec';\n\n/** A JSON Schema document (draft-07 / 2020-12 subset). Plain data, so a catalog can be stored and shipped. */\nexport type JsonSchema = Record<string, unknown>;\n\n/** One problem with a value, addressed by its path from the root of the value. */\nexport interface GenuiIssue {\n path: (string | number)[];\n message: string;\n}\n\nexport type GenuiValidation<T = unknown> =\n | { ok: true; value: T }\n | { ok: false; issues: GenuiIssue[] };\n\n/**\n * Validates a value against a JSON Schema. The package ships {@link builtinJsonSchemaValidator} (a\n * dependency-free subset that covers what component props use); pass {@link ajvValidator} to a\n * catalog for full JSON Schema.\n */\nexport interface JsonSchemaValidator {\n validate(schema: JsonSchema, value: unknown): GenuiIssue[];\n}\n\n/** A component's props schema: any Standard Schema (Zod, Valibot, ArkType) or a JSON Schema object. */\nexport type PropsSchema = StandardSchemaV1 | JsonSchema;\n\nexport function isStandardSchema(schema: unknown): schema is StandardSchemaV1 {\n return (\n typeof schema === 'object' &&\n schema !== null &&\n '~standard' in schema &&\n typeof (schema as StandardSchemaV1)['~standard']?.validate === 'function'\n );\n}\n\n/**\n * The JSON Schema a props schema presents to a model: the schema itself for a JSON Schema, the\n * Standard JSON Schema converter's output for a Standard Schema that has one (Zod 4, Valibot,\n * ArkType). `undefined` when neither is available (e.g. Zod 3) — the model then gets the\n * component's description only.\n */\nexport function toJsonSchema(schema: PropsSchema): JsonSchema | undefined {\n if (!isStandardSchema(schema)) {\n return schema;\n }\n const standard = schema['~standard'] as StandardSchemaV1['~standard'] &\n Partial<StandardJSONSchemaV1['~standard']>;\n const converter = standard.jsonSchema;\n if (converter === undefined || typeof converter.input !== 'function') {\n return undefined;\n }\n try {\n return converter.input({ target: 'draft-07' });\n } catch {\n return undefined;\n }\n}\n\n/** Validate against either kind of props schema. A Standard Schema's own (possibly transformed) output wins. */\nexport async function validateProps(\n schema: PropsSchema,\n value: unknown,\n validator: JsonSchemaValidator,\n): Promise<GenuiValidation> {\n if (isStandardSchema(schema)) {\n const result = await schema['~standard'].validate(value);\n if (result.issues !== undefined) {\n return { ok: false, issues: toGenuiIssues(result.issues) };\n }\n return { ok: true, value: result.value };\n }\n const issues = validator.validate(schema, value);\n return issues.length > 0 ? { ok: false, issues } : { ok: true, value };\n}\n\n/**\n * {@link validateProps} without waiting: the verdict when it is available synchronously (always\n * for JSON Schema, and for every Standard Schema whose `validate` does not return a promise — Zod,\n * Valibot and ArkType all answer synchronously for synchronous schemas), `undefined` otherwise. What\n * a renderer uses to decide on its first paint instead of flashing a placeholder.\n */\nexport function validatePropsSync(\n schema: PropsSchema,\n value: unknown,\n validator: JsonSchemaValidator,\n): GenuiValidation | undefined {\n if (!isStandardSchema(schema)) {\n const issues = validator.validate(schema, value);\n return issues.length > 0 ? { ok: false, issues } : { ok: true, value };\n }\n const result = schema['~standard'].validate(value);\n if (result instanceof Promise) {\n result.catch(() => undefined);\n return undefined;\n }\n return result.issues !== undefined\n ? { ok: false, issues: toGenuiIssues(result.issues) }\n : { ok: true, value: result.value };\n}\n\nfunction toGenuiIssues(issues: readonly StandardSchemaV1.Issue[]): GenuiIssue[] {\n return issues.map((issue) => ({\n path: (issue.path ?? []).map((segment) =>\n typeof segment === 'object' && segment !== null && 'key' in segment\n ? (segment.key as string | number)\n : (segment as string | number),\n ),\n message: issue.message,\n }));\n}\n\n/** `a.b[0].c: message; …` — what a model is handed back when its props were refused. */\nexport function formatIssues(issues: readonly GenuiIssue[]): string {\n return issues\n .map(\n (issue) => `${issue.path.length > 0 ? formatPath(issue.path) : '(root)'}: ${issue.message}`,\n )\n .join('; ');\n}\n\nfunction formatPath(path: readonly (string | number)[]): string {\n return path\n .map((segment, index) =>\n typeof segment === 'number' ? `[${segment}]` : index === 0 ? segment : `.${segment}`,\n )\n .join('');\n}\n\n/**\n * Structural type of an Ajv instance, so the package never imports Ajv: `new Ajv({ allErrors: true })`\n * satisfies it.\n */\nexport interface AjvLike {\n compile(schema: object): ((data: unknown) => boolean | Promise<unknown>) & {\n errors?: { instancePath?: string; message?: string }[] | null;\n };\n}\n\n/**\n * Full JSON Schema validation through the app's own Ajv instance. Compiled validators are cached\n * per schema object.\n */\nexport function ajvValidator(ajv: AjvLike): JsonSchemaValidator {\n const compiled = new WeakMap<object, ReturnType<AjvLike['compile']>>();\n return {\n validate(schema, value) {\n let fn = compiled.get(schema);\n if (fn === undefined) {\n fn = ajv.compile(schema);\n compiled.set(schema, fn);\n }\n if (fn(value) === true) {\n return [];\n }\n return (fn.errors ?? []).map((error) => ({\n path: (error.instancePath ?? '')\n .split('/')\n .filter((segment) => segment.length > 0)\n .map((segment) => {\n const decoded = segment.replace(/~1/g, '/').replace(/~0/g, '~');\n return /^\\d+$/.test(decoded) ? Number(decoded) : decoded;\n }),\n message: error.message ?? 'is invalid',\n }));\n },\n };\n}\n\n/**\n * A dependency-free JSON Schema validator for the keywords component props actually use: `type`\n * (incl. `integer`, `null`, type arrays), `enum`, `const`, `properties`, `required`,\n * `additionalProperties`, `items`, `minItems`/`maxItems`, `minLength`/`maxLength`/`pattern`,\n * `minimum`/`maximum`, `anyOf`/`oneOf`/`allOf`, `not`, and local `$ref`s (`#`, `#/$defs/…`,\n * `#/definitions/…`). Unknown keywords (e.g. `format`) are ignored. Use {@link ajvValidator} when\n * you need the rest.\n */\nexport const builtinJsonSchemaValidator: JsonSchemaValidator = {\n validate(schema, value) {\n const issues: GenuiIssue[] = [];\n check(schema, value, [], schema, issues, 0);\n return issues;\n },\n};\n\nconst MAX_DEPTH = 64;\n\nfunction typeOf(value: unknown): string {\n if (value === null) return 'null';\n if (Array.isArray(value)) return 'array';\n return typeof value;\n}\n\nfunction matchesType(type: string, value: unknown): boolean {\n switch (type) {\n case 'integer':\n return typeof value === 'number' && Number.isInteger(value);\n case 'number':\n return typeof value === 'number' && Number.isFinite(value);\n case 'object':\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n default:\n return typeOf(value) === type;\n }\n}\n\nfunction resolveRef(root: JsonSchema, ref: string): JsonSchema | undefined {\n if (ref === '#') return root;\n if (!ref.startsWith('#/')) return undefined;\n let current: unknown = root;\n for (const raw of ref.slice(2).split('/')) {\n const key = raw.replace(/~1/g, '/').replace(/~0/g, '~');\n if (typeof current !== 'object' || current === null) return undefined;\n current = (current as Record<string, unknown>)[key];\n }\n return typeof current === 'object' && current !== null ? (current as JsonSchema) : undefined;\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n return keysA.every((key) =>\n deepEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key]),\n );\n}\n\nfunction check(\n schema: unknown,\n value: unknown,\n path: (string | number)[],\n root: JsonSchema,\n issues: GenuiIssue[],\n depth: number,\n): void {\n if (schema === true || schema === undefined) return;\n if (schema === false) {\n issues.push({ path, message: 'is not allowed' });\n return;\n }\n if (typeof schema !== 'object' || schema === null) return;\n if (depth > MAX_DEPTH) {\n issues.push({ path, message: 'is nested too deeply' });\n return;\n }\n const s = schema as Record<string, unknown>;\n\n if (typeof s.$ref === 'string') {\n const target = resolveRef(root, s.$ref);\n if (target === undefined) {\n issues.push({ path, message: `references unknown schema ${s.$ref}` });\n return;\n }\n check(target, value, path, root, issues, depth + 1);\n }\n\n if (s.type !== undefined) {\n const types = Array.isArray(s.type) ? (s.type as string[]) : [s.type as string];\n if (!types.some((type) => matchesType(type, value))) {\n issues.push({ path, message: `must be ${types.join(' or ')}` });\n return;\n }\n }\n if (Array.isArray(s.enum) && !s.enum.some((option) => deepEqual(option, value))) {\n issues.push({\n path,\n message: `must be one of ${s.enum.map((option) => JSON.stringify(option)).join(', ')}`,\n });\n }\n if ('const' in s && !deepEqual(s.const, value)) {\n issues.push({ path, message: `must be ${JSON.stringify(s.const)}` });\n }\n\n if (typeof value === 'string') {\n if (typeof s.minLength === 'number' && value.length < s.minLength) {\n issues.push({ path, message: `must be at least ${s.minLength} characters` });\n }\n if (typeof s.maxLength === 'number' && value.length > s.maxLength) {\n issues.push({ path, message: `must be at most ${s.maxLength} characters` });\n }\n if (typeof s.pattern === 'string') {\n let pattern: RegExp | undefined;\n try {\n pattern = new RegExp(s.pattern, 'u');\n } catch {\n pattern = undefined;\n }\n if (pattern !== undefined && !pattern.test(value)) {\n issues.push({ path, message: `must match ${s.pattern}` });\n }\n }\n }\n if (typeof value === 'number') {\n if (typeof s.minimum === 'number' && value < s.minimum) {\n issues.push({ path, message: `must be >= ${s.minimum}` });\n }\n if (typeof s.maximum === 'number' && value > s.maximum) {\n issues.push({ path, message: `must be <= ${s.maximum}` });\n }\n }\n\n if (Array.isArray(value)) {\n if (typeof s.minItems === 'number' && value.length < s.minItems) {\n issues.push({ path, message: `must have at least ${s.minItems} items` });\n }\n if (typeof s.maxItems === 'number' && value.length > s.maxItems) {\n issues.push({ path, message: `must have at most ${s.maxItems} items` });\n }\n if (s.items !== undefined && !Array.isArray(s.items)) {\n value.forEach((item, index) => {\n check(s.items, item, [...path, index], root, issues, depth + 1);\n });\n }\n }\n\n if (matchesType('object', value)) {\n const record = value as Record<string, unknown>;\n const properties =\n typeof s.properties === 'object' && s.properties !== null\n ? (s.properties as Record<string, unknown>)\n : {};\n if (Array.isArray(s.required)) {\n for (const key of s.required as string[]) {\n if (record[key] === undefined) {\n issues.push({ path: [...path, key], message: 'is required' });\n }\n }\n }\n for (const [key, entry] of Object.entries(record)) {\n if (key in properties) {\n if (entry !== undefined) {\n check(properties[key], entry, [...path, key], root, issues, depth + 1);\n }\n } else if (s.additionalProperties === false) {\n issues.push({ path: [...path, key], message: 'is not a known property' });\n } else if (typeof s.additionalProperties === 'object' && s.additionalProperties !== null) {\n check(s.additionalProperties, entry, [...path, key], root, issues, depth + 1);\n }\n }\n }\n\n if (Array.isArray(s.allOf)) {\n for (const sub of s.allOf) check(sub, value, path, root, issues, depth + 1);\n }\n if (Array.isArray(s.anyOf) || Array.isArray(s.oneOf)) {\n const options = (Array.isArray(s.anyOf) ? s.anyOf : s.oneOf) as unknown[];\n const passing = options.filter((sub) => {\n const nested: GenuiIssue[] = [];\n check(sub, value, path, root, nested, depth + 1);\n return nested.length === 0;\n }).length;\n if (Array.isArray(s.anyOf) ? passing === 0 : passing !== 1) {\n issues.push({\n path,\n message: Array.isArray(s.anyOf)\n ? 'does not match any allowed shape'\n : 'must match exactly one allowed shape',\n });\n }\n }\n if (s.not !== undefined) {\n const nested: GenuiIssue[] = [];\n check(s.not, value, path, root, nested, depth + 1);\n if (nested.length === 0) {\n issues.push({ path, message: 'matches a shape that is not allowed' });\n }\n }\n}\n","import {\n type GenuiValidation,\n type JsonSchema,\n type JsonSchemaValidator,\n type PropsSchema,\n builtinJsonSchemaValidator,\n toJsonSchema,\n validateProps,\n validatePropsSync,\n} from './schema.js';\n\n/**\n * One component a server may push into a conversation. Data only — how it LOOKS is each app's own\n * renderer, looked up by {@link name}. The same definition serves the model (description + props\n * schema), the server (validation), text-only channels ({@link fallbackText}) and the client\n * (validation before rendering).\n */\nexport interface ComponentDefinition<P = Record<string, unknown>> {\n /** Registry key, e.g. `DataTable`. What a `ui` frame's `component` names. */\n name: string;\n /** Human label: \"Data table\". */\n title: string;\n /** Shown to the model: what the component is for and when to use it. */\n description: string;\n /** The props schema: a Standard Schema (Zod, Valibot, ArkType) or a JSON Schema object. */\n props: PropsSchema;\n /** Portable normalized props schema. Required when input transformations are not idempotent. */\n outputProps?: PropsSchema;\n /**\n * The component takes nested elements (a layout: `Stack`, `Card`). Only meaningful in tree mode,\n * where a node's `children` are validated against the catalog too. Such a component gets no\n * `ui__show_*` tool and is not offered by the show tool ({@link flatComponents}), and when its\n * {@link fallbackText} comes out empty it writes no text of its own (its children still do).\n */\n children?: boolean;\n /**\n * Plain text / Slack mrkdwn rendering of these props, for a channel that cannot draw the\n * component. Absent → {@link componentToText} prints the props as JSON.\n */\n fallbackText?: (props: P) => string;\n /**\n * Pushed by the server (e.g. an approval card), never offered to the model. Excluded from\n * {@link catalogToModelText} and from the tool factories.\n */\n internal?: boolean;\n /**\n * Schema version of {@link props}. Stamped on every `ui` frame the component is pushed with, so a\n * client can keep rendering messages persisted under an older shape.\n */\n version?: number;\n}\n\n/** Component names: an identifier a registry key, a tool name and a snake_case slug can all be derived from. */\nexport const COMPONENT_NAME = /^[A-Za-z][A-Za-z0-9]{0,63}$/;\n\n/** Declare a component. Validates the name and returns the definition unchanged (typed). */\nexport function defineComponent<P = Record<string, unknown>>(\n definition: ComponentDefinition<P>,\n): ComponentDefinition<P> {\n if (!COMPONENT_NAME.test(definition.name)) {\n throw new Error(\n `genui: component name \"${definition.name}\" must be letters and digits, starting with a letter (e.g. DataTable)`,\n );\n }\n if (\n definition.version !== undefined &&\n (!Number.isSafeInteger(definition.version) || definition.version <= 0)\n )\n throw new RangeError('genui: component version must be a positive safe integer');\n if (definition.fallbackText !== undefined && typeof definition.fallbackText !== 'function')\n throw new TypeError('genui: fallbackText must be a function');\n return definition;\n}\n\nexport interface CatalogOptions {\n /** How JSON Schema props are checked. Default: {@link builtinJsonSchemaValidator}; pass `ajvValidator(new Ajv())` for full JSON Schema. */\n jsonSchemaValidator?: JsonSchemaValidator;\n}\n\n/** An immutable set of component definitions, looked up by name. */\nexport interface Catalog {\n readonly components: readonly ComponentDefinition<any>[];\n readonly validator: JsonSchemaValidator;\n get(name: string): ComponentDefinition<any> | undefined;\n has(name: string): boolean;\n /** The components a model may be offered (every non-`internal` one). */\n modelComponents(): ComponentDefinition<any>[];\n /** Validate `props` for `component`. An unknown component is a validation failure, not a throw. */\n validate(component: string, props: unknown): Promise<GenuiValidation<Record<string, unknown>>>;\n /**\n * {@link validate} without waiting — `undefined` only when the component's Standard Schema\n * validates asynchronously. An unknown component is a failure, as in `validate`.\n */\n validateSync(\n component: string,\n props: unknown,\n ): GenuiValidation<Record<string, unknown>> | undefined;\n /** The component's props as JSON Schema, when it can be derived (see {@link toJsonSchema}). */\n jsonSchemaFor(component: string): JsonSchema | undefined;\n /** A new catalog with these components added (a later definition replaces an earlier one of the same name). */\n extend(components: readonly ComponentDefinition<any>[]): Catalog;\n}\n\n/**\n * The model components a FLAT tool can offer — one whose input is the component's props alone\n * (`ui__show_<name>`, the generic show tool). A layout component (`children: true`) is left out:\n * those tools have no way to pass it children, so it would only ever draw an empty box. Tree mode\n * offers every model component.\n */\nexport function flatComponents(catalog: Catalog): ComponentDefinition<any>[] {\n return catalog.modelComponents().filter((component) => component.children !== true);\n}\n\n/**\n * Collect component definitions into a {@link Catalog}. Names must be unique; to override a\n * definition (e.g. a builtin), use {@link Catalog.extend}.\n */\nexport function defineCatalog(\n components: readonly ComponentDefinition<any>[],\n options: CatalogOptions = {},\n): Catalog {\n const byName = new Map<string, ComponentDefinition<any>>();\n for (const component of components) {\n defineComponent(component);\n if (byName.has(component.name)) {\n throw new Error(`genui: component \"${component.name}\" is defined twice in one catalog`);\n }\n byName.set(component.name, component);\n }\n return buildCatalog(byName, options.jsonSchemaValidator ?? builtinJsonSchemaValidator);\n}\n\nfunction buildCatalog(\n byName: Map<string, ComponentDefinition<any>>,\n validator: JsonSchemaValidator,\n): Catalog {\n const list = Object.freeze([...byName.values()]);\n return {\n components: list,\n validator,\n get: (name) => byName.get(name),\n has: (name) => byName.has(name),\n modelComponents: () => list.filter((component) => component.internal !== true),\n async validate(component, props) {\n const definition = byName.get(component);\n if (definition === undefined) {\n return {\n ok: false,\n issues: [{ path: [], message: `unknown component \"${component}\"` }],\n };\n }\n const result = await validateProps(\n definition.outputProps ?? definition.props,\n props,\n validator,\n );\n return result as GenuiValidation<Record<string, unknown>>;\n },\n validateSync(component, props) {\n const definition = byName.get(component);\n if (definition === undefined) {\n return {\n ok: false,\n issues: [{ path: [], message: `unknown component \"${component}\"` }],\n };\n }\n return validatePropsSync(definition.outputProps ?? definition.props, props, validator) as\n | GenuiValidation<Record<string, unknown>>\n | undefined;\n },\n jsonSchemaFor(component) {\n const definition = byName.get(component);\n return definition === undefined\n ? undefined\n : toJsonSchema(definition.outputProps ?? definition.props);\n },\n extend(more) {\n const next = new Map(byName);\n for (const component of more) {\n defineComponent(component);\n next.set(component.name, component);\n }\n return buildCatalog(next, validator);\n },\n };\n}\n\n/** `DataTable` → `data_table`, `KPICards` → `kpi_cards`. */\nexport function toSnakeCase(name: string): string {\n return name\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')\n .replace(/[^a-zA-Z0-9]+/g, '_')\n .toLowerCase();\n}\n\n/** The per-component tool name: `ui__show_data_table` with the default prefix. */\nexport function toolNameFor(component: string, prefix = 'ui__show_'): string {\n return `${prefix}${toSnakeCase(component)}`;\n}\n","import type { Catalog } from './catalog.js';\nimport { type GenuiIssue, type GenuiValidation, type JsonSchema, validateProps } from './schema.js';\n\n/**\n * One node of a composed UI: a catalog component, its props, and — for components declared with\n * `children: true` — nested nodes. The shape json-render calls a \"nested element\", so a tree\n * converts to a json-render flat spec with {@link treeToFlatSpec}.\n */\nexport interface GenuiElement {\n type: string;\n props: Record<string, unknown>;\n children?: GenuiElement[];\n}\n\n/**\n * The `ui` frame component a tree-mode tool pushes: `{ component: GENUI_TREE_COMPONENT, props: {\n * root } }`. Not a valid component name, so it can never collide with a catalog entry.\n */\nexport const GENUI_TREE_COMPONENT = 'genui:tree';\n\n/** Props of a {@link GENUI_TREE_COMPONENT} frame. */\nexport interface GenuiTreeProps {\n root: GenuiElement;\n}\n\nexport interface TreeLimits {\n /** Deepest nesting accepted. Default 12. */\n maxDepth?: number;\n /** Most nodes accepted in one tree. Default 200. */\n maxNodes?: number;\n}\n\n/**\n * Validate a model-composed tree against the catalog: every node's `type` must be a model-facing\n * component, its props must pass that component's schema, and only components declared with\n * `children: true` may have children. Returns the tree with each node's props as its schema\n * produced them (defaults applied by a Standard Schema, for instance).\n *\n * Lenient about one thing models get wrong: a `children` array sent as a JSON STRING (sometimes\n * with a stray trailing `}`) is parsed back into the array the model plainly meant.\n */\nexport async function validateTree(\n catalog: Catalog,\n tree: unknown,\n limits: TreeLimits = {},\n phase: 'input' | 'output' = 'output',\n): Promise<GenuiValidation<GenuiElement>> {\n const maxDepth = limits.maxDepth ?? 12;\n const maxNodes = limits.maxNodes ?? 200;\n const issues: GenuiIssue[] = [];\n let nodes = 0;\n\n const visit = async (\n node: unknown,\n path: (string | number)[],\n depth: number,\n ): Promise<GenuiElement | undefined> => {\n nodes += 1;\n if (nodes > maxNodes) {\n if (nodes === maxNodes + 1) {\n issues.push({ path, message: `the tree has more than ${maxNodes} elements` });\n }\n return undefined;\n }\n if (depth > maxDepth) {\n issues.push({ path, message: `the tree is nested deeper than ${maxDepth} levels` });\n return undefined;\n }\n if (typeof node !== 'object' || node === null || Array.isArray(node)) {\n issues.push({ path, message: 'must be an element object { type, props, children? }' });\n return undefined;\n }\n const element = node as Record<string, unknown>;\n if (typeof element.type !== 'string') {\n issues.push({ path: [...path, 'type'], message: 'must be a component name' });\n return undefined;\n }\n const definition = catalog.get(element.type);\n if (definition === undefined || definition.internal === true) {\n issues.push({\n path: [...path, 'type'],\n message: `unknown component \"${element.type}\" (allowed: ${catalog\n .modelComponents()\n .map((component) => component.name)\n .join(', ')})`,\n });\n return undefined;\n }\n const validated =\n phase === 'input'\n ? ((await validateProps(\n definition.props,\n element.props ?? {},\n catalog.validator,\n )) as GenuiValidation<Record<string, unknown>>)\n : await catalog.validate(element.type, element.props ?? {});\n let props: Record<string, unknown> = {};\n if (!validated.ok) {\n for (const issue of validated.issues) {\n issues.push({ path: [...path, 'props', ...issue.path], message: issue.message });\n }\n } else {\n props = validated.value;\n }\n const rawChildren = parseChildrenIfStringified(element.children);\n if (rawChildren === undefined || rawChildren === null) {\n return { type: element.type, props };\n }\n if (!Array.isArray(rawChildren)) {\n issues.push({\n path: [...path, 'children'],\n message: 'must be an array of elements (a literal array, not a string)',\n });\n return undefined;\n }\n if (rawChildren.length > 0 && definition.children !== true) {\n issues.push({\n path: [...path, 'children'],\n message: `${element.type} does not take children`,\n });\n return undefined;\n }\n const children: GenuiElement[] = [];\n for (const [index, child] of rawChildren.entries()) {\n const next = await visit(child, [...path, 'children', index], depth + 1);\n if (next !== undefined) {\n children.push(next);\n }\n }\n return children.length > 0\n ? { type: element.type, props, children }\n : { type: element.type, props };\n };\n\n const root = await visit(tree, [], 1);\n return issues.length > 0 || root === undefined\n ? { ok: false, issues: issues.length > 0 ? issues : [{ path: [], message: 'is invalid' }] }\n : { ok: true, value: root };\n}\n\n/**\n * The JSON Schema of a tree-mode tool's input: a recursive `{ type, props, children? }` node whose\n * `type` is one of the catalog's model-facing component names. Per-component props are described\n * to the model in the tool description (see `catalogToModelText`) and checked by\n * {@link validateTree}, which keeps this schema small enough for every provider.\n */\nexport function treeJsonSchema(catalog: Catalog): JsonSchema {\n return {\n type: 'object',\n properties: {\n type: {\n type: 'string',\n enum: catalog.modelComponents().map((component) => component.name),\n description: 'Component name from the catalog',\n },\n props: {\n type: 'object',\n description: \"The component's props, as the catalog describes them\",\n },\n children: {\n type: 'array',\n items: { $ref: '#' },\n description:\n 'Nested elements, only for components that take children. A literal JSON array, never a JSON-stringified one.',\n },\n },\n required: ['type', 'props'],\n };\n}\n\n/** A json-render flat spec: `{ root, elements: { [id]: { type, props, children: id[] } } }`. */\nexport interface FlatSpec {\n root: string;\n elements: Record<string, { type: string; props: Record<string, unknown>; children: string[] }>;\n}\n\n/** Convert a tree to a json-render flat spec (ids are `el-0`, `el-1`, … in depth-first order). */\nexport function treeToFlatSpec(root: GenuiElement): FlatSpec {\n const elements: FlatSpec['elements'] = {};\n let next = 0;\n const visit = (node: GenuiElement): string => {\n const id = `el-${next++}`;\n const entry = { type: node.type, props: node.props, children: [] as string[] };\n elements[id] = entry;\n for (const child of node.children ?? []) {\n entry.children.push(visit(child));\n }\n return id;\n };\n return { root: visit(root), elements };\n}\n\nfunction parseChildrenIfStringified(value: unknown): unknown {\n if (typeof value !== 'string') return value;\n const trimmed = value.trim();\n if (!trimmed.startsWith('[')) return value;\n return leadingJsonArray(trimmed) ?? value;\n}\n\n/**\n * The array `text` opens with, ignoring what follows: a model that stringifies `children` tends to\n * carry the enclosing object's `}` along, which `JSON.parse` refuses whole.\n */\nfunction leadingJsonArray(text: string): unknown[] | undefined {\n let depth = 0;\n let inString = false;\n let escaped = false;\n for (let index = 0; index < text.length; index += 1) {\n const char = text[index];\n if (inString) {\n if (escaped) escaped = false;\n else if (char === '\\\\') escaped = true;\n else if (char === '\"') inString = false;\n continue;\n }\n if (char === '\"') inString = true;\n else if (char === '[' || char === '{') depth += 1;\n else if (char === ']' || char === '}') {\n depth -= 1;\n if (depth === 0) {\n try {\n const parsed: unknown = JSON.parse(text.slice(0, index + 1));\n return Array.isArray(parsed) ? parsed : undefined;\n } catch {\n return undefined;\n }\n }\n }\n }\n return undefined;\n}\n","import { type Catalog, flatComponents, toolNameFor } from './catalog.js';\nimport { type JsonSchema, toJsonSchema } from './schema.js';\nimport { GENUI_TREE_COMPONENT, type GenuiElement } from './tree.js';\n\n/**\n * Plain text (Slack mrkdwn compatible) for a pushed component: its definition's `fallbackText`, or\n * the props as a JSON block when the catalog has no text for it. A tree frame\n * ({@link GENUI_TREE_COMPONENT}) renders node by node. Never throws — a fallback that fails prints\n * the JSON instead. A layout component (`children: true`) whose text comes out empty writes\n * nothing: it has nothing of its own to say, and its props (`direction`, `gap`) are not content.\n */\nexport function componentToText(\n catalog: Catalog,\n component: string,\n props: Record<string, unknown>,\n): string {\n if (component === GENUI_TREE_COMPONENT) {\n const root = props.root as GenuiElement | undefined;\n return root === undefined ? '' : treeToText(catalog, root);\n }\n return ownText(catalog, component, props) ?? '';\n}\n\n/**\n * One component's own text, without its children: its fallback; `undefined` for a layout component\n * with nothing to say; the props as JSON otherwise (no fallback, an empty one, or one that threw).\n */\nfunction ownText(\n catalog: Catalog,\n component: string,\n props: Record<string, unknown>,\n): string | undefined {\n const definition = catalog.get(component);\n const fallback = definition?.fallbackText;\n let failed = false;\n if (fallback !== undefined) {\n try {\n const text = fallback(props);\n if (typeof text === 'string' && text.trim().length > 0) return text;\n } catch {\n failed = true;\n }\n }\n if (definition?.children === true && !failed) return undefined;\n return jsonBlock(props);\n}\n\n/** Plain text for a composed tree: each node's text, depth-first, blank-line free. */\nexport function treeToText(catalog: Catalog, root: GenuiElement): string {\n const out: string[] = [];\n const visit = (node: GenuiElement, depth: number) => {\n if (depth > 32) return;\n const text = ownText(catalog, node.type, node.props);\n if (text !== undefined) out.push(text);\n for (const child of node.children ?? []) visit(child, depth + 1);\n };\n visit(root, 0);\n return out.filter((line) => line.trim().length > 0).join('\\n');\n}\n\nfunction jsonBlock(props: Record<string, unknown>): string {\n const title =\n typeof props.title === 'string' && props.title.length > 0 ? `*${props.title}*\\n` : '';\n return `${title}\\`\\`\\`\\n${JSON.stringify(props, null, 2)}\\n\\`\\`\\``;\n}\n\nexport interface CatalogTextOptions {\n /**\n * `per-component`: each component is its own tool (`ui__show_<snake>`), named in the text.\n * `tree`: one tool takes a nested `{ type, props, children }` tree; the text explains the format.\n * `show`: one tool takes `{ component, props }` (the generic show tool). Default `tree`.\n */\n mode?: 'per-component' | 'tree' | 'show';\n /** Tool-name prefix for `per-component`. Default `ui__show_`. */\n namePrefix?: string;\n}\n\n/**\n * The catalog described for a model: one entry per model-facing component with its description and\n * a compact TypeScript-like signature of its props. What a tree-mode (or show) tool puts in its\n * description, and what a host can add to a system prompt.\n */\nexport function catalogToModelText(catalog: Catalog, options: CatalogTextOptions = {}): string {\n const mode = options.mode ?? 'tree';\n const lines: string[] = [];\n if (mode === 'tree') {\n lines.push(\n 'Compose the UI as ONE tree of elements: { \"type\": <component>, \"props\": { … }, \"children\"?: [ … ] }.',\n 'Only components marked \"takes children\" accept children; `children` is a literal JSON array, never a string.',\n 'Components:',\n );\n } else if (mode === 'show') {\n lines.push('Pass { \"component\": <name>, \"props\": { … } } with one of these components:');\n } else {\n lines.push('Components you can show (one tool each):');\n }\n // Flat modes cannot pass children, so a layout component is not offered there.\n const components = mode === 'tree' ? catalog.modelComponents() : flatComponents(catalog);\n for (const component of components) {\n const schema = toJsonSchema(component.props);\n const head =\n mode === 'per-component'\n ? `- ${component.name} (tool \\`${toolNameFor(component.name, options.namePrefix)}\\`)`\n : `- ${component.name}`;\n lines.push(`${head}: ${component.description}`);\n if (schema !== undefined) {\n lines.push(` props: ${summarizeSchema(schema, schema, 0)}`);\n }\n if (mode === 'tree' && component.children === true) {\n lines.push(' takes children');\n }\n }\n return lines.join('\\n');\n}\n\n/** A JSON Schema as a one-line TypeScript-like type, e.g. `{ title?: string, rows: object[] }`. */\nexport function summarizeSchema(schema: unknown, root: JsonSchema, depth: number): string {\n if (typeof schema !== 'object' || schema === null) return 'unknown';\n const s = schema as Record<string, unknown>;\n if (depth > 5) return '…';\n if (typeof s.$ref === 'string') {\n return s.$ref === '#' ? 'Self' : (s.$ref.split('/').pop() ?? 'unknown');\n }\n if (Array.isArray(s.enum)) {\n return s.enum.map((option) => JSON.stringify(option)).join(' | ');\n }\n if ('const' in s) return JSON.stringify(s.const);\n const variants = (s.anyOf ?? s.oneOf) as unknown[] | undefined;\n if (Array.isArray(variants)) {\n return variants.map((variant) => summarizeSchema(variant, root, depth + 1)).join(' | ');\n }\n const types = Array.isArray(s.type) ? (s.type as string[]) : s.type !== undefined ? [s.type] : [];\n if (types.length > 1) {\n return types.map((type) => summarizeSchema({ ...s, type }, root, depth + 1)).join(' | ');\n }\n const type = types[0] as string | undefined;\n if (type === 'array') {\n const item = s.items === undefined ? 'unknown' : summarizeSchema(s.items, root, depth + 1);\n return /[|\\s]/.test(item) && !item.startsWith('{') ? `(${item})[]` : `${item}[]`;\n }\n if (type === 'object' || (type === undefined && s.properties !== undefined)) {\n const properties = (s.properties ?? {}) as Record<string, unknown>;\n const keys = Object.keys(properties);\n if (keys.length === 0) return 'object';\n const required = new Set(Array.isArray(s.required) ? (s.required as string[]) : []);\n const fields = keys.map((key) => {\n const field = properties[key] as Record<string, unknown> | undefined;\n const note =\n typeof field?.description === 'string' && depth === 0 ? ` /* ${field.description} */` : '';\n return `${key}${required.has(key) ? '' : '?'}: ${summarizeSchema(field, root, depth + 1)}${note}`;\n });\n return `{ ${fields.join(', ')} }`;\n }\n if (type === 'integer') return 'number';\n return type ?? 'unknown';\n}\n\n/** Replace `{{path}}` placeholders with prop values (objects as JSON). */\nexport function fillTemplate(template: string, props: Record<string, unknown>): string {\n return template.replace(/\\{\\{\\s*([\\w.[\\]]+)\\s*\\}\\}/g, (_match, path: string) => {\n const value = getPath(props, path);\n if (value === null || value === undefined) return '';\n return typeof value === 'object' ? JSON.stringify(value) : String(value);\n });\n}\n\n/** Read `a.b[0].c` from a value; `undefined` when any step is missing. */\nexport function getPath(source: unknown, path: string): unknown {\n let current: any = source;\n for (const part of path\n .replace(/\\[(\\d+)\\]/g, '.$1')\n .split('.')\n .filter(Boolean)) {\n if (current === null || current === undefined) return undefined;\n current = current[part];\n }\n return current;\n}\n","import { COMPONENT_NAME, type Catalog, defineCatalog } from './catalog.js';\nimport { formatIssues } from './schema.js';\nimport { componentToText, treeToText } from './text.js';\nimport { GENUI_TREE_COMPONENT, type GenuiElement, validateTree } from './tree.js';\n\n/** Renderer support only. Component definitions and authorization remain server-owned. */\nexport interface UiCapabilities {\n components: Array<{ name: string; version: number }>;\n}\n\nexport function validateUiCapabilities(value: unknown): UiCapabilities {\n if (\n !record(value) ||\n Object.keys(value).some((key) => key !== 'components') ||\n !Array.isArray(value.components)\n )\n throw new TypeError('Invalid UI capabilities');\n const seen = new Set<string>();\n const components = value.components.map((component: unknown) => {\n if (\n !record(component) ||\n Object.keys(component).some((key) => key !== 'name' && key !== 'version') ||\n typeof component.name !== 'string' ||\n !COMPONENT_NAME.test(component.name) ||\n !Number.isSafeInteger(component.version) ||\n Number(component.version) <= 0 ||\n seen.has(component.name)\n )\n throw new TypeError('Invalid UI component capability');\n seen.add(component.name);\n return { name: component.name, version: Number(component.version) };\n });\n return { components };\n}\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function negotiateCatalog(catalog: Catalog, capabilities?: UiCapabilities): Catalog {\n if (capabilities === undefined) return catalog;\n const supported = validateUiCapabilities(capabilities).components;\n return defineCatalog(\n catalog.components.filter((component) =>\n supported.some(\n (entry) => entry.name === component.name && entry.version === (component.version ?? 1),\n ),\n ),\n { jsonSchemaValidator: catalog.validator },\n );\n}\n\nexport type PreparedUiEmission =\n | {\n kind: 'ui';\n component: string;\n props: Record<string, unknown>;\n version: number;\n fallbackText: string;\n componentVersions?: Record<string, number>;\n }\n | { kind: 'text'; text: string };\n\n/** Validate against current trusted definitions before drawing or generating complete text. */\nexport async function prepareUiEmission(\n catalog: Catalog,\n capabilities: UiCapabilities | undefined,\n component: string,\n props: Record<string, unknown>,\n version?: number,\n): Promise<PreparedUiEmission> {\n const drawable = negotiateCatalog(catalog, capabilities);\n if (component === GENUI_TREE_COMPONENT) {\n if (version !== undefined && version !== 1) throw new Error('Invalid UI tree version');\n const validated = await validateTree(catalog, props.root);\n if (!validated.ok) throw new Error(`Invalid UI tree: ${formatIssues(validated.issues)}`);\n const supported = (node: GenuiElement): boolean =>\n drawable.has(node.type) && (node.children ?? []).every(supported);\n const versions = new Map<string, number>();\n const collectVersions = (node: GenuiElement): void => {\n versions.set(node.type, catalog.get(node.type)?.version ?? 1);\n for (const child of node.children ?? []) collectVersions(child);\n };\n collectVersions(validated.value);\n return supported(validated.value)\n ? {\n kind: 'ui',\n component,\n props: { root: validated.value },\n version: 1,\n fallbackText: treeToText(catalog, validated.value),\n componentVersions: Object.fromEntries(versions),\n }\n : { kind: 'text', text: treeToText(catalog, validated.value) };\n }\n const definition = catalog.get(component);\n if (definition === undefined) throw new Error(`Unknown UI component \"${component}\"`);\n const currentVersion = definition.version ?? 1;\n if (version !== undefined && version !== currentVersion)\n throw new Error(`Invalid UI component version for \"${component}\"`);\n const validated = await catalog.validate(component, props);\n if (!validated.ok) throw new Error(`Invalid UI props: ${formatIssues(validated.issues)}`);\n return drawable.has(component)\n ? {\n kind: 'ui',\n component,\n props: validated.value,\n version: currentVersion,\n fallbackText: componentToText(catalog, component, validated.value),\n }\n : { kind: 'text', text: componentToText(catalog, component, validated.value) };\n}\n","import { attachActionProposalOutcome } from './action-proposal-outcome.js';\nimport { validateUiCapabilities } from './genui/capabilities.js';\nimport type {\n ActionProposal,\n ActionProposalDecisionCommand,\n ActionProposalMutationResult,\n ActionProposalScope,\n ClaimActionProposal,\n CreateActionProposal,\n ExtendActionProposalLease,\n ListActionProposals,\n SettleActionProposal,\n} from './spi/action-proposal-store.js';\n\nfunction checkTime(value: number): void {\n if (!Number.isSafeInteger(value))\n throw new RangeError('Action proposal timestamps must be safe integer milliseconds');\n}\nfunction checkString(value: unknown): void {\n if (typeof value !== 'string' || value.length === 0)\n throw new TypeError('Action proposal identifiers must be nonempty strings');\n}\nexport function validateActionProposalCreation(input: CreateActionProposal): void {\n const allowed = [\n 'id',\n 'tenantRef',\n 'actorRef',\n 'threadId',\n 'originRunId',\n 'originMessageId',\n 'originToolCallId',\n 'toolName',\n 'input',\n 'preparationInput',\n 'executionContext',\n 'confirmation',\n 'approver',\n 'expiresAt',\n 'idempotencyKey',\n 'replacementKey',\n ];\n if (Object.keys(input).some((key) => !allowed.includes(key)))\n throw new TypeError('Unknown action proposal creation field');\n for (const key of [\n 'id',\n 'actorRef',\n 'threadId',\n 'originRunId',\n 'originMessageId',\n 'originToolCallId',\n 'toolName',\n 'approver',\n 'idempotencyKey',\n ] as const)\n checkString(input[key]);\n if (input.tenantRef !== null && typeof input.tenantRef !== 'string')\n throw new TypeError('tenantRef must be an explicit string or null');\n for (const value of [input.id, input.actorRef, input.threadId, input.tenantRef]) {\n if (value !== null && value.length > 255)\n throw new RangeError('Action proposal id and scope must fit 255 UTF-16 code units');\n }\n if (input.replacementKey !== undefined) {\n checkString(input.replacementKey);\n if (input.replacementKey.length > 255)\n throw new RangeError('replacementKey must fit 255 UTF-16 code units');\n }\n if (Object.hasOwn(input, 'executionContext')) {\n const context = input.executionContext;\n if (context === null || typeof context !== 'object' || Array.isArray(context))\n throw new TypeError('executionContext must be a JSON object');\n const allowedContext = ['agentName', 'persona', 'requestId', 'pageContext', 'uiCapabilities'];\n if (Object.keys(context).some((key) => !allowedContext.includes(key)))\n throw new TypeError('Unknown execution context field');\n checkString(context.requestId);\n if (Object.hasOwn(context, 'uiCapabilities')) validateUiCapabilities(context.uiCapabilities);\n if (Object.hasOwn(context, 'agentName')) checkString(context.agentName);\n if (Object.hasOwn(context, 'persona')) checkString(context.persona);\n if (Object.hasOwn(context, 'pageContext')) {\n const page = context.pageContext;\n if (page === null || typeof page !== 'object' || Array.isArray(page))\n throw new TypeError('pageContext must be a JSON object');\n if (Object.hasOwn(page, 'kind') && typeof page.kind !== 'string')\n throw new TypeError('pageContext.kind must be a string');\n }\n }\n if (input.expiresAt !== null) checkTime(input.expiresAt);\n checkString(input.confirmation?.title);\n checkString(input.confirmation?.verb);\n canonicalActionProposalJson(input);\n}\n\nexport function validateActionProposalListQuery(query: ListActionProposals = {}): number {\n const limit = query.limit === undefined ? 100 : query.limit;\n if (!Number.isInteger(limit) || limit < 1 || limit > 1000)\n throw new RangeError('limit must be an integer from 1 to 1000');\n if (\n query.decision !== undefined &&\n !['pending', 'approved', 'rejected', 'expired', 'superseded'].includes(query.decision)\n )\n throw new TypeError('Unsupported action proposal list decision');\n if (query.after !== undefined) {\n const after = query.after;\n if (\n typeof after !== 'object' ||\n after === null ||\n Array.isArray(after) ||\n Object.keys(after).some((key) => key !== 'createdAt' && key !== 'id')\n )\n throw new TypeError('Invalid action proposal cursor');\n checkTime(after.createdAt);\n checkString(after.id);\n if (after.id.length > 255) throw new TypeError('Action proposal cursor id is too long');\n }\n return limit;\n}\n\n/** Canonical JSON snapshots keep replay equality independent of object key insertion order. */\nexport function canonicalActionProposalJson(value: unknown): string {\n const ancestors = new Set<object>();\n const sort = (item: unknown): unknown => {\n if (item === null || typeof item === 'string' || typeof item === 'boolean') return item;\n if (typeof item === 'number' && Number.isFinite(item)) return item;\n if (typeof item !== 'object' || item === null || ancestors.has(item))\n throw new TypeError('Action proposals require finite, acyclic JSON values');\n const prototype = Object.getPrototypeOf(item);\n if (!Array.isArray(item) && prototype !== Object.prototype && prototype !== null)\n throw new TypeError('Action proposals require plain JSON objects');\n ancestors.add(item);\n const sorted = Array.isArray(item)\n ? Array.from(item, sort)\n : Object.fromEntries(\n Object.keys(item)\n .sort()\n .map((key) => [key, sort((item as Record<string, unknown>)[key])]),\n );\n ancestors.delete(item);\n return sorted;\n };\n return JSON.stringify(sort(value));\n}\nexport function snapshotActionProposal<T>(value: T): T {\n return JSON.parse(canonicalActionProposalJson(value)) as T;\n}\nexport function actionProposalScopeMatches(\n row: ActionProposalScope,\n scope: ActionProposalScope,\n): boolean {\n return (\n row.tenantRef === scope.tenantRef &&\n row.actorRef === scope.actorRef &&\n row.threadId === scope.threadId\n );\n}\nexport function initialActionProposal(input: CreateActionProposal, now: number): ActionProposal {\n validateActionProposalCreation(input);\n checkTime(now);\n return snapshotActionProposal({\n ...input,\n decision: 'pending',\n decisionAudit: null,\n execution: null,\n createdAt: now,\n updatedAt: now,\n });\n}\nexport function actionProposalCreationMatches(\n row: ActionProposal,\n input: CreateActionProposal,\n): boolean {\n validateActionProposalCreation(input);\n const {\n decision: _decision,\n decisionAudit: _audit,\n execution: _execution,\n createdAt: _created,\n updatedAt: _updated,\n supersededBy: _supersededBy,\n outcome: _outcome,\n outcomeDelivery: _delivery,\n ...original\n } = row;\n return canonicalActionProposalJson(original) === canonicalActionProposalJson(input);\n}\nfunction result(\n status: ActionProposalMutationResult['status'],\n proposal: ActionProposal,\n): ActionProposalMutationResult {\n return { status, proposal: snapshotActionProposal(proposal) };\n}\nexport function transitionActionProposalDecision(\n row: ActionProposal,\n command: ActionProposalDecisionCommand,\n now: number,\n): ActionProposalMutationResult {\n checkTime(now);\n if (!['approved', 'rejected', 'expired'].includes(command.decision))\n throw new TypeError('Unsupported action proposal decision');\n checkString(command.actorRef);\n checkString(command.via);\n if (command.reason !== undefined && typeof command.reason !== 'string')\n throw new TypeError('reason must be a string');\n if (command.remember !== undefined && typeof command.remember !== 'boolean')\n throw new TypeError('remember must be a boolean');\n if (row.decision !== 'pending') {\n return result(\n row.decision === command.decision\n ? 'unchanged'\n : row.decision === 'expired'\n ? 'expired'\n : 'conflict',\n row,\n );\n }\n const next = snapshotActionProposal(row);\n if (row.expiresAt !== null && now >= row.expiresAt) {\n next.decision = 'expired';\n next.decisionAudit = { actorRef: 'system', via: 'expiry', at: now };\n next.updatedAt = now;\n return result(\n command.decision === 'expired' ? 'applied' : 'expired',\n attachActionProposalOutcome(next, now),\n );\n }\n if (command.decision === 'expired') return result('conflict', row);\n const { decision, ...audit } = command;\n next.decision = decision;\n next.decisionAudit = {\n actorRef: audit.actorRef,\n via: audit.via,\n at: now,\n ...(audit.reason === undefined ? {} : { reason: audit.reason }),\n ...(audit.remember === undefined ? {} : { remember: audit.remember }),\n };\n next.updatedAt = now;\n if (decision === 'approved') next.execution = { status: 'queued', generation: 0, lease: null };\n return result('applied', decision === 'approved' ? next : attachActionProposalOutcome(next, now));\n}\nfunction checkLeaseMs(leaseMs: number, now: number): void {\n checkTime(now);\n if (!Number.isSafeInteger(leaseMs) || leaseMs <= 0 || !Number.isSafeInteger(now + leaseMs))\n throw new RangeError('leaseMs must be finite and positive');\n}\nexport function transitionActionProposalClaim(\n row: ActionProposal,\n command: ClaimActionProposal,\n now: number,\n token: string,\n): ActionProposalMutationResult {\n checkLeaseMs(command.leaseMs, now);\n checkString(command.workerId);\n checkString(token);\n const execution = row.execution;\n if (\n row.decision !== 'approved' ||\n !execution ||\n (execution.status !== 'queued' &&\n !(execution.status === 'executing' && execution.lease && now >= execution.lease.expiresAt))\n )\n return result('conflict', row);\n const next = snapshotActionProposal(row);\n const generation = execution.generation + 1;\n next.execution = {\n status: 'executing',\n generation,\n lease: { token, generation, workerId: command.workerId, expiresAt: now + command.leaseMs },\n };\n next.updatedAt = now;\n return result('applied', next);\n}\nfunction leaseStatus(\n row: ActionProposal,\n command: { token: string; generation: number },\n now: number,\n): 'valid' | 'conflict' | 'expired' {\n checkTime(now);\n checkString(command.token);\n if (!Number.isSafeInteger(command.generation) || command.generation < 1)\n throw new RangeError('Invalid lease generation');\n const work = row.execution;\n if (\n row.decision !== 'approved' ||\n work?.status !== 'executing' ||\n !work.lease ||\n work.generation !== command.generation ||\n work.lease.generation !== command.generation ||\n work.lease.token !== command.token\n )\n return 'conflict';\n return now >= work.lease.expiresAt ? 'expired' : 'valid';\n}\nexport function transitionActionProposalLease(\n row: ActionProposal,\n command: ExtendActionProposalLease,\n now: number,\n): ActionProposalMutationResult {\n checkLeaseMs(command.leaseMs, now);\n const status = leaseStatus(row, command, now);\n if (status !== 'valid') return result(status, row);\n const next = snapshotActionProposal(row);\n if (next.execution?.lease)\n next.execution.lease.expiresAt = Math.max(\n next.execution.lease.expiresAt,\n now + command.leaseMs,\n );\n next.updatedAt = now;\n return result('applied', next);\n}\nexport function transitionActionProposalSettlement(\n row: ActionProposal,\n command: SettleActionProposal,\n now: number,\n): ActionProposalMutationResult {\n checkTime(now);\n if (command.status !== 'succeeded' && command.status !== 'failed')\n throw new TypeError('Unsupported settlement status');\n if (\n (command.status === 'succeeded' && command.error !== undefined) ||\n (command.status === 'failed' &&\n (typeof command.error !== 'string' || command.result !== undefined))\n )\n throw new TypeError('Ambiguous action proposal settlement');\n const status = leaseStatus(row, command, now);\n if (status !== 'valid') return result(status, row);\n const next = snapshotActionProposal(row);\n next.execution =\n command.status === 'succeeded'\n ? {\n status: 'succeeded',\n generation: command.generation,\n lease: null,\n ...(command.result === undefined ? {} : { result: command.result }),\n }\n : { status: 'failed', generation: command.generation, lease: null, error: command.error };\n if (command.ui !== undefined) canonicalActionProposalJson(command.ui);\n if (command.text !== undefined && typeof command.text !== 'string')\n throw new TypeError('Outcome text must be a string');\n next.updatedAt = now;\n return result('applied', attachActionProposalOutcome(next, now, command.ui, command.text));\n}\n\n/** Caller must obtain the replacement through the same full scope and persistence authority. */\nexport function transitionActionProposalSupersession(\n row: ActionProposal,\n replacement: ActionProposal,\n command: { replacementProposalId: string; actorRef: string; via: string },\n now: number,\n): ActionProposalMutationResult {\n checkTime(now);\n checkString(command.replacementProposalId);\n checkString(command.actorRef);\n checkString(command.via);\n if (\n replacement.id !== command.replacementProposalId ||\n row.id === replacement.id ||\n !actionProposalScopeMatches(row, replacement) ||\n row.toolName !== replacement.toolName ||\n !row.replacementKey ||\n row.replacementKey !== replacement.replacementKey\n )\n return result('conflict', row);\n if (row.decision === 'superseded')\n return result(row.supersededBy === replacement.id ? 'unchanged' : 'conflict', row);\n if (row.decision !== 'pending') return result('conflict', row);\n if (row.expiresAt !== null && now >= row.expiresAt)\n return {\n ...transitionActionProposalDecision(\n row,\n { decision: 'expired', actorRef: 'system', via: 'expiry' },\n now,\n ),\n status: 'expired',\n };\n const next = snapshotActionProposal({\n ...row,\n decision: 'superseded' as const,\n supersededBy: replacement.id,\n decisionAudit: {\n actorRef: command.actorRef,\n via: command.via,\n replacementProposalId: replacement.id,\n at: now,\n },\n updatedAt: now,\n });\n return result('applied', attachActionProposalOutcome(next, now));\n}\n","/**\n * Optional builtin component DEFINITIONS — names, props schemas, model descriptions and plain-text\n * fallbacks for the components most chat apps want. No visuals: an app renders each with its own\n * look, keyed by name. Use them as-is, pick some, or extend them:\n *\n * ```ts\n * const catalog = defineCatalog([...BUILTIN_COMPONENTS, ...LAYOUT_COMPONENTS, myDealCard]);\n * ```\n */\nimport { type ComponentDefinition, defineComponent } from './catalog.js';\nimport type { JsonSchema } from './schema.js';\n\ntype Props = Record<string, any>;\n\nconst str = (description?: string, extra: JsonSchema = {}): JsonSchema => ({\n type: 'string',\n ...(description !== undefined ? { description } : {}),\n ...extra,\n});\nconst obj = (properties: Record<string, JsonSchema>, required: string[] = []): JsonSchema => ({\n type: 'object',\n properties,\n required,\n additionalProperties: false,\n});\nconst arr = (items: JsonSchema, extra: JsonSchema = {}): JsonSchema => ({\n type: 'array',\n items,\n ...extra,\n});\nconst cell: JsonSchema = { type: ['string', 'number', 'boolean', 'null'] };\nconst row: JsonSchema = { type: 'object', additionalProperties: cell };\n\nconst s = (value: unknown): string => (value === null || value === undefined ? '' : String(value));\nconst heading = (props: Props): string => (props.title ? `*${s(props.title)}*\\n` : '');\n\n/** A fixed-width text table in a code block, at most `max` rows. */\nexport function textTable(\n columns: readonly { key: string; label: string }[],\n rows: readonly Props[],\n max = 15,\n): string {\n const shown = rows.slice(0, max);\n const widths = columns.map((column) =>\n Math.min(28, Math.max(column.label.length, ...shown.map((r) => s(r[column.key]).length))),\n );\n const format = (values: string[]) =>\n values\n .map((value, index) => value.slice(0, widths[index]).padEnd(widths[index] ?? 0))\n .join(' ');\n const lines = [\n format(columns.map((column) => column.label)),\n widths.map((width) => '-'.repeat(width)).join(' '),\n ...shown.map((r) => format(columns.map((column) => s(r[column.key])))),\n ];\n if (rows.length > max) lines.push(`… ${rows.length - max} more rows`);\n return `\\`\\`\\`\\n${lines.join('\\n')}\\n\\`\\`\\``;\n}\n\nexport interface DiffLine {\n op: 'same' | 'add' | 'del';\n text: string;\n}\n\n/** Line diff (LCS) — good enough for snippets up to a few hundred lines. */\nexport function lineDiff(before: string, after: string): DiffLine[] {\n const a = before.split('\\n');\n const b = after.split('\\n');\n if (a.length * b.length > 250_000) {\n return [\n ...a.map((text) => ({ op: 'del' as const, text })),\n ...b.map((text) => ({ op: 'add' as const, text })),\n ];\n }\n const dp: number[][] = Array.from({ length: a.length + 1 }, () =>\n new Array<number>(b.length + 1).fill(0),\n );\n const at = (i: number, j: number): number => dp[i]?.[j] ?? 0;\n for (let i = a.length - 1; i >= 0; i--) {\n for (let j = b.length - 1; j >= 0; j--) {\n (dp[i] as number[])[j] =\n a[i] === b[j] ? at(i + 1, j + 1) + 1 : Math.max(at(i + 1, j), at(i, j + 1));\n }\n }\n const out: DiffLine[] = [];\n let i = 0;\n let j = 0;\n while (i < a.length && j < b.length) {\n if (a[i] === b[j]) {\n out.push({ op: 'same', text: a[i] as string });\n i++;\n j++;\n } else if (at(i + 1, j) >= at(i, j + 1)) {\n out.push({ op: 'del', text: a[i++] as string });\n } else {\n out.push({ op: 'add', text: b[j++] as string });\n }\n }\n while (i < a.length) out.push({ op: 'del', text: a[i++] as string });\n while (j < b.length) out.push({ op: 'add', text: b[j++] as string });\n return out;\n}\n\nfunction bar(value: number, max: number, width = 20): string {\n const n = max > 0 ? Math.round((Math.abs(value) / max) * width) : 0;\n return '█'.repeat(n) || '▏';\n}\n\nexport const DataTable = defineComponent<Props>({\n name: 'DataTable',\n title: 'Data table',\n description:\n 'Tabular data (records with the same fields) as a sortable table. Prefer it over markdown tables for more than 3 rows.',\n props: obj(\n {\n title: str('Short caption'),\n columns: arr(\n obj(\n {\n key: str('Field name in each row'),\n label: str('Column header'),\n align: str(undefined, { enum: ['left', 'right', 'center'] }),\n format: str('How to format values', {\n enum: ['text', 'number', 'currency', 'percent', 'date', 'link'],\n }),\n },\n ['key', 'label'],\n ),\n { minItems: 1, maxItems: 12 },\n ),\n rows: arr(row, { maxItems: 500 }),\n },\n ['columns', 'rows'],\n ),\n fallbackText: (props) => `${heading(props)}${textTable(props.columns ?? [], props.rows ?? [])}`,\n});\n\nexport const Chart = defineComponent<Props>({\n name: 'Chart',\n title: 'Chart',\n description:\n '`bar` to compare categories, `line` for a trend over time. `data` is a list of points; `xKey` names the category/time field and each series names a numeric field.',\n props: obj(\n {\n type: str('Chart type', { enum: ['bar', 'line'] }),\n title: str(),\n xKey: str('Field of each point used for the x axis'),\n series: arr(obj({ key: str('Numeric field'), label: str() }, ['key']), {\n minItems: 1,\n maxItems: 6,\n }),\n data: arr(row, { minItems: 1, maxItems: 200 }),\n unit: str('Unit shown after values, e.g. `KB` or `%`'),\n },\n ['type', 'xKey', 'series', 'data'],\n ),\n fallbackText: (props) => chartText(props),\n});\n\n/**\n * A chart as text. `line` → a table (x, then one column per series), which keeps every value\n * readable; `bar` → one bar per point, and per series when there are several, all on one scale so\n * bars of different series compare.\n */\nfunction chartText(props: Props): string {\n const series: { key: string; label?: string }[] = (props.series ?? []).filter(\n (each: unknown) => typeof (each as { key?: unknown })?.key === 'string',\n );\n const data: Props[] = props.data ?? [];\n const unit = props.unit ? ` ${s(props.unit)}` : '';\n const labelOf = (each: { key: string; label?: string }) => s(each.label) || each.key;\n if (props.type === 'line') {\n const columns = [\n { key: s(props.xKey), label: s(props.xKey) },\n ...series.map((each) => ({ key: each.key, label: `${labelOf(each)}${unit}` })),\n ];\n return `${heading(props)}${textTable(columns, data, 20)}`;\n }\n const max = Math.max(\n 0,\n ...data.flatMap((point) => series.map((each) => Math.abs(Number(point[each.key]) || 0))),\n );\n const shown = data.slice(0, 20);\n const lines: string[] = [];\n if (series.length <= 1) {\n const key = series[0]?.key ?? '';\n for (const point of shown) {\n lines.push(\n `${s(point[props.xKey]).slice(0, 18).padEnd(18)} ${bar(Number(point[key]) || 0, max)} ${s(point[key])}${unit}`,\n );\n }\n } else {\n const width = Math.min(18, Math.max(...series.map((each) => labelOf(each).length)));\n for (const point of shown) {\n lines.push(s(point[props.xKey]).slice(0, 18));\n for (const each of series) {\n lines.push(\n ` ${labelOf(each).slice(0, width).padEnd(width)} ${bar(Number(point[each.key]) || 0, max)} ${s(point[each.key])}${unit}`,\n );\n }\n }\n }\n if (data.length > shown.length) lines.push(`… ${data.length - shown.length} more points`);\n return `${heading(props)}\\`\\`\\`\\n${lines.join('\\n')}\\n\\`\\`\\``;\n}\n\nexport const KpiCards = defineComponent<Props>({\n name: 'KpiCards',\n title: 'KPI cards',\n description: 'A few key numbers (metrics, totals, counts) as cards.',\n props: obj(\n {\n title: str(),\n items: arr(\n obj(\n {\n label: str(),\n value: { type: ['string', 'number'] },\n delta: str('Change, e.g. `+12%`'),\n trend: str(undefined, { enum: ['up', 'down', 'flat'] }),\n hint: str(),\n },\n ['label', 'value'],\n ),\n { minItems: 1, maxItems: 8 },\n ),\n },\n ['items'],\n ),\n fallbackText: (props) =>\n `${heading(props)}${(props.items ?? [])\n .map(\n (item: Props) =>\n `• *${s(item.label)}:* ${s(item.value)}${item.delta ? ` (${s(item.delta)})` : ''}`,\n )\n .join('\\n')}`,\n});\n\nexport const SourceCards = defineComponent<Props>({\n name: 'SourceCards',\n title: 'Sources',\n description: 'The documents, pages or links an answer is based on, as cards.',\n props: obj(\n {\n title: str(),\n items: arr(\n obj({ title: str(), url: str(), snippet: str(), source: str('e.g. Wiki, GitHub') }, [\n 'title',\n ]),\n { minItems: 1, maxItems: 12 },\n ),\n },\n ['items'],\n ),\n fallbackText: (props) =>\n `${heading(props)}${(props.items ?? [])\n .map(\n (item: Props) =>\n `• ${item.url ? `<${s(item.url)}|${s(item.title)}>` : s(item.title)}${item.source ? ` — ${s(item.source)}` : ''}`,\n )\n .join('\\n')}`,\n});\n\nexport const Checklist = defineComponent<Props>({\n name: 'Checklist',\n title: 'Checklist',\n description: 'Steps or a to-do list with done/not-done state.',\n props: obj(\n {\n title: str(),\n items: arr(obj({ label: str(), done: { type: 'boolean' }, note: str() }, ['label']), {\n minItems: 1,\n maxItems: 50,\n }),\n },\n ['items'],\n ),\n fallbackText: (props) =>\n `${heading(props)}${(props.items ?? [])\n .map(\n (item: Props) =>\n `${item.done ? '☑' : '☐'} ${s(item.label)}${item.note ? ` — _${s(item.note)}_` : ''}`,\n )\n .join('\\n')}`,\n});\n\nexport const Timeline = defineComponent<Props>({\n name: 'Timeline',\n title: 'Timeline',\n description: 'Events in chronological order (the history of a project, an incident, a deal).',\n props: obj(\n {\n title: str(),\n events: arr(obj({ date: str(), title: str(), description: str() }, ['title']), {\n minItems: 1,\n maxItems: 50,\n }),\n },\n ['events'],\n ),\n fallbackText: (props) =>\n `${heading(props)}${(props.events ?? [])\n .map(\n (event: Props) =>\n `• ${event.date ? `*${s(event.date)}* ` : ''}${s(event.title)}${event.description ? ` — ${s(event.description)}` : ''}`,\n )\n .join('\\n')}`,\n});\n\nexport const CodeBlock = defineComponent<Props>({\n name: 'CodeBlock',\n title: 'Code',\n description: 'A code snippet or file excerpt with syntax highlighting.',\n props: obj({ title: str(), language: str(), code: str() }, ['code']),\n fallbackText: (props) => `${heading(props)}\\`\\`\\`\\n${s(props.code)}\\n\\`\\`\\``,\n});\n\nexport const Diff = defineComponent<Props>({\n name: 'Diff',\n title: 'Diff',\n description: 'A before/after change to a text or code file, as a line diff.',\n props: obj({ title: str(), language: str(), before: str(), after: str() }, ['before', 'after']),\n fallbackText: (props) =>\n `${heading(props)}\\`\\`\\`\\n${lineDiff(s(props.before), s(props.after))\n .map((line) => `${line.op === 'add' ? '+' : line.op === 'del' ? '-' : ' '} ${line.text}`)\n .join('\\n')}\\n\\`\\`\\``,\n});\n\nexport const Callout = defineComponent<Props>({\n name: 'Callout',\n title: 'Callout',\n description: 'A short note, warning or success message, emphasized.',\n props: obj(\n {\n tone: str(undefined, { enum: ['info', 'success', 'warning', 'danger'] }),\n title: str(),\n text: str(),\n },\n ['text'],\n ),\n fallbackText: (props) =>\n `${props.tone === 'warning' || props.tone === 'danger' ? ':warning: ' : ':information_source: '}${heading(props)}${s(props.text)}`,\n});\n\nexport const Stack = defineComponent<Props>({\n name: 'Stack',\n title: 'Stack',\n description: 'Lays its children out vertically (or horizontally with direction=row).',\n props: obj({ direction: str(undefined, { enum: ['column', 'row'] }), gap: { type: 'number' } }),\n children: true,\n fallbackText: () => '',\n});\n\nexport const Card = defineComponent<Props>({\n name: 'Card',\n title: 'Card',\n description: 'A box with an optional title around its children.',\n props: obj({ title: str(), subtitle: str() }),\n children: true,\n fallbackText: (props) =>\n props.title ? `*${s(props.title)}*${props.subtitle ? ` — ${s(props.subtitle)}` : ''}` : '',\n});\n\nexport const Heading = defineComponent<Props>({\n name: 'Heading',\n title: 'Heading',\n description: 'A heading.',\n props: obj({ text: str() }, ['text']),\n fallbackText: (props) => `*${s(props.text)}*`,\n});\n\nexport const Text = defineComponent<Props>({\n name: 'Text',\n title: 'Text',\n description: 'A paragraph of plain text (no markdown).',\n props: obj({ text: str(), muted: { type: 'boolean' } }, ['text']),\n fallbackText: (props) => s(props.text),\n});\n\nexport const Badge = defineComponent<Props>({\n name: 'Badge',\n title: 'Badge',\n description: 'A small label.',\n props: obj(\n {\n text: str(),\n tone: str(undefined, { enum: ['neutral', 'brand', 'success', 'warning', 'danger'] }),\n },\n ['text'],\n ),\n fallbackText: (props) => `[${s(props.text)}]`,\n});\n\nexport const Link = defineComponent<Props>({\n name: 'Link',\n title: 'Link',\n description: 'A link to an http(s) URL.',\n props: obj({ text: str(), url: str(undefined, { pattern: '^https?://' }) }, ['text', 'url']),\n fallbackText: (props) => `<${s(props.url)}|${s(props.text || props.url)}>`,\n});\n\nexport const Image = defineComponent<Props>({\n name: 'Image',\n title: 'Image',\n description: 'An image from an https URL.',\n props: obj({ url: str(undefined, { pattern: '^https://' }), alt: str() }, ['url']),\n fallbackText: (props) => s(props.url),\n});\n\n/** Content components: data a model shows. */\nexport const BUILTIN_COMPONENTS: readonly ComponentDefinition<Props>[] = [\n DataTable,\n Chart,\n KpiCards,\n SourceCards,\n Checklist,\n Timeline,\n CodeBlock,\n Diff,\n Callout,\n];\n\n/** Layout and text primitives, mostly for composing trees (`Stack`, `Card` take children). */\nexport const LAYOUT_COMPONENTS: readonly ComponentDefinition<Props>[] = [\n Stack,\n Card,\n Heading,\n Text,\n Badge,\n Link,\n Image,\n];\n","import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { Chart, DataTable } from './builtins.js';\nimport {\n type Catalog,\n type CatalogOptions,\n type ComponentDefinition,\n defineCatalog,\n defineComponent,\n} from './catalog.js';\nimport { type JsonSchema, formatIssues, validateProps } from './schema.js';\nimport { componentToText } from './text.js';\n\n/** Plain, durable data. Renderer functions and binary attachments never enter a UI frame. */\nexport interface ComponentPresentation<P = Record<string, unknown>> {\n component: string;\n props: P;\n version: number;\n fallbackText: string;\n}\n\nexport interface ComponentFactory<Input, Output = Input> {\n (props: Input): Promise<ComponentPresentation<Output>>;\n readonly definition: ComponentDefinition<Output>;\n}\n\n/** Reject values JSON would silently discard/coerce, and detach from caller-owned objects. */\nexport function snapshotComponentPresentation<T>(value: T): T {\n const seen = new Set<object>();\n const check = (entry: unknown): void => {\n if (entry === null || typeof entry === 'string' || typeof entry === 'boolean') return;\n if (typeof entry === 'number' && Number.isFinite(entry)) return;\n if (typeof entry !== 'object' || entry === null)\n throw new TypeError('genui: presentation must contain only JSON values');\n if (seen.has(entry))\n throw new TypeError('genui: presentation must contain acyclic JSON values');\n if (\n !Array.isArray(entry) &&\n Object.getPrototypeOf(entry) !== Object.prototype &&\n Object.getPrototypeOf(entry) !== null\n )\n throw new TypeError('genui: presentation must contain plain JSON objects');\n seen.add(entry);\n for (const item of Object.values(entry)) check(item);\n seen.delete(entry);\n };\n check(value);\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nexport function createComponent<S extends StandardSchemaV1>(\n definition: Omit<ComponentDefinition<StandardSchemaV1.InferOutput<S>>, 'props'> & { props: S },\n options?: CatalogOptions,\n): ComponentFactory<StandardSchemaV1.InferInput<S>, StandardSchemaV1.InferOutput<S>>;\nexport function createComponent<P = Record<string, unknown>>(\n definition: ComponentDefinition<P>,\n options?: CatalogOptions,\n): ComponentFactory<P>;\nexport function createComponent<P>(\n definition: ComponentDefinition<P>,\n options: CatalogOptions = {},\n): unknown {\n defineComponent(definition);\n const catalog = defineCatalog([definition], options);\n const factory = async (props: unknown): Promise<ComponentPresentation> => {\n const result = await validateProps(definition.props, props, catalog.validator);\n if (!result.ok)\n throw new Error(`genui: invalid ${definition.name} props: ${formatIssues(result.issues)}`);\n const normalized = snapshotComponentPresentation(result.value);\n if (typeof normalized !== 'object' || normalized === null || Array.isArray(normalized))\n throw new TypeError('genui: component props must be a JSON object');\n const portable = await catalog.validate(definition.name, normalized);\n if (\n !portable.ok ||\n canonicalJson(snapshotComponentPresentation(portable.value)) !== canonicalJson(normalized)\n ) {\n throw new Error(\n `genui: ${definition.name} requires outputProps accepting stable normalized JSON props`,\n );\n }\n return {\n component: definition.name,\n props: normalized as Record<string, unknown>,\n version: definition.version ?? 1,\n fallbackText: componentToText(\n catalog,\n definition.name,\n normalized as Record<string, unknown>,\n ),\n };\n };\n return Object.assign(factory, { definition });\n}\n\nexport type ComponentRenderer<P = Record<string, unknown>, Context = unknown> = (\n props: P,\n context?: Context,\n) => unknown | Promise<unknown>;\n\nexport interface ComponentManifest {\n name: string;\n title: string;\n description: string;\n version: number;\n props?: JsonSchema;\n}\n\nexport interface ComponentRegistry<Context = unknown> {\n readonly catalog: Catalog;\n readonly manifest: readonly ComponentManifest[];\n register<P>(\n definition: ComponentDefinition<P>,\n renderers: Record<string, ComponentRenderer<P, Context>>,\n ): this;\n /** Revalidate against the app's authoritative definition and regenerate trusted fallback text. */\n prepare(presentation: ComponentPresentation): Promise<ComponentPresentation>;\n render(presentation: ComponentPresentation, channel: string, context?: Context): Promise<unknown>;\n}\n\n/** A registry is owned by one app/tenant; registering never mutates a shared singleton. */\nexport function createComponentRegistry<Context = unknown>(\n options: CatalogOptions = {},\n): ComponentRegistry<Context> {\n let catalog = defineCatalog([], options);\n const channels = new Map<string, Record<string, ComponentRenderer<never, Context>>>();\n const registry: ComponentRegistry<Context> = {\n get catalog() {\n return catalog;\n },\n get manifest() {\n return catalog.components.map((definition) => {\n const props = catalog.jsonSchemaFor(definition.name);\n return {\n name: definition.name,\n title: definition.title,\n description: definition.description,\n version: definition.version ?? 1,\n ...(props === undefined ? {} : { props: snapshotComponentPresentation(props) }),\n };\n });\n },\n register(definition, renderers) {\n if (catalog.has(definition.name))\n throw new Error(`genui: component \"${definition.name}\" is already registered`);\n catalog = catalog.extend([definition]);\n channels.set(definition.name, { ...renderers } as Record<\n string,\n ComponentRenderer<never, Context>\n >);\n return this;\n },\n async prepare(presentation) {\n const definition = catalog.get(presentation.component);\n if (definition === undefined)\n throw new Error(`genui: unknown component \"${presentation.component}\"`);\n if (presentation.version !== (definition.version ?? 1))\n throw new Error(`genui: component \"${presentation.component}\" version mismatch`);\n const validated = await catalog.validate(presentation.component, presentation.props);\n if (!validated.ok)\n throw new Error(\n `genui: invalid ${presentation.component} props: ${formatIssues(validated.issues)}`,\n );\n const props = snapshotComponentPresentation(validated.value);\n if (typeof props !== 'object' || props === null || Array.isArray(props))\n throw new TypeError('genui: component props must be a JSON object');\n return {\n component: definition.name,\n props,\n version: definition.version ?? 1,\n fallbackText: componentToText(catalog, definition.name, props),\n };\n },\n async render(presentation, channel, context) {\n const prepared = await this.prepare(presentation);\n const mapping = channels.get(prepared.component);\n const renderer =\n mapping === undefined\n ? undefined\n : Object.hasOwn(mapping, channel)\n ? mapping[channel]\n : Object.hasOwn(mapping, 'text')\n ? mapping.text\n : undefined;\n return renderer === undefined\n ? prepared.fallbackText\n : renderer(prepared.props as never, context);\n },\n };\n return registry;\n}\n\nexport type TableCell = string | number | boolean | null;\nexport interface TableProps {\n title?: string;\n columns: {\n key: string;\n label: string;\n align?: 'left' | 'right' | 'center';\n format?: 'text' | 'number' | 'currency' | 'percent' | 'date' | 'link';\n }[];\n rows: Record<string, TableCell>[];\n}\nexport interface ChartProps {\n type: 'bar' | 'line';\n title?: string;\n xKey: string;\n series: { key: string; label?: string }[];\n data: Record<string, TableCell>[];\n unit?: string;\n}\n\nexport const table = createComponent<TableProps>(DataTable);\nexport const chart = createComponent<ChartProps>(Chart);\n\n/** Prepare all JSON emissions before any sink receives a partial batch. Factories validate schemas. */\nexport function validatePresentationBatch(\n presentations: ComponentPresentation<object> | readonly ComponentPresentation<object>[],\n): ComponentPresentation[] {\n const batch = Array.isArray(presentations) ? presentations : [presentations];\n return batch.map((item: ComponentPresentation<object>) => {\n const presentation = snapshotComponentPresentation(item);\n if (\n typeof presentation !== 'object' ||\n presentation === null ||\n typeof presentation.component !== 'string' ||\n !/^[A-Za-z][A-Za-z0-9]{0,63}$/.test(presentation.component) ||\n !Number.isSafeInteger(presentation.version) ||\n presentation.version <= 0 ||\n typeof presentation.fallbackText !== 'string' ||\n typeof presentation.props !== 'object' ||\n presentation.props === null ||\n Array.isArray(presentation.props)\n ) {\n throw new TypeError('genui: invalid component presentation');\n }\n return presentation as ComponentPresentation;\n });\n}\n\n/** Object order is immaterial; array order remains part of the portable contract. */\nfunction canonicalJson(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(canonicalJson).join(',')}]`;\n if (typeof value === 'object' && value !== null) {\n const record = value as Record<string, unknown>;\n return `{${Object.keys(record)\n .sort()\n .map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`)\n .join(',')}}`;\n }\n return JSON.stringify(value);\n}\n","import { validatePresentationBatch } from './genui/registry.js';\nimport type { AiToolCtx, ToolHandler } from './spi/tool.js';\n\n/** Presentation failures must never cause a successful side effect to be retried. */\nexport async function emitToolPresentations<I, O>(\n handler: ToolHandler<I, O>,\n output: O,\n ctx: AiToolCtx,\n toolName: string,\n): Promise<void> {\n if (handler.present === undefined) return;\n try {\n const result = await handler.present(output, ctx);\n if (result === undefined) return;\n const batch = validatePresentationBatch(result);\n for (const presentation of batch) {\n await ctx.emitUi(presentation.component, presentation.props, {\n version: presentation.version,\n fallbackText: presentation.fallbackText,\n });\n }\n } catch (error) {\n if (ctx.onPresentationError !== undefined) {\n try {\n await ctx.onPresentationError(error, { toolName });\n return;\n } catch (reportError) {\n console.warn(`Tool \"${toolName}\" presentation error reporter failed`, reportError);\n }\n } else {\n console.warn(`Tool \"${toolName}\" presentation failed after successful execution`, error);\n }\n }\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport {\n canonicalActionProposalJson,\n snapshotActionProposal,\n} from './action-proposal-transitions.js';\nimport type { RolesPolicy } from './spi/roles-policy.js';\nimport type { AiToolCtx, ToolDescribeScope, ToolHandler, ToolPreflightResult } from './spi/tool.js';\nimport {\n canActorUseTool,\n filterToolsByAllowList,\n filterToolsByCanUse,\n filterToolsByEnabled,\n filterToolsByRole,\n isToolEnabled,\n} from './tool-filters.js';\nimport { emitToolPresentations } from './tool-presentations.js';\nimport { createNoopEmitUi } from './tool-ui.js';\nimport type { Actor, ToolDefinition, ToolSpec } from './types.js';\n\n/** Thrown when an actor invokes a tool their role is not allowed. */\nexport class ToolForbiddenError extends Error {\n constructor(public readonly toolName: string) {\n super(`Tool \"${toolName}\" is not allowed for this role`);\n this.name = 'ToolForbiddenError';\n }\n}\n\n/**\n * Thrown when a registered tool is invoked while this deployment has it turned off (`enabled` /\n * `isEnabled()`). Distinct from {@link ToolForbiddenError}, which is about the actor, and from\n * {@link ToolNotFoundError}, which is about a name nobody registered — an operator reading a log\n * needs to tell \"you flipped the flag\" apart from \"that tool does not exist in this build\".\n *\n * Reachable in normal operation, not just from a forged call: a HITL `action` approved before the\n * flag was turned off runs its tool afterwards.\n */\nexport class ToolDisabledError extends Error {\n constructor(public readonly toolName: string) {\n super(`Tool \"${toolName}\" is disabled in this deployment`);\n this.name = 'ToolDisabledError';\n }\n}\n\n/** Thrown when a tool is invoked that was never registered. */\nexport class ToolNotFoundError extends Error {\n constructor(public readonly toolName: string) {\n super(`Tool \"${toolName}\" is not registered`);\n this.name = 'ToolNotFoundError';\n }\n}\n\n/** Thrown when a tool's input fails its Standard Schema validation. */\nexport class ToolInputInvalidError extends Error {\n constructor(\n public readonly toolName: string,\n public readonly issues: readonly StandardSchemaV1.Issue[],\n ) {\n super(\n `Invalid input for tool \"${toolName}\": ${issues.map((issue) => issue.message).join('; ')}`,\n );\n this.name = 'ToolInputInvalidError';\n }\n}\n\n/** An action refused by its current domain state, rather than by a person. */\nexport class ToolPreflightDeniedError extends Error {\n constructor(\n public readonly toolName: string,\n public readonly reason: string,\n ) {\n super(reason);\n this.name = 'ToolPreflightDeniedError';\n }\n}\n\n/** Trusted preparation or a fresh schema parse changed the approved JSON input. */\nexport class ToolInputDriftError extends Error {\n constructor(public readonly toolName: string) {\n super(`Tool \"${toolName}\" input differs from its trusted snapshot`);\n this.name = 'ToolInputDriftError';\n }\n}\n\nfunction assertTrustedInput(name: string, value: unknown, approved: unknown): void {\n try {\n if (canonicalActionProposalJson(value) === canonicalActionProposalJson(approved)) return;\n } catch {\n // A non-JSON value cannot match a trusted JSON snapshot, including an explicitly undefined\n // approvedInput. Ordinary invocations never serialize the schema's parsed value.\n }\n throw new ToolInputDriftError(name);\n}\n\ninterface Entry {\n spec: ToolSpec;\n handler: ToolHandler;\n}\n\n/**\n * Holds every registered tool and gates invocation.\n *\n * Note: `definitionsFor` returns NEUTRAL definitions (no `execute`). The agent loop runs\n * each tool itself as a (durable) step — so even read tools are not auto-executed by the\n * model. `action` tools additionally require HITL approval before the loop runs them.\n */\nexport class ToolRegistry {\n private readonly entries = new Map<string, Entry>();\n\n register(spec: ToolSpec, handler: ToolHandler): void {\n this.entries.set(spec.name, { spec, handler });\n }\n\n /** Whether a successful preflight shortcut has UI to journal. */\n hasPresentation(name: string): boolean {\n return typeof this.entries.get(name)?.handler.present === 'function';\n }\n\n /** Present an already authorized successful domain result without executing its action again. */\n async presentOutput(name: string, output: unknown, ctx: AiToolCtx): Promise<void> {\n const entry = this.entries.get(name);\n if (entry !== undefined) await emitToolPresentations(entry.handler, output, ctx, name);\n }\n\n has(name: string): boolean {\n return this.entries.has(name);\n }\n\n /**\n * Give a name back, and report whether it was held. For an importer that registered tools on\n * someone else's behalf — the MCP client is the one in this repo — and has to hand back the ones\n * its source stopped offering.\n *\n * The registry cannot tell whether a caller owns a name, so it does not try: whoever registered a\n * name is responsible for tracking that it did. Unregistering a name it does not own would\n * silently take a tool away from whoever does.\n */\n unregister(name: string): boolean {\n return this.entries.delete(name);\n }\n\n spec(name: string): ToolSpec | undefined {\n return this.entries.get(name)?.spec;\n }\n\n allSpecs(): ToolSpec[] {\n return [...this.entries.values()].map((entry) => entry.spec);\n }\n\n /**\n * The tools to offer the model for this actor+agent, after the four filter layers: what this\n * agent pinned, what this deployment has enabled, what this actor's role allows, and what each\n * tool's own `canUse` allows this actor.\n *\n * Every layer only ever removes tools, so no arrangement of them can widen what a turn reaches.\n * The agent's allow-list therefore goes FIRST, even though it is the narrowest statement: it is a\n * pure name-set match, while each of the three below it may be a round trip — an authz service, a\n * feature-flag store, an MCP server — and this runs once per model step. Asking those about a\n * tool the allow-list has already excluded is a call whose answer nothing reads.\n */\n async definitionsFor(\n actor: Actor,\n policy: RolesPolicy,\n allowedTools?: string[],\n scope: Omit<ToolDescribeScope, 'actor'> = {},\n ): Promise<ToolDefinition[]> {\n const visible = await this.visibleEntries(actor, policy, allowedTools);\n const definitions = await Promise.all(\n visible.map(async ({ spec, handler }) => {\n // After every gate: a tool this actor cannot reach is never asked to describe itself.\n const override =\n handler.describe === undefined ? undefined : await handler.describe({ actor, ...scope });\n if (override?.available === false) return null;\n return {\n name: spec.name,\n kind: spec.kind,\n description: override?.description ?? spec.description,\n inputSchema: override?.inputSchema ?? spec.inputSchema,\n };\n }),\n );\n return definitions.filter((definition): definition is ToolDefinition => definition !== null);\n }\n\n /**\n * The specs {@link definitionsFor} offers the model, whole — the same four gates (allow-list,\n * enabled, role, `canUse`) in the same order. For a surface that lists what an actor can reach\n * (`GET <base>/tools`), which must never disagree with what the model is actually shown.\n */\n async visibleSpecs(\n actor: Actor,\n policy: RolesPolicy,\n allowedTools?: string[],\n ): Promise<ToolSpec[]> {\n return (await this.visibleEntries(actor, policy, allowedTools)).map(({ spec }) => spec);\n }\n\n private async visibleEntries(\n actor: Actor,\n policy: RolesPolicy,\n allowedTools?: string[],\n ): Promise<Entry[]> {\n const pinnedNames = new Set(\n filterToolsByAllowList(this.allSpecs(), allowedTools).map((spec) => spec.name),\n );\n const pinned = [...this.entries.values()].filter((entry) => pinnedNames.has(entry.spec.name));\n const live = await filterToolsByEnabled(pinned);\n const allowedByRole = new Set(\n (\n await filterToolsByRole(\n live.map((entry) => entry.spec),\n actor,\n policy,\n )\n ).map((spec) => spec.name),\n );\n const roleScoped = live.filter((entry) => allowedByRole.has(entry.spec.name));\n return filterToolsByCanUse(roleScoped, actor);\n }\n\n /**\n * Run a tool. Re-checks that the tool is enabled and that the role allows it (defense-in-depth —\n * a call can reach here from a replayed durable step or an approval granted before the flag\n * moved, neither of which went through `definitionsFor` again) and re-parses the input via Zod.\n */\n async invoke(\n name: string,\n input: unknown,\n ctx: AiToolCtx,\n policy: RolesPolicy,\n options: InvokeOptions = {},\n ): Promise<unknown> {\n const { entry, value, ctx: withEmit } = await this.validated(name, input, ctx, policy, options);\n const trusted = Object.hasOwn(options, 'approvedInput');\n if (trusted) assertTrustedInput(name, value, options.approvedInput);\n const executionInput = trusted ? snapshotActionProposal(value) : value;\n const hookInput = trusted ? snapshotActionProposal(executionInput) : value;\n const result =\n entry.spec.kind === 'action'\n ? await entry.handler.preflight?.(hookInput, withEmit, { phase: 'execute' })\n : undefined;\n // The hook receives its own snapshot, so retained references cannot alter later execution.\n if (trusted) assertTrustedInput(name, hookInput, executionInput);\n if (result?.status === 'denied') throw new ToolPreflightDeniedError(name, result.reason);\n const output =\n result?.status === 'completed'\n ? result.output\n : await entry.handler.execute(executionInput, withEmit);\n await emitToolPresentations(entry.handler, output, withEmit, name);\n return output;\n }\n\n /** Authorize and validate without executing. The caller journals this result before approval. */\n async prepare(\n name: string,\n input: unknown,\n ctx: AiToolCtx,\n policy: RolesPolicy,\n options: PrepareOptions = {},\n ): Promise<ToolPreflightResult> {\n return (await this.prepareValidated(name, input, ctx, policy, options)).preflight;\n }\n\n /** Expose the single schema parse; snapshotInput opts proposal callers into immutable JSON. */\n async prepareValidated(\n name: string,\n input: unknown,\n ctx: AiToolCtx,\n policy: RolesPolicy,\n options: PrepareOptions = {},\n ): Promise<ToolPreparationResult> {\n const { entry, value, ctx: withEmit } = await this.validated(name, input, ctx, policy, options);\n const normalized = options.snapshotInput === true ? snapshotActionProposal(value) : value;\n const hookInput = options.snapshotInput === true ? snapshotActionProposal(normalized) : value;\n const preflight: ToolPreflightResult = (entry.spec.kind === 'action'\n ? await entry.handler.preflight?.(hookInput, withEmit, { phase: 'prepare' })\n : undefined) ?? { status: 'ready' };\n // A hook can retain its input or mutate nested values after an await. Only the isolated\n // normalized snapshot can be approved; reject mutation before exposing its confirmation.\n if (options.snapshotInput === true) assertTrustedInput(name, hookInput, normalized);\n return { input: normalized, preflight };\n }\n\n private async validated(\n name: string,\n input: unknown,\n ctx: AiToolCtx,\n policy: RolesPolicy,\n options: InvokeOptions,\n ): Promise<{ entry: Entry; value: unknown; ctx: AiToolCtx }> {\n const entry = this.entries.get(name);\n if (entry === undefined) {\n throw new ToolNotFoundError(name);\n }\n if (!(await isToolEnabled(entry.spec, entry.handler))) {\n throw new ToolDisabledError(name);\n }\n if (!(await policy.can(ctx.actor, entry.spec))) {\n throw new ToolForbiddenError(name);\n }\n if (!(await canActorUseTool(ctx.actor, entry.handler))) {\n throw new ToolForbiddenError(name);\n }\n // Last, like the persona filter on the offer: the same layers in the same order, so a call the\n // model was never offered under this persona cannot run because the model named it anyway.\n if (options.allowedTools !== undefined && !options.allowedTools.includes(name)) {\n throw new ToolForbiddenError(name);\n }\n const validation = await entry.spec.inputSchema['~standard'].validate(input);\n if (validation.issues !== undefined) {\n throw new ToolInputInvalidError(name, validation.issues);\n }\n // `emitUi` is part of the context's contract; a caller without a conversation (a test, a script,\n // a JavaScript host) gets the no-op rather than a tool that crashes calling it.\n const withEmit: AiToolCtx =\n typeof ctx.emitUi === 'function' ? ctx : { ...ctx, emitUi: createNoopEmitUi(ctx.requestId) };\n return { entry, value: validation.value, ctx: withEmit };\n }\n}\n\n/** Per-call narrowing for {@link ToolRegistry.invoke}. */\nexport interface InvokeOptions {\n /**\n * Only these tool names may run — the turn's persona allow-list. Checked after `enabled`, the\n * roles policy and `canUse`. Undefined → no such check (every caller predating personas).\n */\n allowedTools?: readonly string[];\n /** Trusted normalized JSON input. Own-property presence requires comparison even if undefined. */\n approvedInput?: unknown;\n}\n\nexport interface PrepareOptions extends InvokeOptions {\n /** Preserve a detached normalized JSON snapshot and refuse mutation by the prepare hook. */\n snapshotInput?: boolean;\n}\n\nexport interface ToolPreparationResult {\n input: unknown;\n preflight: ToolPreflightResult;\n}\n\n/**\n * Default gate: a tool that names `roles` is callable by an actor holding one of them; a tool that\n * names none falls back to `defaultRoles`, and an empty list — the default — restricts nobody. So\n * out of the box every tool is callable by whoever the `ActorResolver` resolved (an anonymous\n * visitor included, when no resolver is configured); restrict with `@AiTool({ roles })` per tool,\n * `AgentModule.forRoot({ defaultRoles })` module-wide, or a `rolesPolicy` of your own. `action`\n * tools still park on approval either way.\n *\n * A tool gated by an `ability` and naming no `roles` is refused: this policy cannot evaluate an\n * ability, and falling through to the open default would hand the tool to everyone. Bind an\n * ability-aware policy (`AgentAuthzModule`) to reach it — or give the tool `roles` as well.\n */\nexport class DefaultRolesPolicy implements RolesPolicy {\n /** What an empty roles list means here — see {@link EmptyRoles}. */\n readonly emptyRoles: EmptyRoles;\n\n constructor(\n readonly defaultRoles: string[] = [],\n options: RolesPolicyOptions = {},\n ) {\n this.emptyRoles = options.emptyRoles ?? 'allow';\n }\n\n can(actor: Actor, tool: ToolSpec): boolean {\n if (tool.ability !== undefined && tool.roles === undefined) return false;\n const allowed = tool.roles ?? this.defaultRoles;\n if (allowed.length === 0) return this.emptyRoles === 'allow';\n return (actor.roles ?? []).some((role) => allowed.includes(role));\n }\n}\n\n/**\n * What an empty roles list means to {@link DefaultRolesPolicy}: `'allow'` (the default) — no\n * restriction; `'deny'` — nobody.\n *\n * The open default is what makes a one-line `AgentModule.forRoot({ model })` a working chat. It is\n * also why an app that used `[]` to DENY — a `roles` computed from permissions that can come out\n * empty, `defaultRoles: []` on a multi-tenant MCP surface — reaches everyone instead, silently.\n * `'deny'` keeps such an app closed.\n */\nexport type EmptyRoles = 'allow' | 'deny';\n\nexport interface RolesPolicyOptions {\n /** What an empty roles list means. Default `'allow'`. */\n emptyRoles?: EmptyRoles;\n}\n\n/**\n * The closed gate — {@link DefaultRolesPolicy} with `emptyRoles: 'deny'`: the actor needs a role the\n * tool declares (else one of the default roles). A tool with no `roles` and no default roles, or with\n * an explicitly empty list, reaches nobody. What `AgentModule.forRoot({ emptyRoles: 'deny' })` binds.\n */\nexport class ClosedRolesPolicy extends DefaultRolesPolicy {\n constructor(defaultRoles: string[] = []) {\n super(defaultRoles, { emptyRoles: 'deny' });\n }\n}\n\n/**\n * Close a policy you did not build: a tool whose roles come out empty — declared `[]`, or undeclared\n * with no default roles to fall back on — reaches nobody; anything else is the inner policy's call.\n *\n * The default roles are read off a {@link DefaultRolesPolicy}; any other inner policy keeps its own\n * defaults to itself, so for it an undeclared list counts as empty. A tool gated by `ability` has\n * nothing to do with roles and is always left to the inner policy. What the MCP server's\n * `emptyRoles: 'deny'` wraps the agent's shared policy in.\n */\nexport function closeEmptyRoles(inner: RolesPolicy): RolesPolicy {\n const defaults = inner instanceof DefaultRolesPolicy ? inner.defaultRoles : [];\n return {\n can(actor: Actor, tool: ToolSpec): boolean | Promise<boolean> {\n if (tool.ability === undefined && (tool.roles ?? defaults).length === 0) {\n return false;\n }\n return inner.can(actor, tool);\n },\n };\n}\n","import { createHash } from 'node:crypto';\nimport { trace } from '@dudousxd/nestjs-diagnostics';\nimport type { PayloadOf } from '@dudousxd/nestjs-diagnostics';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { resolveActionProposalApproval } from './action-proposal-approval.js';\nimport { prepareActionProposal } from './action-proposal-preparation.js';\nimport { type ActionApprovalMode, actionProposalReceipt } from './action-proposal-receipt.js';\nimport { isControlFlowSignal } from './control-flow.js';\nimport {\n type ToolCallOutcome,\n danglingToolCallIds,\n settleDanglingToolCalls,\n} from './dangling-tool-calls.js';\nimport {\n type DetachedDelegationReceipt,\n detachedDelivered,\n detachedStarted,\n} from './delegation.js';\nimport {\n type AgentSpanEvent,\n publishAgentDelegated,\n publishAgentMemoryResolved,\n publishAgentMemoryWritten,\n publishAgentMessage,\n publishAgentQuotaExceeded,\n publishAgentRetrieved,\n publishAgentRunFinished,\n publishAgentRunStarted,\n publishAgentSkillsResolved,\n publishAgentToolCall,\n publishAgentToolRetry,\n} from './diagnostics.js';\nimport {\n ASK_TOOL_NAME,\n type AgentIntake,\n DEFAULT_INTAKE_PREAMBLE,\n type ElicitationReply,\n type ElicitationRequest,\n type ElicitationResult,\n askInputSchema,\n askToolDefinition,\n normalizeElicitationReply,\n settleElicitation,\n} from './elicitation.js';\nimport { estimateCost } from './governance/compute.js';\nimport {\n type MemoryConfig,\n type MemoryDigest,\n type MemoryRecord,\n REMEMBER_TOOL_NAME,\n buildMemoryBlock,\n offerMemories,\n rememberInputSchema,\n withMemoryTool,\n writeMemory,\n} from './memory.js';\nimport { type ResolveToolUiCatalog, createNegotiatedUiCollector } from './negotiated-tool-ui.js';\nimport { findPersona, intersectAllowLists } from './personas.js';\nimport {\n createFrameBuffer,\n createIncrementalGate,\n gateFollowUps,\n gateTail,\n releaseGatedFrames,\n resolveGateLookback,\n resolveOutputGateMode,\n runInputProcessors,\n runOutputProcessors,\n} from './processors.js';\nimport { isReplayIntegrityError } from './replay-integrity.js';\nimport {\n SKILL_TOOL_NAME,\n type SkillContext,\n type SkillOffer,\n type SkillsConfig,\n buildSkillsBlock,\n loadSkill,\n offerSkills,\n skillInputSchema,\n withSkillTool,\n} from './skills.js';\nimport type {\n ActionProposalStore,\n ActionProposalSupersessionStore,\n} from './spi/action-proposal-store.js';\nimport type { AgentStore, ThreadTurnReader } from './spi/agent-store.js';\nimport {\n type ApprovalPolicy,\n type ApprovalRequirement,\n DefaultApprovalPolicy,\n} from './spi/approval-policy.js';\nimport type {\n HistoryPolicy,\n HistoryPolicyContext,\n HistorySelection,\n} from './spi/history-policy.js';\nimport { withSelectedModel } from './spi/model-catalog.js';\nimport type {\n BufferedModelTurnResult,\n ModelProvider,\n ModelTurnResult,\n} from './spi/model-provider.js';\nimport type { AgentPricingStore, CurrentModelPrice } from './spi/pricing-store.js';\nimport {\n type InputProcessor,\n type OutputProcessor,\n OutputRejectedError,\n type ProcessedPrompt,\n type ProcessorContext,\n} from './spi/processors.js';\nimport type { QuotaStore } from './spi/quota-store.js';\nimport type { Passage, Retriever } from './spi/retriever.js';\nimport type { RolesPolicy } from './spi/roles-policy.js';\nimport type { SinkWriter, StreamError } from './spi/token-stream-sink.js';\nimport type { AiToolCtx, ToolPreflightResult } from './spi/tool.js';\nimport {\n type AgentStreamEvent,\n type AgentUiComponent,\n encodeStreamEvent,\n} from './stream-events.js';\nimport {\n DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION,\n StructuredOutputError,\n repairInstruction,\n validateStructured,\n} from './structured-output.js';\nimport type { ToolRegistry } from './tool-registry.js';\nimport { invokeWithTransientRetry, resolveToolTransientRetryNumbers } from './tool-retry.js';\nimport type { ToolTransientRetrySetting } from './tool-retry.js';\nimport {\n createNoopEmitUi,\n createUiCollector,\n escapeUnsafeToolUiText,\n mergeUi,\n unwrapToolStepOutput,\n wrapToolPreflightDenied,\n wrapToolStepOutput,\n} from './tool-ui.js';\nimport { observeTurnFrames, withTurnFrames } from './turn-frames.js';\nimport type {\n AgentRunInput,\n Decision,\n HumanReply,\n LlmStepEnvelope,\n MessageUsage,\n ModelMessage,\n Persona,\n PromptBuilder,\n PromptContext,\n PromptContributor,\n StoredMessage,\n ToolCallRequest,\n ToolDefinition,\n ToolKind,\n ToolResult,\n ToolSpec,\n ToolStepCtx,\n ToolStepEnvelope,\n TurnPersona,\n} from './types.js';\n\nexport interface AgentLoopDeps<TOutput = unknown> {\n actionApprovalMode?: ActionApprovalMode;\n resolveUiCatalog?: ResolveToolUiCatalog;\n model: ModelProvider;\n store: AgentStore;\n registry: ToolRegistry;\n rolesPolicy: RolesPolicy;\n /**\n * Who has to approve an `action` call, and for how long the request stays open. Undefined →\n * {@link DefaultApprovalPolicy}: the requester, with no expiry — the behaviour before the SPI.\n */\n approvalPolicy?: ApprovalPolicy;\n quota?: QuotaStore;\n /**\n * Fallback accounting label when the provider's turn result doesn't report a `modelId`.\n * Optional — a provider that reports its own model makes this unnecessary.\n */\n modelId?: string;\n /** Pre-computed (YYYY-MM-DD) so the loop body stays deterministic under durable replay. */\n day: string;\n /** The agent's base prompt. A flat string, or a {@link PromptBuilder} resolved per turn. */\n systemPrompt: string | PromptBuilder;\n /**\n * Cross-agent system-prompt contributors, applied in order AFTER the agent's base prompt. Each\n * returns a section to append (or `null` to skip this turn). The app registers them via\n * `@SystemPromptContributor()`; the loop composes base + contributors into the effective prompt.\n */\n promptContributors?: PromptContributor[];\n maxSteps?: number;\n /**\n * How deep agent→agent delegation may nest before the loop refuses further hops.\n * Defaults to {@link MAX_DELEGATION_DEPTH}.\n *\n * It bounds NESTING, never fan-out: how many agents a turn delegates to is the model's, one tool\n * call each, and nothing here caps that. What it guards is a hop the model cannot see — a\n * `delegatesTo` cycle (A→B→A), where each agent is making one reasonable call and the recursion\n * is a property of the wiring rather than of any decision.\n */\n maxDelegationDepth?: number;\n /**\n * How many times one agent may appear on a single delegation chain.\n * Defaults to {@link DEFAULT_MAX_AGENT_APPEARANCES}.\n *\n * This is the guard the depth ceiling was a proxy for, made exact: the loop compares the target\n * against {@link AgentRunInput.delegationPath} and knows whether the chain has been here before,\n * and how often. A chain of eight DISTINCT agents is long, not looping, and no longer refused for\n * resembling one.\n */\n maxAgentAppearances?: number;\n /** Optional host handle threaded to tool ctx (e.g. an ORM EntityManager). */\n host?: unknown;\n /** Agent-level tool allow-list. Undefined → all tools (after role filtering). */\n toolAllowList?: string[];\n /**\n * The agent's personas. Read ONLY when the run names one (`AgentRunInput.persona`), and then only\n * once, inside the `persona:resolve` checkpoint — so a replay runs under the persona the turn\n * started with even after this list changed. Undefined → no personas.\n */\n personas?: Persona[];\n /**\n * Per-tool execution timeout in ms. A tool that runs longer is aborted and recorded as failed\n * (the model gets the timeout as its result and can adapt) rather than hanging the turn.\n * Undefined → no timeout.\n */\n toolTimeoutMs?: number;\n /**\n * Retries a tool's own invocation, in place, when it throws a classified-transient error (a DB\n * deadlock, a lock-wait timeout, a serialization failure — see `isTransientToolError`) — never a\n * new durable step/checkpoint, just repeated attempts inside the same `tool:<call.id>` step body.\n * Default ON (`{ attempts: 2, backoffMs: 150 }` with the default classifier) when undefined; set\n * `{ classify }` to widen/narrow which errors count as transient, or `false` to disable entirely.\n * A tool's other (non-transient) failures are unaffected — they remain a one-shot business\n * outcome, exactly as before.\n */\n toolTransientRetry?: ToolTransientRetrySetting;\n /**\n * When set, after the final turn the loop makes one extra model call to propose up to this many\n * short follow-up questions, stored on the assistant message's `followUps`. Costs an extra call\n * (recorded as `follow_ups` usage). Undefined/0 → disabled.\n */\n followUpsCount?: number;\n /**\n * Enables always-on (\"inject\") RAG: before the turn, retrieve passages for the user message and\n * augment the system prompt with them. Its presence IS inject mode — agentic (tool) retrieval sets\n * no retriever here (it rides a normal `read` tool). Undefined → no injection, and no `retrieve`\n * position: which answer a RUN got is journaled (see {@link PromptStages}), so wiring one does not\n * move the checkpoints of a turn already in flight.\n */\n retriever?: Retriever;\n /** How many passages inject-mode retrieval requests. Undefined → 5. */\n retrievalTopK?: number;\n /**\n * Prices each step's token usage into `costUsd` (on the `step-finish` stream frame and the\n * persisted assistant message's `usage`). The current price list is fetched ONCE per run (not per\n * message/step) and reused for every step's estimate. Undefined → `costUsd` is always `null`.\n */\n pricingStore?: AgentPricingStore;\n /**\n * Bounds how much of the thread rides into the turn. Undefined → the WHOLE thread, every message\n * the store holds, which is unbounded: a long-lived thread eventually exceeds the provider's\n * context limit, and pays for the full transcript on every turn up to that point. See\n * `windowHistory` for the built-in.\n */\n historyPolicy?: HistoryPolicy;\n /**\n * Rewrites the prompt before EACH model call of the turn, in order (see {@link InputProcessor}).\n * Transformation only — `historyPolicy` owns which messages are there in the first place. Adds\n * one `process:input:<step>` checkpoint per step; empty/undefined adds none.\n */\n inputProcessors?: InputProcessor[];\n /**\n * Inspects each model step's answer before the stream, the store or the next step sees it, and\n * may redact, replace or refuse it (see {@link OutputProcessor}).\n *\n * REGISTERING ONE TAKES THE MODEL CALL OFF THE RUN'S SINK for the turn — a gate cannot run after\n * the answer has already reached the reader. What the chain costs the subscriber depends on what\n * it declares:\n *\n * - Any processor WITHOUT `incremental` → the whole answer is buffered and released as one `text`\n * frame once the chain has passed. No token-by-token text, and (for a provider that writes bytes\n * outside the `AgentStreamEvent` vocabulary) no frame the gate cannot classify.\n * - EVERY processor with `incremental` → the chain runs over the growing prefix and releases it as\n * it arrives, holding back the widest `lookbackChars` any of them asked for. The whole-answer\n * pass still runs and is still authoritative for the stream and the store.\n *\n * Both add one `process:output:<step>` checkpoint per step, in the same position, so a chain can\n * change its declaration without moving a checkpoint. Empty/undefined adds none, and the turn\n * streams exactly as it always did.\n */\n outputProcessors?: OutputProcessor[];\n /**\n * Constrain the turn's answer to a schema, returned validated as `object` on the loop's result and\n * recorded on the assistant message as a synthetic `structured_output` tool call (the same shape\n * inject-mode retrieval uses, so no store gains a column for it).\n *\n * HOW IT COMPOSES WITH TOOL CALLING: as a separate formatting pass, ALWAYS. The turn runs its\n * model→tools iteration exactly as it would without a schema; once a step comes back with no tool\n * calls, one extra non-streamed call (`structured:<step>`, `tools: []`, `outputSchema` set)\n * restates that answer as the schema. Most providers cannot serve a response format and a tool set\n * in one request, and skipping the pass for an agent that happens to have no tools would make the\n * checkpoint sequence depend on a tool-registry lookup — the registry of whichever process is\n * replaying — which is exactly how a run ends up asking for a position its history has no room\n * for. So the pass is unconditional, and it costs one model call per turn (recorded as\n * `structured_output` usage).\n */\n outputSchema?: StandardSchemaV1<unknown, TOutput>;\n /** Overrides the formatting pass's system prompt. Undefined → `DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION`. */\n outputInstruction?: string;\n /**\n * How many extra model calls may try to fix an answer that failed `outputSchema`, each shown the\n * previous attempt's validation issues. Undefined → 1; `0` → fail on the first invalid reply.\n * Bounded because a model that cannot satisfy a schema usually cannot satisfy it on the fourth\n * try either, and every attempt is billed.\n */\n outputRepairAttempts?: number;\n /**\n * Show the formatting pass the turn's whole transcript instead of just the question and the\n * answer. For an agent whose answer cannot be restated from its own words — one that reports on\n * rows a tool returned and names only their total in the prose, say.\n *\n * OFF by default because the pass is a translation, and a translation needs the thing being\n * translated. The transcript it would otherwise carry is the turn's entire prompt a second time,\n * at no discount: the pass swaps the system block for the schema instruction, and the system block\n * is the prompt cache's prefix, so nothing of the first call's cache survives into it.\n */\n outputFromTranscript?: boolean;\n /**\n * A question set the agent puts to the user BEFORE it starts working — collecting the scope, as\n * against `awaitApproval`, which sanctions work already proposed. The questions are AUTHORED, so\n * the turn spends no model call producing them and a client knows the total (\"Question 1 of 3\")\n * the moment the form appears.\n *\n * The turn parks on the answers exactly as it parks on an approval, and the request persists as\n * the same tool-call row the model's `ask` writes — see {@link ask}. Undefined → no intake, and a\n * turn's checkpoint sequence is byte-identical to one that never had the option.\n */\n intake?: AgentIntake;\n /**\n * Offer the model the built-in `ask` tool, so it can put its own question set to the user when it\n * judges the scope is missing — the same surface as {@link intake}, minus the \"known in advance\".\n *\n * `ask` is NOT a registered tool: it has no handler (the loop settles it against a human), and\n * keeping it out of the `ToolRegistry` is what keeps its kind out of a process-local lookup. The\n * loop appends its definition to the turn's tool list from THIS flag, which is module config and\n * therefore uniform across a deployment. Undefined/false → the model never sees it.\n */\n ask?: boolean;\n /**\n * Authored procedures the model may pull in when a task calls for one, resolved per turn against\n * the actor's scopes — see `skills.ts`. Undefined → no catalog block, no `skill` tool, and a\n * turn's checkpoint sequence is byte-identical to one that never had the option — including for a\n * turn that was already in flight when this was wired, because which answer a RUN got is journaled\n * (see {@link PromptStages}).\n *\n * HOW IT COMPOSES WITH THE OTHER FOUR THINGS THAT WRITE THE PROMPT. The system block is assembled\n * in one fixed order — the agent's base prompt, then each `promptContributors` section, then\n * {@link memory}, then the injected retrieval block, then the skills CATALOG — and skills are the\n * cheapest of the five by construction: the catalog is one line per skill and nothing else. The\n * instructions themselves arrive as a tool RESULT, on the transcript, which means the budget they\n * draw on is the one `historyPolicy` already governs rather than a private allowance of their own.\n *\n * A BODY IS NOT LIKE A MEMORY, which does ride the system block. A body is read BECAUSE the model\n * went and asked for it, so the transcript — what this conversation happened to pull in — is where\n * it belongs. A memory is worthless unless it is in front of the model on the turn nobody thought\n * to look for it, and it is affordable there only because it has no body to carry.\n */\n skills?: SkillsConfig;\n /**\n * What the assistant has previously concluded about the actor and their organisation, resolved per\n * turn against the same scope tokens skills use — see `memory.ts`. Undefined → no memory block, no\n * `remember` tool, and a turn's checkpoint sequence is byte-identical to one that never had the\n * option — including for a turn that was already in flight when this was wired, because which\n * answer a RUN got is journaled (see {@link PromptStages}).\n *\n * WHERE IT SITS IN THE PROMPT. The system block is assembled most-durable-first: the agent's base\n * prompt (the same for everyone, every turn), then `promptContributors`, then MEMORY (the same for\n * this person, every turn), then the injected retrieval block (this question only), then the\n * skills catalog (a menu rather than an instruction, so a reader meets instructions before\n * options).\n *\n * WHY IT IS IN THE SYSTEM BLOCK AT ALL, when a skill's body deliberately is not. A body is read\n * BECAUSE the model went and asked for it; a memory is worthless unless it is in front of the\n * model on the turn nobody thought to look for it — \"they report in nautical miles\" only works\n * unprompted. What makes that affordable is that a memory has no body: `maxMemories` lines, each\n * capped at `maxFactChars` when it is written, so the block's ceiling is a product of two numbers\n * an operator set rather than however much the model felt like writing down.\n */\n memory?: MemoryConfig;\n}\n\n/**\n * A step's cost: the provider's own reported figure when it has one (a gateway), else an estimate\n * from `price` when the model has one, else `null` — never a fabricated `0` for \"we don't know\".\n */\nfunction resolveCostUsd(\n usage: MessageUsage,\n reportedCostUsd: number | undefined,\n price: CurrentModelPrice | undefined,\n): number | null {\n if (reportedCostUsd !== undefined) {\n return reportedCostUsd;\n }\n return price === undefined ? null : estimateCost(usage, price);\n}\n\n/** Renders retrieved passages as a numbered, citable context block for the system prompt. */\nfunction buildContextBlock(passages: Passage[]): string {\n const items = passages\n .map((passage, index) => {\n const label = passage.source !== undefined ? ` (${passage.source})` : '';\n return `[${index + 1}]${label} ${passage.text}`;\n })\n .join('\\n\\n');\n return `<retrieved_context>\\n${items}\\n</retrieved_context>\\nUse the retrieved context above to answer when relevant, and cite sources by their bracket number.`;\n}\n\n/** Renders a folded-history summary as the leading `system` message of a windowed turn. */\nfunction buildSummaryBlock(summary: string): string {\n return `<conversation_summary>\\n${summary}\\n</conversation_summary>\\nEarlier messages in this thread are no longer included verbatim. Treat the summary above as an accurate record of them.`;\n}\n\n/** One task's outcome under {@link AgentLoopHooks.parallel}, reported instead of thrown. */\nexport type SettledTask<T> = { ok: true; value: T } | { ok: false; error: unknown };\n\n/**\n * The {@link AgentLoopHooks.parallel} implementation for a runner whose checkpoint positions are\n * handed out on the CALL (both durable primitives are: `ctx.localStep` and `ctx.step` take their\n * position before their first `await`). Every task is invoked here, synchronously and in list\n * order, before any of them is awaited — which is what fixes the block of positions the tasks\n * occupy, whatever order they then settle in. Nothing rejects: the caller decides what an\n * individual failure means.\n */\nexport function settleAll<T>(tasks: readonly (() => Promise<T>)[]): Promise<SettledTask<T>[]> {\n const started = tasks.map((task) => task());\n return Promise.all(\n started.map((work) =>\n work.then<SettledTask<T>, SettledTask<T>>(\n (value) => ({ ok: true, value }),\n (error: unknown) => ({ ok: false, error }),\n ),\n ),\n );\n}\n\nexport interface AgentLoopHooks {\n runId: string;\n /** A writer for this run's live token stream (data plane). */\n openSink(): SinkWriter | Promise<SinkWriter>;\n /**\n * HITL gate for an action tool. Inline resolves a pending promise; durable awaits a signal.\n *\n * `opts.timeoutMs` is the request's time to live, from the turn's `ApprovalPolicy`. When it\n * elapses with no decision the runner resolves `{ approved: false, expired: true }` — it must not\n * throw — and the loop settles the call `expired`. The value comes out of the call's\n * `persist:toolcall` checkpoint, so it is the same on every replay; a durable runner hands it to\n * its own timed wait (whose deadline the runtime journals), an inline one arms a timer.\n */\n awaitApproval(\n call: ToolCallRequest,\n ctx: AiToolCtx,\n opts?: { timeoutMs?: number },\n ): Promise<Decision>;\n /**\n * Park the run on a question set and resolve with what the human sent back. The SAME wait\n * `awaitApproval` is — the durable runner maps both to `ctx.waitForSignal` on\n * `tool:<runId>:<callId>`, so an answer and an approval reach a parked run through one path.\n *\n * Optional, and its absence changes no checkpoint: the loop falls back to `awaitApproval` and\n * reads the decision as \"the user confirmed the pre-picked answers\" (approved) or \"the user\n * skipped\" (rejected). That is the honest reduction of a yes/no channel, and it means a host that\n * only ever implemented approval still runs an elicitation to completion instead of hanging.\n *\n * Declared as `HumanReply` rather than `ElicitationReply` because that is what the channel really\n * carries: a question set is parked as a `pending_approval` action, so a `Decision` can arrive on\n * this wait from the approvals inbox even where the host implements it. The loop reduces one to\n * the other — see {@link normalizeElicitationReply} — so an implementer never has to.\n */\n awaitAnswers?(request: ElicitationRequest, ctx: AiToolCtx): Promise<HumanReply>;\n /**\n * Run another named agent and return its answer. Provided only when the host wired multi-agent\n * support (durable → child workflow, inline → nested loop). Exposed to tools as `ctx.runAgent`.\n */\n runAgent?(agentName: string, task: string): Promise<{ text: string }>;\n /**\n * Start another named agent and return its run id WITHOUT waiting for it, so the calling turn can\n * finish while the delegate is still working. The durable runner maps this to `ctx.startChild`\n * (checkpointed as `spawn:<id>`; no suspend, unlike the `ctx.child` behind {@link runAgent}); the\n * inline runner to a nested loop nobody awaits.\n *\n * `toolCallId` is the delegation's own call, which the started run carries as its delivery\n * address: it posts its answer back into the calling thread against that row.\n *\n * Absent -> a delegation the journal declares detached is AWAITED instead. The loop writes the\n * same checkpoint names either way (see {@link delegateToolCall}), so a runner that cannot detach\n * still answers the user; only the runner's own positions differ, and a given runner always makes\n * the same choice for the same call.\n */\n startAgent?(args: {\n agentName: string;\n task: string;\n toolCallId: string;\n }): Promise<{ runId: string }>;\n /**\n * Checkpoint wrapper. Inline = call fn directly; durable = ctx.localStep(name, fn) — the\n * in-process checkpointed primitive (`name` is a checkpoint identity, not a worker group).\n * EVERY side-effect and control-flow read goes through this so durable replay returns\n * cached results (stable ids, no double-write, no re-streaming).\n */\n step<T>(name: string, fn: () => Promise<T>): Promise<T>;\n /**\n * Dispatch the model turn as a routed remote step. When present the loop uses it INSTEAD of\n * running the model inline under hooks.step. Must resolve to exactly what deps.model.runTurn\n * resolves, plus `bufferedFrames` when (and only when) the envelope set `bufferOutput` — the\n * handler streams to a worker-side sink the loop cannot wrap, so an output gate depends on it\n * honouring that flag. The durable runner enriches the envelope with sink routing\n * (sinkRunId/childSink) on its side — core stays sink-topology-agnostic.\n */\n dispatchLlm?(index: number, envelope: LlmStepEnvelope): Promise<BufferedModelTurnResult>;\n /**\n * Dispatch one tool execution as a routed remote step. Replaces ONLY the registry.invoke call\n * (+ its timeout, applied handler-side); all persist steps around it stay local.\n */\n dispatchTool?(call: ToolCallRequest, envelope: ToolStepEnvelope): Promise<unknown>;\n /**\n * Recognizes the runner's control-flow signals (durable suspend / continue-as-new) so the loop\n * rethrows them untouched instead of recording a failure. An OVERRIDE, not the gate: the loop\n * already recognizes any signal carrying the durable runtime's `Symbol.for` marker on its own (see\n * {@link isControlFlowSignal}), so a host that omits this — an inline runner with no control-flow\n * exceptions, or one that simply forgot — never turns a suspend into a persisted tool failure.\n * Supply it for a runner whose signals carry no marker.\n */\n isControlFlowError?(error: unknown): boolean;\n /**\n * Run `tasks` concurrently, resolving once EVERY one has settled — one outcome per task, in INPUT\n * order, never rejecting. Supplying it is a statement about the runner's checkpointing: each task\n * MUST be invoked synchronously, in list order, before any is awaited, so a runner that hands out\n * positions on the call assigns them in that order regardless of which task finishes first.\n * {@link settleAll} is exactly that, and is what both bundled runners pass.\n *\n * Waiting for ALL of them is the other half of the contract. A durable runner unwinds a turn by\n * THROWING (a dispatched step suspends), and a sibling abandoned part-way through its own dispatch\n * is a tool nobody ever runs.\n *\n * Absent → the loop runs a turn's tool calls one at a time. That is the honest answer for a runner\n * whose positions are assigned anywhere other than the call, and it is the only behaviour that\n * existed before, so nothing gains concurrency without saying so.\n */\n parallel?<T>(tasks: readonly (() => Promise<T>)[]): Promise<SettledTask<T>[]>;\n /**\n * Has someone asked this run to stop?\n *\n * Answered at the points where stopping is safe and cheap — between steps, before the next model\n * call, before the turn's tools are dispatched — and NEVER consulted anywhere else. Two properties\n * make it safe to ask a live question inside a replayed loop body:\n *\n * 1. THE ANSWER IS JOURNALED. The loop only ever calls this inside a checkpoint, so the first\n * process to reach a given position writes the answer there and every later replay reads it\n * back. A cancel that arrives between two replays is therefore seen at the first position the\n * history does NOT yet hold, and cannot change the branch a replayed position already took.\n * 2. THE POSITIONS ARE PATCHED IN. They exist only for a run that {@link patched} admits to the\n * `agent:cancellation` shape, so a run already in flight when a deployment gained this keeps\n * replaying against the sequence it recorded.\n *\n * Undefined → the run cannot be cancelled and takes not one extra checkpoint, which is the honest\n * answer for a host with nowhere to record the request.\n *\n * WHAT IT CANNOT REACH: a turn parked on a human (`awaitApproval`/`awaitAnswers`) is suspended\n * INSIDE a position the journal already holds, so no observation of any kind fires there. Stopping\n * a parked run is the runner's job, through whatever hard cancel its runtime has.\n */\n cancelled?(): Promise<boolean>;\n /**\n * Does this run take the loop shape guarded by `id`? A runner replaying against recorded\n * checkpoints answers `false` for a run that started before the shape changed, so that run keeps\n * replaying the shape its history holds (the durable runtime's `ctx.patched`, which consumes a\n * position for a new run and gives it back to an old one). Absent → `true`: a runner that records\n * no positions has no older shape to preserve.\n */\n patched?(id: string): Promise<boolean>;\n}\n\nexport class QuotaExceededError extends Error {\n constructor() {\n super('Daily token quota exceeded');\n this.name = 'QuotaExceededError';\n }\n}\n\n/**\n * Someone asked this run to stop, and it did. NOT a failure — it is the outcome a user pressing Stop\n * is entitled to, and a consumer whose reliability numbers count `failed` runs must be able to leave\n * it out. Thrown by the loop at the point it observed the cancel, and settled by the runner, which\n * records the run `cancelled` and ends the stream with a `cancelled` frame rather than failing it.\n *\n * Carries no message detail on purpose: there is nothing to diagnose, and a cancel reads the same\n * whether it came from a Stop button, an operator console, or a deployment draining.\n */\nexport class RunCancelledError extends Error {\n constructor() {\n super('Run cancelled');\n this.name = 'RunCancelledError';\n }\n}\n\n/**\n * The stream error code a failed run surfaces to its subscriber. A refusal by an output processor\n * and an answer that never satisfied `outputSchema` are the CONTROLS working, not the model\n * breaking: a client that retries on `run_failed` must not retry either of them, and neither should\n * page whoever is on call for model failures.\n */\nexport function agentFailureCode(error: unknown): string {\n // A cancel is not a failure at all — both runners settle it on its own path and never reach here.\n // It is answered anyway so that a host which does route it through the failure machinery cannot\n // end up reporting a user's Stop as `run_failed`.\n if (error instanceof RunCancelledError) {\n return 'cancelled';\n }\n if (error instanceof QuotaExceededError) {\n return 'quota_exceeded';\n }\n if (error instanceof OutputRejectedError) {\n return 'output_rejected';\n }\n if (error instanceof StructuredOutputError) {\n return 'structured_output_invalid';\n }\n if (isReplayIntegrityError(error)) {\n return 'replay_diverged';\n }\n return isNoOutputError(error) ? 'model_no_output' : 'run_failed';\n}\n\n/**\n * A model call that ended without producing anything — the AI SDK's `NoOutputGeneratedError`.\n * Matched by name, and by its message as well: an error that crossed a dispatched step comes back\n * rebuilt by the runtime, which keeps the message and not always the class name.\n */\nfunction isNoOutputError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n return (\n error.name === 'AI_NoOutputGeneratedError' ||\n error.name === 'NoOutputGeneratedError' ||\n error.message.startsWith('No output generated')\n );\n}\n\n/**\n * What a person is told when a run fails for a reason that is ours rather than theirs. The error's\n * own text is for whoever operates the deployment: it names run ids, checkpoint positions and\n * provider internals (\"non-determinism at <uuid>#41 …\", \"No output generated. Check the stream for\n * errors.\"), which mean nothing to the person reading the chat and are not theirs to see.\n */\nexport const RUN_FAILED_MESSAGE = 'The assistant could not finish this answer. Please try again.';\n\nlet streamErrorDetails: boolean | undefined;\n\n/**\n * Whether an error frame carries the error's own message. Unset → only outside production\n * (`NODE_ENV !== 'production'`), where the person reading the stream is the one debugging it.\n * `true`/`false` decides it outright; `undefined` returns to the default.\n */\nexport function exposeStreamErrorDetails(expose: boolean | undefined): void {\n streamErrorDetails = expose;\n}\n\n/** The codes whose message the library wrote for the person, and is therefore safe to show. */\nconst WORDED_CODES = new Set(['quota_exceeded', 'output_rejected', 'structured_output_invalid']);\n\n/**\n * The terminal a failed run closes its stream with — what `SinkWriter.fail` takes, and what the\n * transport sends as the `event: error` frame.\n *\n * The frame is what the PERSON sees. For a crash it carries a stable `code` (what a client branches\n * on, and translates) and {@link RUN_FAILED_MESSAGE}; the error itself belongs in the log and on the\n * run row, which is where the runners put it. Outside production the raw message rides the frame as\n * it always did (see {@link exposeStreamErrorDetails}). A message the library words itself\n * (`quota_exceeded`, `output_rejected`, `structured_output_invalid`) is sent as it is.\n */\nexport function streamFailure(error: unknown): StreamError {\n const detail = error instanceof Error ? error.message : String(error);\n const code = agentFailureCode(error);\n if (WORDED_CODES.has(code)) {\n return { code, message: detail };\n }\n const exposed = streamErrorDetails ?? process.env.NODE_ENV !== 'production';\n return { code, message: exposed ? detail : RUN_FAILED_MESSAGE };\n}\n\n/**\n * The default depth at which agent→agent delegation stops nesting, when the host names none.\n * Override with {@link AgentLoopDeps.maxDelegationDepth}.\n *\n * A backstop for a chain that is merely LONG. The cycle it used to stand in for is now detected\n * directly — see {@link DEFAULT_MAX_AGENT_APPEARANCES}.\n *\n * WHEN IT ACTUALLY BINDS. At one appearance per agent, a chain cannot be longer than the number of\n * registered agents, so a deployment with fewer agents than this number never reaches it: the cycle\n * guard always fires first. It starts mattering with a larger fleet of agents than the ceiling, or\n * once a host raises {@link AgentLoopDeps.maxAgentAppearances}, which is what lets a chain revisit\n * an agent and therefore grow past the fleet's size.\n */\nexport const MAX_DELEGATION_DEPTH = 5;\n\n/**\n * How many times one agent may appear on a single delegation chain, when the host names no other\n * number. Once: a chain that reaches an agent it has already passed through is going in circles.\n *\n * Override with {@link AgentLoopDeps.maxAgentAppearances} — a supervisor that genuinely hands work\n * back to an earlier agent needs a larger number, and it is the count of APPEARANCES, so 2 admits\n * exactly one return.\n */\nexport const DEFAULT_MAX_AGENT_APPEARANCES = 1;\n\n/**\n * Why this delegation must not happen, or `null` to let it through.\n *\n * Two different refusals, and the order matters: a CYCLE is named before a depth, because they\n * describe different faults and the depth is the vaguer of the two. \"A→B→A\" points at the wiring;\n * \"depth limit of 5 reached\" leaves a reader to work out whether the chain was looping or merely\n * long, which is exactly the question a count cannot answer.\n */\nfunction delegationRefusal(args: {\n deps: Pick<AgentLoopDeps, 'maxAgentAppearances' | 'maxDelegationDepth'>;\n input: Pick<AgentRunInput, 'agentName' | 'delegationDepth' | 'delegationPath'>;\n targetAgent: string;\n}): string | null {\n const { deps, input, targetAgent } = args;\n // `delegationPath` is the chain that REACHED this run, so it stops short of the agent running\n // now — a runner appends its own name only on the way into a child. Both the count and the named\n // chain want the hop being taken, so this run's agent joins the end of the ancestry: without it a\n // mutual handoff is refused as `alpha → alpha`, an edge no deployment declares, and an agent\n // delegating to ITSELF from a top-level turn is not caught at all until one hop later.\n const ancestry = [\n ...(input.delegationPath ?? []),\n ...(input.agentName !== undefined ? [input.agentName] : []),\n ];\n const appearances = ancestry.filter((name) => name === targetAgent).length;\n const maxAppearances = deps.maxAgentAppearances ?? DEFAULT_MAX_AGENT_APPEARANCES;\n if (appearances >= maxAppearances) {\n const chain = [...ancestry, targetAgent].join(' → ');\n const times = appearances + 1;\n return `(delegation cycle: ${chain} — ${targetAgent} ${times} times on one chain)`;\n }\n const maxDepth = deps.maxDelegationDepth ?? MAX_DELEGATION_DEPTH;\n if ((input.delegationDepth ?? 0) >= maxDepth) {\n return `(delegation depth limit of ${maxDepth} reached)`;\n }\n return null;\n}\n\n/** Resolve a prompt that may be a flat string or a {@link PromptBuilder}. */\nasync function resolvePrompt(prompt: string | PromptBuilder, ctx: PromptContext): Promise<string> {\n return typeof prompt === 'function' ? prompt(ctx) : prompt;\n}\n\n/**\n * The effective system prompt for a turn: the agent's own base prompt, then each cross-agent\n * contributor's section appended in order (skipping any that return `null`/empty this turn). This is\n * resolved from stable inputs (actor / agent / pageContext) once per turn; contributors should be\n * derived from those rather than from uncached I/O so it stays replay-safe.\n */\nasync function resolveSystemPrompt(\n deps: AgentLoopDeps,\n input: AgentRunInput,\n persona: TurnPersona | undefined,\n): Promise<string> {\n const ctx = promptContext(input, persona);\n // A persona that carries a prompt stands in for the base — resolved, with the base it may wrap,\n // inside `persona:resolve`, so a replay reads back the exact text the turn started with.\n const sections = [persona?.prompt ?? (await resolvePrompt(deps.systemPrompt, ctx))];\n for (const contribute of deps.promptContributors ?? []) {\n const section = await contribute(ctx);\n if (section !== null && section.length > 0) {\n sections.push(section);\n }\n }\n return sections.join('\\n\\n');\n}\n\n/** The run's input with no persona — what a turn whose persona did not resolve runs as. */\nfunction withoutPersona(input: AgentRunInput): AgentRunInput {\n const { persona: _dropped, ...rest } = input;\n return rest;\n}\n\n/** What every prompt builder of a turn is handed. */\nfunction promptContext(input: AgentRunInput, persona: TurnPersona | undefined): PromptContext {\n return {\n actor: input.actor,\n agentName: input.agentName ?? 'default',\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(input.uiCapabilities !== undefined ? { uiCapabilities: input.uiCapabilities } : {}),\n ...(persona !== undefined ? { persona: { id: persona.id, label: persona.label } } : {}),\n };\n}\n\n/**\n * The `persona:resolve` checkpoint's body: the persona the run names, looked up in this process's\n * config and FROZEN — its id, label and allow-list, and its prompt resolved against the agent's base\n * prompt. `null` when the agent no longer declares it, which the turn runs as no persona at all.\n *\n * Reached only for a run whose input names a persona, and every such run was started by a release\n * that has this checkpoint; a run started before personas existed names none, spends no position\n * here, and replays on the sequence it recorded.\n */\nasync function resolveTurnPersona(\n deps: AgentLoopDeps,\n input: AgentRunInput,\n): Promise<TurnPersona | null> {\n const persona = findPersona(deps, input.persona);\n if (persona === undefined) {\n return null;\n }\n const ref = { id: persona.id, label: persona.label };\n let prompt: string | undefined;\n if (persona.systemPrompt !== undefined) {\n const ctx = promptContext(input, ref);\n const basePrompt =\n typeof persona.systemPrompt === 'function'\n ? await resolvePrompt(deps.systemPrompt, ctx)\n : undefined;\n prompt = await resolvePrompt(persona.systemPrompt, {\n ...ctx,\n ...(basePrompt !== undefined ? { basePrompt } : {}),\n });\n }\n return {\n ...ref,\n ...(persona.allowedTools !== undefined ? { allowedTools: [...persona.allowedTools] } : {}),\n ...(prompt !== undefined ? { prompt } : {}),\n };\n}\n\n/**\n * Why a delegation must not happen under this persona, or `null`. A delegate tool is a tool like any\n * other to the persona's allow-list: one it was not offered is refused, even if the model names it.\n */\nfunction personaRefusal(persona: TurnPersona | undefined, toolName: string): string | null {\n if (persona?.allowedTools === undefined || persona.allowedTools.includes(toolName)) {\n return null;\n }\n return `(tool \"${toolName}\" is not available to the \"${persona.id}\" persona)`;\n}\n\n/** An `agent`-kind tool's input is `{ task }` by convention; fall back to a JSON dump. */\nfunction extractTask(input: unknown): string {\n if (typeof input === 'object' && input !== null && 'task' in input) {\n const task = (input as { task: unknown }).task;\n if (typeof task === 'string') {\n return task;\n }\n }\n return JSON.stringify(input);\n}\n\nfunction deriveTitle(userText: string): string {\n const trimmed = userText.trim().replace(/\\s+/g, ' ');\n return trimmed.length > 60 ? `${trimmed.slice(0, 57)}...` : trimmed || 'New chat';\n}\n\n/** Thrown when a tool exceeds `toolTimeoutMs`; caught by the loop and recorded as a failed call. */\nclass ToolTimeoutError extends Error {\n constructor(toolName: string, ms: number) {\n super(`Tool \"${toolName}\" exceeded its ${ms}ms timeout`);\n this.name = 'ToolTimeoutError';\n }\n}\n\n/** Reject if `work` doesn't settle within `ms`. The underlying work is left to finish on its own. */\nexport function withToolTimeout<T>(work: Promise<T>, ms: number, toolName: string): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => reject(new ToolTimeoutError(toolName, ms)), ms);\n work.then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n}\n\n/** Best-effort parse of the follow-ups model reply: a bare JSON array, tolerating code fences/prose. */\nfunction parseFollowUps(text: string, count: number): string[] {\n const source = text.match(/\\[[\\s\\S]*\\]/)?.[0] ?? text;\n try {\n const parsed: unknown = JSON.parse(source);\n if (Array.isArray(parsed)) {\n return parsed.filter((item): item is string => typeof item === 'string').slice(0, count);\n }\n } catch {\n /* not JSON — no follow-ups this turn */\n }\n return [];\n}\n\n/**\n * One extra, non-streamed model call that proposes short follow-up questions. Writes to a discarding\n * sink so its tokens never reach the user's live stream; the reply is parsed as a JSON string array.\n */\nasync function generateFollowUps(\n model: ModelProvider,\n messages: ModelMessage[],\n count: number,\n): Promise<{ followUps: string[]; usage: MessageUsage; modelId?: string }> {\n const discard: SinkWriter = { write: () => {}, end: () => {}, fail: () => {} };\n const turn = await model.runTurn({\n system: `Based on the conversation so far, propose up to ${count} short, distinct follow-up questions the user is likely to ask next. Respond with ONLY a JSON array of strings — no prose, no code fences.`,\n messages,\n tools: [],\n sink: discard,\n });\n return {\n followUps: parseFollowUps(turn.text, count),\n usage: turn.usage,\n ...(turn.modelId !== undefined ? { modelId: turn.modelId } : {}),\n };\n}\n\n/**\n * Wrap a genuinely-executing operation in an `aviary:agent:<event>` span (the diagnostics\n * `trace()` API — five `:start`/`:end`/`:asyncStart`/`:asyncEnd`/`:error` sub-channels),\n * correlated to its run by `traceId = runId`, WITHOUT letting the operation's raw return value\n * ride the span envelope: `trace` publishes the traced fn's return as the span's `result`, so the\n * traced fn returns only `summarize`d metadata (token counts / lengths / names — never prompt or\n * output text, the point events' redaction posture) while the real value is handed back to the\n * caller through the closure. Zero-cost when no span sub-channel has a subscriber.\n *\n * REPLAY SAFETY: call sites MUST sit INSIDE a `hooks.step` body (or another genuinely-executed\n * path). Durable replay skips step bodies and returns checkpoints, which is exactly what keeps a\n * replayed run from re-emitting spans. Never wrap a `hooks.step(...)`/`hooks.dispatch*(...)`\n * CALL — those run (and resolve from cache) on every replay.\n */\nasync function spanned<TEvent extends AgentSpanEvent, T>(\n event: TEvent,\n runId: string,\n payload: PayloadOf<'agent', TEvent>,\n run: () => Promise<T>,\n summarize: (value: T) => Record<string, unknown>,\n): Promise<T> {\n let value!: T;\n await trace(\n 'agent',\n event,\n async () => {\n value = await run();\n return summarize(value);\n },\n payload,\n { traceId: runId },\n );\n return value;\n}\n\n/**\n * Span-wrap one model call (`aviary:agent:llm.turn`). Exported so the durable dispatched-step\n * handler (which executes the genuine remote llm step) can emit the same span — core cannot wrap\n * `hooks.dispatchLlm` itself, because that call also runs (from cache) on replay.\n */\nexport function traceLlmTurn(\n runId: string,\n step: number,\n run: () => Promise<ModelTurnResult>,\n): Promise<ModelTurnResult> {\n return spanned('llm.turn', runId, { runId, step }, run, (turn) => ({\n ...(turn.modelId !== undefined ? { modelId: turn.modelId } : {}),\n inputTokens: turn.usage.inputTokens,\n outputTokens: turn.usage.outputTokens,\n textLength: turn.text.length,\n toolCalls: turn.toolCalls.length,\n }));\n}\n\n/**\n * Span-wrap one tool invocation (`aviary:agent:tool.execution`). The tool's raw output never\n * rides the span (only the start payload's name/type metadata + duration). Exported for the\n * durable dispatched-step handler, like {@link traceLlmTurn}.\n */\nexport function traceToolExecution<T>(\n runId: string,\n call: { toolCallId: string; toolName: string; toolType: 'read' | 'action' },\n run: () => Promise<T>,\n): Promise<T> {\n return spanned('tool.execution', runId, { runId, ...call }, run, () => ({}));\n}\n\n/** Everything a turn needs off its thread, with the history ceiling already applied. */\ninterface TurnHistory {\n actionApprovalMode?: ActionApprovalMode;\n /** What rides into the turn, oldest-first — already through {@link HistoryPolicy.select}. */\n messages: ModelMessage[];\n /**\n * What the ceiling left out. Carried ONLY where a summarizer is configured to fold them back in:\n * `history:summarize` can run in a later process than the one that loaded the thread, so the\n * journal is the only place it can read them from. Everywhere else they are exactly the half of\n * the transcript the ceiling exists to leave behind.\n */\n dropped: ModelMessage[];\n /** The thread's title, or `null` where the store has no such thread. */\n title: string | null;\n /** Does the thread already hold an assistant message? Decides a `thread-start` intake. */\n hasAssistantMessage: boolean;\n}\n\n/** The thread's stored rows as the model sees them — the store's own bookkeeping left behind. */\nfunction toModelMessages(messages: StoredMessage[]): ModelMessage[] {\n return messages.map((message) => ({\n role: message.role,\n content: message.content,\n ...(message.toolCalls !== undefined ? { toolCalls: message.toolCalls } : {}),\n ...(message.toolResults !== undefined ? { toolResults: message.toolResults } : {}),\n ...(message.attachments !== undefined ? { attachments: message.attachments } : {}),\n }));\n}\n\n/** Whose history this is, as the policy's two halves both see it. */\nfunction historyContext(input: AgentRunInput): HistoryPolicyContext {\n return {\n threadId: input.threadId,\n actor: input.actor,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n };\n}\n\n/** The configured ceiling's split, or the whole transcript where no policy is configured. */\nfunction splitHistory(\n policy: HistoryPolicy | undefined,\n input: AgentRunInput,\n messages: ModelMessage[],\n): HistorySelection {\n return policy === undefined\n ? { keep: messages, drop: [] }\n : policy.select(messages, historyContext(input));\n}\n\n/**\n * Load the thread and journal the messages the turn is going to send.\n *\n * `select` runs INSIDE the checkpoint, so what the position holds is the ceiling's RESULT. It is\n * contractually pure and takes no position of its own. `hooks.step` checkpoints its body's output,\n * and a `ThreadDetail` is the store's entire transcript — every message row, its id and timestamp,\n * and every tool result the thread ever recorded — written to a JSON column once and then re-read\n * and re-parsed by every process that resumes the run. Recording the selection makes the bound the\n * model's prompt respects the bound that payload respects too.\n *\n * The title and the assistant-message flag ride along because they are the only other things the\n * turn reads off the thread, and re-reading the store for them would put the row back.\n */\nasync function loadSelectedHistory(\n deps: AgentLoopDeps,\n input: AgentRunInput,\n hooks: AgentLoopHooks,\n): Promise<TurnHistory> {\n const recorded = await hooks.step('load:thread', async (): Promise<TurnHistory> => {\n const thread = await readThreadForTurn(deps, input.threadId);\n // Settled BEFORE the ceiling sees it and inside the checkpoint: what the calls' rows said is\n // part of the recorded payload, so a replay composes the same prompt without asking again.\n const { keep, drop } = splitHistory(\n deps.historyPolicy,\n input,\n await settleHistory(deps, toModelMessages(thread.messages)),\n );\n return {\n messages: keep,\n dropped: deps.historyPolicy?.summarize === undefined ? [] : drop,\n title: thread.title,\n hasAssistantMessage: thread.hasAssistantMessage,\n actionApprovalMode: deps.actionApprovalMode ?? 'blocking',\n };\n });\n // Settled once more on the way out of the journal: a payload recorded before the read settled\n // dangling calls itself still has to reach the model as a prompt a provider accepts. A no-op —\n // the same array elements — on a payload that is already whole.\n return { ...recorded, messages: settleDanglingToolCalls(recorded.messages) };\n}\n\n/**\n * Settle the history's dangling tool calls (see {@link settleDanglingToolCalls}) from the calls' own\n * rows where the store can read them. A store that cannot answer, or fails to, leaves the calls to\n * be put to the model as never completed.\n */\nasync function settleHistory(\n deps: AgentLoopDeps,\n messages: ModelMessage[],\n): Promise<ModelMessage[]> {\n const dangling = danglingToolCallIds(messages);\n if (dangling.length === 0) {\n return messages;\n }\n const outcomes = await Promise.resolve(deps.store.toolCallOutcomes?.(dangling) ?? []).catch(\n (): ToolCallOutcome[] => [],\n );\n return settleDanglingToolCalls(messages, outcomes);\n}\n\n/** The three things a turn reads off its thread, however the store was able to answer them. */\ninterface ThreadForTurn {\n /** Oldest-first, and at most what the ceiling was going to keep. */\n messages: StoredMessage[];\n title: string | null;\n hasAssistantMessage: boolean;\n}\n\n/**\n * Read the thread: the store's bounded WINDOW where it offers one, else its whole transcript.\n *\n * Probed structurally, the same seam as `defaultAgentForThread` — the window is an optimization a\n * store either offers or does not, and one that predates it still answers correctly through\n * `getThread`. Which branch runs is invisible to the journal on purpose: both produce the same three\n * answers, so the payload this checkpoint records is identical either way and a deployment's choice\n * of store can never decide a run's checkpoints. That is also why the probe lives INSIDE\n * `load:thread` rather than around it — it adds no position, and a replaying process reads the\n * recorded payload back without calling the store at all.\n *\n * `hasAssistantMessage` is taken from the page's own flag rather than scanned out of its messages,\n * because the page's flag answers over the whole thread. It decides a `thread-start` intake, and a\n * window that happens to hold only the user's last questions belongs to a conversation that has\n * still been answered — scanned off the window, such a thread re-introduces itself every turn.\n */\nasync function readThreadForTurn(deps: AgentLoopDeps, threadId: string): Promise<ThreadForTurn> {\n const windowing = deps.store as Partial<ThreadTurnReader>;\n if (typeof windowing.loadThreadForTurn === 'function') {\n const messageLimit = turnMessageLimit(deps.historyPolicy);\n const page = await windowing.loadThreadForTurn({\n threadId,\n ...(messageLimit !== undefined ? { messageLimit } : {}),\n });\n return page === null\n ? { messages: [], title: null, hasAssistantMessage: false }\n : {\n messages: page.messages,\n title: page.title,\n hasAssistantMessage: page.hasAssistantMessage,\n };\n }\n const thread = await deps.store.getThread(threadId);\n const stored = thread?.messages ?? [];\n return {\n messages: stored,\n title: thread?.title ?? null,\n hasAssistantMessage: stored.some((message) => message.role === 'assistant'),\n };\n}\n\n/**\n * How many of the thread's newest rows to ask the store for — the policy's own row ceiling, or\n * nothing at all, which asks for the transcript.\n *\n * A policy that SUMMARIZES gets no limit. `summarize` is handed what `select` dropped, and a read\n * bounded to what `select` keeps drops nothing: the turn would fold an empty summary into a prompt\n * that is missing the messages it stands in for, with no error anywhere.\n *\n * A ceiling expressed only in TOKENS gets no limit either, and none can be derived from it: one\n * message can be four tokens or forty thousand, so no row count follows from a token budget. Naming\n * one too low reads fewer rows than `select` would have kept, which changes the prompt itself;\n * leaving it out only costs the read. A policy that wants its bound to reach the database states\n * {@link HistoryPolicy.maxMessages} alongside the token budget.\n */\nfunction turnMessageLimit(policy: HistoryPolicy | undefined): number | undefined {\n if (policy === undefined || policy.summarize !== undefined) {\n return undefined;\n }\n return policy.maxMessages;\n}\n\n/**\n * The load a run recorded before the selection moved inside the checkpoint has to keep replaying\n * against: the whole `ThreadDetail` journaled, the split taken outside it. Reachable only through\n * {@link SELECTED_HISTORY_PATCH} answering false, and deletable once no such run is still in flight.\n */\nasync function loadWholeThread(\n deps: AgentLoopDeps,\n input: AgentRunInput,\n hooks: AgentLoopHooks,\n): Promise<TurnHistory> {\n const thread = await hooks.step('load:thread', () => deps.store.getThread(input.threadId));\n const stored = thread?.messages ?? [];\n // Outside the checkpoint (this shape journals the store's whole `ThreadDetail`), so it is settled\n // from the messages alone: a pure function of the recorded payload, the same on every replay.\n const { keep, drop } = splitHistory(\n deps.historyPolicy,\n input,\n settleDanglingToolCalls(toModelMessages(stored)),\n );\n return {\n messages: keep,\n dropped: drop,\n title: thread?.title ?? null,\n hasAssistantMessage: stored.some((message) => message.role === 'assistant'),\n };\n}\n\n/**\n * Fold what the ceiling dropped into a leading `system` message the model reads in their place.\n *\n * Summarizing calls a model, so it is journaled under `history:summarize`: a resumed run reads back\n * the summary the suspended attempt produced instead of writing a different one into the prompt.\n * This checkpoint and the usage row below are reachable ONLY through a configured summarizer, so no\n * run that predates one can land on either.\n */\nasync function foldDroppedHistory(\n summarize: NonNullable<HistoryPolicy['summarize']>,\n deps: AgentLoopDeps,\n input: AgentRunInput,\n hooks: AgentLoopHooks,\n history: TurnHistory,\n): Promise<ModelMessage[]> {\n const summary = await hooks.step('history:summarize', () =>\n summarize(history.dropped, historyContext(input)),\n );\n if (summary.usage !== undefined) {\n const usage = summary.usage;\n await hooks.step('persist:usage:history', () =>\n deps.store.recordUsage({\n threadId: input.threadId,\n actorRef: input.actor.id,\n modelId: summary.modelId ?? deps.modelId ?? 'unknown',\n purpose: 'history_summary',\n usage,\n }),\n );\n }\n return [{ role: 'system', content: buildSummaryBlock(summary.text) }, ...history.messages];\n}\n\n/** One turn's identity, as both processor chains see it. */\nfunction processorContext(input: AgentRunInput, step: number): ProcessorContext {\n return {\n threadId: input.threadId,\n actor: input.actor,\n step,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n };\n}\n\n/**\n * What the formatting pass is shown: the question, then the answer it has to restate.\n *\n * The question comes off the PROCESSED prompt rather than `AgentRunInput.userText`, because the pass\n * is a second route out of the model and has to stand behind the same input chain the streamed turn\n * did — a question a processor masked must not reappear in the clear here. Falls back to the answer\n * alone where the chain left no user message to point at.\n *\n * See {@link AgentLoopDeps.outputFromTranscript} for the agent that needs more than this, and why it\n * is the opt-in rather than the default.\n */\nfunction restatementPrompt(\n messages: ModelMessage[],\n answer: string,\n fromTranscript: boolean,\n): ModelMessage[] {\n const restated: ModelMessage = { role: 'assistant', content: answer };\n if (fromTranscript) {\n return [...messages, restated];\n }\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index];\n if (message?.role === 'user') {\n return [message, restated];\n }\n }\n return [restated];\n}\n\n/** One attempt of the formatting pass: what the model replied, and what it cost. */\ninterface StructuredAttempt {\n text: string;\n object?: unknown;\n usage: MessageUsage;\n modelId?: string;\n}\n\n/**\n * Restate a finished answer as `deps.outputSchema`, repairing a rejected reply up to\n * `outputRepairAttempts` times. Every model call is its own checkpoint (`structured:<step>:<n>`)\n * with its own usage row, so a suspend between two attempts resumes on the reply the first one got\n * rather than paying for a third.\n *\n * Validation itself sits OUTSIDE the checkpoints, on the same footing as `HistoryPolicy.select`: its\n * inputs are the schema (module config, identical on every process of a deployment) and the reply\n * a checkpoint already holds, so every replay reaches the same verdict — and therefore the same\n * number of attempts — without a checkpoint of its own.\n *\n * THE OUTPUT CHAIN RULES ON EACH ATTEMPT, before the schema does. This pass is a second route out of\n * the model: it is handed the finished answer and asked to restate it, so anything the chain held\n * back from the prose can be restated into the schema and leave through here. It is gated on the\n * WHOLE reply regardless of what the chain declared, because nothing here is streamed — there is no\n * prefix for an `incremental` processor to release, and the release path it buys does not exist.\n */\nasync function structureAnswer<TOutput>(\n schema: StandardSchemaV1<unknown, TOutput>,\n deps: AgentLoopDeps<TOutput>,\n input: AgentRunInput,\n hooks: AgentLoopHooks,\n messages: ModelMessage[],\n step: number,\n): Promise<TOutput> {\n const instruction = deps.outputInstruction ?? DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION;\n const maxAttempts = 1 + (deps.outputRepairAttempts ?? 1);\n const outputProcessors = deps.outputProcessors ?? [];\n let issues: readonly StandardSchemaV1.Issue[] = [];\n let text = '';\n for (let attempt = 0; attempt < maxAttempts; attempt += 1) {\n const system = attempt === 0 ? instruction : repairInstruction(instruction, issues);\n const reply = await hooks.step(`structured:${step}:${attempt}`, () =>\n spanned(\n 'structured-output',\n hooks.runId,\n { runId: hooks.runId, step, attempt },\n async (): Promise<StructuredAttempt> => {\n const discard: SinkWriter = { write: () => {}, end: () => {}, fail: () => {} };\n const turn = await deps.model.runTurn({\n system,\n messages,\n tools: [],\n sink: discard,\n outputSchema: schema,\n });\n return {\n text: turn.text,\n usage: turn.usage,\n ...(turn.object !== undefined ? { object: turn.object } : {}),\n ...(turn.modelId !== undefined ? { modelId: turn.modelId } : {}),\n };\n },\n (result) => ({\n inputTokens: result.usage.inputTokens,\n outputTokens: result.usage.outputTokens,\n textLength: result.text.length,\n }),\n ),\n );\n await hooks.step(`persist:usage:structured:${step}:${attempt}`, () =>\n deps.store.recordUsage({\n threadId: input.threadId,\n actorRef: input.actor.id,\n modelId: reply.modelId ?? deps.modelId ?? 'unknown',\n purpose: 'structured_output',\n usage: reply.usage,\n }),\n );\n text = reply.text;\n if (outputProcessors.length > 0) {\n // Its own checkpoint, after the usage row: the tokens were spent either way, and a refusal\n // that also hid its own cost would let a mis-tuned gate burn a budget invisibly — the same\n // ordering the streamed answer's gate takes.\n const gate = await hooks.step(`process:output:structured:${step}:${attempt}`, () =>\n runOutputProcessors(\n outputProcessors,\n { text: reply.text, toolCalls: [] },\n processorContext(input, step),\n ),\n );\n if (gate.rejection !== undefined) {\n throw new OutputRejectedError(gate.rejection.processor, gate.rejection.reason);\n }\n text = gate.text;\n }\n // A provider that constrained its own generation reports a parsed `object`, but that object\n // describes the reply the chain has just rewritten. Once the two disagree, the gated text is the\n // only version anything downstream may see, so it is re-parsed rather than trusted.\n const reported = text === reply.text ? reply.object : undefined;\n const outcome = await validateStructured(schema, text, reported);\n if (outcome.ok) {\n return outcome.value;\n }\n issues = outcome.issues;\n }\n throw new StructuredOutputError(issues, text, maxAttempts);\n}\n\n/**\n * What resolving a call's kind needs: the registry, plus the three config flags whose reserved names\n * have no `ToolSpec` to look up. Narrow on purpose — {@link stampToolKinds} is called from a\n * dispatched step handler, which holds the host's own deps rather than a loop's.\n */\nexport type ToolKindDeps = Pick<AgentLoopDeps, 'registry' | 'ask' | 'skills' | 'memory'>;\n\n/**\n * Stamp each of a model turn's calls with the kind declared WHERE THE TOOL WAS OFFERED.\n *\n * A call exists only because some process put that tool's definition in front of the model, so that\n * process is the one that certainly knows the tool. Another process might not: a deployment that\n * splits its pods by role has one that serves HTTP and replays run bodies without registering the\n * tool classes, and its registry answers `undefined`. Stamping here, INSIDE the llm checkpoint, is\n * what puts the kind in the journal — so the branch a call takes is a fact about the turn rather\n * than about whichever process happened to replay it (see {@link claimToolCall}).\n *\n * Only unstamped calls are touched: a kind already on a call was settled upstream, and a process\n * further down never second-guesses it.\n */\nexport function stampToolKinds<T extends { toolCalls: ToolCallRequest[] }>(\n result: T,\n deps: ToolKindDeps,\n): T {\n return {\n ...result,\n toolCalls: result.toolCalls.map((call) => {\n // Preflight is a worker fact, never a field the model may supply.\n const {\n preflight: _untrusted,\n prepared: _untrustedPrepared,\n actionApproval: _untrustedApproval,\n ...trusted\n } = call;\n return trusted.kind === undefined\n ? { ...trusted, kind: declaredKind(deps, trusted.name) }\n : trusted;\n }),\n };\n}\n\n/**\n * A call's declared kind, as settled inside `persist:toolcall` and journaled from there.\n *\n * The reserved `ask` name resolves from module CONFIG, never from the registry: `ask` has no handler\n * to register, and grounding its branch in config is what keeps a process with a partial registry\n * from disagreeing about it — the same property the registry lookup below has only because its\n * answer is written into the journal. Every other name is the registry's `ToolSpec`, exactly as\n * before.\n */\nfunction declaredKind(deps: ToolKindDeps, name: string): ToolKind {\n if (deps.ask === true && name === ASK_TOOL_NAME) {\n return 'ask';\n }\n // Same reserved-name reasoning as `ask`: `skill` has no handler either, and it is the JOURNALED\n // value below — not this config — that every replay reads the branch back from.\n if (deps.skills !== undefined && name === SKILL_TOOL_NAME) {\n return 'skill';\n }\n if (memoryIsWritable(deps) && name === REMEMBER_TOOL_NAME) {\n return 'memory';\n }\n return deps.registry.spec(name)?.kind ?? 'read';\n}\n\n/**\n * Does this deployment offer the `remember` tool at all? Memory a host serves read-only (a provider\n * with no `write`) still writes its block into the prompt and still spends `memory:digest`, but the\n * model is never shown a tool it would only be refused by. Module config either way, so the worker\n * re-deriving a dispatched turn's tool list reaches the same answer as the loop.\n */\nfunction memoryIsWritable(deps: Pick<AgentLoopDeps, 'memory'>): boolean {\n return deps.memory?.provider.write !== undefined;\n}\n\n/**\n * Append the built-in `ask` definition to a turn's tool list. Exported because the dispatched llm\n * step re-derives the tool list on a worker and has to reach the same list the loop would have.\n */\nexport function withAskTool({\n tools,\n ask,\n}: { tools: ToolDefinition[]; ask: boolean | undefined }): ToolDefinition[] {\n return ask === true ? [...tools, askToolDefinition()] : tools;\n}\n\n/**\n * Park on a question set, through whichever wait the host implemented, and read back whatever that\n * wait delivered as answers.\n *\n * The reduction of a yes/no channel — approve is \"confirmed the pre-picked answers\", reject is\n * \"skipped\" — applies to BOTH branches, because the shape of the reply is decided by whoever settled\n * the tool call, not by which hook the host wired. The question set sits in the approvals inbox as a\n * `pending_approval` action, so an operator pressing Approve there sends a `Decision` into a run\n * whose host implements `awaitAnswers` perfectly well. See {@link normalizeElicitationReply}.\n *\n * Neither branch moves a checkpoint: the wait sits at the same position either way, so the choice of\n * hook cannot change the sequence a replay lines up with.\n */\nasync function awaitElicitation(\n hooks: AgentLoopHooks,\n request: ElicitationRequest,\n ctx: AiToolCtx,\n): Promise<ElicitationReply> {\n if (hooks.awaitAnswers !== undefined) {\n return normalizeElicitationReply(await hooks.awaitAnswers(request, ctx));\n }\n return normalizeElicitationReply(\n await hooks.awaitApproval(\n { id: request.id, name: ASK_TOOL_NAME, input: request, kind: 'ask' },\n ctx,\n ),\n );\n}\n\n/**\n * The per-CALL half of a tool's context: which call this is, and the key that stays the same for\n * every execution of it (see {@link AiToolCtx.idempotencyKey}).\n */\nexport function toolCallContext<T extends { runId: string }>(\n ctx: T,\n toolCallId: string,\n): T & { toolCallId: string; idempotencyKey: string } {\n return { ...ctx, toolCallId, idempotencyKey: `${ctx.runId}:${toolCallId}` };\n}\n\n/** The tool context a turn hands to a handler — and to the wait an elicitation parks on. */\nfunction toolContext(deps: AgentLoopDeps, input: AgentRunInput, hooks: AgentLoopHooks): AiToolCtx {\n return {\n actor: input.actor,\n threadId: input.threadId,\n runId: hooks.runId,\n requestId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(input.uiCapabilities !== undefined ? { uiCapabilities: input.uiCapabilities } : {}),\n ...(deps.host !== undefined ? { host: deps.host } : {}),\n // Replaced per tool call by the call's own collector (see the tool step); this one only serves\n // what runs outside a call — the elicitation wait.\n emitUi: createNoopEmitUi(hooks.runId),\n };\n}\n\n/**\n * Does the configured intake run this turn? Both inputs are facts the journal already holds — the\n * config, and `load:thread`'s record of whether the thread had an assistant message when the turn\n * began. Neither is re-read from the store here, and that is the point: by the time a replay reaches\n * this line the first attempt has already appended the intake's own assistant message to the thread,\n * so a fresh read would answer differently on the resume than it did on the way in, and the answer\n * decides how many checkpoints follow it.\n */\nfunction intakeApplies(intake: AgentIntake, threadHasAssistant: boolean): boolean {\n return intake.when === 'every-turn' || !threadHasAssistant;\n}\n\n/**\n * The configured intake: post the authored question set, park until a human settles it, and leave\n * the exchange on the transcript as an ordinary tool round-trip so the model reads the answers the\n * same way it reads its own `ask`'s.\n *\n * COSTS NO MODEL CALL. The questions, their options and their pre-picked defaults are all authored\n * on the `@Agent`, so nothing here is generated and nothing here is billed — which is also why the\n * total is knowable before the first question is shown.\n *\n * One checkpoint whenever an `intake` is configured, plus two more on the turns it actually asks —\n * all of them reachable only through that config, so a run that predates the option cannot land on\n * any of them and no marker is spent keeping the sequence stable for it. See\n * {@link AgentLoopHooks.patched} for the case that does need one.\n */\nasync function runIntake(\n intake: AgentIntake,\n deps: AgentLoopDeps,\n input: AgentRunInput,\n hooks: AgentLoopHooks,\n writer: SinkWriter,\n threadHasAssistant: boolean,\n): Promise<ModelMessage | null> {\n const preamble = intake.preamble ?? DEFAULT_INTAKE_PREAMBLE;\n // Derived from the run, so a replay rebuilds the same id without minting one — the id is a\n // checkpoint name's suffix and the signal's own key, so it cannot come from a random source.\n const request: ElicitationRequest = {\n id: `intake-${hooks.runId}`,\n source: 'intake',\n preamble,\n questions: intake.questions,\n };\n const call: ToolCallRequest = {\n id: request.id,\n name: ASK_TOOL_NAME,\n input: { preamble, questions: intake.questions },\n kind: 'ask',\n };\n // The message id rides the checkpoint because the answers land on the SAME message the questions\n // did, and the step that settles them runs after a wait that can outlive the process.\n const asked = await hooks.step('intake:ask', async (): Promise<{ messageId: string } | null> => {\n if (!intakeApplies(intake, threadHasAssistant)) {\n return null;\n }\n const message = await deps.store.appendMessage({\n threadId: input.threadId,\n role: 'assistant',\n content: preamble,\n runId: hooks.runId,\n toolCalls: [call],\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n });\n await deps.store.recordToolCall({\n toolCallId: request.id,\n messageId: message.id,\n toolName: ASK_TOOL_NAME,\n // The store knows read/action only. An unanswered question is work waiting on a human, which\n // is what `action` + `pending_approval` already mean — so it surfaces in an approvals inbox\n // rather than needing one of its own.\n toolType: 'action',\n input: call.input,\n status: 'pending_approval',\n runId: hooks.runId,\n });\n await writer.write(encodeStreamEvent({ kind: 'elicitation', id: request.id, request }));\n return { messageId: message.id };\n });\n if (asked === null) {\n return null;\n }\n const messageId = asked.messageId;\n const reply = await awaitElicitation(hooks, request, toolContext(deps, input, hooks));\n const result = settleElicitation(request, reply);\n await hooks.step('intake:answers', async () => {\n await deps.store.updateToolCall({\n toolCallId: request.id,\n // A skip is not an answer. Both leave the agent holding the same values, but only one of them\n // is evidence the user chose them, and a reader auditing what the agent was told has to be\n // able to tell those apart.\n status: result.skipped ? 'rejected' : 'executed',\n output: result,\n ...(result.skipped ? { error: 'skipped by the user' } : {}),\n ...(reply.answeredByRef !== undefined ? { executedByRef: reply.answeredByRef } : {}),\n });\n await deps.store.setMessageToolResults(messageId, [\n { id: request.id, name: ASK_TOOL_NAME, output: result },\n ]);\n await writer.write(encodeStreamEvent({ kind: 'tool-output', id: request.id, output: result }));\n });\n return {\n role: 'assistant',\n content: preamble,\n toolCalls: [call],\n toolResults: [{ id: request.id, name: ASK_TOOL_NAME, output: result }],\n };\n}\n\n/**\n * Identifies the batched tool-call shape to {@link AgentLoopHooks.patched}. Batching hoists the\n * turn's `persist:toolcall` checkpoints ahead of its first tool execution, so a run that suspended\n * mid-turn under the one-call-at-a-time shape must keep replaying against THAT one.\n */\nconst PARALLEL_TOOLS_PATCH = 'agent:parallel-tools';\n\n/**\n * Identifies the cancellable loop shape to {@link AgentLoopHooks.patched}. The observation points it\n * guards are new positions in the middle of the sequence, so a run that suspended before a\n * deployment gained them must keep replaying against the sequence its history holds.\n */\nconst CANCELLATION_PATCH = 'agent:cancellation';\n\n/**\n * Identifies the selected-history load to {@link AgentLoopHooks.patched}. `load:thread` keeps its\n * name and its position; what changed is what it CHECKPOINTS — the messages the turn will send\n * rather than the whole `ThreadDetail` — and a checkpoint's payload is a wire contract with every\n * run already in flight just as its name is.\n *\n * A marker rather than a tolerance for the old payload, because the two shapes cannot be told apart\n * where it matters: both carry `messages` and a `title`, and an empty thread serializes to something\n * either release could have written. The marker is a fact the JOURNAL holds, at a position the\n * runtime hands back to a run that recorded a real step there, so the branch is decided by the run's\n * own history rather than by a guess at its bytes. What rides on getting it right is\n * `history:summarize`: its presence depends on a split the old payload carries no record of, so a\n * resume that read that payload as the new shape would skip a position the history has spent.\n */\nconst SELECTED_HISTORY_PATCH = 'agent:selected-history';\n\n/**\n * Identifies the JOURNALED prompt-stage set to {@link AgentLoopHooks.patched} — the marker that lets\n * {@link PromptStages} be read back from a run's own history instead of re-derived from whatever\n * module config the process replaying it happens to hold.\n *\n * WHERE IT SITS, and why the choice is narrow. Probed after the history load and immediately before\n * `run:started-at`. The position has to be one that every journal written before this marker existed\n * fills with a REAL step whatever it was configured with — because `patched` refuses, raising\n * `NonDeterminismError` rather than rewinding, when it finds a DIFFERENT `patch:` marker where it\n * looks. That rules out the position after `persist:user`, which holds `agent:selected-history`, and\n * the position after `persist:run:start`, which holds `agent:cancellation` on a deployment that\n * enables none of the three stages. `load:thread`, `run:started-at` and `persist:run:start` are the\n * unconditional steps in between, and this marker takes the gap before the second of them.\n *\n * WHY NOT A MARKER PER STAGE, guarding each stage's own position. Because a stage's position is\n * already occupied on every deployment that has the stage switched on: a journal written with memory\n * enabled holds `memory:digest` exactly where that marker would sit, `patched` rewinds and answers\n * false there, and the guard would then SKIP a checkpoint the history holds — diverging a few\n * positions later, on every in-flight run of every host already using the feature. That is the\n * opposite of the protection it was reached for. `agent:dispatched-steps` can be guarded that way\n * only because no journal anywhere holds the shape it guards without also holding the marker.\n * Journals DO hold `memory:digest`, `retrieve` and `skills:catalog` with no marker in front of them.\n *\n * So the marker records a property of the BODY — \"this run journals which prompt stages it had\" —\n * and the per-stage answers ride in the checkpoint below, where three independent switches are\n * stated separately instead of one boolean standing in for all of them.\n */\nconst PROMPT_STAGES_PATCH = 'agent:prompt-stages';\n\n/**\n * Which of the three optional prompt stages this RUN had. Each spends a checkpoint position that\n * exists only where a host wired the matching dep, so together they decide the turn's checkpoint\n * SEQUENCE:\n *\n * - `memory` → `memory:digest`\n * - `retriever` → `retrieve`\n * - `skills` → `skills:catalog`\n *\n * Read from module config ONCE, at {@link PROMPT_STAGES_PATCH}'s position, and journaled there.\n * Every later replay reads those three answers back — so enabling memory on a deployment cannot\n * insert a position into a run that is parked on a human's approval, and disabling it cannot take\n * one away.\n *\n * WHAT IT DOES NOT COVER, because the next reader should not have to assume. `quota` is the one\n * stage of this kind that CANNOT be guarded this way: `quota:check` is the loop's first position, so\n * the only marker position that precedes it is the workflow's own first, which\n * `agent:dispatched-steps` already owns — and a second marker there would make that guard raise\n * instead of rewind. Enabling a quota store under a parked run therefore still shifts its sequence.\n * `pricingStore` (`pricing:list`), `intake` (`intake:ask`/`intake:answers`), `inputProcessors`\n * (`process:input:<step>`), `outputProcessors` (`process:output:<step>` and the follow-ups gate),\n * `followUpsCount` (`followups:<step>` and its usage row) and `outputSchema` (`structured:*`) all\n * sit after this marker and so COULD join this payload; they do not yet. A field added here for one\n * of them reads back `undefined` on a run journaled before it, which has to mean \"fall back to\n * config\" — that run's exposure unchanged rather than inverted.\n *\n * WHAT STAYS MODULE CONFIG, deliberately: the turn's TOOL LIST. Whether the model is offered `skill`\n * or `remember` is uniform across a deployment and is re-derived on whichever worker serves a\n * dispatched model call, and the `skill`/`remember` handlers already answer a call they have no\n * catalog or digest for as a tool failure. Only positions are journaled here.\n */\ninterface PromptStages {\n memory: boolean;\n retriever: boolean;\n skills: boolean;\n}\n\n/**\n * The prompt stages this run is held to: the journal's record of them, or — for a run whose journal\n * predates {@link PROMPT_STAGES_PATCH} — the live configuration, which is what that run's own body\n * used.\n */\nasync function resolvePromptStages(\n deps: AgentLoopDeps,\n hooks: AgentLoopHooks,\n): Promise<PromptStages> {\n const configured: PromptStages = {\n memory: deps.memory !== undefined,\n retriever: deps.retriever !== undefined,\n skills: deps.skills !== undefined,\n };\n return (await (hooks.patched?.(PROMPT_STAGES_PATCH) ?? Promise.resolve(true)))\n ? hooks.step('run:prompt-stages', () => Promise.resolve(configured))\n : configured;\n}\n\n// What a stage answers where the RUN recorded it but this process has nothing wired to serve it —\n// the mid-rollout case of a dep taken away under a run that is still in flight.\n//\n// Reachable only on the attempt that first ARRIVES at the position: a replay is served the journaled\n// payload without running the body at all. So what it costs is one run's worth of the stage\n// degrading to nothing, in exchange for the position staying where the history put it — the same\n// posture the `skill` and `remember` handlers take when their config has gone.\nconst UNSERVED_MEMORY: MemoryDigest = { scopes: [], entries: [], omitted: 0, pinnedOmitted: 0 };\nconst UNSERVED_SKILLS: SkillOffer = { scopes: [], entries: [], omitted: 0 };\n\n/**\n * Read the cancel flag at one of the loop's safe points, and unwind the turn if it is set.\n *\n * The read is a checkpoint, which is the whole design: the answer becomes a fact the journal holds\n * rather than one each replaying process asks afresh — see {@link AgentLoopHooks.cancelled}. Unwinds\n * by THROWING, the same way a suspend leaves the turn, so every `catch` between here and the runner\n * already knows to let it past without writing checkpoints of its own.\n *\n * A tool that is already executing is NOT interrupted. There is no un-executing a side effect, and\n * abandoning a dispatched step mid-flight would leave the journal holding a dispatch whose result\n * never lands — so an in-flight call finishes, is recorded exactly as it would have been, and the\n * cancel is observed at the next point instead.\n */\nasync function haltIfCancelled(\n hooks: AgentLoopHooks,\n cancellable: boolean,\n name: string,\n): Promise<void> {\n const observe = hooks.cancelled;\n if (!cancellable || observe === undefined) {\n return;\n }\n if (await hooks.step(name, () => observe())) {\n throw new RunCancelledError();\n }\n}\n\n/** What every per-call helper below needs from the turn that requested the call. */\ninterface ToolTurnContext {\n deps: AgentLoopDeps;\n input: AgentRunInput;\n hooks: AgentLoopHooks;\n /** The assistant message the calls hang off. */\n messageId: string;\n /** The run's live stream — an `ask` posts its question set here while the turn parks. */\n writer: SinkWriter;\n /**\n * What each call pushed through `ctx.emitUi`, by call id, read off the tool steps' results. The\n * step persists them onto the message in call order once every tool has settled.\n */\n toolUi: Map<string, AgentUiComponent[]>;\n toolText: Map<string, string>;\n /** Set when a `terminal` tool succeeded: the turn ends after this step. */\n halt: { terminal: boolean; independentProposal?: boolean };\n actionApprovalMode?: ActionApprovalMode;\n /**\n * What `skills:catalog` recorded this turn, or undefined where skills are not configured. A\n * `skill` call is served against THIS, never against a fresh provider read — see {@link loadSkill}.\n */\n skills?: SkillOffer;\n /**\n * What `memory:digest` recorded this turn, or undefined where memory is not configured. A\n * `remember` call is authorized against THIS digest's scopes, never a fresh resolution — see\n * {@link writeMemory}.\n */\n memory?: MemoryDigest;\n /** What `persona:resolve` recorded, or undefined where the turn runs under no persona. */\n persona?: TurnPersona;\n}\n\n/** A tool call whose kind has been settled by its `persist:toolcall` checkpoint. */\ninterface ClaimedToolCall {\n /** The call as the model asked for it. */\n call: ToolCallRequest;\n /** The same call with `kind` agreeing with the branch actually taken. */\n resolvedCall: ToolCallRequest;\n toolType: ToolKind;\n targetAgent?: string;\n /** For an `agent` call — whether the journal says this delegation runs detached. */\n detached?: boolean;\n /** The journal says a successful call ends the turn (`ToolSpec.terminal`). */\n terminal?: boolean;\n /** Opt in to the completed-preflight presentation checkpoint from the journaled claim. */\n presentCompletedPreflight?: true;\n /**\n * For an `action` call — how the journal says it is approved. Undefined for a call claimed before\n * approval policies existed, which waits on the requester with no expiry, as it always did.\n */\n approval?: ClaimedApproval;\n preflight?: ToolPreflightResult | { status: 'failed'; error: string };\n proposalId?: string;\n ctx: AiToolCtx;\n}\n\n/**\n * The approval branch an `action` call takes, settled inside its `persist:toolcall` checkpoint:\n * - `ask` → park on a person (`approver`), for at most `ttlMs` when set;\n * - `auto` → the policy did not require one: run straight away;\n * - `remembered` → an earlier decision in this thread approved this tool for good: run straight away.\n */\ntype ClaimedApproval =\n | { mode: 'ask'; approver: string; ttlMs?: number; expiresAt?: string }\n | { mode: 'auto' }\n | { mode: 'remembered'; approver: string };\n\n/** What a decided action call records next to its outcome, and streams as `approval-settled`. */\ninterface ApprovalMeta {\n approver?: string;\n decidedBy: string;\n decidedVia?: string;\n remember?: boolean;\n /**\n * Stream `approval-settled` with the outcome. False for a call claimed before approval policies\n * existed: its decision is still recorded, but that run keeps writing the frames it always wrote.\n */\n streamed: boolean;\n}\n\n/** One invocation's result, already reduced to what the persist checkpoint writes. */\ntype ToolOutcome =\n | { status: 'executed'; output: unknown; executionMs: number }\n | { status: 'failed'; error: string; executionMs: number }\n | { status: 'denied'; reason: string; executionMs: number };\n\n/**\n * Record the call and settle its KIND, which decides this call's control flow: an `action` suspends\n * the run on an approval signal (`signal:tool:<runId>:<callId>`), anything else records a step.\n * Reading it from `deps.registry` in the loop body would tie that branch to the registry of\n * WHICHEVER PROCESS runs the body — and a process whose registry lacks this tool reads `undefined`,\n * falls back to 'read', and expects a `tool:` checkpoint where the history holds `signal:tool:`.\n * That is a NonDeterminismError on resume, and worse, when execution is dispatched\n * (`hooks.dispatchTool`) it reaches a worker that DOES have the tool: an action executed with\n * nobody's approval.\n *\n * Two things keep that from happening, and they answer different halves of it:\n *\n * - The kind is RETURNED from the `persist:toolcall` step, so every replay reads back the same\n * verdict instead of asking its own registry. That makes the decision CONSISTENT.\n * - The kind it writes is the one {@link stampToolKinds} put on the call inside the llm\n * checkpoint, where the tool was offered. That makes the decision CORRECT — the step is not\n * necessarily first reached by a process that knows the tool. A dispatched turn resumes on\n * whichever instance consumes the model step's result, and settling an approval resumes it on\n * whichever instance took the decision; neither is chosen by role. A pod that registers no\n * tool classes reached this step and journaled `read` for an action tool, intermittently,\n * depending on which pod won that race.\n *\n * The local lookup remains as the fallback for a call that arrives unstamped: a journal written\n * before kinds travelled, or a host driving the loop with no llm checkpoint of its own. Same step\n * name at the same position throughout, so runs already in flight keep replaying.\n */\nasync function claimToolCall(\n turn: ToolTurnContext,\n call: ToolCallRequest,\n): Promise<ClaimedToolCall> {\n const { deps, input, hooks, messageId } = turn;\n const persisted = (await hooks.step(`persist:toolcall:${call.id}`, async () => {\n const spec = deps.registry.spec(call.name);\n const kind: ToolKind = call.kind ?? declaredKind(deps, call.name);\n // Both kinds that park the turn on a person. The store knows read/action only; a delegation is\n // neither approved nor rejected by a human, so it persists as a read.\n const awaitsHuman = kind === 'action' || kind === 'ask';\n // Decided HERE, inside the checkpoint, and returned from it: the policy and the remembered set\n // can both change while a run is parked, and the branch below (park or run) has to be the one\n // the journal recorded. A run claimed before this existed reads `approval` back as undefined and\n // waits on the requester, exactly as it did.\n const independentApproval =\n turn.actionApprovalMode === 'independent' && kind === 'action'\n ? hooks.dispatchLlm !== undefined && call.actionApproval !== undefined\n ? call.actionApproval\n : await resolveActionProposalApproval({\n actor: input.actor,\n store: deps.store,\n tool: { name: call.name, kind: 'action', ...(spec !== undefined ? { spec } : {}) },\n thread: {\n threadId: input.threadId,\n runId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n },\n ...(deps.approvalPolicy !== undefined ? { policy: deps.approvalPolicy } : {}),\n })\n : undefined;\n let preflight: ClaimedToolCall['preflight'];\n let prepared: Awaited<ReturnType<typeof prepareActionProposal>> | undefined;\n if (\n turn.actionApprovalMode === 'independent' &&\n call.prepared !== undefined &&\n hooks.dispatchLlm !== undefined\n )\n prepared = call.prepared;\n if (kind === 'action' && hooks.dispatchLlm !== undefined && call.preflight !== undefined) {\n preflight = call.preflight;\n } else if (kind === 'action' && hooks.dispatchLlm !== undefined && spec === undefined) {\n // A legacy remote journal has no prepared stamp. Keep its original approval branch;\n // every new worker stamps preparation before returning the turn.\n preflight = { status: 'ready' };\n } else if (kind === 'action') {\n try {\n const allowedTools =\n turn.persona?.allowedTools === undefined\n ? deps.toolAllowList\n : intersectAllowLists(deps.toolAllowList, turn.persona.allowedTools);\n if (independentApproval?.mode === 'ask') {\n prepared = await prepareActionProposal(\n deps.registry,\n call.name,\n call.input,\n toolCallContext(toolContext(deps, input, hooks), call.id),\n deps.rolesPolicy,\n allowedTools === undefined ? {} : { allowedTools },\n );\n preflight = prepared.preflight;\n } else {\n preflight = await deps.registry.prepare(\n call.name,\n call.input,\n toolCallContext(toolContext(deps, input, hooks), call.id),\n deps.rolesPolicy,\n allowedTools === undefined ? {} : { allowedTools },\n );\n }\n } catch (error) {\n if (\n hooks.isControlFlowError?.(error) === true ||\n isControlFlowSignal(error) ||\n isReplayIntegrityError(error)\n )\n throw error;\n preflight = {\n status: 'failed',\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n let confirmation = preflight?.status === 'ready' ? preflight.confirmation : undefined;\n const approval =\n kind === 'action' && preflight?.status === 'ready'\n ? (independentApproval ?? (await claimApproval(turn, call, spec)))\n : undefined;\n let proposalId: string | undefined;\n if (turn.actionApprovalMode === 'independent' && approval?.mode === 'ask') {\n if (!prepared) throw new Error('Independent action lacks trusted prepared input');\n const proposalStore = deps.store as AgentStore & ActionProposalStore;\n if (typeof proposalStore.createActionProposal !== 'function')\n throw new Error('Independent action proposal store unavailable');\n proposalId = `proposal-${createHash('sha256')\n .update(JSON.stringify([hooks.runId, call.id]))\n .digest('hex')}`;\n const display = confirmation ??\n spec?.presentation?.confirm ?? { title: `Allow ${call.name}?`, verb: 'Approve' };\n const fill = (value: string) =>\n value.replace(/\\{([^}]+)\\}/g, (_match, path: string) => {\n let current: unknown = prepared?.input;\n for (const part of path.split('.'))\n current =\n current !== null && typeof current === 'object'\n ? (current as Record<string, unknown>)[part]\n : undefined;\n return current === undefined ? '' : String(current);\n });\n const create =\n prepared.replacementKey === undefined\n ? proposalStore.createActionProposal.bind(proposalStore)\n : (() => {\n const store = proposalStore as AgentStore &\n ActionProposalStore &\n ActionProposalSupersessionStore;\n if (typeof store.createReplacingActionProposal !== 'function')\n throw new Error('Independent replacement requires atomic supersession store');\n return store.createReplacingActionProposal.bind(store);\n })();\n const created = await create({\n ...(prepared.replacementKey !== undefined\n ? { replacementKey: prepared.replacementKey }\n : {}),\n id: proposalId,\n tenantRef: input.actor.tenantRef ?? null,\n actorRef: input.actor.id,\n threadId: input.threadId,\n originRunId: hooks.runId,\n originMessageId: messageId,\n originToolCallId: call.id,\n toolName: call.name,\n input: prepared.input,\n preparationInput: prepared.preparationInput,\n executionContext: {\n requestId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(input.uiCapabilities !== undefined ? { uiCapabilities: input.uiCapabilities } : {}),\n },\n confirmation: confirmation ?? {\n title: fill(display.title),\n verb: fill(display.verb),\n ...(display.detail !== undefined ? { detail: fill(display.detail) } : {}),\n },\n approver: approval.approver,\n expiresAt: approval.expiresAt === undefined ? null : Date.parse(approval.expiresAt),\n idempotencyKey: toolCallContext(toolContext(deps, input, hooks), call.id).idempotencyKey,\n });\n if (created.status === 'conflict') throw new Error('Action proposal replay payload conflict');\n confirmation = created.proposal?.confirmation ?? confirmation;\n }\n const parks = kind === 'ask' || (approval?.mode === 'ask' && proposalId === undefined);\n await deps.store.recordToolCall({\n toolCallId: call.id,\n messageId,\n toolName: call.name,\n toolType: awaitsHuman ? 'action' : 'read',\n input: call.input,\n status: proposalId !== undefined ? 'proposed' : parks ? 'pending_approval' : 'auto_executed',\n ...(proposalId !== undefined ? { proposalId } : {}),\n runId: hooks.runId,\n ...(confirmation !== undefined ? { confirmation } : {}),\n ...(approval !== undefined && approval.mode !== 'auto'\n ? { approver: approval.approver }\n : {}),\n ...(approval?.mode === 'ask' && approval.expiresAt !== undefined\n ? { expiresAt: approval.expiresAt }\n : {}),\n });\n if (approval?.mode === 'ask') {\n // Streamed from inside the same checkpoint so a replay never repeats it. The call itself was\n // announced by the model step that asked for it, so the frame can name it by id.\n await turn.writer.write(\n encodeStreamEvent({\n kind: 'approval-requested',\n id: call.id,\n ...(proposalId !== undefined\n ? { target: { kind: 'proposal' as const, proposalId } }\n : {}),\n approver: approval.approver,\n ...(confirmation !== undefined ? { confirmation } : {}),\n ...(approval.expiresAt !== undefined ? { expiresAt: approval.expiresAt } : {}),\n }),\n );\n }\n return {\n kind,\n ...(spec?.targetAgent !== undefined ? { targetAgent: spec.targetAgent } : {}),\n // Only an `agent` spec ever carries this, and only when the author declared it — so a\n // deployment with no detached edge writes the same bytes here it always has.\n ...(spec?.detached === true ? { detached: true } : {}),\n // Same for `terminal`: absent unless declared, so a deployment with no terminal tool writes\n // the bytes it always has, and a replay reads the branch back instead of re-deciding it.\n ...(spec?.terminal === true ? { terminal: true } : {}),\n // Journal this extra checkpoint's opt-in; historical claims without it keep their sequence.\n ...(preflight?.status === 'completed' && deps.registry.hasPresentation(call.name)\n ? { presentCompletedPreflight: true }\n : {}),\n ...(approval !== undefined ? { approval } : {}),\n ...(preflight !== undefined ? { preflight } : {}),\n ...(proposalId !== undefined ? { proposalId } : {}),\n };\n })) as\n | {\n kind?: ToolKind;\n targetAgent?: string;\n detached?: boolean;\n terminal?: boolean;\n presentCompletedPreflight?: true;\n approval?: ClaimedApproval;\n preflight?: ClaimedToolCall['preflight'];\n proposalId?: string;\n }\n | undefined;\n const toolType: ToolKind = persisted?.kind ?? call.kind ?? 'read';\n return {\n call,\n // What the rest of the turn — the dispatched tool envelope, the stream frames — sees as this\n // call's kind, so it agrees with the branch actually taken instead of with a second lookup.\n resolvedCall: call.kind === toolType ? call : { ...call, kind: toolType },\n toolType,\n ...(persisted?.targetAgent !== undefined ? { targetAgent: persisted.targetAgent } : {}),\n ...(persisted?.detached === true ? { detached: true } : {}),\n ...(persisted?.terminal === true ? { terminal: true } : {}),\n ...(persisted?.presentCompletedPreflight === true ? { presentCompletedPreflight: true } : {}),\n ...(toolType === 'action' && persisted?.approval !== undefined\n ? { approval: persisted.approval }\n : {}),\n ...(persisted?.preflight !== undefined ? { preflight: persisted.preflight } : {}),\n ...(persisted?.proposalId !== undefined ? { proposalId: persisted.proposalId } : {}),\n ctx: toolContext(deps, input, hooks),\n };\n}\n\n/**\n * How an `action` call gets approved: ask the turn's policy, then — when it wants a person — check\n * whether someone in this thread already approved this tool for good. Runs INSIDE the call's\n * `persist:toolcall` checkpoint; see {@link claimToolCall}.\n */\nasync function claimApproval(\n turn: ToolTurnContext,\n call: ToolCallRequest,\n spec: ToolSpec | undefined,\n): Promise<ClaimedApproval> {\n const { deps, input, hooks } = turn;\n const policy = deps.approvalPolicy ?? new DefaultApprovalPolicy();\n const requirement: ApprovalRequirement = await policy.requirementFor(\n { name: call.name, kind: 'action', ...(spec !== undefined ? { spec } : {}) },\n input.actor,\n {\n threadId: input.threadId,\n runId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n },\n );\n if (!requirement.required) {\n return { mode: 'auto' };\n }\n const remembered = (await deps.store.rememberedApprovals?.(input.threadId)) ?? [];\n if (remembered.includes(call.name)) {\n return { mode: 'remembered', approver: requirement.approver };\n }\n const ttlMs =\n requirement.ttlMs !== undefined && Number.isFinite(requirement.ttlMs) && requirement.ttlMs > 0\n ? Math.floor(requirement.ttlMs)\n : undefined;\n return {\n mode: 'ask',\n approver: requirement.approver,\n ...(ttlMs !== undefined\n ? { ttlMs, expiresAt: new Date(Date.now() + ttlMs).toISOString() }\n : {}),\n };\n}\n\n/** What a served `skill` call hands back to the model — the procedure, and where it came from. */\ninterface LoadedSkillOutput {\n name: string;\n scope: string;\n body: string;\n /** Scopes of same-named skills this one overrode. Present only when it overrode something. */\n shadows?: string[];\n}\n\n/**\n * Serve one `skill` call: read the body and hand it to the model as an ordinary tool result.\n *\n * WHY THE BODY IS RETURNED FROM THE CHECKPOINT. Which instructions entered a turn's prompt is a\n * decision about the turn, and a decision about a turn has to be readable from its journal — the\n * same property `persist:toolcall` gives the read/action branch. A replay that re-read the provider\n * would compose a DIFFERENT prompt from a skill edited in between, on a transcript position the\n * history already holds: the model would then be answering something nobody can reconstruct from the\n * record, and a turn whose step count depends on what it was told would ask for a position its\n * history has no room for. Inside `tool:<callId>` the first attempt's text is the only text there\n * ever was.\n *\n * The positions are a read tool's, exactly (`persist:toolcall` above, `tool:<id>` here,\n * `persist:toolexec:<id>`/`persist:toolfail:<id>` after), so nothing about the shape of a turn\n * depends on whether a call was a skill — only on the kind the journal recorded.\n */\nasync function loadSkillIntoTurn(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n startedAt: number,\n): Promise<ToolOutcome> {\n const { deps, input, hooks } = turn;\n const { call } = claimed;\n const config = deps.skills;\n const offer = turn.skills;\n const outcome = await hooks.step(\n `tool:${call.id}`,\n async (): Promise<{ ok: true; output: LoadedSkillOutput } | { ok: false; error: string }> => {\n if (config === undefined || offer === undefined) {\n // Reachable only where a call's journaled kind is `skill` but this process has no skills\n // configured — a deployment mid-rollout. A tool failure, because it is the one vocabulary\n // the model can act on, and because failing the run would strand a turn over a lookup.\n return { ok: false, error: 'Skills are not available in this deployment.' };\n }\n const parsed = await skillInputSchema['~standard'].validate(call.input);\n if (parsed.issues !== undefined) {\n return {\n ok: false,\n error: `invalid skill input: ${parsed.issues.map((each) => `${(each.path ?? []).join('.') || '(root)'}: ${each.message}`).join('; ')}`,\n };\n }\n const loaded = await loadSkill(config, offer, parsed.value.name, skillContext(input));\n if (!loaded.ok) {\n return { ok: false, error: loaded.error };\n }\n return {\n ok: true,\n output: {\n name: loaded.skill.name,\n scope: loaded.skill.scope,\n body: loaded.skill.body,\n ...(loaded.shadows !== undefined ? { shadows: loaded.shadows } : {}),\n },\n };\n },\n );\n return outcome.ok\n ? { status: 'executed', output: outcome.output, executionMs: Date.now() - startedAt }\n : { status: 'failed', error: outcome.error, executionMs: Date.now() - startedAt };\n}\n\n/**\n * Serve one `remember` call: write the fact and hand the stored record back as an ordinary tool\n * result.\n *\n * WHY THE WRITE HAPPENS INSIDE THE CHECKPOINT. Two reasons, and the second is the one that is easy\n * to miss. It makes the write idempotent under replay — a resumed run reads the record back from\n * `tool:<callId>` instead of storing a second copy of a fact the model only decided once. And it\n * makes what the model was TOLD about the write part of the journal, so the transcript a later step\n * reads is the one the first attempt built, rather than whatever a second write would have returned.\n *\n * The positions are a read tool's, exactly, so nothing about the shape of a turn depends on whether\n * a call wrote a memory — only on the kind the journal recorded.\n */\nasync function rememberIntoTurn(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n startedAt: number,\n): Promise<ToolOutcome> {\n const { deps, input, hooks } = turn;\n const { call } = claimed;\n const config = deps.memory;\n const digest = turn.memory;\n const outcome = await hooks.step(\n `tool:${call.id}`,\n async (): Promise<{ ok: true; record: MemoryRecord } | { ok: false; error: string }> => {\n if (config === undefined || digest === undefined) {\n // Reachable only where a call's journaled kind is `memory` but this process has none\n // configured — a deployment mid-rollout. A tool failure, because it is the one vocabulary\n // the model can act on, and because failing the run would strand a turn over a lookup.\n return { ok: false, error: 'Memory is not available in this deployment.' };\n }\n const parsed = await rememberInputSchema['~standard'].validate(call.input);\n if (parsed.issues !== undefined) {\n return {\n ok: false,\n error: `invalid remember input: ${parsed.issues.map((each) => `${(each.path ?? []).join('.') || '(root)'}: ${each.message}`).join('; ')}`,\n };\n }\n return await writeMemory({\n config,\n digest,\n call: parsed.value,\n ctx: skillContext(input),\n runId: hooks.runId,\n });\n },\n );\n if (!outcome.ok) {\n return { status: 'failed', error: outcome.error, executionMs: Date.now() - startedAt };\n }\n publishAgentMemoryWritten({\n runId: hooks.runId,\n scope: outcome.record.scope,\n chars: outcome.record.text.length,\n });\n return { status: 'executed', output: outcome.record, executionMs: Date.now() - startedAt };\n}\n\n/** The turn's identity as the skills seam sees it — the same inputs the prompt is resolved from. */\nfunction skillContext(input: AgentRunInput): SkillContext {\n return {\n actor: input.actor,\n threadId: input.threadId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(input.uiCapabilities !== undefined ? { uiCapabilities: input.uiCapabilities } : {}),\n };\n}\n\n/**\n * Execute one claimed call. Requests its checkpoint SYNCHRONOUSLY (nothing is awaited before\n * `hooks.dispatchTool`/`hooks.step`), which is what lets a batch of these be launched together and\n * still occupy positions in call order — see {@link AgentLoopHooks.parallel}.\n *\n * A tool's own failure is an outcome, not a throw: the model gets it as a result and adapts. Only\n * the runner's control flow (a durable suspend / continue-as-new) and a replay-integrity refusal\n * escape — a `catch` that answered either of those by writing a `persist:toolfail` checkpoint would\n * diverge from the replay's real result, or ask for a position a diverged history has no room for\n * so the operator reads the second refusal instead of the disagreement that caused it.\n */\nasync function invokeClaimedTool(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n): Promise<ToolOutcome> {\n const { deps, input, hooks } = turn;\n const { call, resolvedCall, ctx } = claimed;\n // An `agent` call branches to delegation before reaching here, so anything that isn't an `action`\n // is a read — the same posture the kind fallback itself takes.\n const toolType = claimed.toolType === 'action' ? 'action' : 'read';\n const startedAt = Date.now();\n try {\n // Inside the same `try` as a registered tool's invocation, so a provider that throws is recorded\n // as this call's failure — and a suspend or a replay refusal still leaves untouched below.\n if (claimed.toolType === 'skill') {\n return await loadSkillIntoTurn(turn, claimed, startedAt);\n }\n if (claimed.toolType === 'memory') {\n return await rememberIntoTurn(turn, claimed, startedAt);\n }\n // Under a persona with an allow-list, the same narrowing the offer had — agent ∩ persona — is\n // what `invoke` holds the call to. Without one, nothing new is checked.\n const invokeAllowList =\n turn.persona?.allowedTools === undefined\n ? deps.toolAllowList\n : intersectAllowLists(deps.toolAllowList, turn.persona.allowedTools);\n let raw: unknown;\n if (hooks.dispatchTool) {\n const stepCtx: ToolStepCtx = {\n actor: input.actor,\n threadId: input.threadId,\n runId: hooks.runId,\n requestId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(input.uiCapabilities !== undefined ? { uiCapabilities: input.uiCapabilities } : {}),\n };\n const envelope: ToolStepEnvelope = {\n toolName: call.name,\n input: call.input,\n ctx: stepCtx,\n ...(invokeAllowList !== undefined ? { allowedTools: invokeAllowList } : {}),\n ...(deps.toolTimeoutMs !== undefined ? { timeoutMs: deps.toolTimeoutMs } : {}),\n // Numeric-only: the handler applies withToolTimeout AND its own local `classify` — see\n // ToolStepEnvelope.transientRetry.\n transientRetry: resolveToolTransientRetryNumbers(deps.toolTransientRetry),\n // The handler hands back what the tool pushed through `ctx.emitUi` with its output.\n collectUi: true,\n };\n // The handler applies withToolTimeout (and the retry loop) itself — no loop-side wrap for\n // a dispatched call.\n raw = await hooks.dispatchTool(resolvedCall, envelope);\n } else {\n const invocation = hooks.step(`tool:${call.id}`, async () => {\n // Pushed components stream as they happen and ride this step's RESULT into the journal\n // (see `wrapToolStepOutput`), so a replay neither re-streams nor re-persists them.\n const ui = createNegotiatedUiCollector(call.id, ctx, deps.resolveUiCatalog, (event) =>\n turn.writer.write(encodeStreamEvent(event)),\n );\n let output: unknown;\n try {\n output = await traceToolExecution(\n hooks.runId,\n { toolCallId: call.id, toolName: call.name, toolType },\n () =>\n invokeWithTransientRetry(\n () => {\n ui.restart();\n return deps.registry.invoke(\n call.name,\n call.input,\n { ...toolCallContext(ctx, call.id), emitUi: ui.emit },\n deps.rolesPolicy,\n invokeAllowList !== undefined ? { allowedTools: invokeAllowList } : {},\n );\n },\n deps.toolTransientRetry ?? {},\n {\n ...(hooks.isControlFlowError !== undefined\n ? { isControlFlowError: hooks.isControlFlowError }\n : {}),\n onRetry: (attempt, retryError) => {\n publishAgentToolRetry({\n toolName: call.name,\n toolCallId: call.id,\n attempt,\n message:\n retryError instanceof Error ? retryError.message : String(retryError),\n });\n },\n },\n ),\n );\n } catch (error) {\n if (error instanceof Error && error.name === 'ToolPreflightDeniedError')\n return wrapToolPreflightDenied(error.message);\n throw error;\n }\n return wrapToolStepOutput(output, ui.components(), ui.text());\n });\n raw =\n deps.toolTimeoutMs !== undefined\n ? await withToolTimeout(invocation, deps.toolTimeoutMs, call.name)\n : await invocation;\n }\n const { output, ui, preflightDenied, text } = unwrapToolStepOutput(raw);\n if (text) turn.toolText.set(call.id, text);\n if (preflightDenied !== undefined)\n return { status: 'denied', reason: preflightDenied, executionMs: Date.now() - startedAt };\n if (ui.length > 0) {\n turn.toolUi.set(call.id, ui);\n }\n if (claimed.terminal === true) {\n turn.halt.terminal = true;\n }\n return { status: 'executed', output, executionMs: Date.now() - startedAt };\n } catch (error) {\n if (\n hooks.isControlFlowError?.(error) === true ||\n isControlFlowSignal(error) ||\n isReplayIntegrityError(error)\n ) {\n throw error;\n }\n if (error instanceof Error && error.name === 'ToolPreflightDeniedError') {\n return { status: 'denied', reason: error.message, executionMs: Date.now() - startedAt };\n }\n return {\n status: 'failed',\n error: error instanceof Error ? error.message : String(error),\n executionMs: Date.now() - startedAt,\n };\n }\n}\n\n/** Persist one settled invocation and shape the result the model is fed. */\nasync function recordToolOutcome(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n outcome: ToolOutcome,\n deciderRef: string,\n meta?: ApprovalMeta,\n): Promise<ToolResult> {\n const { deps, hooks } = turn;\n const { call } = claimed;\n const toolType = claimed.toolType === 'action' ? 'action' : 'read';\n // What a decided call adds to its row: how it was decided. Written with the outcome rather than\n // at a checkpoint of its own, so an approval adds no position to the turn.\n const decided =\n meta === undefined\n ? {}\n : {\n executedByRef: meta.decidedBy,\n ...(meta.decidedVia !== undefined ? { decidedVia: meta.decidedVia } : {}),\n ...(meta.remember === true ? { remember: true } : {}),\n };\n const settle = async () => {\n if (meta === undefined || !meta.streamed) {\n return;\n }\n await turn.writer.write(\n encodeStreamEvent({\n kind: 'approval-settled',\n id: call.id,\n status: 'approved',\n ...(meta.approver !== undefined ? { approver: meta.approver } : {}),\n decidedBy: meta.decidedBy,\n ...(meta.decidedVia !== undefined ? { decidedVia: meta.decidedVia } : {}),\n ...(meta.remember === true ? { remember: true } : {}),\n }),\n );\n };\n if (outcome.status === 'denied') {\n await hooks.step(`persist:toolreject:${call.id}`, async () => {\n await deps.store.updateToolCall({\n toolCallId: call.id,\n status: meta === undefined ? 'rejected' : 'failed',\n error: outcome.reason,\n ...decided,\n });\n await settle();\n });\n return {\n id: call.id,\n name: call.name,\n output: { rejected: true, reason: outcome.reason },\n denied: true,\n error: `This action was denied by its preflight check: ${outcome.reason}. The requested mutation did not run.`,\n };\n }\n if (outcome.status === 'failed') {\n await hooks.step(`persist:toolfail:${call.id}`, async () => {\n await deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'failed',\n error: outcome.error,\n executionMs: outcome.executionMs,\n ...decided,\n });\n await settle();\n });\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType,\n status: 'failed',\n durationMs: outcome.executionMs,\n });\n return { id: call.id, name: call.name, output: null, error: outcome.error };\n }\n await hooks.step(`persist:toolexec:${call.id}`, async () => {\n await deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'executed',\n output: outcome.output,\n executionMs: outcome.executionMs,\n ...(toolType === 'action' ? { executedByRef: deciderRef } : {}),\n ...decided,\n });\n await settle();\n });\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType,\n status: 'executed',\n durationMs: outcome.executionMs,\n });\n return { id: call.id, name: call.name, output: outcome.output };\n}\n\n/**\n * Delegate to another agent (an `agent`-kind call) and record what came back as this call's output:\n * the delegate's ANSWER when the turn waited for it, a {@link DetachedDelegationReceipt} when it did\n * not.\n *\n * The two branches write the same checkpoint, under the same name, at the same position — every\n * difference between them lives in the RUNNER's own positions (`ctx.child` suspends and joins;\n * `ctx.startChild` records a `spawn:` and moves on). That is deliberate: which branch a call takes\n * is decided by `persist:toolcall`, whose answer comes out of the journal, so the loop's sequence\n * cannot depend on a registry the replaying process happens to hold.\n */\nasync function delegateToolCall(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n): Promise<ToolResult> {\n const { deps, input, hooks } = turn;\n const { call, targetAgent = call.name } = claimed;\n const task = extractTask(call.input);\n // A detached hop counts like any other: a cycle is cheaper to start that way, not less unbounded.\n const refusal =\n personaRefusal(turn.persona, call.name) ?? delegationRefusal({ deps, input, targetAgent });\n const start = claimed.detached === true && refusal === null ? hooks.startAgent : undefined;\n publishAgentDelegated({\n runId: hooks.runId,\n toAgent: targetAgent,\n ...(input.agentName !== undefined ? { fromAgent: input.agentName } : {}),\n ...(start !== undefined ? { detached: true } : {}),\n });\n let sub: { text: string } | DetachedDelegationReceipt;\n if (refusal !== null) {\n sub = { text: refusal };\n } else if (start !== undefined) {\n const started = await start({ agentName: targetAgent, task, toolCallId: call.id });\n sub = detachedStarted({ agent: targetAgent, runId: started.runId });\n } else if (hooks.runAgent) {\n sub = await hooks.runAgent(targetAgent, task);\n } else {\n sub = { text: `(no multi-agent support wired; cannot reach \"${targetAgent}\")` };\n }\n await hooks.step(`persist:toolexec:${call.id}`, () =>\n deps.store.updateToolCall({ toolCallId: call.id, status: 'executed', output: sub }),\n );\n return { id: call.id, name: call.name, output: sub };\n}\n\n/**\n * Settle an `ask` call against a human. The model authored the questions, so unlike the configured\n * intake there is nothing to persist first — `persist:toolcall` already wrote the row, under the\n * same name and at the same position any other kind would have used.\n *\n * Costs nothing beyond the step that produced it: the question set arrived as the ARGUMENTS of a\n * tool call the model was already making, in a step already billed as `chat`. There is no second\n * model call and therefore no usage row of its own — the opposite of the structured-output pass,\n * which really does buy an extra call.\n *\n * The two new positions here (`stream:elicitation:<id>`, and the wait) are reachable only when this\n * call's journaled kind is `ask`, which no run recorded before the kind existed. Every replay reads\n * that kind back rather than re-deciding it, so no run can disagree about whether they are there.\n */\nasync function elicitToolCall(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n): Promise<ToolResult> {\n const { deps, hooks } = turn;\n const { call, ctx } = claimed;\n // Validated HERE rather than by the registry, which never sees this tool. Deterministic on the\n // same footing as `validateStructured`: a module-constant schema over an input the `llm:<i>`\n // checkpoint already holds, so every replay reaches the same verdict — and the same branch.\n const parsed = await askInputSchema['~standard'].validate(call.input);\n if (parsed.issues !== undefined) {\n const error = `invalid ask input: ${parsed.issues.map((each) => `${(each.path ?? []).join('.') || '(root)'}: ${each.message}`).join('; ')}`;\n await hooks.step(`persist:toolfail:${call.id}`, () =>\n deps.store.updateToolCall({ toolCallId: call.id, status: 'failed', error }),\n );\n // A malformed question set is the model's mistake to fix, so it comes back as a tool failure —\n // the vocabulary the model already knows how to answer — rather than failing the run.\n return { id: call.id, name: call.name, output: null, error };\n }\n const request: ElicitationRequest = {\n id: call.id,\n source: 'ask',\n questions: parsed.value.questions,\n ...(parsed.value.preamble !== undefined ? { preamble: parsed.value.preamble } : {}),\n };\n await hooks.step(`stream:elicitation:${call.id}`, async () => {\n await turn.writer.write(encodeStreamEvent({ kind: 'elicitation', id: call.id, request }));\n });\n const reply = await awaitElicitation(hooks, request, ctx);\n const result = settleElicitation(request, reply);\n await hooks.step(\n result.skipped ? `persist:toolreject:${call.id}` : `persist:toolexec:${call.id}`,\n () =>\n deps.store.updateToolCall({\n toolCallId: call.id,\n status: result.skipped ? 'rejected' : 'executed',\n output: result,\n ...(result.skipped ? { error: 'skipped by the user' } : {}),\n ...(reply.answeredByRef !== undefined ? { executedByRef: reply.answeredByRef } : {}),\n }),\n );\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType: 'action',\n status: result.skipped ? 'rejected' : 'executed',\n });\n return { id: call.id, name: call.name, output: result };\n}\n\n/** Everything a claimed call still needs, on its own: delegation or approval, then execute. */\nasync function runClaimedToolCall(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n): Promise<ToolResult> {\n const { deps, input, hooks } = turn;\n const { call, toolType, ctx } = claimed;\n if (claimed.proposalId !== undefined) {\n turn.halt.independentProposal = true;\n return { id: call.id, name: call.name, output: actionProposalReceipt(claimed.proposalId) };\n }\n // Delegation is handled at the LOOP level (not in a step) because the durable runner maps it to\n // `ctx.child`, a ctx-level suspend point.\n if (toolType === 'agent') {\n return delegateToolCall(turn, claimed);\n }\n // An `ask` never reaches a handler: it is settled by a person, not executed.\n if (toolType === 'ask') {\n return elicitToolCall(turn, claimed);\n }\n if (claimed.preflight !== undefined && claimed.preflight.status !== 'ready') {\n const result = claimed.preflight;\n if (result.status === 'completed' && claimed.presentCompletedPreflight === true) {\n // Journal presentation separately: a completed preflight never enters the execution step.\n const raw = await hooks.step(`present:${call.id}`, async () => {\n const ui = createNegotiatedUiCollector(call.id, ctx, deps.resolveUiCatalog, (event) =>\n turn.writer.write(encodeStreamEvent(event)),\n );\n await deps.registry.presentOutput(call.name, result.output, {\n ...toolCallContext(ctx, call.id),\n emitUi: ui.emit,\n });\n return wrapToolStepOutput(result.output, ui.components(), ui.text());\n });\n const presented = unwrapToolStepOutput(raw);\n if (presented.ui.length > 0) turn.toolUi.set(call.id, presented.ui);\n if (presented.text) turn.toolText.set(call.id, presented.text);\n }\n if (result.status === 'completed' && claimed.terminal === true) turn.halt.terminal = true;\n const outcome: ToolOutcome =\n result.status === 'completed'\n ? { status: 'executed', output: result.output, executionMs: 0 }\n : result.status === 'denied'\n ? { status: 'denied', reason: result.reason, executionMs: 0 }\n : { status: 'failed', error: result.error, executionMs: 0 };\n return recordToolOutcome(turn, claimed, outcome, input.actor.id);\n }\n // WHO settled an action tool: the Decision's ref (a console admin) when it carries one, else\n // the run's own actor (the chat flow). Stamped on both the executed and rejected persists.\n let deciderRef = input.actor.id;\n let meta: ApprovalMeta | undefined;\n if (toolType === 'action' && claimed.approval?.mode === 'remembered') {\n meta = {\n approver: claimed.approval.approver,\n decidedBy: input.actor.id,\n decidedVia: 'remembered',\n remember: true,\n streamed: true,\n };\n } else if (toolType === 'action' && claimed.approval?.mode !== 'auto') {\n const ttlMs = claimed.approval?.mode === 'ask' ? claimed.approval.ttlMs : undefined;\n const decision =\n ttlMs !== undefined\n ? await hooks.awaitApproval(call, ctx, { timeoutMs: ttlMs })\n : await hooks.awaitApproval(call, ctx);\n deciderRef = decision.executedByRef ?? input.actor.id;\n // Only a call claimed under a policy streams how it settled — a run from before that keeps\n // writing exactly the frames it always wrote.\n const streamsSettlement = claimed.approval !== undefined;\n if (decision.expired === true) {\n return expireToolCall(turn, claimed);\n }\n if (!decision.approved) {\n await hooks.step(`persist:toolreject:${call.id}`, async () => {\n await deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'rejected',\n executedByRef: deciderRef,\n ...(decision.reason !== undefined ? { error: decision.reason } : {}),\n ...(decision.decidedVia !== undefined ? { decidedVia: decision.decidedVia } : {}),\n });\n if (streamsSettlement) {\n await turn.writer.write(\n encodeStreamEvent({\n kind: 'approval-settled',\n id: call.id,\n status: 'rejected',\n decidedBy: deciderRef,\n ...(decision.decidedVia !== undefined ? { decidedVia: decision.decidedVia } : {}),\n ...(decision.reason !== undefined ? { reason: decision.reason } : {}),\n }),\n );\n }\n });\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType,\n status: 'rejected',\n });\n return {\n id: call.id,\n name: call.name,\n output: { rejected: true, reason: decision.reason ?? DEFAULT_REFUSAL_REASON },\n denied: true,\n // What the MODEL is told. It used to be the bare word `rejected`, which names no actor and\n // reads exactly like a tool that blew up — so the answer that followed would speculate about\n // causes (\"the key may not exist\", \"there may be permission restrictions\") and offer to try\n // again. A person's decision is not a fault to diagnose, so this says who decided, that\n // nothing ran, and what not to do next.\n error: refusalNarrative(decision.reason),\n };\n }\n meta = {\n decidedBy: deciderRef,\n ...(decision.decidedVia !== undefined ? { decidedVia: decision.decidedVia } : {}),\n ...(decision.remember === true ? { remember: true } : {}),\n streamed: streamsSettlement,\n };\n }\n return recordToolOutcome(turn, claimed, await invokeClaimedTool(turn, claimed), deciderRef, meta);\n}\n\n/**\n * The approval request lapsed with nobody deciding. Settled on the rejection's own checkpoint name\n * — an expiry is a refusal as far as the sequence is concerned, and one fewer name to keep stable —\n * but persisted as `expired`, streamed as `approval-settled { status: 'expired' }`, and put to the\n * model as \"nobody approved this in time\" rather than as someone's \"no\".\n */\nasync function expireToolCall(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n): Promise<ToolResult> {\n const { deps, hooks } = turn;\n const { call } = claimed;\n await hooks.step(`persist:toolreject:${call.id}`, async () => {\n await deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'expired',\n error: APPROVAL_EXPIRED_REASON,\n });\n await turn.writer.write(\n encodeStreamEvent({ kind: 'approval-settled', id: call.id, status: 'expired' }),\n );\n });\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType: 'action',\n status: 'rejected',\n });\n return {\n id: call.id,\n name: call.name,\n output: { rejected: true, expired: true, reason: APPROVAL_EXPIRED_REASON },\n denied: true,\n expired: true,\n error: expiryNarrative(),\n };\n}\n\n/** The reason an expired call is denied with — on the row, the stream frame and the result. */\nexport const APPROVAL_EXPIRED_REASON = 'approval expired';\n\n/**\n * How an expiry is put to the model. Nobody said no, so it must not read like a refusal — but it\n * must stop the model from simply trying again, which would park the turn on the same unanswered\n * request.\n */\nfunction expiryNarrative(): string {\n return (\n 'This action needed approval, and the approval request expired before anyone decided. ' +\n 'Nothing ran and nothing changed. Do not run it again on your own; tell the person it was not ' +\n 'approved in time and ask whether they still want it.'\n );\n}\n\n/**\n * The frame a settled call is streamed on. A refusal is its own kind, ahead of the error branch:\n * `denied` and `error` are both set on a declined call — the first for every consumer, the second\n * because `error` is the channel a model reads an outcome on — and a client that saw the error\n * frame would draw a person's \"no\" as a malfunction.\n */\nfunction outputFrame(result: ToolResult): AgentStreamEvent {\n if (result.denied === true) {\n const reason = refusalReason(result);\n return {\n kind: 'tool-output-denied',\n id: result.id,\n ...(reason !== undefined ? { reason } : {}),\n };\n }\n return result.error !== undefined\n ? { kind: 'tool-output-error', id: result.id, error: result.error }\n : { kind: 'tool-output', id: result.id, output: result.output };\n}\n\n/** The reason a person gave when declining, if they gave one — read back off the result. */\nfunction refusalReason(result: ToolResult): string | undefined {\n const { output } = result;\n if (output !== null && typeof output === 'object' && 'reason' in output) {\n const reason = (output as { reason: unknown }).reason;\n return typeof reason === 'string' && reason !== DEFAULT_REFUSAL_REASON ? reason : undefined;\n }\n return undefined;\n}\n\n/**\n * Stored as the reason when someone declines without giving one. It is a placeholder, not something\n * a person said, so every reader has to filter it out — which is why it is exported rather than\n * spelled again wherever a refusal is read back.\n */\nexport const DEFAULT_REFUSAL_REASON = 'rejected by user';\n\n/**\n * How a refusal is put to the model. Written as instructions rather than as a status because the\n * model's next move is the whole problem: told only that something was \"rejected\", it treats the\n * refusal as a fault, lists possible causes it cannot check, and offers to retry the same action —\n * which asks the person to say no twice.\n */\nfunction refusalNarrative(reason: string | undefined): string {\n const base =\n 'The person was asked to approve this action and declined it. Nothing ran and nothing changed. ' +\n 'This is their decision, not an error, a missing record or a permissions problem — do not ' +\n 'explain it as one, do not guess at causes, and do not run this action again or reach for ' +\n 'another way to do the same thing. Acknowledge the decision and ask what they would like instead.';\n return reason === undefined ? base : `${base} They said: ${reason}`;\n}\n\n/**\n * Overlap the INVOCATIONS of a batch of claimed calls, and only those. The persist checkpoints on\n * either side stay strictly sequential, in call order — they are asked for after their neighbours'\n * positions are already spent, so nothing about them depends on which tool finished first.\n *\n * A rejection here is the runner unwinding the turn, never a tool's own failure\n * ({@link invokeClaimedTool} reports those). Rethrow the first one in call order and persist\n * NOTHING: the resume replays this whole block, and a `persist:toolexec` written now would sit at\n * the position the replay computes for the FIRST call's — which, when the invocations are dispatched\n * steps, all share one checkpoint name, so the mismatch raises no refusal at all and simply hands\n * one call's output to another.\n */\nasync function invokeClaimedToolsTogether(\n turn: ToolTurnContext,\n parallel: NonNullable<AgentLoopHooks['parallel']>,\n claimed: ClaimedToolCall[],\n): Promise<ToolResult[]> {\n const settled = await parallel(claimed.map((entry) => () => invokeClaimedTool(turn, entry)));\n for (const outcome of settled) {\n if (!outcome.ok) {\n throw outcome.error;\n }\n }\n const results: ToolResult[] = [];\n for (const [index, entry] of claimed.entries()) {\n const outcome = settled[index];\n if (outcome?.ok === true) {\n results.push(await recordToolOutcome(turn, entry, outcome.value, turn.input.actor.id));\n }\n }\n return results;\n}\n\n/**\n * Something the LOOP produced that the model did not ask for — retrieved passages, a validated\n * structured answer — carried to a client as an ordinary auto-executed tool call. It rides the\n * assistant message it informed (calls and results both, so a reader can pair them), a row in the\n * tool-call table (so a governance surface counts it), and a live pair of stream frames.\n */\ninterface SyntheticToolCall {\n /** The checkpoint that records the row, minus its `:<messageId>` suffix. */\n step: string;\n call: ToolCallRequest;\n result: ToolResult;\n}\n\n/** What a turn answered with: the assistant text, plus the validated `outputSchema` value if any. */\nexport interface AgentLoopResult<TOutput = unknown> {\n text: string;\n /** Present only when `AgentLoopDeps.outputSchema` was set — the validated structured answer. */\n object?: TOutput;\n}\n\n/**\n * The provider-agnostic agent turn, reused by both the inline and durable runners.\n * It drives the model→tools→model iteration; the runner supplies the `step`/`awaitApproval`\n * hooks that make the same loop body either in-process or a replay-safe durable workflow.\n */\nexport async function runAgentLoop<TOutput = unknown>(\n boundDeps: AgentLoopDeps<TOutput>,\n requested: AgentRunInput,\n hooks: AgentLoopHooks,\n): Promise<AgentLoopResult<TOutput>> {\n // The persona, FIRST and only when the run names one: its definition is read from config once and\n // frozen in this checkpoint, so a run resumed after the persona was edited or removed keeps the\n // prompt and allow-list it started with. A run that names none spends no position here — which is\n // every run started before personas existed, so those replay on the sequence they recorded.\n const persona =\n requested.persona === undefined\n ? undefined\n : ((await hooks.step('persona:resolve', () => resolveTurnPersona(boundDeps, requested))) ??\n undefined);\n // From here on the input names the persona the turn actually runs under — none, when the one it\n // asked for is no longer declared — so provenance and tool context never claim one that did not apply.\n const input: AgentRunInput =\n persona === undefined || persona.id !== requested.persona\n ? withoutPersona(requested)\n : requested;\n // A turn with a selected model runs EVERY call it makes on it — the answer, a structured-output\n // pass, the follow-ups — and labels its usage with it when the provider reports no model id.\n const deps: AgentLoopDeps<TOutput> =\n input.model === undefined\n ? boundDeps\n : {\n ...boundDeps,\n model: withSelectedModel(boundDeps.model, input.model),\n modelId: input.model,\n };\n const maxSteps = deps.maxSteps ?? 8;\n let system = await resolveSystemPrompt(deps, input, persona);\n const inputProcessors = deps.inputProcessors ?? [];\n const outputProcessors = deps.outputProcessors ?? [];\n // An output gate and the run's own sink are mutually exclusive, so the presence of a processor —\n // not a per-turn condition — decides whether the model call writes to the sink or through a gate.\n // What the chain DECLARES then decides what that costs the reader: an incremental chain releases a\n // lookback-bounded prefix as it arrives, an undeclared one holds the answer whole.\n const gateMode = resolveOutputGateMode(outputProcessors);\n const gated = gateMode !== 'off';\n const gateLookback = resolveGateLookback(outputProcessors);\n let structured: TOutput | undefined;\n\n if (deps.quota !== undefined) {\n const quota = deps.quota;\n const state = await hooks.step('quota:check', () => quota.check(input.actor.id, deps.day));\n if (!state.withinLimit) {\n publishAgentQuotaExceeded({\n actorId: input.actor.id,\n usedTokens: state.usedTokens,\n limitTokens: state.limitTokens,\n });\n throw new QuotaExceededError();\n }\n }\n\n if (input.regenerate === true) {\n // Re-run the last exchange: drop every message after the thread's last user message (keeping\n // it), then answer it again. No new user message is appended.\n await hooks.step('regenerate:truncate', async () => {\n const existing = await deps.store.getThread(input.threadId);\n const messages = existing?.messages ?? [];\n let lastUserIndex = -1;\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n if (messages[index]?.role === 'user') {\n lastUserIndex = index;\n break;\n }\n }\n const firstDropped = messages[lastUserIndex + 1];\n if (firstDropped !== undefined) {\n await deps.store.truncateFrom(input.threadId, firstDropped.id);\n }\n });\n } else {\n await hooks.step('persist:user', () =>\n deps.store.appendMessage({\n threadId: input.threadId,\n role: 'user',\n content: input.userText,\n runId: hooks.runId,\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(input.attachments !== undefined ? { attachments: input.attachments } : {}),\n }),\n );\n }\n\n const history = (await (hooks.patched?.(SELECTED_HISTORY_PATCH) ?? Promise.resolve(true)))\n ? await loadSelectedHistory(deps, input, hooks)\n : await loadWholeThread(deps, input, hooks);\n let modelMessages: ModelMessage[] = history.messages;\n const summarize = deps.historyPolicy?.summarize?.bind(deps.historyPolicy);\n if (summarize !== undefined && history.dropped.length > 0) {\n modelMessages = await foldDroppedHistory(summarize, deps, input, hooks, history);\n }\n\n const writer = await hooks.openSink();\n let lastText = '';\n let steps = 0;\n let totalInput = 0;\n let totalOutput = 0;\n\n publishAgentRunStarted({\n runId: hooks.runId,\n threadId: input.threadId,\n actorId: input.actor.id,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n });\n\n // Which of the three optional prompt stages below this run takes a position for, decided ONCE and\n // journaled — see {@link PromptStages}. Every `stages.*` read after this is therefore a fact about\n // the run rather than about the deployment replaying it, which is what lets a turn parked on a\n // human survive an operator switching one of them on.\n const stages = await resolvePromptStages(deps, hooks);\n\n // Its own step so durable replay reuses the ORIGINAL wall-clock start — durationMs stays honest\n // across suspend/resume.\n const startedAt = await hooks.step('run:started-at', () => Promise.resolve(Date.now()));\n // Optional-chained: a store without run recording makes this (and persist:run:end) a no-op.\n await hooks.step('persist:run:start', async () => {\n // Hashed BEFORE the retrieved-context block is folded in below, so the hash identifies the\n // prompt VERSION (agent base + contributors), not a given turn's retrieval.\n const promptHash = createHash('sha256').update(system).digest('hex');\n await deps.store.recordRunStart?.({\n runId: hooks.runId,\n threadId: input.threadId,\n actorRef: input.actor.id,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.parentRunId !== undefined ? { parentRunId: input.parentRunId } : {}),\n promptHash,\n });\n });\n\n // What the assistant already believes about this person, folded in ABOVE the retrieved passages\n // and the skills catalog — see `AgentLoopDeps.memory` for why the order runs most-durable-first.\n // Below `persist:run:start` on purpose: that step hashes the prompt VERSION, and a hash that moved\n // with whose memory was loaded would identify a person rather than a prompt.\n //\n // One checkpoint, holding the WHOLE digest: the scopes the resolver returned and the entries that\n // survived selection, precedence and the ceiling. That payload is what the block is rendered from\n // AND what a later `remember` call is authorized against — so which memories entered this prompt,\n // and which scopes this turn could write, are facts the journal holds rather than answers a\n // replaying process's provider would give afresh. Where the host runs an index, the SEARCH happens\n // in here too: a ranking is the most re-derivable decision in this library, so a replay has to\n // read its result back rather than ask an index that has since moved.\n //\n // THE QUERY IS THE USER'S OWN MESSAGE, and nothing else. It is the only thing available before the\n // first model call — which is where memory has to be, since a memory is worthless unless it is in\n // front of the model on the turn nobody thought to look — and it is already a journaled input to\n // this run, so it needs no determinism machinery of its own. What it fails at is a turn with no\n // topic (\"and the other thing?\"): `pinned` is the answer to those, not a cleverer query.\n let memoryDigest: MemoryDigest | undefined;\n if (stages.memory) {\n const config = deps.memory;\n memoryDigest = await hooks.step('memory:digest', () =>\n config === undefined\n ? Promise.resolve(UNSERVED_MEMORY)\n : offerMemories({ config, ctx: skillContext(input), query: input.userText }),\n );\n // No entries, no block: an actor the assistant has concluded nothing about pays nothing, rather\n // than reading a heading over an empty list and inferring something from its presence.\n const digest = memoryDigest;\n const block =\n digest.entries.length > 0\n ? buildMemoryBlock({\n entries: digest.entries,\n writable: memoryIsWritable(deps),\n partial: digest.omitted > 0 || digest.recalled === true,\n })\n : '';\n if (block.length > 0) {\n system = `${system}\\n\\n${block}`;\n }\n // What memory cost this prompt, next to what the ceiling left out — the only way an operator can\n // name which of the prompt's contributors grew when a turn's input tokens jump.\n publishAgentMemoryResolved({\n runId: hooks.runId,\n scopes: digest.scopes.length,\n offered: digest.entries.length,\n omitted: digest.omitted,\n pinnedOmitted: digest.pinnedOmitted,\n recalled: digest.recalled === true,\n promptChars: block.length,\n });\n }\n\n // Inject-mode RAG: retrieve once for the user message and fold the passages into the system prompt\n // (a `ctx.step` so it's replay-cached under durable). Recorded below as a synthetic tool call on\n // the first assistant message, so citations surface through the same machinery as agentic search.\n let injectedPassages: Passage[] | undefined;\n if (stages.retriever) {\n const retriever = deps.retriever;\n const topK = deps.retrievalTopK ?? 5;\n const passages = await hooks.step('retrieve', () =>\n spanned(\n 'retrieval',\n hooks.runId,\n { runId: hooks.runId, queryLength: input.userText.length, topK },\n () => retriever?.retrieve(input.userText, { topK }) ?? Promise.resolve([]),\n (retrieved) => ({ count: retrieved.length }),\n ),\n );\n if (passages.length > 0) {\n injectedPassages = passages;\n system = `${system}\\n\\n${buildContextBlock(passages)}`;\n }\n publishAgentRetrieved({ runId: hooks.runId, query: input.userText, count: passages.length });\n }\n\n // The skills catalog, LAST of the four things that write the system block (base prompt,\n // contributors, retrieved context, this) — so a reader of the assembled prompt meets the agent's\n // own instructions before the menu of ones it could go and fetch.\n //\n // One checkpoint, holding the WHOLE offer: the scopes the resolver returned and the entries that\n // survived precedence. That payload is what the block is rendered from and what a later `skill`\n // call is served against, so the two things a turn's prompt depends on — which scopes applied, and\n // which skills they yielded — are facts the journal holds rather than answers a replaying\n // process's provider would give afresh.\n let skillOffer: SkillOffer | undefined;\n if (stages.skills) {\n const config = deps.skills;\n skillOffer = await hooks.step('skills:catalog', () =>\n config === undefined\n ? Promise.resolve(UNSERVED_SKILLS)\n : offerSkills(config, skillContext(input)),\n );\n // No entries, no block: an actor whose scopes yield nothing pays nothing, rather than reading a\n // heading over an empty list and wondering what it was for.\n const block = skillOffer.entries.length > 0 ? buildSkillsBlock(skillOffer.entries) : '';\n if (block.length > 0) {\n system = `${system}\\n\\n${block}`;\n }\n // What skills cost this prompt, reported next to what they left out — the only way an operator\n // can name which of the prompt's contributors grew when a turn's input tokens jump.\n publishAgentSkillsResolved({\n runId: hooks.runId,\n scopes: skillOffer.scopes.length,\n offered: skillOffer.entries.length,\n omitted: skillOffer.omitted,\n promptChars: block.length,\n });\n }\n\n // Fetched ONCE per run (not per step/message) and reused for every step's cost estimate below.\n // Returned as a plain array (not the Map built from it) so durable replay can JSON-cache the step.\n let prices: CurrentModelPrice[] = [];\n if (deps.pricingStore !== undefined) {\n const pricingStore = deps.pricingStore;\n prices = await hooks.step('pricing:list', () => pricingStore.listCurrentPrices());\n }\n const priceByModel = new Map(prices.map((price) => [price.modelId, price]));\n\n // The configured intake, LAST before the first model call: everything the run records about\n // itself (start time, run row, retrieval, prices) is settled before the turn parks on a person,\n // who may take a day. Its whole block is reachable only through `deps.intake`.\n if (deps.intake !== undefined) {\n const asked = await runIntake(\n deps.intake,\n deps,\n input,\n hooks,\n writer,\n history.hasAssistantMessage,\n );\n if (asked !== null) {\n modelMessages.push(asked);\n }\n }\n\n // Whether this run can observe a cancel at all, resolved ONCE at a fixed position rather than per\n // step: `patched` consumes a position of its own for a fresh run and gives it back to an in-flight\n // one, so asking once is both cheaper and the only form whose cost does not depend on how many\n // steps a turn happens to take. Gated on the hook's presence, which is a property of the runner\n // (uniform across a deployment's pods), never of the run.\n const cancellable =\n hooks.cancelled !== undefined &&\n (await (hooks.patched?.(CANCELLATION_PATCH) ?? Promise.resolve(true)));\n\n // NOTE: no try/finally around this loop. A durable runner suspends by THROWING through the stack\n // at `awaitApproval` (ctx.waitForSignal); a finally would then call writer.end() on every suspend\n // and prematurely close the live stream. We only end on normal completion — the throw propagates\n // to the engine, and the resumed replay reaches the writer.end() below.\n for (let i = 0; i < maxSteps; i += 1) {\n // Between steps, and therefore before the next model call: the cheapest point in the turn to\n // stop at, since nothing has been spent on this step yet.\n await haltIfCancelled(hooks, cancellable, `cancel:check:${i}`);\n\n // Open a UI step spanning this model call AND its tool execution — matching the AI SDK's own\n // step semantics, so tool-output lands inside the step that made the call. Wrapped in a durable\n // step so replay doesn't re-emit it (a no-op for the inline runner).\n await hooks.step(`stream:step-start:${i}`, async () => {\n await writer.write(encodeStreamEvent({ kind: 'step-start' }));\n });\n\n // Every step, not once per run: the transcript grows between steps, so a processor that only\n // saw the opening prompt would wave through whatever a tool result carried back. The result is\n // a per-step DERIVED prompt — `modelMessages` stays the loop's canonical transcript, so a\n // redaction never becomes the thread's own memory of what was said.\n let prompt: ProcessedPrompt = { system, messages: modelMessages };\n if (inputProcessors.length > 0) {\n prompt = await hooks.step(`process:input:${i}`, () =>\n runInputProcessors(inputProcessors, prompt, processorContext(input, i)),\n );\n }\n\n let turn: BufferedModelTurnResult;\n if (hooks.dispatchLlm) {\n // No definitionsFor here: the envelope carries only wire-safe data (a ToolDefinition holds a\n // live schema instance) — the serving handler re-derives tool definitions from the actor.\n // `bufferOutput` for EITHER gate mode, incremental included: the handler streams into a\n // worker-side sink this loop cannot interpose on, so there is no prefix to release here and\n // the declaration buys the reader nothing. The turn is held whole — the result comes back with\n // `bufferedFrames` and no `releasedText`, which is what puts the gate step on its whole-answer\n // release path.\n turn = await hooks.dispatchLlm(i, {\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n system: prompt.system,\n messages: prompt.messages,\n actor: input.actor,\n threadId: input.threadId,\n actionApprovalMode: history.actionApprovalMode ?? 'blocking',\n preflightContext: {\n actor: input.actor,\n threadId: input.threadId,\n runId: hooks.runId,\n requestId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(input.uiCapabilities !== undefined ? { uiCapabilities: input.uiCapabilities } : {}),\n },\n ...(gated ? { bufferOutput: true } : {}),\n ...(input.model !== undefined ? { model: input.model } : {}),\n ...(persona?.allowedTools !== undefined\n ? { personaAllowedTools: persona.allowedTools }\n : {}),\n });\n } else {\n const tools = withMemoryTool({\n tools: withSkillTool({\n tools: withAskTool({\n tools: await deps.registry.definitionsFor(\n input.actor,\n deps.rolesPolicy,\n intersectAllowLists(deps.toolAllowList, persona?.allowedTools),\n {\n threadId: input.threadId,\n ...(input.uiCapabilities !== undefined\n ? { uiCapabilities: input.uiCapabilities }\n : {}),\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n },\n ),\n ask: deps.ask,\n }),\n enabled: deps.skills !== undefined,\n }),\n enabled: memoryIsWritable(deps),\n });\n turn = await hooks.step(`llm:${i}`, async () => {\n // Both of these ride the CHECKPOINT rather than a local variable: a run that suspends\n // between the model call and the gate resumes with `llm:<i>` served from the journal, and\n // state held in this process would be gone by then — the turn's whole stream, silently\n // dropped, or a prefix flushed into the reader's stream a second time.\n const incremental =\n gateMode === 'incremental'\n ? createIncrementalGate({\n processors: outputProcessors,\n ctx: processorContext(input, i),\n lookbackChars: gateLookback,\n writer,\n })\n : undefined;\n const buffer = gateMode === 'whole' ? createFrameBuffer() : undefined;\n // Reasoning and pushed UI are read off the frames INSIDE the checkpoint, so they are\n // journaled with the turn and a replay persists the same thinking instead of none.\n const frames = observeTurnFrames(incremental?.writer ?? buffer?.writer ?? writer);\n // Stamped from THIS process's registry, which is the one that built `tools` above — and\n // stamped inside the checkpoint, so the kinds are journaled with the calls they describe\n // rather than re-derived by whatever process replays this turn.\n const result = stampToolKinds(\n withTurnFrames(\n await traceLlmTurn(hooks.runId, i, () =>\n deps.model.runTurn({\n system: prompt.system,\n messages: prompt.messages,\n tools,\n sink: frames.writer,\n }),\n ),\n frames.summary(),\n ),\n deps,\n );\n if (incremental !== undefined) {\n await incremental.settled();\n const refusal = incremental.rejection();\n return {\n ...result,\n releasedText: incremental.released(),\n ...(refusal !== undefined ? { gateRejection: refusal } : {}),\n };\n }\n return buffer === undefined ? result : { ...result, bufferedFrames: buffer.frames() };\n });\n }\n // The gate runs before ANYTHING downstream: before the held frames reach the subscriber, before\n // the assistant message is persisted, before this text becomes the next step's context.\n let rejection: { processor: string; reason: string } | undefined;\n if (gated) {\n const gate = await hooks.step(`process:output:${i}`, async () => {\n // Which release this turn still owes is read from the JOURNALED model result, never from\n // the chain configured on whichever process is running now: `releasedText` is the record\n // that a prefix already reached the reader, so a run that resumes under a re-declared chain\n // cannot flush the same answer a second time.\n const released = turn.releasedText;\n // A refusal an incremental gate already reached, carried out of `llm:<i>` instead of thrown\n // from it. Re-running the chain would bill the same verdict twice.\n if (turn.gateRejection !== undefined) {\n return { text: turn.text, rejection: turn.gateRejection };\n }\n const settled = await runOutputProcessors(\n outputProcessors,\n { text: turn.text, toolCalls: turn.toolCalls },\n processorContext(input, i),\n );\n // Releasing inside the same checkpoint as the verdict is what makes \"refused\" and \"nothing\n // was streamed\" one fact rather than two that a suspend could separate. For an incremental\n // turn the second half of that is weaker by construction — a prefix is already out — and\n // the whole-answer pass stays authoritative for both the stream and the store.\n if (settled.rejection === undefined) {\n if (released === undefined) {\n for (const chunk of releaseGatedFrames(turn.bufferedFrames ?? [], settled.text)) {\n await writer.write(chunk);\n }\n } else {\n const tail = gateTail(outputProcessors, released, settled.text);\n if (tail.length > 0) {\n await writer.write(encodeStreamEvent({ kind: 'text', text: tail }));\n }\n }\n }\n return settled;\n });\n rejection = gate.rejection;\n turn = { ...turn, text: gate.text };\n }\n // provider-reported model wins over the configured fallback, so cost can't misattribute\n const resolvedModelId = turn.modelId ?? deps.modelId ?? 'unknown';\n // The same model, for the stream: absent rather than a made-up `'unknown'`.\n const stepModel = turn.modelId ?? deps.modelId;\n // Provider-reported spend wins; else an estimate from the (once-per-run cached) price list; else\n // `null` — surfaced on the stream's step-finish frame and the persisted assistant message below.\n const costUsd = resolveCostUsd(turn.usage, turn.costUsd, priceByModel.get(resolvedModelId));\n // Each call's declared kind, so thread-read consumers (and the stream frames the model adapter\n // writes) know it without hardcoding a tool-name allowlist. The kind the llm checkpoint already\n // stamped WINS: it came from the process that offered the tool, whereas this one is only the\n // process replaying the turn, and the two disagree exactly when that matters — see\n // {@link stampToolKinds}. The fallback is for a journal written before kinds travelled.\n const toolCallsWithKind: ToolCallRequest[] = turn.toolCalls.map((call) => ({\n ...call,\n kind: call.kind ?? declaredKind(deps, call.name),\n }));\n\n await hooks.step(`persist:usage:${i}`, () =>\n deps.store.recordUsage({\n threadId: input.threadId,\n actorRef: input.actor.id,\n modelId: resolvedModelId,\n purpose: 'chat',\n usage: turn.usage,\n // persist the provider's actual cost when reported; the read-model prefers it over pricing\n ...(turn.costUsd !== undefined ? { costUsd: turn.costUsd } : {}),\n }),\n );\n if (deps.quota !== undefined) {\n const quota = deps.quota;\n await hooks.step(`quota:bump:${i}`, () =>\n quota.bump(input.actor.id, deps.day, turn.usage.inputTokens + turn.usage.outputTokens),\n );\n }\n\n // Thrown only AFTER the two accounting checkpoints: those tokens were genuinely spent, and a\n // refusal that also hid its own cost would let a mis-tuned gate burn a budget invisibly.\n if (rejection !== undefined) {\n throw new OutputRejectedError(rejection.processor, rejection.reason);\n }\n\n steps += 1;\n totalInput += turn.usage.inputTokens;\n totalOutput += turn.usage.outputTokens;\n lastText = turn.text;\n publishAgentMessage({\n runId: hooks.runId,\n threadId: input.threadId,\n role: 'assistant',\n textLength: turn.text.length,\n });\n\n // A turn with no tool calls is the last one. Generate follow-up suggestions here (before the\n // append) so they land on the final assistant message, and stop after.\n const isFinalTurn = turn.toolCalls.length === 0;\n // Restating the GATED text, never the model's raw reply: the formatting pass is a translation of\n // the answer that survived the gate, not a second route out of the model.\n if (isFinalTurn && deps.outputSchema !== undefined) {\n structured = await structureAnswer(\n deps.outputSchema,\n deps,\n input,\n hooks,\n restatementPrompt(prompt.messages, turn.text, deps.outputFromTranscript === true),\n i,\n );\n }\n let followUps: string[] | undefined;\n if (isFinalTurn && deps.followUpsCount !== undefined && deps.followUpsCount > 0) {\n const count = deps.followUpsCount;\n // Stays on hooks.step (not dispatchLlm) — a short, non-streamed call, deliberately not\n // dispatched as a routed remote step.\n const generated = await hooks.step(`followups:${i}`, () =>\n spanned(\n 'follow-ups',\n hooks.runId,\n { runId: hooks.runId, step: i, count },\n () =>\n generateFollowUps(\n deps.model,\n [...modelMessages, { role: 'assistant', content: turn.text }],\n count,\n ),\n (result) => ({\n followUps: result.followUps.length,\n inputTokens: result.usage.inputTokens,\n outputTokens: result.usage.outputTokens,\n ...(result.modelId !== undefined ? { modelId: result.modelId } : {}),\n }),\n ),\n );\n // Model-generated, persisted and rendered — so the chain rules on each one, on the whole\n // suggestion (they are never streamed, so an `incremental` declaration buys nothing here). A\n // refusal DROPS that suggestion rather than ending a run whose answer already passed — see\n // {@link gateFollowUps}.\n let suggestions = generated.followUps;\n if (outputProcessors.length > 0) {\n suggestions = await hooks.step(`process:output:followups:${i}`, () =>\n gateFollowUps(outputProcessors, suggestions, processorContext(input, i)),\n );\n }\n if (suggestions.length > 0) {\n followUps = suggestions;\n }\n await hooks.step(`persist:usage:followups:${i}`, () =>\n deps.store.recordUsage({\n threadId: input.threadId,\n actorRef: input.actor.id,\n modelId: generated.modelId ?? deps.modelId ?? 'unknown',\n purpose: 'follow_ups',\n usage: generated.usage,\n }),\n );\n }\n\n // Inject-mode retrieval and the structured answer both reach a client as ordinary tool calls.\n // Their ids are derived from the RUN, not from the message they hang off, because the message\n // does not exist yet and both have to be on the append below: a reader pairs a call with its\n // result off the message, so a call added afterwards would render as a tool still running.\n // Every value here is already settled by a checkpoint this turn ran (`retrieve`,\n // `structured:<step>:<n>`), so a replay rebuilds the same pair without minting anything.\n const synthetic: SyntheticToolCall[] = [];\n if (i === 0 && injectedPassages !== undefined) {\n const call: ToolCallRequest = {\n id: `retrieve-${hooks.runId}`,\n name: 'retrieve',\n input: { query: input.userText },\n kind: 'read',\n };\n const output = { passages: injectedPassages };\n synthetic.push({\n step: 'persist:retrieval',\n call,\n result: { id: call.id, name: call.name, output },\n });\n }\n if (structured !== undefined) {\n const call: ToolCallRequest = {\n id: `structured-${hooks.runId}`,\n name: 'structured_output',\n input: {},\n kind: 'read',\n };\n synthetic.push({\n step: 'persist:structured',\n call,\n result: { id: call.id, name: call.name, output: structured },\n });\n }\n const messageCalls = [...toolCallsWithKind, ...synthetic.map((entry) => entry.call)];\n const syntheticResults = synthetic.map((entry) => entry.result);\n\n const assistant = await hooks.step(`persist:assistant:${i}`, () =>\n deps.store.appendMessage({\n threadId: input.threadId,\n role: 'assistant',\n content: turn.text,\n // Stamps which turn wrote this message, so a reader does not have to infer it from\n // timestamps — an inference a regenerate breaks, since it re-answers a surviving prompt.\n runId: hooks.runId,\n usage: { ...turn.usage, costUsd },\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(turn.reasoning !== undefined ? { reasoning: turn.reasoning } : {}),\n ...(turn.reasoningMs !== undefined ? { reasoningMs: turn.reasoningMs } : {}),\n ...(turn.ui !== undefined && turn.ui.length > 0 ? { ui: turn.ui } : {}),\n ...(messageCalls.length > 0 ? { toolCalls: messageCalls } : {}),\n ...(syntheticResults.length > 0 ? { toolResults: syntheticResults } : {}),\n ...(followUps !== undefined ? { followUps } : {}),\n }),\n );\n // Tool results ride on the same assistant message that made the calls — the compact shape the\n // store persists and `mapMessages` (in every model adapter) expands into an assistant + tool\n // message pair. We keep the reference and attach the model's own `toolResults` below once the\n // tools have run.\n const assistantMessage: ModelMessage = {\n role: 'assistant',\n content: turn.text,\n ...(messageCalls.length > 0 ? { toolCalls: messageCalls } : {}),\n ...(syntheticResults.length > 0 ? { toolResults: syntheticResults } : {}),\n };\n modelMessages.push(assistantMessage);\n\n for (const entry of synthetic) {\n const { call, result } = entry;\n await hooks.step(`${entry.step}:${assistant.id}`, async () => {\n await deps.store.recordToolCall({\n toolCallId: call.id,\n messageId: assistant.id,\n toolName: call.name,\n toolType: 'read',\n input: call.input,\n status: 'auto_executed',\n runId: hooks.runId,\n });\n await deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'executed',\n output: result.output,\n });\n // The same pair of frames an executed read tool writes, so a live subscriber renders this\n // through the tool-call machinery it already has rather than learning a frame kind.\n await writer.write(\n encodeStreamEvent({\n kind: 'tool-input-available',\n id: call.id,\n name: call.name,\n input: call.input,\n toolKind: 'read',\n }),\n );\n await writer.write(\n encodeStreamEvent({ kind: 'tool-output', id: call.id, output: result.output }),\n );\n });\n }\n\n if (isFinalTurn) {\n await hooks.step(`stream:step-finish:${i}`, async () => {\n await writer.write(\n encodeStreamEvent({\n kind: 'step-finish',\n usage: turn.usage,\n costUsd,\n ...(turn.reasoningMs !== undefined ? { reasoningMs: turn.reasoningMs } : {}),\n ...(stepModel !== undefined ? { model: stepModel } : {}),\n }),\n );\n });\n break;\n }\n\n // Before the turn's tools are DISPATCHED — the last point at which stopping costs nothing,\n // because the moment the first handler runs there is a side effect no cancel can take back. One\n // observation for the whole batch rather than one per call: the calls are a single ask from the\n // model, and stopping half way through leaves the next step reading a message whose tool results\n // it cannot pair with the calls above them.\n await haltIfCancelled(hooks, cancellable, `cancel:tools:${i}`);\n\n const results: ToolResult[] = [];\n const turnCalls: ToolTurnContext = {\n deps,\n input,\n hooks,\n messageId: assistant.id,\n writer,\n toolUi: new Map(),\n toolText: new Map(),\n halt: { terminal: false },\n actionApprovalMode: history.actionApprovalMode ?? 'blocking',\n ...(skillOffer !== undefined ? { skills: skillOffer } : {}),\n ...(memoryDigest !== undefined ? { memory: memoryDigest } : {}),\n ...(persona !== undefined ? { persona } : {}),\n };\n // A model routinely asks for several tools at once, and running them back to back makes the turn\n // cost their sum. Overlapping them is safe here because a checkpoint position is handed out on\n // the CALL, not when the work settles: launching every invocation in one tick — what\n // `hooks.parallel` promises — pins the `tool:` block in call order however the tools then finish,\n // the same anchor `ctx.all` gets by reserving its block before dispatching. The claim and persist\n // checkpoints stay sequential around it.\n //\n // Only a turn whose every call is a plain `read` qualifies:\n // - an `action` suspends on an approval signal, which is human time rather than I/O, so\n // overlapping what follows it buys nothing — and reserving an invocation position for a call\n // that may yet be REJECTED spends a position the rejected branch never fills.\n // - an `agent` delegation is `ctx.child`, whose parallel form is the runtime's own `ctx.all`:\n // one workflow ref over a reserved block, carrying the `parallelGroup` bookkeeping that makes\n // a fan render as a fan. That is not N independent task closures, so it cannot ride this hook.\n // The kinds come from the `persist:toolcall` checkpoints, never from a local registry lookup, so\n // every process replaying this turn reaches the same verdict.\n const parallel = hooks.parallel;\n if (\n parallel !== undefined &&\n toolCallsWithKind.length > 1 &&\n (await (hooks.patched?.(PARALLEL_TOOLS_PATCH) ?? Promise.resolve(true)))\n ) {\n // Claiming the whole turn first is what makes the kinds knowable before the first execution —\n // and it is also what moves the checkpoints, hence the `patched` gate above.\n const claimed: ClaimedToolCall[] = [];\n for (const call of toolCallsWithKind) {\n claimed.push(await claimToolCall(turnCalls, call));\n }\n // A `skill` load and a `remember` write qualify alongside a `read`: each takes its position on\n // the call exactly as a read does, and each spends a read's `tool:`/`persist:` names. What\n // disqualifies the other two kinds is not that they have effects — it is that an `action`\n // suspends on human time and an `agent` delegation is the runtime's own `ctx.all`.\n if (\n claimed.every(\n (entry) =>\n entry.toolType === 'read' || entry.toolType === 'skill' || entry.toolType === 'memory',\n )\n ) {\n results.push(...(await invokeClaimedToolsTogether(turnCalls, parallel, claimed)));\n } else {\n for (const entry of claimed) {\n results.push(await runClaimedToolCall(turnCalls, entry));\n }\n }\n } else {\n for (const call of toolCallsWithKind) {\n results.push(await runClaimedToolCall(turnCalls, await claimToolCall(turnCalls, call)));\n }\n }\n const settledResults = [...results, ...syntheticResults];\n const toolText = escapeUnsafeToolUiText(\n toolCallsWithKind\n .map((call) => turnCalls.toolText.get(call.id))\n .filter((text): text is string => text !== undefined)\n .join('\\n'),\n );\n assistantMessage.toolResults = settledResults;\n\n // Stream each tool's result so the client flips its live tool card from \"running\" to the\n // rendered output (renderResult → DataTable/Chart, executeSql → rows). One durable step keeps\n // replay from re-emitting. Which frame each result goes out on is `outputFrame`'s call: a\n // refusal has its own, and `error` carries only what the model is told.\n await hooks.step(`stream:tool-outputs:${i}`, async () => {\n // The results land on the message from INSIDE this checkpoint rather than at one of their\n // own: this turn's checkpoint sequence is a wire contract with every run already in flight,\n // and a position inserted between two recorded ones is refused on resume. Every value in\n // `settledResults` comes from a checkpoint above, so a replay writes the same list anyway.\n await deps.store.setMessageToolResults(assistant.id, settledResults);\n if (toolText)\n await deps.store.appendMessage({\n threadId: input.threadId,\n role: 'assistant',\n content: toolText,\n runId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n });\n // What the tools pushed joins what the model turn streamed, on the same message, in call\n // order. Every list here was read off a checkpoint above, so a replay writes the same value.\n const toolUi = toolCallsWithKind.flatMap((call) => turnCalls.toolUi.get(call.id) ?? []);\n if (toolUi.length > 0) {\n await deps.store.setMessageUi?.(assistant.id, mergeUi(turn.ui, toolUi));\n }\n for (const result of results) {\n await writer.write(encodeStreamEvent(outputFrame(result)));\n }\n });\n\n if (toolText) {\n modelMessages.push({ role: 'assistant', content: toolText });\n lastText += `\\n${toolText}`;\n }\n await hooks.step(`stream:step-finish:${i}`, async () => {\n await writer.write(\n encodeStreamEvent({\n kind: 'step-finish',\n usage: turn.usage,\n costUsd,\n ...(turn.reasoningMs !== undefined ? { reasoningMs: turn.reasoningMs } : {}),\n ...(stepModel !== undefined ? { model: stepModel } : {}),\n }),\n );\n });\n\n // A `terminal` tool succeeded: its effect is the answer, so no model call narrates it. Read off\n // the calls' `persist:toolcall` checkpoints and their outcomes, so a replay ends here too.\n if (turnCalls.halt.terminal || turnCalls.halt.independentProposal) {\n break;\n }\n }\n\n if (history.title === '' || history.title === 'New chat') {\n await hooks.step('persist:title', () =>\n deps.store.setTitle(input.threadId, deriveTitle(input.userText)),\n );\n }\n\n const delivery = input.deliverTo;\n if (delivery !== undefined) {\n // A detached run's answer has nowhere to go but a message of its own: the turn that delegated it\n // ended without it, so there is no tool result left to fill and no live stream to write into.\n // Stamped with THIS run and agent, which is how a reader tells \"the research agent finished\"\n // from the assistant's next reply.\n //\n // The position exists only for a run carrying a delivery address, and only a detached\n // delegation's own child run carries one — so the sequence of every other turn is untouched.\n await hooks.step('deliver:detached', async () => {\n if ((await deps.store.getThread(delivery.threadId)) === null) {\n // The conversation was deleted while this ran. The work cannot be un-run, but delivering\n // into a thread nobody kept would resurrect it, and the tool-call row it would settle went\n // with it.\n return;\n }\n const agent = input.agentName ?? 'default';\n await deps.store.appendMessage({\n threadId: delivery.threadId,\n role: 'assistant',\n content: lastText,\n agentName: agent,\n runId: hooks.runId,\n });\n await deps.store.updateToolCall({\n toolCallId: delivery.toolCallId,\n status: 'executed',\n output: detachedDelivered({ agent, runId: hooks.runId, text: lastText }),\n });\n });\n }\n\n // Normal completion only. The loop never records 'failed' — it doesn't catch its own crash;\n // failure recording is the RUNNER's job. A checkpointed step, so a resumed replay settles once.\n await hooks.step('persist:run:end', async () => {\n await deps.store.recordRunEnd?.({\n runId: hooks.runId,\n status: 'completed',\n durationMs: Date.now() - startedAt,\n });\n });\n\n await writer.end();\n publishAgentRunFinished({\n runId: hooks.runId,\n threadId: input.threadId,\n steps,\n inputTokens: totalInput,\n outputTokens: totalOutput,\n });\n return { text: lastText, ...(structured !== undefined ? { object: structured } : {}) };\n}\n","import { DefaultApprovalPolicy } from './spi/approval-policy.js';\nimport type { ApprovalPolicy, ApprovalThreadRef, ApprovalToolRef } from './spi/approval-policy.js';\nimport type { Actor } from './types.js';\nexport type ClaimedActionApproval =\n | { mode: 'auto' }\n | { mode: 'remembered'; approver: string }\n | { mode: 'ask'; approver: string; ttlMs?: number; expiresAt?: string };\nexport interface ResolveActionProposalApprovalInput {\n actor: Actor;\n thread: ApprovalThreadRef;\n tool: ApprovalToolRef;\n store: { rememberedApprovals?(threadId: string): Promise<string[]> };\n policy?: ApprovalPolicy;\n clock?: () => number;\n}\n/** Journal this result on the trusted producer before choosing strict proposal preparation. */\nexport async function resolveActionProposalApproval(\n input: ResolveActionProposalApprovalInput,\n): Promise<ClaimedActionApproval> {\n const policy = input.policy ?? new DefaultApprovalPolicy();\n const requirement = await policy.requirementFor(input.tool, input.actor, input.thread);\n if (!requirement.required) return { mode: 'auto' };\n const remembered = (await input.store.rememberedApprovals?.(input.thread.threadId)) ?? [];\n if (remembered.includes(input.tool.name))\n return { mode: 'remembered', approver: requirement.approver };\n const roundedTtl =\n requirement.ttlMs !== undefined && Number.isFinite(requirement.ttlMs)\n ? Math.floor(requirement.ttlMs)\n : 0;\n if (roundedTtl <= 0) return { mode: 'ask', approver: requirement.approver };\n const now = (input.clock ?? Date.now)();\n if (\n !Number.isSafeInteger(now) ||\n !Number.isSafeInteger(roundedTtl) ||\n !Number.isSafeInteger(now + roundedTtl)\n )\n throw new RangeError('Invalid action approval deadline');\n return {\n mode: 'ask',\n approver: requirement.approver,\n ttlMs: roundedTtl,\n expiresAt: new Date(now + roundedTtl).toISOString(),\n };\n}\n","import { snapshotActionProposal } from './action-proposal-transitions.js';\nimport type { RolesPolicy } from './spi/roles-policy.js';\nimport type { AiToolCtx } from './spi/tool.js';\nimport type { InvokeOptions, ToolRegistry } from './tool-registry.js';\n\n/** Trusted producer path: retain the original JSON and the exact data shown for approval. */\nexport async function prepareActionProposal(\n registry: ToolRegistry,\n name: string,\n input: unknown,\n ctx: AiToolCtx,\n policy: RolesPolicy,\n options: InvokeOptions = {},\n) {\n const preparationInput = snapshotActionProposal(input);\n const prepared = await registry.prepareValidated(\n name,\n snapshotActionProposal(preparationInput),\n ctx,\n policy,\n { ...options, snapshotInput: true },\n );\n let replacementKey: string | undefined;\n const replacement = registry.spec(name)?.replacementKey;\n if (prepared.preflight.status === 'ready' && replacement !== undefined) {\n replacementKey =\n typeof replacement === 'string'\n ? replacement\n : await replacement(snapshotActionProposal(prepared.input), ctx);\n if (\n replacementKey !== undefined &&\n (typeof replacementKey !== 'string' || !replacementKey || replacementKey.length > 255)\n )\n throw new TypeError(\n 'replacementKey must be a nonempty string of at most 255 UTF-16 code units',\n );\n }\n return {\n ...(replacementKey !== undefined ? { replacementKey } : {}),\n preparationInput,\n input: prepared.input,\n // Completed results keep their normal handler contract; they never create a proposal.\n preflight:\n prepared.preflight.status === 'ready'\n ? snapshotActionProposal(prepared.preflight)\n : prepared.preflight,\n };\n}\n","export type ActionApprovalMode = 'blocking' | 'independent';\nexport type ActionProposalTarget = { kind: 'proposal'; proposalId: string };\nexport interface ActionProposalReceipt {\n proposalId: string;\n status: 'pending';\n executed: false;\n}\nexport function actionProposalReceipt(proposalId: string): ActionProposalReceipt {\n return { proposalId, status: 'pending', executed: false };\n}\n","import { emit } from '@dudousxd/nestjs-diagnostics';\nimport type { ChannelRegistry } from '@dudousxd/nestjs-diagnostics';\nimport type { QuotaPeriod } from './spi/quota-provider.js';\n\n/** Payloads carried on each `aviary:agent:*` channel. */\nexport interface AgentRunStarted {\n runId: string;\n threadId: string;\n actorId: string;\n /** Which agent is handling the run. */\n agentName?: string;\n /** The persona of that agent the run is under, when it is under one. */\n persona?: string;\n}\nexport interface AgentMessageEvent {\n runId: string;\n threadId: string;\n role: 'user' | 'assistant';\n textLength: number;\n}\nexport interface AgentToolCallEvent {\n runId: string;\n toolName: string;\n toolType: 'read' | 'action';\n status: string;\n durationMs?: number;\n}\n/**\n * A turn refused for budget. Published by the send gate (`429`) and the message queue when a\n * `QuotaProvider` reports `blocked`, and by the loop's own per-day `QuotaStore` gate. The figures\n * are the exhausted window's: a window that does not count tokens (a USD-only spend cap) carries no\n * token figures, never a made-up `0`.\n */\nexport interface AgentQuotaExceeded {\n actorId: string;\n /** The window that ran out. Absent from the loop's per-day `QuotaStore` gate. */\n period?: QuotaPeriod;\n /** The provider's words for the block, when it gave some. */\n reason?: string;\n usedTokens?: number;\n limitTokens?: number;\n usedUsd?: number;\n limitUsd?: number;\n}\nexport interface AgentRunFinished {\n runId: string;\n threadId: string;\n steps: number;\n inputTokens: number;\n outputTokens: number;\n}\nexport interface AgentRunFailed {\n runId: string;\n /** Stable failure slug, e.g. `quota_exceeded` or `run_failed`. */\n code: string;\n message: string;\n}\nexport interface AgentDelegated {\n runId: string;\n fromAgent?: string;\n toAgent: string;\n /** The delegate was STARTED, not awaited — this run's turn ended without its answer. */\n detached?: boolean;\n}\nexport interface AgentRetrieved {\n runId: string;\n query: string;\n /** How many passages the retriever returned. */\n count: number;\n}\n/**\n * The skills a turn was offered, published once per run at the `skills:catalog` checkpoint. Metadata\n * only — counts and the block's size, never a skill's name or its body.\n */\nexport interface AgentSkillsResolved {\n runId: string;\n /** How many scope tokens the resolver returned for this turn. */\n scopes: number;\n /** Skills in the catalog block the model was shown. */\n offered: number;\n /** Applicable skills the `maxSkills` ceiling left out — non-zero means the catalog is partial. */\n omitted: number;\n /**\n * Characters the catalog block added to the system prompt. The WHOLE of what skills cost it: a\n * skill's body never enters the system block, it arrives as a tool result on the transcript.\n */\n promptChars: number;\n}\n/**\n * The memories a turn was shown, published once per run at the `memory:digest` checkpoint. Metadata\n * only — counts and the block's size, never a memory's key or its text. A key is as revealing as a\n * fact (`diagnosis`, `clearance`), so it does not travel on a diagnostics channel either.\n */\nexport interface AgentMemoryResolved {\n runId: string;\n /** How many scope tokens the resolver returned for this turn. */\n scopes: number;\n /** Memories in the block the model was shown. */\n offered: number;\n /** Applicable memories the `maxMemories` ceiling left out — non-zero means the block is partial. */\n omitted: number;\n /**\n * Of `omitted`, how many were ALWAYS-ON. The one to alert on: ordinary omission is the budget\n * working, while a dropped always-on memory is a deployment's own standing policies having stopped\n * reaching any prompt — more was pinned than the block holds.\n */\n pinnedOmitted: number;\n /**\n * Whether the block was selected by relevance to this turn rather than read whole. Distinguishes\n * \"this deployment holds few memories\" from \"this turn drew twenty out of two thousand\", which\n * `offered` alone reports identically.\n */\n recalled: boolean;\n /** Characters the memory block added to the system prompt. The WHOLE of what memory cost it. */\n promptChars: number;\n}\n/**\n * A turn writing one memory — the event an operator watches to see the agent's own write volume,\n * which is the risk surface memory has and retrieval does not. The scope token travels (it is what\n * says whose prompt just changed, and `run.started` already carries an actor id); the key and the\n * text do not.\n */\nexport interface AgentMemoryWritten {\n runId: string;\n scope: string;\n /** Length of the stored fact in characters — never the fact itself. */\n chars: number;\n}\n/**\n * A transient-classified tool error being retried in place (no new checkpoint) — see\n * `invokeWithTransientRetry`. Emitted once per retry (not for the final, non-retried outcome).\n */\nexport interface AgentToolRetry {\n toolName: string;\n toolCallId: string;\n /** 1-based ordinal of the attempt that just failed and is about to be retried. */\n attempt: number;\n /** The failed attempt's error message. */\n message: string;\n}\n\n// --- Span (trace) payloads — the START-phase payload of each traced operation. Metadata only:\n// token counts / lengths / names, never prompt or output text (the point events' redaction\n// posture). The traced result rides the `end`/`asyncEnd` envelope; see agent-loop's span helpers.\n\n/** START payload of an `aviary:agent:llm.turn:*` span — one model call within a run. */\nexport interface AgentLlmTurnSpan {\n runId: string;\n /** Zero-based model-call index within the run (the loop's step counter). */\n step: number;\n}\n/** START payload of an `aviary:agent:tool.execution:*` span — one tool invocation. */\nexport interface AgentToolExecutionSpan {\n runId: string;\n toolCallId: string;\n toolName: string;\n toolType: 'read' | 'action';\n}\n/** START payload of an `aviary:agent:retrieval:*` span — inject-mode RAG retrieval. */\nexport interface AgentRetrievalSpan {\n runId: string;\n /** Length of the retrieval query in characters — never the query text itself. */\n queryLength: number;\n topK: number;\n}\n/** START payload of an `aviary:agent:follow-ups:*` span — the extra follow-up-suggestions call. */\nexport interface AgentFollowUpsSpan {\n runId: string;\n /** Zero-based model-call index of the final turn the follow-ups ride on. */\n step: number;\n /** How many follow-up questions were requested. */\n count: number;\n}\n\n/**\n * START payload of an `aviary:agent:structured-output:*` span — the formatting pass that restates a\n * finished answer as `AgentLoopDeps.outputSchema`. `attempt` is 0 for the pass itself and counts up\n * for each bounded repair, so a run that needed three tries is visible as three spans.\n */\nexport interface AgentStructuredOutputSpan {\n runId: string;\n /** Zero-based model-call index of the final turn whose answer is being restated. */\n step: number;\n attempt: number;\n}\n\n/** Declaration-merge so `emit('agent', ...)`, `trace('agent', ...)` and telescope infer the agent payloads. */\ndeclare module '@dudousxd/nestjs-diagnostics' {\n interface ChannelRegistry {\n agent: {\n 'run.started': AgentRunStarted;\n message: AgentMessageEvent;\n 'tool-call': AgentToolCallEvent;\n 'quota.exceeded': AgentQuotaExceeded;\n 'run.finished': AgentRunFinished;\n 'run.failed': AgentRunFailed;\n delegated: AgentDelegated;\n retrieved: AgentRetrieved;\n 'skills.resolved': AgentSkillsResolved;\n 'memory.resolved': AgentMemoryResolved;\n 'memory.written': AgentMemoryWritten;\n 'tool.retry': AgentToolRetry;\n // Span-only events (published via trace() on :start/:end/:asyncStart/:asyncEnd/:error\n // sub-channels, never as point events) — see AgentSpanEvent below.\n 'llm.turn': AgentLlmTurnSpan;\n 'tool.execution': AgentToolExecutionSpan;\n retrieval: AgentRetrievalSpan;\n 'follow-ups': AgentFollowUpsSpan;\n 'structured-output': AgentStructuredOutputSpan;\n };\n }\n}\n\nexport function publishAgentRunStarted(payload: AgentRunStarted): void {\n emit('agent', 'run.started', payload);\n}\nexport function publishAgentMessage(payload: AgentMessageEvent): void {\n emit('agent', 'message', payload);\n}\nexport function publishAgentToolCall(payload: AgentToolCallEvent): void {\n emit('agent', 'tool-call', payload);\n}\nexport function publishAgentQuotaExceeded(payload: AgentQuotaExceeded): void {\n emit('agent', 'quota.exceeded', payload);\n}\nexport function publishAgentRunFinished(payload: AgentRunFinished): void {\n emit('agent', 'run.finished', payload);\n}\nexport function publishAgentRunFailed(payload: AgentRunFailed): void {\n emit('agent', 'run.failed', payload);\n}\nexport function publishAgentDelegated(payload: AgentDelegated): void {\n emit('agent', 'delegated', payload);\n}\nexport function publishAgentRetrieved(payload: AgentRetrieved): void {\n emit('agent', 'retrieved', payload);\n}\nexport function publishAgentToolRetry(payload: AgentToolRetry): void {\n emit('agent', 'tool.retry', payload);\n}\nexport function publishAgentSkillsResolved(payload: AgentSkillsResolved): void {\n emit('agent', 'skills.resolved', payload);\n}\nexport function publishAgentMemoryResolved(payload: AgentMemoryResolved): void {\n emit('agent', 'memory.resolved', payload);\n}\nexport function publishAgentMemoryWritten(payload: AgentMemoryWritten): void {\n emit('agent', 'memory.written', payload);\n}\n\n/**\n * Events published ONLY as spans — via `trace('agent', ...)` on the five `:start`/`:end`/\n * `:asyncStart`/`:asyncEnd`/`:error` sub-channels — never as point events on the base channel.\n * They are deliberately NOT in {@link AGENT_DIAGNOSTIC_EVENTS}: the point-event watcher has\n * nothing to subscribe to on their base channels, and claiming their keys would be meaningless\n * (the generic bridge only records point traffic).\n */\nexport type AgentSpanEvent =\n | 'llm.turn'\n | 'tool.execution'\n | 'retrieval'\n | 'follow-ups'\n | 'structured-output';\n\n/** All span-only events, in a stable order — for a future span recorder to derive sub-channels from. */\nexport const AGENT_SPAN_EVENTS: readonly AgentSpanEvent[] = [\n 'llm.turn',\n 'tool.execution',\n 'retrieval',\n 'follow-ups',\n 'structured-output',\n];\n\n/** Compile-time-only check: every {@link AgentSpanEvent} must appear in `AGENT_SPAN_EVENTS`. */\ntype AgentSpanEventsCoverAllKeys = [AgentSpanEvent] extends [(typeof AGENT_SPAN_EVENTS)[number]]\n ? true\n : ['AGENT_SPAN_EVENTS is missing an AgentSpanEvent'];\nconst agentSpanEventsCoverAllKeys: AgentSpanEventsCoverAllKeys = true;\nvoid agentSpanEventsCoverAllKeys;\n\n/** Compile-time-only check: every span event must be declared on `ChannelRegistry['agent']`. */\ntype AgentSpanEventsAreRegistered = [AgentSpanEvent] extends [keyof ChannelRegistry['agent']]\n ? true\n : [\"AGENT_SPAN_EVENTS names an event not declared on ChannelRegistry['agent']\"];\nconst agentSpanEventsAreRegistered: AgentSpanEventsAreRegistered = true;\nvoid agentSpanEventsAreRegistered;\n\n/** Every POINT event key declared on `ChannelRegistry['agent']` above — derived, not hand-copied. */\nexport type AgentDiagnosticEvent = Exclude<keyof ChannelRegistry['agent'], AgentSpanEvent>;\n\n/**\n * All 12 point events on `ChannelRegistry['agent']`, in a stable order — handy for wiring\n * subscribers (mirrors nestjs-media's `MEDIA_DIAGNOSTIC_EVENTS`). Span-only events (see\n * {@link AgentSpanEvent}) are excluded. A drift between this list and the registry is a compile\n * error in both directions: an extra/misspelled entry fails this array's own\n * `readonly AgentDiagnosticEvent[]` annotation immediately; a missing entry fails the\n * {@link AgentDiagnosticEventsCoverAllKeys} check below.\n */\nexport const AGENT_DIAGNOSTIC_EVENTS: readonly AgentDiagnosticEvent[] = [\n 'run.started',\n 'message',\n 'tool-call',\n 'quota.exceeded',\n 'run.finished',\n 'run.failed',\n 'delegated',\n 'retrieved',\n 'skills.resolved',\n 'memory.resolved',\n 'memory.written',\n 'tool.retry',\n];\n\n/** Compile-time-only check: every point event of `ChannelRegistry['agent']` must appear above. */\ntype AgentDiagnosticEventsCoverAllKeys = [AgentDiagnosticEvent] extends [\n (typeof AGENT_DIAGNOSTIC_EVENTS)[number],\n]\n ? true\n : [\"AGENT_DIAGNOSTIC_EVENTS is missing a key declared on ChannelRegistry['agent']\"];\n\n// If this line stops typechecking, an event was added to (or renamed on) ChannelRegistry['agent']\n// without a matching update to AGENT_DIAGNOSTIC_EVENTS (point events) or AgentSpanEvent (spans).\nconst agentDiagnosticEventsCoverAllKeys: AgentDiagnosticEventsCoverAllKeys = true;\nvoid agentDiagnosticEventsCoverAllKeys;\n\n/**\n * The telescope key for an agent diagnostics channel — `agent:<event>`. This is the key the\n * `@dudousxd/nestjs-diagnostics-telescope` generic bridge matches its `exclude` option against,\n * and the label its \"Busiest events\" panel shows. Distinct from the `aviary:agent:<event>` channel\n * name used on the wire. Mirrors `mediaDiagnosticKey`.\n */\nexport type AgentDiagnosticKey = `agent:${AgentDiagnosticEvent}`;\n\n/**\n * Compose the telescope key for an agent event, typed against {@link AgentDiagnosticEvent} so a\n * misspelled event is a compile error. Feed the result to `nestjsDiagnosticsTelescope({ exclude:\n * [...] })` to mute a noisy channel, e.g. `agentDiagnosticKey('message')`.\n */\nexport function agentDiagnosticKey(event: AgentDiagnosticEvent): AgentDiagnosticKey {\n return `agent:${event}`;\n}\n","import { snapshotActionProposal } from './action-proposal-transitions.js';\nimport { prepareUiEmission } from './genui/capabilities.js';\nimport type { Catalog } from './genui/catalog.js';\nimport type { ToolDescribeScope } from './spi/tool.js';\nimport type { AgentStreamEvent } from './stream-events.js';\nimport { type UiCollector, createUiCollector } from './tool-ui.js';\nexport type ResolveToolUiCatalog = (scope: ToolDescribeScope) => Catalog | Promise<Catalog>;\nexport interface NegotiatedUiCollector extends UiCollector {\n text(): string;\n}\nexport function createNegotiatedUiCollector(\n toolCallId: string,\n scope: ToolDescribeScope,\n resolveCatalog?: ResolveToolUiCatalog,\n write?: (event: AgentStreamEvent) => void | Promise<void>,\n): NegotiatedUiCollector {\n const collector = createUiCollector(toolCallId, write);\n const texts = new Map<string, string>();\n let next = 0;\n return {\n components: collector.components,\n text: () => [...texts.values()].join('\\n'),\n restart: () => {\n next = 0;\n texts.clear();\n collector.restart();\n },\n emit: async (component, props, options = {}) => {\n if (!resolveCatalog) {\n // No server catalog to negotiate against: the client's declaration can only narrow what is\n // drawn. A component it does not declare (at this version) degrades to its fallback text,\n // else is left out — never a throw, which would fail the tool body itself.\n const declared =\n scope.uiCapabilities === undefined ||\n scope.uiCapabilities.components.some(\n (entry) => entry.name === component && entry.version === (options.version ?? 1),\n );\n if (declared) return collector.emit(component, props, options);\n const id = options.id ?? `${toolCallId}:ui:${next++}`;\n if (options.fallbackText !== undefined && options.fallbackText.length > 0) {\n texts.set(id, options.fallbackText);\n await write?.({ kind: 'text', text: options.fallbackText });\n }\n return { id };\n }\n const capturedProps = snapshotActionProposal(props);\n const capturedOptions = { ...options };\n const catalog = await resolveCatalog(scope);\n const prepared = await prepareUiEmission(\n catalog,\n scope.uiCapabilities,\n component,\n capturedProps,\n capturedOptions.version,\n );\n const id = capturedOptions.id ?? `${toolCallId}:ui:${next++}`;\n if (prepared.kind === 'text') {\n texts.set(id, prepared.text);\n await write?.({ kind: 'text', text: prepared.text });\n return { id };\n }\n return collector.emit(prepared.component, prepared.props, {\n id,\n version: prepared.version,\n fallbackText: prepared.fallbackText,\n ...(prepared.componentVersions !== undefined\n ? { componentVersions: prepared.componentVersions }\n : {}),\n });\n },\n };\n}\n","/**\n * Transient tool-error classification + the retry loop that wraps a tool's own invocation. A\n * classified-transient error (a DB deadlock, a lock-wait timeout, a serialization failure) means\n * the server rolled the tool's work back — retrying THAT class is safe, unlike a tool's general\n * business failure, which stays a one-shot outcome (no durable step retries: a tool may not be\n * idempotent). See `runAgentLoop`'s `tool:<call.id>` step body and `AgentRunSteps.tool` — both wrap\n * `registry.invoke(...)` with {@link invokeWithTransientRetry} so a retry never becomes a new\n * checkpoint; history still shows exactly one step per tool call.\n */\n\nimport { isControlFlowSignal } from './control-flow.js';\nimport { ToolPreflightDeniedError } from './tool-registry.js';\n\n/** Narrow, structural check for a MySQL/Postgres/SQLite transient error shape — no casts. */\nfunction hasTransientShape(error: unknown): boolean {\n if (typeof error !== 'object' || error === null) {\n return false;\n }\n const code = 'code' in error ? (error as { code: unknown }).code : undefined;\n const errno = 'errno' in error ? (error as { errno: unknown }).errno : undefined;\n const sqlState = 'sqlState' in error ? (error as { sqlState: unknown }).sqlState : undefined;\n if (code === 1213 || code === 1205 || errno === 1213 || errno === 1205) {\n return true; // MySQL ER_LOCK_DEADLOCK / ER_LOCK_WAIT_TIMEOUT numeric codes\n }\n if (code === 'ER_LOCK_DEADLOCK' || code === 'ER_LOCK_WAIT_TIMEOUT') {\n return true; // MySQL driver string codes\n }\n if (code === '40001' || code === '40P01' || sqlState === '40001' || sqlState === '40P01') {\n return true; // Postgres serialization_failure / deadlock_detected SQLSTATEs\n }\n if (code === 'SQLITE_BUSY') {\n return true;\n }\n const message = 'message' in error ? (error as { message: unknown }).message : undefined;\n return (\n typeof message === 'string' && /deadlock|lock wait timeout|serialization failure/i.test(message)\n );\n}\n\n/**\n * Default transient-tool-error classifier: true for a recognized MySQL/Postgres/SQLite\n * lock-contention shape (by driver `code`/`errno`/`sqlState`, or a matching message), checked on\n * the error itself and one level of `cause` (drivers commonly wrap the original error). A plain\n * `Error` with none of these markers — any other business failure — is `false`.\n */\nexport function isTransientToolError(error: unknown): boolean {\n if (error instanceof ToolPreflightDeniedError) return false;\n if (hasTransientShape(error)) {\n return true;\n }\n if (typeof error === 'object' && error !== null && 'cause' in error) {\n const cause = (error as { cause: unknown }).cause;\n if (cause !== undefined && cause !== error && hasTransientShape(cause)) {\n return true;\n }\n }\n return false;\n}\n\n/** Total attempts (initial try + retries) when `toolTransientRetry` doesn't set `attempts`. */\nexport const DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS = 2;\n/** Backoff base in ms — the wait between attempt N and N+1 is `backoffMs * N`. */\nexport const DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS = 150;\n\n/** The host-configurable half of the policy — everything except the (non-wire-safe) `classify` fn. */\nexport interface ToolTransientRetryOptions {\n /** Total attempts (initial try + retries). Defaults to {@link DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS}. */\n attempts?: number;\n /** Backoff base in ms. Defaults to {@link DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS}. */\n backoffMs?: number;\n /** Overrides the default classifier — widen or narrow which errors are treated as transient. */\n classify?: (error: unknown) => boolean;\n}\n\n/** `false` disables transient retry entirely — a tool's own thrown error surfaces immediately. */\nexport type ToolTransientRetrySetting = ToolTransientRetryOptions | false;\n\n/** Just the wire-safe (numeric) half of a resolved policy — what a dispatched envelope carries. */\nexport interface ToolTransientRetryNumbers {\n attempts: number;\n backoffMs: number;\n}\n\n/**\n * Resolves the numeric half of `toolTransientRetry` for the dispatched wire envelope: `false` when\n * explicitly disabled, else concrete `{ attempts, backoffMs }` (defaults filled in) — never\n * `undefined`, so the dispatched handler always gets a definite answer instead of re-deriving its\n * own default. The `classify` function never rides this — it isn't wire-safe; the dispatched\n * handler resolves its own `classify` from its local module options (see `AgentRunSteps.tool`).\n */\nexport function resolveToolTransientRetryNumbers(\n setting: ToolTransientRetrySetting | undefined,\n): ToolTransientRetryNumbers | false {\n if (setting === false) {\n return false;\n }\n return {\n attempts: setting?.attempts ?? DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS,\n backoffMs: setting?.backoffMs ?? DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS,\n };\n}\n\nexport interface InvokeWithTransientRetryOptions {\n /**\n * Widens what counts as a control-flow signal (durable suspend / continue-as-new) so a retry never\n * swallows one — same rule the loop's tool catch applies. An ADDITION to the built-in marker check\n * ({@link isControlFlowSignal}), which already covers every signal the durable runtimes raise;\n * supply this only for a runner whose signals carry no marker.\n */\n isControlFlowError?: (error: unknown) => boolean;\n /**\n * Called before each wait-and-retry, with the 1-based ordinal of the attempt that just failed and\n * the error it threw. The call site uses this to emit the `tool.retry` diagnostics point event —\n * `invokeWithTransientRetry` itself carries no tool identity (name/callId), only the thunk.\n */\n onRetry?: (attempt: number, error: unknown) => void;\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\n/**\n * Retries `fn` in place — never a new durable step/checkpoint, just repeated attempts inside\n * whichever step body already wraps this call. `setting: false` runs `fn` once, unwrapped (no\n * classify/backoff bookkeeping at all). Otherwise: try; on a thrown error, rethrow immediately if\n * it's a recognized control-flow signal, else if the (possibly custom) classifier calls it\n * transient AND attempts remain, wait `backoffMs * attemptNumber` and retry; otherwise rethrow the\n * error as-is.\n */\nexport async function invokeWithTransientRetry<T>(\n fn: () => Promise<T>,\n setting: ToolTransientRetrySetting,\n options?: InvokeWithTransientRetryOptions,\n): Promise<T> {\n if (setting === false) {\n return fn();\n }\n const attempts = setting.attempts ?? DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS;\n const backoffMs = setting.backoffMs ?? DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS;\n const classify = setting.classify ?? isTransientToolError;\n\n let attempt = 1;\n for (;;) {\n try {\n return await fn();\n } catch (error) {\n if (\n error instanceof ToolPreflightDeniedError ||\n isControlFlowSignal(error) ||\n options?.isControlFlowError?.(error) === true\n ) {\n throw error;\n }\n const attemptsRemain = attempt < attempts;\n if (!attemptsRemain || !classify(error)) {\n throw error;\n }\n options?.onRetry?.(attempt, error);\n await delay(backoffMs * attempt);\n attempt += 1;\n }\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport {\n validateActionProposalExpiryBatch,\n validateActionProposalWorkerClaim,\n} from './action-proposal-discovery.js';\nimport { claimActionProposalOutcome } from './action-proposal-outcome.js';\nimport {\n actionProposalCreationMatches,\n actionProposalScopeMatches,\n initialActionProposal,\n snapshotActionProposal,\n transitionActionProposalClaim,\n transitionActionProposalDecision,\n transitionActionProposalLease,\n transitionActionProposalSettlement,\n transitionActionProposalSupersession,\n validateActionProposalCreation,\n validateActionProposalListQuery,\n} from './action-proposal-transitions.js';\nimport type {\n ActionProposalOutcome,\n ActionProposalOutcomeLease,\n} from './spi/action-proposal-outcome-store.js';\nimport type {\n ActionProposal,\n ActionProposalDecisionCommand,\n ActionProposalMutationResult,\n ActionProposalScope,\n ActionProposalStore,\n ActionProposalStoreOptions,\n ClaimActionProposal,\n CreateActionProposal,\n CreateActionProposalResult,\n ExtendActionProposalLease,\n ListActionProposals,\n SettleActionProposal,\n} from './spi/action-proposal-store.js';\nimport type { ActionProposalWorkerStore } from './spi/action-proposal-worker-store.js';\n\n/** Reference single-process implementation; durable adapters use the same transitions under CAS. */\nexport class InMemoryActionProposalStore implements ActionProposalStore, ActionProposalWorkerStore {\n protected readonly rows = new Map<string, ActionProposal>();\n protected readonly clock: () => number;\n constructor(options: ActionProposalStoreOptions = {}) {\n this.clock = options.clock ?? Date.now;\n }\n async createActionProposal(input: CreateActionProposal): Promise<CreateActionProposalResult> {\n validateActionProposalCreation(input);\n const row = this.rows.get(input.id);\n if (row) {\n if (!actionProposalScopeMatches(row, input)) return { status: 'conflict' };\n return {\n status: actionProposalCreationMatches(row, input) ? 'unchanged' : 'conflict',\n proposal: snapshotActionProposal(row),\n };\n }\n const proposal = initialActionProposal(input, this.clock());\n this.rows.set(input.id, proposal);\n return { status: 'created', proposal: snapshotActionProposal(proposal) };\n }\n async getActionProposal(scope: ActionProposalScope, id: string): Promise<ActionProposal | null> {\n const row = this.rows.get(id);\n return row && actionProposalScopeMatches(row, scope) ? snapshotActionProposal(row) : null;\n }\n async listActionProposals(\n scope: ActionProposalScope,\n query: ListActionProposals = {},\n ): Promise<ActionProposal[]> {\n const limit = validateActionProposalListQuery(query);\n return [...this.rows.values()]\n .filter(\n (row) =>\n actionProposalScopeMatches(row, scope) &&\n (query.decision === undefined || row.decision === query.decision) &&\n (query.after === undefined ||\n row.createdAt > query.after.createdAt ||\n (row.createdAt === query.after.createdAt && row.id > query.after.id)),\n )\n .sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))\n .slice(0, limit)\n .map(snapshotActionProposal);\n }\n private mutate(\n scope: ActionProposalScope,\n id: string,\n transition: (row: ActionProposal, now: number) => ActionProposalMutationResult,\n ): ActionProposalMutationResult {\n const row = this.rows.get(id);\n if (!row || !actionProposalScopeMatches(row, scope)) return { status: 'not_found' };\n const result = transition(row, this.clock());\n if (result.proposal) this.rows.set(id, snapshotActionProposal(result.proposal));\n return result;\n }\n async decideActionProposal(\n scope: ActionProposalScope,\n id: string,\n command: ActionProposalDecisionCommand,\n ): Promise<ActionProposalMutationResult> {\n return this.mutate(scope, id, (row, now) =>\n transitionActionProposalDecision(row, command, now),\n );\n }\n async claimActionProposal(\n scope: ActionProposalScope,\n id: string,\n command: ClaimActionProposal,\n ): Promise<ActionProposalMutationResult> {\n return this.mutate(scope, id, (row, now) =>\n transitionActionProposalClaim(row, command, now, randomUUID()),\n );\n }\n async extendActionProposalLease(\n scope: ActionProposalScope,\n id: string,\n command: ExtendActionProposalLease,\n ): Promise<ActionProposalMutationResult> {\n return this.mutate(scope, id, (row, now) => transitionActionProposalLease(row, command, now));\n }\n async settleActionProposal(\n scope: ActionProposalScope,\n id: string,\n command: SettleActionProposal,\n ): Promise<ActionProposalMutationResult> {\n return this.mutate(scope, id, (row, now) =>\n transitionActionProposalSettlement(row, command, now),\n );\n }\n\n async claimNextActionProposal(command: ClaimActionProposal): Promise<ActionProposal | null> {\n const now = this.clock();\n validateActionProposalWorkerClaim(command, now);\n const candidates = [...this.rows.values()]\n .filter(\n (row) =>\n row.decision === 'approved' &&\n (row.execution?.status === 'queued' ||\n (row.execution?.status === 'executing' &&\n row.execution.lease !== null &&\n now >= row.execution.lease.expiresAt)),\n )\n .sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))\n .slice(0, 32);\n for (const candidate of candidates) {\n const claimed = await this.claimActionProposal(candidate, candidate.id, command);\n if (claimed.status === 'applied' && claimed.proposal) return claimed.proposal;\n }\n return null;\n }\n\n async expireActionProposals(command: { limit: number }): Promise<number> {\n const now = this.clock();\n validateActionProposalExpiryBatch(command, now);\n const candidates = [...this.rows.values()]\n .filter((row) => row.decision === 'pending' && row.expiresAt !== null && now >= row.expiresAt)\n .sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))\n .slice(0, command.limit);\n let expired = 0;\n for (const candidate of candidates) {\n const result = await this.decideActionProposal(candidate, candidate.id, {\n decision: 'expired',\n actorRef: 'system',\n via: 'expiry',\n });\n if (result.status === 'applied') expired++;\n }\n return expired;\n }\n async claimNextActionProposalOutcome(\n command: ClaimActionProposal,\n ): Promise<{ outcome: ActionProposalOutcome; lease: ActionProposalOutcomeLease } | null> {\n const now = this.clock();\n validateActionProposalWorkerClaim(command, now);\n const candidates = [...this.rows.values()]\n .filter(\n (row) =>\n row.outcomeDelivery?.status === 'pending' &&\n (!row.outcomeDelivery.lease || now >= row.outcomeDelivery.lease.expiresAt),\n )\n .sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))\n .slice(0, 32);\n for (const candidate of candidates) {\n const row = this.rows.get(candidate.id);\n if (!row) continue;\n const next = claimActionProposalOutcome(row, command, this.clock(), randomUUID());\n if (!next?.outcome || !next.outcomeDelivery?.lease) continue;\n this.rows.set(next.id, next);\n return {\n outcome: snapshotActionProposal(next.outcome),\n lease: {\n outcomeId: next.outcome.id,\n token: next.outcomeDelivery.lease.token,\n generation: next.outcomeDelivery.generation,\n },\n };\n }\n return null;\n }\n\n async createReplacingActionProposal(\n input: CreateActionProposal,\n ): Promise<CreateActionProposalResult> {\n validateActionProposalCreation(input);\n const existing = this.rows.get(input.id);\n if (existing) return this.createActionProposal(input);\n const proposal = initialActionProposal(input, this.clock());\n // Build every replacement snapshot before changing any row; no await exposes partial state.\n const replacements: ActionProposal[] = [];\n if (input.replacementKey)\n for (const row of this.rows.values()) {\n if (\n row.decision !== 'pending' ||\n !actionProposalScopeMatches(row, input) ||\n row.toolName !== input.toolName ||\n row.replacementKey !== input.replacementKey\n )\n continue;\n const result = transitionActionProposalSupersession(\n row,\n proposal,\n { replacementProposalId: proposal.id, actorRef: input.actorRef, via: 'supersession' },\n this.clock(),\n );\n if (result.proposal) replacements.push(result.proposal);\n }\n this.rows.set(proposal.id, proposal);\n for (const row of replacements) this.rows.set(row.id, row);\n return { status: 'created', proposal: snapshotActionProposal(proposal) };\n }\n async supersedeActionProposal(\n scope: ActionProposalScope,\n id: string,\n command: { replacementProposalId: string; actorRef: string; via: string },\n ): Promise<ActionProposalMutationResult> {\n const replacement = this.rows.get(command.replacementProposalId);\n if (!replacement || !actionProposalScopeMatches(replacement, scope))\n return { status: 'not_found' };\n return this.mutate(scope, id, (row, now) =>\n transitionActionProposalSupersession(row, replacement, command, now),\n );\n }\n}\n","import {\n actionProposalOutcomeFenceValid,\n actionProposalOutcomeText,\n} from './action-proposal-outcome.js';\nimport { snapshotActionProposal } from './action-proposal-transitions.js';\nimport type { ToolCallOutcome } from './dangling-tool-calls.js';\nimport { InMemoryActionProposalStore } from './in-memory-action-proposal-store.js';\nimport type {\n ActionProposalOutcomeLease,\n ActionProposalOutcomeStore,\n} from './spi/action-proposal-outcome-store.js';\nimport type { ActionProposalScope } from './spi/action-proposal-store.js';\nimport {\n type AgentStore,\n type AppendMessageInput,\n type CreateThreadInput,\n type RecordRunStartInput,\n type RecordToolCallInput,\n type RecordUsageInput,\n type ToolCallApprovalState,\n type UpdateThreadInput,\n type UpdateToolCallInput,\n} from './spi/agent-store.js';\nimport { toolCallApprovalFromRow } from './spi/approval-policy.js';\nimport type {\n ChatQueueStore,\n EnqueueMessageInput,\n QueuePause,\n QueuedMessage,\n QueuedMessagePatch,\n} from './spi/chat-queue.js';\nimport { type AgentUiComponent } from './stream-events.js';\nimport type { ToolConfirmation } from './tool-presentation.js';\nimport {\n type MessageFeedback,\n type StoredMessage,\n type ThreadDetail,\n type ThreadSummary,\n type ToolCallApproval,\n type ToolCallStatus,\n type ToolResult,\n} from './types.js';\n\ninterface ThreadRow extends ThreadSummary {\n actorRef: string;\n tenantRef: string | null;\n activeStreamId?: string;\n messages: StoredMessage[];\n}\n\ninterface ToolCallRow {\n proposalId?: string;\n toolCallId: string;\n messageId: string;\n threadId: string;\n toolName: string;\n toolType: 'read' | 'action';\n input: unknown;\n output?: unknown;\n status: ToolCallStatus;\n error?: string;\n executionMs?: number;\n createdAt: string;\n /** The run this call belongs to; `undefined` when the caller didn't supply one. */\n runId?: string;\n executedByRef?: string;\n approver?: string;\n confirmation?: ToolConfirmation;\n expiresAt?: string;\n remember?: boolean;\n decidedVia?: string;\n}\n\ninterface UsageRow {\n actorRef: string;\n threadId: string;\n modelId: string;\n inputTokens: number;\n outputTokens: number;\n cacheWriteTokens?: number;\n cacheReadTokens?: number;\n costUsd?: number;\n day: string;\n createdAt: string;\n}\n\n/** A recorded usage row exposed to the governance read-model (input/output split + thread/day). */\nexport interface GovernanceUsageRow {\n actorRef: string;\n threadId: string;\n modelId: string;\n inputTokens: number;\n outputTokens: number;\n /** Subset of `inputTokens` written to the prompt cache this turn; undefined when not reported. */\n cacheWriteTokens?: number;\n /** Subset of `inputTokens` served from the prompt cache this turn; undefined when not reported. */\n cacheReadTokens?: number;\n /** Provider-reported actual cost for the turn, when known; undefined → estimate from pricing. */\n costUsd?: number;\n day: string;\n createdAt: string;\n}\n\n/** A recorded tool call exposed to the governance read-model (thread resolved, with timestamp). */\nexport interface GovernanceToolCallRow {\n toolCallId: string;\n toolName: string;\n toolType: 'read' | 'action';\n status: ToolCallStatus;\n threadId: string;\n /** The message that requested the call — the thread drill-down groups by it. */\n messageId: string;\n /** Wall-clock milliseconds the tool took to run; undefined when it never recorded one. */\n executionMs?: number;\n /** The failure text for a `failed` call; undefined otherwise. */\n error?: string;\n createdAt: string;\n /** The run this call belongs to; undefined when the caller didn't supply one. */\n runId?: string;\n}\n\n/** A stored message exposed to the governance read-model (the thread drill-down's transcript). */\nexport interface GovernanceMessageRow {\n messageId: string;\n threadId: string;\n role: string;\n content: string;\n agentName?: string;\n createdAt: string;\n}\n\n/** A tool call awaiting a HITL decision, joined to its thread + message for the approvals inbox. */\nexport interface GovernancePendingApprovalRow {\n toolCallId: string;\n toolName: string;\n input: unknown;\n threadId: string;\n threadTitle: string;\n actorRef: string;\n agentName?: string;\n requestedAt: string;\n /** The run this call belongs to; undefined when the caller didn't supply one. */\n runId?: string;\n}\n\n/** Thread metadata exposed to the governance read-model (title/actor/count/last activity). */\nexport interface GovernanceThreadRow {\n threadId: string;\n title: string;\n actorRef: string;\n messageCount: number;\n updatedAt: string;\n}\n\ninterface RunRow {\n runId: string;\n threadId: string;\n actorRef: string;\n agentName?: string;\n status: 'running' | 'completed' | 'failed' | 'cancelled';\n durationMs?: number;\n errorCode?: string;\n errorMessage?: string;\n retries: number;\n startedAt: string;\n settledAt?: string;\n /** sha256 hex of the run's resolved (pre-RAG) system prompt; undefined for a pre-existing run. */\n promptHash?: string;\n /** The run that delegated this one; undefined for a turn nobody delegated. */\n parentRunId?: string;\n}\n\n/** A recorded run outcome exposed to the governance read-model (reliability surfaces). */\nexport interface GovernanceRunRow {\n runId: string;\n threadId: string;\n actorRef: string;\n agentName?: string;\n status: 'running' | 'completed' | 'failed' | 'cancelled';\n durationMs?: number;\n errorCode?: string;\n errorMessage?: string;\n retries: number;\n startedAt: string;\n settledAt?: string;\n promptHash?: string;\n /**\n * The run that delegated this one; undefined for a turn nobody delegated. The edge exists in the\n * durable journal too, but a reader of run rows has only this — and a DETACHED child outlives its\n * parent's turn, so nothing in the transcript pairs them either.\n */\n parentRunId?: string;\n}\n\n/** A fully in-memory `AgentStore` for tests and the offline demo. */\nexport class InMemoryAgentStore\n extends InMemoryActionProposalStore\n implements AgentStore, ChatQueueStore, ActionProposalOutcomeStore\n{\n private readonly threads = new Map<string, ThreadRow>();\n /** Each thread's waiting messages, in run order. */\n private readonly queues = new Map<string, QueuedMessage[]>();\n private readonly pauses = new Map<string, QueuePause>();\n private readonly toolCalls = new Map<string, ToolCallRow>();\n private readonly usage: UsageRow[] = [];\n private readonly runs = new Map<string, RunRow>();\n\n private now(): string {\n return new Date().toISOString();\n }\n\n async createThread(input: CreateThreadInput): Promise<ThreadSummary> {\n const id = input.id ?? crypto.randomUUID();\n if (this.threads.has(id)) {\n throw new Error(`thread ${id} already exists`);\n }\n const ts = this.now();\n const row: ThreadRow = {\n id,\n actorRef: input.actor.id,\n tenantRef: input.actor.tenantRef ?? null,\n title: input.title ?? 'New chat',\n transient: input.transient ?? false,\n createdAt: ts,\n updatedAt: ts,\n messages: [],\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n };\n this.threads.set(id, row);\n return this.toSummary(row);\n }\n\n async getThread(threadId: string): Promise<ThreadDetail | null> {\n const row = this.threads.get(threadId);\n if (row === undefined) {\n return null;\n }\n return {\n ...this.toSummary(row),\n messages: row.messages.map((message) => this.withApprovals(message)),\n // The run streaming right now — the one field the read-model reports it under.\n ...(row.activeStreamId !== undefined ? { activeRunId: row.activeStreamId } : {}),\n };\n }\n\n /** A message with the approval record of every call on it that was put to a person. */\n private withApprovals(message: StoredMessage): StoredMessage {\n const approvals: ToolCallApproval[] = [];\n for (const call of this.toolCalls.values()) {\n if (call.messageId !== message.id) {\n continue;\n }\n const approval = toolCallApprovalFromRow({\n toolCallId: call.toolCallId,\n ...(call.proposalId !== undefined ? { proposalId: call.proposalId } : {}),\n status: call.status,\n approver: call.approver,\n confirmation: call.confirmation,\n expiresAt: call.expiresAt,\n remember: call.remember,\n executedByRef: call.executedByRef,\n decidedVia: call.decidedVia,\n error: call.error,\n });\n if (approval !== null) {\n approvals.push(approval);\n }\n }\n return approvals.length > 0 ? { ...message, approvals } : message;\n }\n\n async rememberedApprovals(threadId: string): Promise<string[]> {\n const names = new Set<string>();\n for (const call of this.toolCalls.values()) {\n if (call.threadId === threadId && call.remember === true) {\n names.add(call.toolName);\n }\n }\n const thread = this.threads.get(threadId);\n if (thread)\n for (const proposal of this.rows.values())\n if (\n proposal.threadId === threadId &&\n proposal.actorRef === thread.actorRef &&\n proposal.tenantRef === thread.tenantRef &&\n proposal.decisionAudit?.remember === true &&\n (proposal.execution?.status === 'succeeded' || proposal.execution?.status === 'failed')\n )\n names.add(proposal.toolName);\n return [...names];\n }\n\n async toolCallInput(toolCallId: string): Promise<unknown> {\n return this.toolCalls.get(toolCallId)?.input ?? null;\n }\n\n async toolCallApproval(toolCallId: string): Promise<ToolCallApprovalState | null> {\n const call = this.toolCalls.get(toolCallId);\n if (call === undefined) {\n return null;\n }\n return {\n status: call.status,\n approver: call.approver ?? null,\n expiresAt: call.expiresAt ?? null,\n };\n }\n\n async listThreads(actorRef: string, limit = 50): Promise<ThreadSummary[]> {\n return [...this.threads.values()]\n .filter((row) => row.actorRef === actorRef && !row.transient)\n .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt))\n .slice(0, limit)\n .map((row) => this.toSummary(row));\n }\n\n async softDeleteThread(threadId: string): Promise<void> {\n this.threads.delete(threadId);\n }\n\n async forkThread(threadId: string, fromMessageId: string): Promise<ThreadSummary> {\n const source = this.threads.get(threadId);\n if (source === undefined) {\n throw new Error(`thread ${threadId} not found`);\n }\n const cutoff = source.messages.findIndex((message) => message.id === fromMessageId);\n const kept = cutoff >= 0 ? source.messages.slice(0, cutoff + 1) : [...source.messages];\n const id = crypto.randomUUID();\n const ts = this.now();\n const row: ThreadRow = {\n id,\n actorRef: source.actorRef,\n tenantRef: source.tenantRef,\n title: source.title,\n transient: false,\n createdAt: ts,\n updatedAt: ts,\n // Feedback rates a message in ITS thread; a fork starts unrated.\n messages: kept.map(({ feedback: _feedback, ...message }) => ({ ...message })),\n ...(source.defaultAgent != null ? { defaultAgent: source.defaultAgent } : {}),\n ...(source.model != null ? { model: source.model } : {}),\n ...(source.persona != null ? { persona: source.persona } : {}),\n };\n this.threads.set(id, row);\n return this.toSummary(row);\n }\n\n async ownerOfThread(threadId: string): Promise<string | null> {\n return this.threads.get(threadId)?.actorRef ?? null;\n }\n\n async ownerOfToolCall(toolCallId: string): Promise<string | null> {\n const call = this.toolCalls.get(toolCallId);\n if (call === undefined) {\n return null;\n }\n return this.threads.get(call.threadId)?.actorRef ?? null;\n }\n\n async runForToolCall(toolCallId: string): Promise<string | null> {\n const call = this.toolCalls.get(toolCallId);\n if (call === undefined) {\n return null;\n }\n return call.runId ?? this.threads.get(call.threadId)?.activeStreamId ?? null;\n }\n\n async ownerOfActiveStream(runId: string): Promise<string | null> {\n for (const row of this.threads.values()) {\n if (row.activeStreamId === runId) {\n return row.actorRef;\n }\n }\n return null;\n }\n\n async setTitle(threadId: string, title: string): Promise<void> {\n const row = this.threads.get(threadId);\n if (row !== undefined) {\n row.title = title;\n row.updatedAt = this.now();\n }\n }\n\n async updateThread(threadId: string, patch: UpdateThreadInput): Promise<void> {\n const row = this.threads.get(threadId);\n if (row === undefined) {\n return;\n }\n if (patch.title !== undefined) {\n row.title = patch.title;\n }\n if (patch.defaultAgent !== undefined) {\n row.defaultAgent = patch.defaultAgent;\n }\n if (patch.model !== undefined) {\n row.model = patch.model;\n }\n if (patch.persona !== undefined) {\n row.persona = patch.persona;\n }\n row.updatedAt = this.now();\n }\n\n async activeRunForThread(threadId: string): Promise<string | null> {\n return this.threads.get(threadId)?.activeStreamId ?? null;\n }\n\n /**\n * The thread's default agent, projected. A map lookup here, but the SQL adapters answer this with\n * a one-column read instead of materializing the whole transcript — so the caller that only needs\n * this scalar has a method to ask for it.\n */\n async defaultAgentForThread(threadId: string): Promise<string | null> {\n return this.threads.get(threadId)?.defaultAgent ?? null;\n }\n\n /** The thread's persona, projected like {@link defaultAgentForThread}. */\n async personaForThread(threadId: string): Promise<string | null> {\n return this.threads.get(threadId)?.persona ?? null;\n }\n\n /** The thread's pinned model, projected like {@link defaultAgentForThread}. */\n async modelForThread(threadId: string): Promise<string | null> {\n return this.threads.get(threadId)?.model ?? null;\n }\n\n /**\n * Persist the start of a run (turn). Replay-safe: called under a durable localStep.\n *\n * Takes the SPI's own {@link RecordRunStartInput} rather than a hand-copied shape: a field added\n * to the input is otherwise accepted and dropped, silently, by every adapter that re-declares it.\n */\n async recordRunStart(run: RecordRunStartInput): Promise<void> {\n this.runs.set(run.runId, {\n runId: run.runId,\n threadId: run.threadId,\n actorRef: run.actorRef,\n status: 'running',\n retries: 0,\n startedAt: this.now(),\n ...(run.agentName !== undefined ? { agentName: run.agentName } : {}),\n ...(run.parentRunId !== undefined ? { parentRunId: run.parentRunId } : {}),\n ...(run.promptHash !== undefined ? { promptHash: run.promptHash } : {}),\n });\n }\n\n /** Settle a run's outcome. A no-op when the run is unknown (mirrors `setTitle`/`updateThread`). */\n async recordRunEnd(end: {\n runId: string;\n status: 'completed' | 'failed' | 'cancelled';\n durationMs?: number;\n errorCode?: string;\n errorMessage?: string;\n }): Promise<void> {\n const row = this.runs.get(end.runId);\n if (row === undefined) {\n return;\n }\n row.status = end.status;\n row.settledAt = this.now();\n if (end.durationMs !== undefined) {\n row.durationMs = end.durationMs;\n }\n if (end.errorCode !== undefined) {\n row.errorCode = end.errorCode;\n }\n if (end.errorMessage !== undefined) {\n row.errorMessage = end.errorMessage;\n }\n }\n\n /** Bump the run's llm-step retry counter. */\n async bumpRunRetries(runId: string): Promise<void> {\n const row = this.runs.get(runId);\n if (row !== undefined) {\n row.retries += 1;\n }\n }\n\n async promoteThread(threadId: string): Promise<void> {\n const row = this.threads.get(threadId);\n if (row?.transient) {\n row.transient = false;\n row.updatedAt = this.now();\n }\n }\n\n async setActiveStream(threadId: string, runId: string | null): Promise<void> {\n const row = this.threads.get(threadId);\n if (row !== undefined) {\n if (runId === null) {\n // biome-ignore lint/performance/noDelete: exactOptionalPropertyTypes forbids assigning undefined to an optional prop\n delete row.activeStreamId;\n } else {\n row.activeStreamId = runId;\n }\n }\n }\n\n async claimActiveStream(\n threadId: string,\n runId: string,\n options: { replacing?: string } = {},\n ): Promise<boolean> {\n const row = this.threads.get(threadId);\n if (row === undefined) {\n return false;\n }\n const holder = row.activeStreamId;\n if (holder !== undefined && holder !== runId && holder !== options.replacing) {\n return false;\n }\n row.activeStreamId = runId;\n return true;\n }\n\n async releaseActiveStream(threadId: string, runId: string): Promise<boolean> {\n const row = this.threads.get(threadId);\n if (row?.activeStreamId !== runId) {\n return false;\n }\n // biome-ignore lint/performance/noDelete: exactOptionalPropertyTypes forbids assigning undefined to an optional prop\n delete row.activeStreamId;\n return true;\n }\n\n async enqueueMessage(input: EnqueueMessageInput): Promise<QueuedMessage> {\n const ts = this.now();\n const message: QueuedMessage = {\n id: crypto.randomUUID(),\n threadId: input.threadId,\n actor: input.actor,\n content: input.content,\n ...(input.attachments !== undefined && input.attachments.length > 0\n ? { attachments: input.attachments }\n : {}),\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(input.model !== undefined ? { model: input.model } : {}),\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(input.uiCapabilities !== undefined ? { uiCapabilities: input.uiCapabilities } : {}),\n ...(input.hostContext !== undefined ? { hostContext: input.hostContext } : {}),\n ...(input.interrupt === true ? { interrupt: true } : {}),\n createdAt: ts,\n updatedAt: ts,\n };\n const queue = this.queues.get(input.threadId) ?? [];\n if (input.at === 'head') {\n queue.unshift(message);\n } else {\n queue.push(message);\n }\n this.queues.set(input.threadId, queue);\n return { ...message };\n }\n\n async listQueue(threadId: string): Promise<QueuedMessage[]> {\n return (this.queues.get(threadId) ?? []).map((message) => ({ ...message }));\n }\n\n async getQueuedMessage(id: string): Promise<QueuedMessage | null> {\n const found = this.findQueued(id);\n return found === undefined ? null : { ...found.message };\n }\n\n async updateQueuedMessage(id: string, patch: QueuedMessagePatch): Promise<QueuedMessage | null> {\n const found = this.findQueued(id);\n if (found === undefined) {\n return null;\n }\n const { message } = found;\n if (patch.content !== undefined) {\n message.content = patch.content;\n }\n if (patch.attachments !== undefined) {\n if (patch.attachments === null || patch.attachments.length === 0) {\n // biome-ignore lint/performance/noDelete: exactOptionalPropertyTypes forbids assigning undefined to an optional prop\n delete message.attachments;\n } else {\n message.attachments = patch.attachments;\n }\n }\n if (patch.interrupt !== undefined) {\n if (patch.interrupt) {\n message.interrupt = true;\n } else {\n // biome-ignore lint/performance/noDelete: exactOptionalPropertyTypes forbids assigning undefined to an optional prop\n delete message.interrupt;\n }\n }\n message.updatedAt = this.now();\n return { ...message };\n }\n\n async moveQueuedMessage(id: string, index: number): Promise<boolean> {\n const found = this.findQueued(id);\n if (found === undefined) {\n return false;\n }\n const { queue, position, message } = found;\n queue.splice(position, 1);\n const target = Math.max(0, Math.min(queue.length, Math.trunc(index)));\n queue.splice(target, 0, message);\n return true;\n }\n\n async removeQueuedMessage(id: string): Promise<boolean> {\n const found = this.findQueued(id);\n if (found === undefined) {\n return false;\n }\n found.queue.splice(found.position, 1);\n return true;\n }\n\n async clearQueue(threadId: string): Promise<number> {\n const count = this.queues.get(threadId)?.length ?? 0;\n this.queues.delete(threadId);\n return count;\n }\n\n async queuePause(threadId: string): Promise<QueuePause | null> {\n return this.pauses.get(threadId) ?? null;\n }\n\n async setQueuePause(threadId: string, pause: QueuePause | null): Promise<void> {\n if (pause === null) {\n this.pauses.delete(threadId);\n } else {\n this.pauses.set(threadId, pause);\n }\n }\n\n private findQueued(\n id: string,\n ): { queue: QueuedMessage[]; position: number; message: QueuedMessage } | undefined {\n for (const queue of this.queues.values()) {\n const position = queue.findIndex((message) => message.id === id);\n const message = queue[position];\n if (message !== undefined) {\n return { queue, position, message };\n }\n }\n return undefined;\n }\n\n async getThreadActionProposalScope(threadId: string): Promise<ActionProposalScope | null> {\n const row = this.threads.get(threadId);\n return row ? { threadId, actorRef: row.actorRef, tenantRef: row.tenantRef } : null;\n }\n async admitActionProposalOutcome(\n command: ActionProposalOutcomeLease,\n ): ReturnType<ActionProposalOutcomeStore['admitActionProposalOutcome']> {\n const row = [...this.rows.values()].find((row) => row.outcome?.id === command.outcomeId);\n if (!row?.outcome || !row.outcomeDelivery) return { status: 'not_found' };\n if (row.outcomeDelivery.status === 'admitted')\n return {\n status: 'unchanged',\n ...(row.outcomeDelivery.messageId !== undefined\n ? { messageId: row.outcomeDelivery.messageId }\n : {}),\n };\n if (row.outcomeDelivery.status === 'discarded') return { status: 'discarded' };\n if (!actionProposalOutcomeFenceValid(row, command, this.clock())) return { status: 'conflict' };\n const thread = this.threads.get(row.threadId);\n if (!thread) {\n this.rows.set(\n row.id,\n snapshotActionProposal({\n ...row,\n outcomeDelivery: { ...row.outcomeDelivery, status: 'discarded', lease: null },\n }),\n );\n return { status: 'discarded' };\n }\n if (thread.actorRef !== row.actorRef || thread.tenantRef !== row.tenantRef)\n return { status: 'conflict' };\n if (thread.activeStreamId) return { status: 'busy' };\n // No await between checking the thread holder and committing both in-memory mutations.\n const message: StoredMessage = {\n id: crypto.randomUUID(),\n role: 'assistant',\n content: actionProposalOutcomeText(row.outcome),\n createdAt: this.now(),\n actionProposalOutcome: snapshotActionProposal(row.outcome),\n ui: snapshotActionProposal(row.outcome.ui),\n };\n const next = snapshotActionProposal({\n ...row,\n outcomeDelivery: {\n ...row.outcomeDelivery,\n status: 'admitted' as const,\n lease: null,\n messageId: message.id,\n },\n });\n thread.messages.push(message);\n thread.updatedAt = message.createdAt;\n this.rows.set(row.id, next);\n return { status: 'applied', messageId: message.id };\n }\n async appendMessage(input: AppendMessageInput): Promise<StoredMessage> {\n const row = this.threads.get(input.threadId);\n if (row === undefined) {\n throw new Error(`thread ${input.threadId} not found`);\n }\n const message: StoredMessage = {\n id: crypto.randomUUID(),\n role: input.role,\n content: input.content,\n createdAt: this.now(),\n ...(input.toolCalls !== undefined ? { toolCalls: input.toolCalls } : {}),\n ...(input.toolResults !== undefined ? { toolResults: input.toolResults } : {}),\n ...(input.attachments !== undefined ? { attachments: input.attachments } : {}),\n ...(input.followUps !== undefined ? { followUps: input.followUps } : {}),\n ...(input.usage !== undefined ? { usage: input.usage } : {}),\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(input.runId !== undefined ? { runId: input.runId } : {}),\n ...(input.reasoning !== undefined ? { reasoning: input.reasoning } : {}),\n ...(input.reasoningMs !== undefined ? { reasoningMs: input.reasoningMs } : {}),\n ...(input.ui !== undefined ? { ui: input.ui } : {}),\n ...(input.actionProposalOutcome !== undefined\n ? { actionProposalOutcome: input.actionProposalOutcome }\n : {}),\n };\n row.messages.push(message);\n row.updatedAt = message.createdAt;\n return message;\n }\n\n async setMessageToolResults(messageId: string, results: ToolResult[]): Promise<void> {\n for (const row of this.threads.values()) {\n const message = row.messages.find((candidate) => candidate.id === messageId);\n if (message !== undefined) {\n message.toolResults = results;\n return;\n }\n }\n }\n\n async setMessageUi(messageId: string, ui: AgentUiComponent[]): Promise<void> {\n for (const row of this.threads.values()) {\n const index = row.messages.findIndex((candidate) => candidate.id === messageId);\n const message = row.messages[index];\n if (message !== undefined) {\n const { ui: _previous, ...rest } = message;\n row.messages[index] = ui.length > 0 ? { ...rest, ui } : rest;\n return;\n }\n }\n }\n\n async threadOfMessage(messageId: string): Promise<string | null> {\n return this.threadIdForMessage(messageId) ?? null;\n }\n\n async setMessageFeedback(messageId: string, feedback: MessageFeedback | null): Promise<void> {\n for (const row of this.threads.values()) {\n const index = row.messages.findIndex((candidate) => candidate.id === messageId);\n const message = row.messages[index];\n if (message !== undefined) {\n const { feedback: _previous, ...rest } = message;\n row.messages[index] = feedback !== null ? { ...rest, feedback } : rest;\n return;\n }\n }\n }\n\n async truncateFrom(threadId: string, messageId: string): Promise<void> {\n const row = this.threads.get(threadId);\n if (row === undefined) {\n return;\n }\n const cutoff = row.messages.findIndex((message) => message.id === messageId);\n if (cutoff >= 0) {\n row.messages = row.messages.slice(0, cutoff);\n }\n }\n\n /**\n * Of `mediaIds`, the ones a surviving message — or a message waiting in the queue — in one of\n * this actor's threads still carries.\n * Re-derived from the messages each call, so a media whose message was truncated away reads as\n * unreferenced again.\n */\n async referencedMediaIds(actorRef: string, mediaIds: readonly string[]): Promise<string[]> {\n if (mediaIds.length === 0) {\n return [];\n }\n const wanted = new Set(mediaIds);\n const found = new Set<string>();\n for (const thread of this.threads.values()) {\n if (thread.actorRef !== actorRef) {\n continue;\n }\n // A message waiting in the thread's queue carries its attachments too: it has been sent, it\n // just has not run yet — collecting its media would fail the turn it is waiting to start.\n const queued = this.queues.get(thread.id) ?? [];\n for (const message of [...thread.messages, ...queued]) {\n for (const attachment of message.attachments ?? []) {\n if (wanted.has(attachment.mediaId)) {\n found.add(attachment.mediaId);\n }\n }\n }\n }\n return [...wanted].filter((mediaId) => found.has(mediaId));\n }\n\n async recordToolCall(input: RecordToolCallInput): Promise<void> {\n this.toolCalls.set(input.toolCallId, {\n toolCallId: input.toolCallId,\n ...(input.proposalId !== undefined ? { proposalId: input.proposalId } : {}),\n messageId: input.messageId,\n threadId: this.threadIdForMessage(input.messageId) ?? '',\n toolName: input.toolName,\n toolType: input.toolType,\n input: input.input,\n status: input.status,\n createdAt: this.now(),\n ...(input.runId !== undefined ? { runId: input.runId } : {}),\n ...(input.approver !== undefined ? { approver: input.approver } : {}),\n ...(input.confirmation !== undefined\n ? { confirmation: structuredClone(input.confirmation) }\n : {}),\n ...(input.expiresAt !== undefined ? { expiresAt: input.expiresAt } : {}),\n });\n }\n\n async toolCallOutcomes(toolCallIds: readonly string[]): Promise<ToolCallOutcome[]> {\n const outcomes: ToolCallOutcome[] = [];\n for (const id of toolCallIds) {\n const row = this.toolCalls.get(id);\n if (row !== undefined) {\n outcomes.push({\n id,\n status: row.status,\n ...(row.output !== undefined ? { output: row.output } : {}),\n ...(row.error !== undefined ? { error: row.error } : {}),\n });\n }\n }\n return outcomes;\n }\n\n async failUnsettledToolCalls(runId: string, error: string): Promise<number> {\n let settled = 0;\n for (const row of this.toolCalls.values()) {\n if (row.runId === runId && row.status === 'pending_approval') {\n row.status = 'failed';\n row.error = error;\n settled += 1;\n }\n }\n return settled;\n }\n\n async updateToolCall(input: UpdateToolCallInput): Promise<void> {\n const row = this.toolCalls.get(input.toolCallId);\n if (row === undefined) {\n return;\n }\n row.status = input.status;\n if (input.output !== undefined) {\n row.output = input.output;\n }\n if (input.error !== undefined) {\n row.error = input.error;\n }\n if (input.executionMs !== undefined) {\n row.executionMs = input.executionMs;\n }\n if (input.executedByRef !== undefined) {\n row.executedByRef = input.executedByRef;\n }\n if (input.remember !== undefined) {\n row.remember = input.remember;\n }\n if (input.decidedVia !== undefined) {\n row.decidedVia = input.decidedVia;\n }\n }\n\n async recordUsage(input: RecordUsageInput): Promise<void> {\n const createdAt = this.now();\n this.usage.push({\n actorRef: input.actorRef,\n threadId: input.threadId,\n modelId: input.modelId,\n inputTokens: input.usage.inputTokens,\n outputTokens: input.usage.outputTokens,\n day: createdAt.slice(0, 10),\n createdAt,\n ...(input.usage.cacheWriteTokens !== undefined\n ? { cacheWriteTokens: input.usage.cacheWriteTokens }\n : {}),\n ...(input.usage.cacheReadTokens !== undefined\n ? { cacheReadTokens: input.usage.cacheReadTokens }\n : {}),\n ...(input.costUsd !== undefined ? { costUsd: input.costUsd } : {}),\n });\n }\n\n async quotaToday(\n actorRef: string,\n day: string,\n ): Promise<{ usedTokens: number; costUsd: number }> {\n return this.usageBetween(actorRef, day, day);\n }\n\n async usageBetween(\n actorRef: string,\n fromDay: string,\n toDay: string,\n ): Promise<{ usedTokens: number; costUsd: number }> {\n const rows = this.usage.filter(\n (row) => row.actorRef === actorRef && row.day >= fromDay && row.day <= toDay,\n );\n const usedTokens = rows.reduce((sum, row) => sum + row.inputTokens + row.outputTokens, 0);\n const costUsd = rows.reduce((sum, row) => sum + (row.costUsd ?? 0), 0);\n return { usedTokens, costUsd };\n }\n\n /** Test helper: read the recorded usage rows (modelId + token totals). */\n usageRows(): { actorRef: string; tokens: number; modelId: string }[] {\n return this.usage.map((row) => ({\n actorRef: row.actorRef,\n tokens: row.inputTokens + row.outputTokens,\n modelId: row.modelId,\n }));\n }\n\n /** Governance read-model feed: recorded usage rows with the input/output split + thread/day. */\n governanceUsage(): GovernanceUsageRow[] {\n return this.usage.map((row) => ({\n actorRef: row.actorRef,\n threadId: row.threadId,\n modelId: row.modelId,\n inputTokens: row.inputTokens,\n outputTokens: row.outputTokens,\n day: row.day,\n createdAt: row.createdAt,\n ...(row.cacheWriteTokens !== undefined ? { cacheWriteTokens: row.cacheWriteTokens } : {}),\n ...(row.cacheReadTokens !== undefined ? { cacheReadTokens: row.cacheReadTokens } : {}),\n ...(row.costUsd !== undefined ? { costUsd: row.costUsd } : {}),\n }));\n }\n\n /** Governance read-model feed: recorded tool calls with the resolved thread + timestamp. */\n governanceToolCalls(): GovernanceToolCallRow[] {\n return [...this.toolCalls.values()].map((row) => ({\n toolCallId: row.toolCallId,\n toolName: row.toolName,\n toolType: row.toolType,\n status: row.status,\n threadId: row.threadId,\n messageId: row.messageId,\n createdAt: row.createdAt,\n ...(row.executionMs !== undefined ? { executionMs: row.executionMs } : {}),\n ...(row.error !== undefined ? { error: row.error } : {}),\n ...(row.runId !== undefined ? { runId: row.runId } : {}),\n }));\n }\n\n /** Governance read-model feed: every stored message, thread-resolved, for the thread drill-down. */\n governanceMessages(): GovernanceMessageRow[] {\n const rows: GovernanceMessageRow[] = [];\n for (const thread of this.threads.values()) {\n for (const message of thread.messages) {\n rows.push({\n messageId: message.id,\n threadId: thread.id,\n role: message.role,\n content: message.content,\n createdAt: message.createdAt,\n ...(message.agentName !== undefined ? { agentName: message.agentName } : {}),\n });\n }\n }\n return rows;\n }\n\n /**\n * Governance read-model feed: tool calls sitting `pending_approval`, joined to their thread\n * (title/actorRef) and the message that requested them (`agentName`, when the message has one).\n */\n governancePendingApprovals(): GovernancePendingApprovalRow[] {\n const rows: GovernancePendingApprovalRow[] = [];\n for (const call of this.toolCalls.values()) {\n if (call.status !== 'pending_approval') {\n continue;\n }\n const thread = this.threads.get(call.threadId);\n if (thread === undefined) {\n continue;\n }\n const message = thread.messages.find((candidate) => candidate.id === call.messageId);\n rows.push({\n toolCallId: call.toolCallId,\n toolName: call.toolName,\n input: call.input,\n threadId: call.threadId,\n threadTitle: thread.title,\n actorRef: thread.actorRef,\n requestedAt: call.createdAt,\n ...(message?.agentName !== undefined ? { agentName: message.agentName } : {}),\n ...(call.runId !== undefined ? { runId: call.runId } : {}),\n });\n }\n return rows;\n }\n\n /** Governance read-model feed: thread metadata (title/actor/message count/last activity). */\n governanceThreads(): GovernanceThreadRow[] {\n return [...this.threads.values()].map((row) => ({\n threadId: row.id,\n title: row.title,\n actorRef: row.actorRef,\n messageCount: row.messages.length,\n updatedAt: row.updatedAt,\n }));\n }\n\n /** Governance read-model feed: recorded run outcomes (the reliability surfaces). */\n governanceRuns(): GovernanceRunRow[] {\n return [...this.runs.values()].map((row) => ({\n runId: row.runId,\n threadId: row.threadId,\n actorRef: row.actorRef,\n status: row.status,\n retries: row.retries,\n startedAt: row.startedAt,\n ...(row.agentName !== undefined ? { agentName: row.agentName } : {}),\n ...(row.parentRunId !== undefined ? { parentRunId: row.parentRunId } : {}),\n ...(row.durationMs !== undefined ? { durationMs: row.durationMs } : {}),\n ...(row.errorCode !== undefined ? { errorCode: row.errorCode } : {}),\n ...(row.errorMessage !== undefined ? { errorMessage: row.errorMessage } : {}),\n ...(row.settledAt !== undefined ? { settledAt: row.settledAt } : {}),\n ...(row.promptHash !== undefined ? { promptHash: row.promptHash } : {}),\n }));\n }\n\n private threadIdForMessage(messageId: string): string | undefined {\n for (const [threadId, row] of this.threads) {\n if (row.messages.some((message) => message.id === messageId)) {\n return threadId;\n }\n }\n return undefined;\n }\n\n /** Test helper: read the recorded tool-call rows. */\n toolCallRows(): {\n toolCallId: string;\n toolName: string;\n toolType: 'read' | 'action';\n status: ToolCallStatus;\n input?: unknown;\n output?: unknown;\n error?: string;\n runId?: string;\n executedByRef?: string;\n approver?: string;\n expiresAt?: string;\n remember?: boolean;\n decidedVia?: string;\n }[] {\n return [...this.toolCalls.values()].map((row) => ({\n toolCallId: row.toolCallId,\n toolName: row.toolName,\n toolType: row.toolType,\n status: row.status,\n input: row.input,\n ...(row.output !== undefined ? { output: row.output } : {}),\n ...(row.error !== undefined ? { error: row.error } : {}),\n ...(row.runId !== undefined ? { runId: row.runId } : {}),\n ...(row.executedByRef !== undefined ? { executedByRef: row.executedByRef } : {}),\n ...(row.approver !== undefined ? { approver: row.approver } : {}),\n ...(row.expiresAt !== undefined ? { expiresAt: row.expiresAt } : {}),\n ...(row.remember !== undefined ? { remember: row.remember } : {}),\n ...(row.decidedVia !== undefined ? { decidedVia: row.decidedVia } : {}),\n }));\n }\n\n private toSummary(row: ThreadRow): ThreadSummary {\n const last = row.messages[row.messages.length - 1];\n return {\n id: row.id,\n title: row.title,\n transient: row.transient,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n ...(last !== undefined ? { lastMessagePreview: last.content.slice(0, 120) } : {}),\n defaultAgent: row.defaultAgent ?? null,\n ...(row.model != null ? { model: row.model } : {}),\n persona: row.persona ?? null,\n };\n }\n}\n","import { createHash, createHmac, timingSafeEqual } from 'node:crypto';\nimport type { ConfirmTokenClaim, ConfirmTokenStore } from './spi/confirm-token-store.js';\n\n/** How long a preview stays confirmable unless the tool says otherwise. */\nexport const DEFAULT_CONFIRM_TTL_MS = 15 * 60 * 1000;\n\n/** What a confirm token is bound to. Change any of it and the token stops matching. */\nexport interface ConfirmTokenSubject {\n /** The tool's name. */\n tool: string;\n /** `ctx.actor.id`. */\n actorId: string;\n /** `ctx.actor.tenantRef`; absent and `''` sign the same. */\n tenantRef?: string;\n /** The call's arguments, WITHOUT `confirm` / `confirmToken`. */\n args: unknown;\n}\n\n/**\n * JSON with object keys sorted at every depth, so two argument objects that differ only in key\n * order produce the same text. `undefined` properties are dropped (as `JSON.stringify` does); a\n * bare `undefined` and an `undefined` array element are `null`.\n */\nexport function canonicalJson(value: unknown): string {\n if (value === undefined) return 'null';\n if (value === null || typeof value !== 'object') return JSON.stringify(value) ?? 'null';\n if (Array.isArray(value)) return `[${value.map(canonicalJson).join(',')}]`;\n if (typeof (value as { toJSON?: unknown }).toJSON === 'function') {\n return canonicalJson((value as { toJSON(): unknown }).toJSON());\n }\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([, entry]) => entry !== undefined)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n return `{${entries.map(([key, entry]) => `${JSON.stringify(key)}:${canonicalJson(entry)}`).join(',')}}`;\n}\n\n/** The signed text is itself canonical JSON, so no field can bleed into its neighbour. */\nfunction signature(subject: ConfirmTokenSubject, expiresAt: number, secret: string): string {\n if (secret === '') {\n throw new Error('confirm token: the secret is empty');\n }\n return createHmac('sha256', secret)\n .update(\n canonicalJson([\n 'agent-confirm',\n subject.tool,\n subject.actorId,\n subject.tenantRef ?? '',\n expiresAt,\n subject.args,\n ]),\n )\n .digest('base64url');\n}\n\n/**\n * Issue a confirm token: `<expiresAt>.<signature>`, an HMAC-SHA256 (keyed by `secret`) over the tool,\n * the actor, the tenant, the expiry and the canonical arguments. Stateless — nothing is stored — and\n * useless for another actor, tenant, tool or argument, or after `expiresAt` (epoch-ms).\n */\nexport function signConfirmToken(\n subject: ConfirmTokenSubject,\n options: { secret: string; expiresAt: number },\n): string {\n return `${options.expiresAt}.${signature(subject, options.expiresAt, options.secret)}`;\n}\n\n/** The expiry (epoch-ms) a token carries, or `undefined` for a malformed one. Not a verification. */\nexport function confirmTokenExpiry(token: string): number | undefined {\n const separator = token.indexOf('.');\n if (separator <= 0) return undefined;\n const expiresAt = Number(token.slice(0, separator));\n return Number.isSafeInteger(expiresAt) && expiresAt > 0 ? expiresAt : undefined;\n}\n\n/** Was this token issued for exactly this subject, with this secret, and is it still valid at `now`? */\nexport function verifyConfirmToken(\n token: string | null | undefined,\n subject: ConfirmTokenSubject,\n options: { secret: string; now?: number },\n): boolean {\n if (typeof token !== 'string') return false;\n const expiresAt = confirmTokenExpiry(token);\n if (expiresAt === undefined || expiresAt < (options.now ?? Date.now())) return false;\n const expected = Buffer.from(signature(subject, expiresAt, options.secret));\n const given = Buffer.from(token.slice(token.indexOf('.') + 1));\n return expected.length === given.length && timingSafeEqual(expected, given);\n}\n\n/** SHA-256 (hex) of a token — what a {@link ConfirmTokenStore} keys on, so the token is never stored. */\nexport function hashConfirmToken(token: string): string {\n return createHash('sha256').update(token).digest('hex');\n}\n\n/**\n * A single-process {@link ConfirmTokenStore}: tests, scripts, and a deployment that runs ONE replica.\n * With more than one, a token spent on replica A is still fresh on replica B — use the Drizzle or\n * MikroORM store (`AGENT_CONFIRM_TOKEN_STORE`, bound by their modules).\n * Expired marks are dropped lazily, on the next claim.\n */\nexport class InMemoryConfirmTokenStore implements ConfirmTokenStore {\n private readonly claims = new Map<string, ConfirmTokenClaim>();\n\n async claim(input: ConfirmTokenClaim): Promise<boolean> {\n await this.purgeExpired();\n if (this.claims.has(input.hash)) return false;\n this.claims.set(input.hash, { ...input });\n return true;\n }\n\n async release(hash: string): Promise<void> {\n this.claims.delete(hash);\n }\n\n async purgeExpired(now: number = Date.now()): Promise<number> {\n let purged = 0;\n for (const [hash, claim] of this.claims) {\n if (claim.expiresAt < now) {\n this.claims.delete(hash);\n purged += 1;\n }\n }\n return purged;\n }\n\n /** How many tokens are currently marked as spent. */\n get size(): number {\n return this.claims.size;\n }\n}\n","import type { ChannelStore } from './spi/channel-store.js';\n\n/**\n * Process-local {@link ChannelStore}: a single replica, tests, development. Keeps at most\n * `maxEntries` live keys; past that the oldest writes are forgotten first.\n */\nexport class InMemoryChannelStore implements ChannelStore {\n readonly #entries = new Map<string, { value: string | null; expiresAt: number }>();\n\n constructor(private readonly maxEntries = 50_000) {}\n\n #live(key: string) {\n const entry = this.#entries.get(key);\n if (entry === undefined) return undefined;\n if (entry.expiresAt > Date.now()) return entry;\n this.#entries.delete(key);\n return undefined;\n }\n\n #put(key: string, value: string | null, ttlMs: number) {\n const now = Date.now();\n this.#entries.delete(key);\n this.#entries.set(key, { value, expiresAt: now + ttlMs });\n if (this.#entries.size <= this.maxEntries) return;\n // Insertion order is write order: the first keys are the oldest.\n for (const [stored, entry] of this.#entries) {\n if (this.#entries.size <= this.maxEntries && entry.expiresAt > now) break;\n this.#entries.delete(stored);\n }\n }\n\n async claim(key: string, ttlMs: number): Promise<boolean> {\n if (this.#live(key) !== undefined) return false;\n this.#put(key, null, ttlMs);\n return true;\n }\n\n async get(key: string): Promise<string | null> {\n return this.#live(key)?.value ?? null;\n }\n\n async set(key: string, value: string, ttlMs: number): Promise<void> {\n this.#put(key, value, ttlMs);\n }\n\n async delete(key: string): Promise<void> {\n this.#entries.delete(key);\n }\n\n async purgeExpired(now: number = Date.now()): Promise<number> {\n let purged = 0;\n for (const [key, entry] of this.#entries) {\n if (entry.expiresAt <= now) {\n this.#entries.delete(key);\n purged += 1;\n }\n }\n return purged;\n }\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport {\n DEFAULT_CONFIRM_TTL_MS,\n confirmTokenExpiry,\n hashConfirmToken,\n signConfirmToken,\n verifyConfirmToken,\n} from './confirm-token.js';\nimport type { ConfirmTokenStore } from './spi/confirm-token-store.js';\nimport type { AiToolCtx, ToolHandler } from './spi/tool.js';\nimport type { ToolSpec } from './types.js';\n\n/** The two fields {@link defineConfirmedTool} adds to a tool's input. */\nexport interface ConfirmFields {\n /** `true` to commit; absent (or `false`) to preview. */\n confirm?: boolean;\n /** The `confirmToken` the preview returned. */\n confirmToken?: string;\n}\n\n/** The words a confirmed tool says to the model. Each has an English default. */\nexport interface ConfirmedToolMessages {\n /** Sent with every preview: how to confirm. `{minutes}` is replaced with the token's lifetime. */\n confirm?: string;\n /** Thrown for a missing, tampered, mismatched or expired token. */\n invalid?: string;\n /** Thrown for a token that already committed. */\n used?: string;\n}\n\nconst DEFAULT_MESSAGES: Required<ConfirmedToolMessages> = {\n confirm:\n 'Nothing was written. Show this preview to the user and ask them to confirm. To commit, call this tool again with the SAME arguments plus \"confirm\": true and this \"confirmToken\" (valid for {minutes} minutes).',\n invalid:\n 'Invalid or expired confirmation: nothing was written. Call the tool without \"confirm\" to get a fresh preview, then confirm with the \"confirmToken\" it returns, without changing the arguments.',\n used: 'This preview was already confirmed: nothing was written again. To repeat the operation, ask for a new preview.',\n};\n\n/** Thrown by a confirmed tool that refused a confirmation. Nothing was written. */\nexport class ConfirmTokenError extends Error {\n constructor(\n /** `invalid`: missing, tampered, mismatched or expired. `used`: it already committed once. */\n readonly reason: 'invalid' | 'used',\n message: string,\n ) {\n super(message);\n this.name = 'ConfirmTokenError';\n }\n}\n\n/** What {@link defineConfirmedTool} takes: the usual spec fields (no `kind`), plus the gate's own. */\nexport interface ConfirmedToolOptions\n extends Omit<ToolSpec, 'kind' | 'inputSchema' | 'targetAgent' | 'detached' | 'terminal'> {\n /** The app's own input schema. `confirm` / `confirmToken` are added by {@link withConfirmFields}. */\n input: StandardSchemaV1;\n /**\n * The HMAC key the tokens are signed with — the app's secret (`ConfigService.getOrThrow(...)`), or\n * one of its own. A function is read on every call. Required: there is no default, and an empty\n * one throws.\n */\n secret: string | (() => string);\n /** How long a preview stays confirmable. Default 15 minutes. */\n ttlMs?: number;\n /**\n * Makes a token single use. WITHOUT a store a token commits as many times as it is sent until it\n * expires — a retry or a repeated call writes twice. The store modules bind one to\n * `AGENT_CONFIRM_TOKEN_STORE`; `InMemoryConfirmTokenStore` is for one replica.\n */\n store?: ConfirmTokenStore;\n messages?: ConfirmedToolMessages;\n}\n\n/** What a step reports: a sentence for the model to relay, and the structured detail behind it. */\nexport interface ConfirmedToolOutcome {\n summary: string;\n data?: unknown;\n}\n\n/** The three steps of a confirmed write. */\nexport interface ConfirmedToolSteps<Args, Prepared> {\n /**\n * Resolve and validate everything the write needs, applying the SAME rules the commit relies on.\n * Throw to refuse. Writes nothing. Runs for the preview AND again for the confirmation — state may\n * have changed in between — and a refusal here does not spend the token.\n */\n prepare(args: Args, ctx: AiToolCtx): Promise<Prepared> | Prepared;\n /** What is about to happen. Writes nothing. */\n preview(prepared: Prepared, ctx: AiToolCtx): Promise<ConfirmedToolOutcome> | ConfirmedToolOutcome;\n /** Write, and say what was written. A throw gives the token back. */\n commit(prepared: Prepared, ctx: AiToolCtx): Promise<ConfirmedToolOutcome> | ConfirmedToolOutcome;\n}\n\n/** A confirmed tool's answer to a call without `confirm`. */\nexport interface ConfirmedToolPreview {\n status: 'preview';\n summary: string;\n data?: unknown;\n confirmToken: string;\n /** ISO-8601 instant the token stops working. */\n expiresAt: string;\n /** Instructions for the model: show the preview, then call again with the token. */\n confirm: string;\n}\n\n/** A confirmed tool's answer to a confirmation that committed. */\nexport interface ConfirmedToolDone {\n status: 'done';\n summary: string;\n data?: unknown;\n}\n\nexport type ConfirmedToolResult = ConfirmedToolPreview | ConfirmedToolDone;\n\n/** The JSON Schema of {@link ConfirmFields}, merged into the schema the model is shown. */\nexport const CONFIRM_JSON_SCHEMA_PROPERTIES = {\n confirm: {\n type: 'boolean',\n description:\n 'Omit to get a preview (nothing is written). Send true, with confirmToken, to commit.',\n },\n confirmToken: {\n type: 'string',\n description: 'The confirmToken the preview returned. Required when confirm is true.',\n },\n} as const;\n\n/**\n * Marks a schema that is ANOTHER schema plus a few JSON Schema properties. A converter that knows the\n * inner schema better than the wrapper can (a Zod 3 schema has no Standard JSON Schema extension, so\n * only the AI SDK's or the MCP SDK's own converter can describe it) converts `base` and adds\n * `properties`. `@dudousxd/nestjs-agent-ai-sdk` and `-mcp-server` both read it.\n */\nexport const SCHEMA_EXTENSION = Symbol.for('@dudousxd/nestjs-agent:schema-extension');\n\nexport interface SchemaExtension {\n base: StandardSchemaV1;\n properties: Record<string, unknown>;\n}\n\n/** The {@link SchemaExtension} a schema carries, if any. */\nexport function schemaExtensionOf(schema: StandardSchemaV1): SchemaExtension | undefined {\n const extension = (schema as { [SCHEMA_EXTENSION]?: unknown })[SCHEMA_EXTENSION];\n return typeof extension === 'object' && extension !== null\n ? (extension as SchemaExtension)\n : undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Split a call's input into the app's arguments and the two confirmation fields. */\nfunction splitConfirm(input: unknown): { args: unknown; fields: ConfirmFields } {\n if (!isRecord(input)) return { args: input, fields: {} };\n const { confirm, confirmToken, ...args } = input;\n return {\n args,\n fields: {\n ...(typeof confirm === 'boolean' ? { confirm } : {}),\n ...(typeof confirmToken === 'string' ? { confirmToken } : {}),\n },\n };\n}\n\ntype JsonSchemaConverter = (options?: unknown) => Record<string, unknown>;\n\n/** The schema's Standard JSON Schema `input` converter, when it has one. */\nfunction jsonSchemaInputOf(schema: StandardSchemaV1): JsonSchemaConverter | undefined {\n const standard = schema['~standard'] as { jsonSchema?: { input?: unknown } };\n const input = standard.jsonSchema?.input;\n return typeof input === 'function'\n ? (options) => (input as JsonSchemaConverter).call(standard.jsonSchema, options)\n : undefined;\n}\n\n/**\n * Wrap a tool's input schema so it also accepts {@link ConfirmFields}, without the app declaring\n * them. `validate` takes the two fields off, checks them itself, hands the REST to the app's schema\n * (so a strict schema never sees a key it did not declare) and puts them back on the validated value.\n *\n * The wrapper always carries the Standard JSON Schema extension: the app schema's own JSON Schema\n * plus the two properties. A schema without the extension (Zod 3, a bare Standard Schema) degrades\n * there to a permissive object that still declares the two fields — but the wrapper also carries a\n * {@link SchemaExtension}, so the AI SDK adapter and the MCP server convert a Zod 3 schema with their\n * own converters and show the model its real shape. `validate` stays the authority either way.\n */\nexport function withConfirmFields<Schema extends StandardSchemaV1>(\n schema: Schema,\n): StandardSchemaV1<\n StandardSchemaV1.InferInput<Schema> & ConfirmFields,\n StandardSchemaV1.InferOutput<Schema> & ConfirmFields\n> {\n const inner = schema['~standard'];\n const innerJsonSchema = jsonSchemaInputOf(schema);\n const describe = (options?: unknown): Record<string, unknown> => {\n const base = innerJsonSchema?.(options) ?? { additionalProperties: true };\n return {\n ...base,\n type: 'object',\n properties: {\n ...(isRecord(base.properties) ? base.properties : {}),\n ...CONFIRM_JSON_SCHEMA_PROPERTIES,\n },\n };\n };\n const wrapped = {\n [SCHEMA_EXTENSION]: { base: schema, properties: CONFIRM_JSON_SCHEMA_PROPERTIES },\n '~standard': {\n version: 1,\n vendor: '@dudousxd/nestjs-agent',\n validate: async (value: unknown) => {\n if (!isRecord(value)) {\n return { issues: [{ message: 'expected an object' }] };\n }\n const issues: StandardSchemaV1.Issue[] = [];\n // `null` is how some models say \"absent\"; it is read as absent rather than refused.\n if (value.confirm != null && typeof value.confirm !== 'boolean') {\n issues.push({ message: 'expected a boolean', path: ['confirm'] });\n }\n if (value.confirmToken != null && typeof value.confirmToken !== 'string') {\n issues.push({ message: 'expected a string', path: ['confirmToken'] });\n }\n const { args, fields } = splitConfirm(value);\n const result = await inner.validate(args);\n if (result.issues !== undefined) {\n return { issues: [...issues, ...result.issues] };\n }\n if (issues.length > 0) {\n return { issues };\n }\n return { value: isRecord(result.value) ? { ...result.value, ...fields } : result.value };\n },\n jsonSchema: { input: describe, output: describe },\n },\n };\n return wrapped as unknown as StandardSchemaV1<\n StandardSchemaV1.InferInput<Schema> & ConfirmFields,\n StandardSchemaV1.InferOutput<Schema> & ConfirmFields\n >;\n}\n\n/**\n * A write with a human gate that lives INSIDE the tool: preview first, commit on confirmation.\n *\n * - Called without `confirm`: runs `prepare`, writes nothing, and returns the `preview` with a signed\n * `confirmToken`.\n * - Called again with the SAME arguments, `confirm: true` and that token: runs `prepare` again, then\n * `commit`.\n *\n * The token is an HMAC over the tool, `ctx.actor.id`, `ctx.actor.tenantRef`, the expiry and the\n * canonical arguments, so it cannot be replayed by another actor, in another tenant, on another\n * tool or with a changed argument. With a `store` it is also single use: it is claimed right before\n * `commit` (a refusal in `prepare` does not spend it) and released if `commit` throws.\n *\n * Registered as `kind: 'read'` on purpose. An `action` parks on the loop's HITL approval, which an\n * MCP caller cannot answer — `AgentMcpServerModule` keeps `action` tools off the surface, and MCP clients\n * without elicitation have no other channel. The gate being in the handler is what lets the same\n * tool serve the chat loop and MCP; the user sees the preview because the model has to relay it to\n * get a token it can confirm with.\n *\n * ```ts\n * provideAgentTool(\n * (store: ConfirmTokenStore, config: ConfigService, orders: OrdersService) =>\n * defineConfirmedTool(\n * { name: 'refund_order', description: '...', input: z.object({ orderId: z.string() }),\n * secret: () => config.getOrThrow('CONFIRM_SECRET'), store },\n * {\n * prepare: ({ orderId }, ctx) => orders.loadRefundable(orderId, ctx.actor),\n * preview: (order) => ({ summary: `Refund ${order.total} to ${order.customer}?`, data: order }),\n * commit: async (order) => ({ summary: 'Refunded.', data: await orders.refund(order) }),\n * },\n * ),\n * [AGENT_CONFIRM_TOKEN_STORE, ConfigService, OrdersService],\n * );\n * ```\n *\n * `input` is the app's own schema: `confirm` and `confirmToken` are added by\n * {@link withConfirmFields}, and `prepare` receives the arguments without them.\n */\nexport function defineConfirmedTool<Args = unknown, Prepared = unknown>(\n options: ConfirmedToolOptions,\n steps: ConfirmedToolSteps<Args, Prepared>,\n): ConfirmedTool {\n const { secret, ttlMs = DEFAULT_CONFIRM_TTL_MS, store, messages, input, ...specFields } = options;\n const text = { ...DEFAULT_MESSAGES, ...messages };\n const howToConfirm = text.confirm.replaceAll('{minutes}', String(Math.round(ttlMs / 60_000)));\n const secretNow = () => (typeof secret === 'function' ? secret() : secret);\n\n const handler: ToolHandler = {\n async execute(value: unknown, ctx: AiToolCtx): Promise<ConfirmedToolResult> {\n const { args, fields } = splitConfirm(value);\n const subject = {\n tool: options.name,\n actorId: ctx.actor.id,\n ...(ctx.actor.tenantRef !== undefined ? { tenantRef: ctx.actor.tenantRef } : {}),\n args,\n };\n const confirming = fields.confirm === true;\n const token = fields.confirmToken;\n if (confirming && !verifyConfirmToken(token, subject, { secret: secretNow() })) {\n throw new ConfirmTokenError('invalid', text.invalid);\n }\n\n const prepared = await steps.prepare(args as Args, ctx);\n\n if (!confirming || token === undefined) {\n const preview = await steps.preview(prepared, ctx);\n const expiresAt = Date.now() + ttlMs;\n return {\n status: 'preview',\n summary: preview.summary,\n ...(preview.data !== undefined ? { data: preview.data } : {}),\n confirmToken: signConfirmToken(subject, { secret: secretNow(), expiresAt }),\n expiresAt: new Date(expiresAt).toISOString(),\n confirm: howToConfirm,\n };\n }\n\n // Claimed only now: everything `prepare` refuses leaves the token usable, and a commit that\n // throws gives it back so the same preview can be confirmed again.\n const hash = hashConfirmToken(token);\n if (store !== undefined) {\n const claimed = await store.claim({\n hash,\n actorRef: ctx.actor.id,\n tool: options.name,\n expiresAt: confirmTokenExpiry(token) ?? Date.now() + ttlMs,\n });\n if (!claimed) {\n throw new ConfirmTokenError('used', text.used);\n }\n }\n try {\n const done = await steps.commit(prepared, ctx);\n return {\n status: 'done',\n summary: done.summary,\n ...(done.data !== undefined ? { data: done.data } : {}),\n };\n } catch (error) {\n // The commit's own error is the one worth reporting, whatever the release does.\n await store?.release(hash).catch(() => undefined);\n throw error;\n }\n },\n };\n return {\n spec: { ...specFields, kind: 'read', inputSchema: withConfirmFields(input) },\n handler,\n };\n}\n\n/**\n * What {@link defineConfirmedTool} returns: a functional tool (`{ spec, handler }`) — pass it to\n * `AgentModule.forRoot({ tools })`, or build it in `provideAgentTool(factory, inject)` when it\n * needs injected services (the confirm-token store, the secret from `ConfigService`).\n */\nexport interface ConfirmedTool {\n spec: ToolSpec;\n handler: ToolHandler;\n}\n","import {\n AgentStreamError,\n type SinkWriter,\n type StreamError,\n type TokenStreamSink,\n} from './spi/token-stream-sink.js';\nimport { encodeStreamEvent } from './stream-events.js';\n\n/** One stored row of a run's stream. `frame` is `null` on the terminal row. */\nexport interface StreamFrameRow {\n seq: number;\n /** One NDJSON line (`{...}\\n`) as the writer wrote it; `null` marks the end of the run. */\n frame: string | null;\n /** On the terminal row of a FAILED run: the `StreamError` as JSON. `null` otherwise. */\n error: string | null;\n}\n\n/**\n * The table a {@link SqlTokenStreamSink} keeps its rows in — the only part of it that speaks SQL, so\n * a store package implements this and inherits the rest (coalescing, ordering, polling, TTL).\n * `@dudousxd/nestjs-agent-store-drizzle` and `-store-mikro-orm` ship one each, over\n * `agent_stream_frame` (`run_id`, `seq`, `frame`, `error`, `created_at`; primary key\n * `(run_id, seq)`).\n */\nexport interface StreamFrameTable {\n /**\n * Insert the run's NEXT row: `seq = MAX(seq) + 1` for the run, taken in the SAME statement as the\n * insert, so the `(run_id, seq)` primary key settles two writers that ask at once. Throws on that\n * collision ({@link isUniqueViolation} says which errors are one) — the sink retries.\n */\n append(\n runId: string,\n row: { frame: string | null; error: string | null; createdAt: number },\n ): Promise<void>;\n /** The run's rows with `seq > after`, ascending, at most `limit`. */\n read(runId: string, after: number, limit: number): Promise<StreamFrameRow[]>;\n /** Does the table hold any row for the run? */\n has(runId: string): Promise<boolean>;\n /** Delete every row of these runs. */\n remove(runIds: readonly string[]): Promise<void>;\n /** Runs whose LAST row was written before `cutoff` (epoch-ms). */\n lapsedRuns(cutoff: number): Promise<string[]>;\n /**\n * Is this error a lost race for a `(run_id, seq)` — a duplicate key, or the database rolling this\n * writer back as a deadlock victim (InnoDB's way of settling two concurrent `INSERT … SELECT`) —\n * and nothing else (a missing table, a dead connection)?\n */\n isUniqueViolation(error: unknown): boolean;\n}\n\nexport interface SqlTokenStreamSinkOptions {\n /**\n * Gap (ms) between two reads of a run a subscriber is following — the most a frame waits in the\n * table before a browser sees it. Default 250.\n */\n pollIntervalMs?: number;\n /**\n * Gap (ms) between two reads once the run has written nothing for five seconds (parked on a\n * person, a slow tool), so an open SSE connection on a quiet run costs one query a second. The\n * first frame to arrive puts the subscriber back on `pollIntervalMs`. Default 1000; never below\n * `pollIntervalMs`.\n */\n idlePollIntervalMs?: number;\n /**\n * Window (ms) consecutive `text` frames are gathered over and written as ONE row — a model\n * streams token by token, and a row per token is more writes than a database should take for a\n * chat answer. Any other frame, `end()`, `fail()` and `flush()` write what is gathered first, so\n * order is kept. Default 50. `0` writes every frame as its own row.\n */\n flushMs?: number;\n /**\n * TTL (seconds) of a run's rows, counted from its LAST write — a long run stays, a run that\n * crashed without ending still lapses. {@link SqlTokenStreamSink.purgeExpired} deletes them.\n * Default 3600 (1h). `0` keeps rows until `close()`.\n */\n ttlSeconds?: number;\n /**\n * Purge lapsed runs as a side effect of ending a run, at most once a minute, so the table stays\n * bounded in an app that never schedules {@link SqlTokenStreamSink.purgeExpired}. Default `true`.\n */\n autoPurge?: boolean;\n}\n\nconst DEFAULT_TTL_SECONDS = 3600;\nconst DEFAULT_POLL_INTERVAL_MS = 250;\nconst DEFAULT_IDLE_POLL_INTERVAL_MS = 1000;\nconst IDLE_AFTER_MS = 5000;\nconst DEFAULT_FLUSH_MS = 50;\nconst READ_PAGE = 500;\nconst PURGE_CHUNK = 200;\nconst AUTO_PURGE_EVERY_MS = 60_000;\nconst APPEND_ATTEMPTS = 8;\n\n/** One run's write side in this process: the text being gathered, and the writes already queued. */\ninterface RunWrites {\n text: string | null;\n timer: ReturnType<typeof setTimeout> | undefined;\n /** Settles when every write queued so far has been attempted. Never rejects. */\n tail: Promise<void>;\n pending: number;\n /** A gathered write that failed on its timer, with nobody awaiting it — raised by the next call. */\n failure: { error: unknown } | undefined;\n}\n\nconst decoder = new TextDecoder();\nconst encoder = new TextEncoder();\nconst sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\n\n/** The text of a chunk that is exactly one `{\"kind\":\"text\",\"text\":…}` line, else `null`. */\nfunction textOf(line: string): string | null {\n if (!line.startsWith('{\"kind\":\"text\"')) return null;\n try {\n const parsed: unknown = JSON.parse(line);\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n Object.keys(parsed).length === 2 &&\n (parsed as { kind?: unknown }).kind === 'text' &&\n typeof (parsed as { text?: unknown }).text === 'string'\n ) {\n return (parsed as { text: string }).text;\n }\n } catch {\n /* not one event: stored as written */\n }\n return null;\n}\n\n/**\n * A multi-replica {@link TokenStreamSink} over the app's SQL database — for a deployment with\n * several replicas and NO Redis. The replica running the turn appends each frame as a row; any\n * replica serves the run's SSE by reading the rows past its cursor, in order, until the terminal\n * row. A late subscriber replays from the first row, as with the in-process and Redis sinks, and a\n * run that `fail()`ed throws its {@link AgentStreamError} after the replay.\n *\n * Two things differ from the Redis sink, both the price of having no broker:\n *\n * - **Delivery is polled** — a frame waits up to `pollIntervalMs` before a browser sees it.\n * - **Text is coalesced on the way in.** Consecutive `text` frames written within `flushMs` are\n * stored as ONE `text` frame. The stored rows ARE the run's stream: every subscriber, on every\n * replica, reads the same rows in the same order, so the SSE ids `chat/:runId/stream` numbers\n * them with — and an `?after=` cursor — stay exact across replicas.\n *\n * Sequence numbers are per run, start at 1 and have no gaps (see {@link StreamFrameTable.append}).\n * Text a writer is still gathering lives in the process for at most `flushMs`; a process that dies\n * in that window loses it from the LIVE stream (the persisted message is unaffected).\n *\n * Framework- and dialect-free: the SQL is the {@link StreamFrameTable}'s. Use\n * `DrizzleTokenStreamSink` / `MikroOrmTokenStreamSink` from the store packages.\n */\nexport class SqlTokenStreamSink implements TokenStreamSink {\n private readonly pollIntervalMs: number;\n private readonly idlePollIntervalMs: number;\n private readonly flushMs: number;\n private readonly ttlSeconds: number;\n private readonly autoPurge: boolean;\n private readonly writes = new Map<string, RunWrites>();\n private lastAutoPurge = 0;\n\n constructor(\n private readonly table: StreamFrameTable,\n options: SqlTokenStreamSinkOptions = {},\n ) {\n this.pollIntervalMs = Math.max(1, options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);\n this.idlePollIntervalMs = Math.max(\n this.pollIntervalMs,\n options.idlePollIntervalMs ?? DEFAULT_IDLE_POLL_INTERVAL_MS,\n );\n this.flushMs = Math.max(0, options.flushMs ?? DEFAULT_FLUSH_MS);\n this.ttlSeconds = options.ttlSeconds ?? DEFAULT_TTL_SECONDS;\n this.autoPurge = options.autoPurge ?? true;\n }\n\n private runWrites(runId: string): RunWrites {\n let state = this.writes.get(runId);\n if (state === undefined) {\n state = {\n text: null,\n timer: undefined,\n tail: Promise.resolve(),\n pending: 0,\n failure: undefined,\n };\n this.writes.set(runId, state);\n }\n return state;\n }\n\n /** Forget a run's write state once nothing is gathered, queued or left to report. */\n private release(runId: string, state: RunWrites): void {\n if (\n state.pending === 0 &&\n state.text === null &&\n state.failure === undefined &&\n this.writes.get(runId) === state\n ) {\n this.writes.delete(runId);\n }\n }\n\n /** Queue `work` behind every write already queued for the run, so rows land in call order. */\n private enqueue(runId: string, state: RunWrites, work: () => Promise<void>): Promise<void> {\n state.pending += 1;\n const next = state.tail.then(work);\n state.tail = next\n .then(\n () => undefined,\n () => undefined,\n )\n .then(() => {\n state.pending -= 1;\n this.release(runId, state);\n });\n return next;\n }\n\n /** Queue the gathered text (if any) as one `text` row. */\n private flushText(runId: string, state: RunWrites): Promise<void> {\n if (state.timer !== undefined) {\n clearTimeout(state.timer);\n state.timer = undefined;\n }\n if (state.text === null) return Promise.resolve();\n const line = decoder.decode(encodeStreamEvent({ kind: 'text', text: state.text }));\n state.text = null;\n return this.enqueue(runId, state, () => this.append(runId, line, null));\n }\n\n /** Raise, once, a gathered write that failed with nobody awaiting it. */\n private raiseFailure(state: RunWrites): void {\n const failure = state.failure;\n if (failure !== undefined) {\n state.failure = undefined;\n throw failure.error;\n }\n }\n\n /** Append one row — a frame, or the terminal row (`frame: null`, with `error` on a failure). */\n private async append(runId: string, frame: string | null, error: string | null): Promise<void> {\n for (let attempt = 1; ; attempt += 1) {\n try {\n await this.table.append(runId, { frame, error, createdAt: Date.now() });\n return;\n } catch (caught) {\n if (attempt >= APPEND_ATTEMPTS || !this.table.isUniqueViolation(caught)) throw caught;\n }\n }\n }\n\n /** Write out what is gathered, then a terminal row; raise a failure nobody saw. */\n private async terminate(runId: string, error: string | null): Promise<void> {\n const state = this.runWrites(runId);\n const flushed = this.flushText(runId, state);\n const ended = this.enqueue(runId, state, () => this.append(runId, null, error));\n await Promise.all([flushed, ended]);\n this.raiseFailure(state);\n this.release(runId, state);\n this.purgeInBackground();\n }\n\n /**\n * The run's writer. Writers opened for the same run in one process share what they are gathering,\n * so a delegated run's text (forwarded through a child writer) and its parent's next frame keep\n * the order they were written in.\n */\n open(runId: string): SinkWriter {\n return {\n write: async (chunk: Uint8Array) => {\n const state = this.runWrites(runId);\n this.raiseFailure(state);\n const line = decoder.decode(chunk);\n const text = this.flushMs > 0 ? textOf(line.trimEnd()) : null;\n if (text !== null) {\n state.text = (state.text ?? '') + text;\n // Counted from the FIRST gathered token, not the last: a steady stream still reaches the\n // table every `flushMs`, instead of being held for as long as the model keeps talking.\n if (state.timer === undefined) {\n state.timer = setTimeout(() => {\n state.timer = undefined;\n this.flushText(runId, state).catch((error: unknown) => {\n state.failure = { error };\n });\n }, this.flushMs);\n }\n return;\n }\n const flushed = this.flushText(runId, state);\n const appended = this.enqueue(runId, state, () => this.append(runId, line, null));\n await Promise.all([flushed, appended]);\n },\n flush: async () => {\n const state = this.runWrites(runId);\n const flushed = this.flushText(runId, state);\n await Promise.all([flushed, state.tail]);\n this.raiseFailure(state);\n this.release(runId, state);\n },\n end: () => this.terminate(runId, null),\n fail: (error: StreamError) =>\n this.terminate(runId, JSON.stringify({ code: error.code, message: error.message })),\n };\n }\n\n async *subscribe(runId: string): AsyncIterable<Uint8Array> {\n let cursor = 0;\n let quietSince = Date.now();\n while (true) {\n const rows = await this.table.read(runId, cursor, READ_PAGE);\n for (const row of rows) {\n cursor = row.seq;\n if (row.frame === null) {\n if (row.error !== null) {\n throw new AgentStreamError(JSON.parse(row.error) as StreamError);\n }\n return;\n }\n yield encoder.encode(row.frame);\n }\n if (rows.length > 0) {\n quietSince = Date.now();\n // A full page means there may be more already written: read on without waiting.\n if (rows.length >= READ_PAGE) continue;\n }\n await sleep(\n Date.now() - quietSince >= IDLE_AFTER_MS ? this.idlePollIntervalMs : this.pollIntervalMs,\n );\n }\n }\n\n /** Does the table hold anything for the run — a frame, or its end? */\n has(runId: string): Promise<boolean> {\n return this.table.has(runId);\n }\n\n async close(runId: string): Promise<void> {\n const state = this.writes.get(runId);\n if (state !== undefined) {\n if (state.timer !== undefined) clearTimeout(state.timer);\n state.timer = undefined;\n state.text = null;\n state.failure = undefined;\n await state.tail;\n this.writes.delete(runId);\n }\n await this.table.remove([runId]);\n }\n\n /**\n * Delete every run whose last write is older than `ttlSeconds` at `now` (epoch-ms) — ended runs\n * past their replay window and runs that crashed without ending alike. Returns how many runs went.\n * Safe from any replica, and from several at once. A no-op under `ttlSeconds: 0`.\n */\n async purgeExpired(now: number = Date.now()): Promise<number> {\n if (this.ttlSeconds <= 0) return 0;\n const lapsed = await this.table.lapsedRuns(now - this.ttlSeconds * 1000);\n for (let index = 0; index < lapsed.length; index += PURGE_CHUNK) {\n await this.table.remove(lapsed.slice(index, index + PURGE_CHUNK));\n }\n return lapsed.length;\n }\n\n /** {@link purgeExpired}, unawaited and at most once a minute. Its failure is not the run's. */\n private purgeInBackground(): void {\n if (!this.autoPurge || this.ttlSeconds <= 0) return;\n const now = Date.now();\n if (now - this.lastAutoPurge < AUTO_PURGE_EVERY_MS) return;\n this.lastAutoPurge = now;\n this.purgeExpired(now).catch(() => {\n // Retried after the next run ends; a purge that cannot run must not fail a finished turn.\n });\n }\n}\n","import type {\n ActionProposalDecision,\n ActionProposalMutationResult,\n} from './spi/action-proposal-store.js';\n\nexport interface TextActionProposalCandidate {\n id: string;\n decision: ActionProposalDecision;\n}\nexport type TextActionProposalResolution =\n | { status: 'unmatched' }\n | { status: 'ambiguous'; proposalIds: string[] }\n | {\n status: 'decision';\n proposalId: string;\n decision: 'approved' | 'rejected';\n remember: boolean;\n };\n\n/**\n * Recognizes complete, explicit decision messages. This grants no authority: callers must\n * resolve the authenticated actor and use the normal scoped decision service with via=text.\n * Never feed model output here or consume an unmatched message as an approval.\n */\nexport function resolveTextActionProposalDecision(\n text: string,\n proposals: readonly TextActionProposalCandidate[],\n vocabulary?: TextActionProposalVocabulary,\n): TextActionProposalResolution {\n const command = parseTextActionProposalCommand(text, vocabulary);\n if (command.status === 'unmatched') return command;\n const { decision, remember } = command;\n const pending = proposals.filter((proposal) => proposal.decision === 'pending');\n const explicitId = command.proposalId;\n if (explicitId !== undefined) {\n if (!pending.some((proposal) => proposal.id === explicitId)) return { status: 'unmatched' };\n return { status: 'decision', proposalId: explicitId, decision, remember };\n }\n if (pending.length === 0) return { status: 'unmatched' };\n if (pending.length > 1) return { status: 'ambiguous', proposalIds: pending.map(({ id }) => id) };\n const candidate = pending[0];\n if (!candidate) return { status: 'unmatched' };\n return { status: 'decision', proposalId: candidate.id, decision, remember };\n}\n\nexport type TextActionProposalCommand =\n | { status: 'unmatched' }\n | {\n status: 'command';\n decision: 'approved' | 'rejected';\n remember: boolean;\n proposalId?: string;\n };\n\n/**\n * The words a whole chat message must consist of to decide a proposal by text. Matched\n * case-insensitively, as the complete message (an optional trailing `.`/`!`, an optional `#ID`).\n */\nexport interface TextActionProposalVocabulary {\n /** Approve, e.g. `sim`, `yes`. */\n approve: readonly string[];\n /** Reject, e.g. `não`, `no`. */\n reject: readonly string[];\n /** The phrase after an approve word that also approves later calls of the tool in this thread. */\n remember: readonly string[];\n}\n\n/**\n * English. Portuguese ships as {@link ptBrActionProposalText}; any other language through\n * `AgentModule.forRoot({ actionProposalText })`.\n */\nexport const DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY: TextActionProposalVocabulary = {\n approve: ['yes', 'confirm', 'approve', 'approved', 'ok'],\n reject: ['no', 'cancel', 'reject', 'deny'],\n remember: ['always in this conversation'],\n};\n\n/** What the agent answers to a text decision. Every field has an English default. */\nexport interface TextActionProposalReplies {\n approved: string;\n rejected: string;\n expired: string;\n /** The proposal could not change (already decided by someone else, superseded, …). */\n unchanged: string;\n /** More than one pending proposal could be meant: ask for the `#ID`. */\n ambiguous(proposalIds: readonly string[]): string;\n /** Too many pending proposals to pick one without an explicit `#ID`. */\n tooMany: string;\n}\n\nexport const DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES: TextActionProposalReplies = {\n approved: 'Proposal approved and queued to run.',\n rejected: 'Proposal rejected; nothing was run.',\n expired: 'The proposal expired; nothing was run.',\n unchanged: 'This proposal could not be changed; refresh the list to see where it stands.',\n ambiguous: (ids) => `Which proposal? Reply confirm #ID or cancel #ID: ${ids.join(', ')}`,\n tooMany: 'There are several proposals. Confirm or reject one with an explicit #ID.',\n};\n\n/** `AgentModule.forRoot({ actionProposalText })`: either part replaces the default it names. */\nexport interface TextActionProposalConfig {\n vocabulary?: Partial<TextActionProposalVocabulary>;\n replies?: Partial<TextActionProposalReplies>;\n}\n\n/** The reply to a decision the store answered with `result`. */\nexport function textActionProposalReply(\n result: Pick<ActionProposalMutationResult, 'status'> & {\n proposal?: { decision: ActionProposalDecision };\n },\n decision: 'approved' | 'rejected',\n replies: TextActionProposalReplies = DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES,\n): string {\n return result.status === 'expired' || result.proposal?.decision === 'expired'\n ? replies.expired\n : result.status === 'applied' || result.status === 'unchanged'\n ? decision === 'approved'\n ? replies.approved\n : replies.rejected\n : replies.unchanged;\n}\n\nconst escapeRegExp = (word: string) => word.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\nconst alternatives = (words: readonly string[]) =>\n words\n .map((word) => word.trim())\n .filter((word) => word.length > 0)\n .map((word) => escapeRegExp(word).replace(/\\s+/g, '\\\\s+'))\n .join('|');\nconst fold = (word: string) => word.trim().toLowerCase();\n\n/** Parse exact consent syntax only. Authentication and target lookup remain the caller's responsibility. */\nexport function parseTextActionProposalCommand(\n text: string,\n vocabulary: TextActionProposalVocabulary = DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY,\n): TextActionProposalCommand {\n if (/[\\r\\n]/u.test(text)) return { status: 'unmatched' };\n const verbs = alternatives([...vocabulary.approve, ...vocabulary.reject]);\n if (verbs.length === 0) return { status: 'unmatched' };\n const remember = alternatives(vocabulary.remember);\n const match = new RegExp(\n `^(${verbs})${remember.length > 0 ? `(?: (${remember}))?` : '()'}(?: #([^\\\\s]+?))?[.!]?$`,\n 'iu',\n ).exec(text.trim());\n if (!match) return { status: 'unmatched' };\n const verb = match[1] === undefined ? undefined : fold(match[1]);\n if (verb === undefined) return { status: 'unmatched' };\n // A word on both lists is read as a refusal: never infer consent from an ambiguous word.\n const decision = vocabulary.reject.some((word) => fold(word) === verb) ? 'rejected' : 'approved';\n const remembers = match[2] !== undefined && match[2] !== '';\n if (remembers && decision !== 'approved') return { status: 'unmatched' };\n return {\n status: 'command',\n decision,\n remember: remembers,\n ...(match[3] !== undefined ? { proposalId: match[3] } : {}),\n };\n}\n\n/**\n * Brazilian Portuguese text decisions — `AgentModule.forRoot({ actionProposalText: ptBrActionProposalText })`.\n * Commands in Portuguese (English ones still work), replies in Portuguese.\n */\nexport const ptBrActionProposalText: Required<TextActionProposalConfig> = {\n vocabulary: {\n approve: [\n 'sim',\n 'confirmo',\n 'confirmar',\n 'aprovar',\n 'aprovo',\n 'pode',\n ...DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY.approve,\n ],\n reject: [\n 'não',\n 'nao',\n 'cancelar',\n 'cancela',\n 'rejeitar',\n 'rejeito',\n ...DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY.reject,\n ],\n remember: ['sempre nesta conversa', ...DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY.remember],\n },\n replies: {\n approved: 'Proposta aprovada e enfileirada para execução.',\n rejected: 'Proposta rejeitada; nenhuma ação foi executada.',\n expired: 'A proposta expirou; nenhuma ação foi executada.',\n unchanged:\n 'Não foi possível alterar esta proposta; atualize a lista para consultar seu estado.',\n ambiguous: (ids) => `Qual proposta? Responda confirmar #ID ou cancelar #ID: ${ids.join(', ')}`,\n tooMany: 'Há várias propostas. Confirme ou rejeite usando #ID explícito.',\n },\n};\n","import type { ActionProposalOutcomeDelivery } from './spi/action-proposal-outcome-store.js';\nimport type {\n ActionProposal,\n ActionProposalExecution,\n ActionProposalMutationResult,\n} from './spi/action-proposal-store.js';\n\n/**\n * What leaves the server about a proposal — the routes, a text decision's answer, AG-UI, the approval\n * port. The stored row minus what only the worker and the store may hold: the execution and\n * delivery leases (whose token lets a holder settle the work), the idempotency key the tool's side\n * effect is keyed on, and the execution address (the original preparation input and the request's\n * context).\n */\nexport interface ActionProposalView\n extends Omit<\n ActionProposal,\n 'execution' | 'outcomeDelivery' | 'idempotencyKey' | 'preparationInput' | 'executionContext'\n > {\n execution: Omit<ActionProposalExecution, 'lease'> | null;\n outcomeDelivery?: Omit<ActionProposalOutcomeDelivery, 'lease'>;\n}\n\n/** {@link ActionProposalMutationResult} with its proposal as an {@link ActionProposalView}. */\nexport interface ActionProposalMutationView extends Omit<ActionProposalMutationResult, 'proposal'> {\n proposal?: ActionProposalView;\n}\n\n/** The public view of a stored proposal. See {@link ActionProposalView}. */\nexport function toActionProposalView(proposal: ActionProposal): ActionProposalView {\n const {\n execution,\n outcomeDelivery,\n idempotencyKey: _idempotencyKey,\n preparationInput: _preparationInput,\n executionContext: _executionContext,\n ...rest\n } = proposal;\n return {\n ...rest,\n execution: execution === null ? null : withoutLease(execution),\n ...(outcomeDelivery !== undefined ? { outcomeDelivery: withoutLease(outcomeDelivery) } : {}),\n };\n}\n\n/** The public view of a mutation's answer. See {@link ActionProposalView}. */\nexport function toActionProposalMutationView(\n result: ActionProposalMutationResult,\n): ActionProposalMutationView {\n const { proposal, ...rest } = result;\n return {\n ...rest,\n ...(proposal !== undefined ? { proposal: toActionProposalView(proposal) } : {}),\n };\n}\n\nfunction withoutLease<T extends { lease: unknown }>(value: T): Omit<T, 'lease'> {\n const { lease: _lease, ...rest } = value;\n return rest;\n}\n","import { snapshotActionProposal } from './action-proposal-transitions.js';\nimport { type ResolveToolUiCatalog, createNegotiatedUiCollector } from './negotiated-tool-ui.js';\nimport type { ActionProposal } from './spi/action-proposal-store.js';\nimport type { BackgroundActorResolver } from './spi/background-actor-resolver.js';\nimport type { RolesPolicy } from './spi/roles-policy.js';\nimport type { AgentUiComponent } from './stream-events.js';\nimport type { ToolRegistry } from './tool-registry.js';\nimport type { Actor } from './types.js';\n\nexport interface ActionProposalExecutionDeps {\n registry: ToolRegistry;\n rolesPolicy: RolesPolicy;\n allowedTools?: string[];\n host?: unknown;\n resolveUiCatalog?: ResolveToolUiCatalog;\n}\nexport interface ActionProposalExecutorOptions {\n resolver: BackgroundActorResolver;\n /** Resolve exact recorded agent/persona against current configuration; throw if it disappeared. */\n resolveExecution(proposal: ActionProposal, actor: Actor): Promise<ActionProposalExecutionDeps>;\n}\nexport type ActionProposalExecutionResult =\n | { status: 'succeeded'; result?: unknown; ui: AgentUiComponent[]; text?: string }\n | { status: 'failed'; error: string; ui: AgentUiComponent[]; text?: string };\nexport class ActionProposalExecutor {\n constructor(private readonly options: ActionProposalExecutorOptions) {}\n async execute(proposal: ActionProposal): Promise<ActionProposalExecutionResult> {\n let ui = createNegotiatedUiCollector(proposal.originToolCallId, {\n actor: { id: proposal.actorRef },\n threadId: proposal.threadId,\n });\n try {\n const actor = await this.options.resolver.resolve({\n actorRef: proposal.actorRef,\n tenantRef: proposal.tenantRef,\n });\n if (\n !actor ||\n actor.id !== proposal.actorRef ||\n (actor.tenantRef ?? null) !== proposal.tenantRef\n )\n throw new Error('Action proposal requester no longer exists or scope changed');\n const deps = await this.options.resolveExecution(proposal, actor);\n if (deps.registry.spec(proposal.toolName)?.kind !== 'action')\n throw new Error('Action proposal tool no longer exists as an action');\n const context = proposal.executionContext;\n ui = createNegotiatedUiCollector(\n proposal.originToolCallId,\n {\n actor,\n threadId: proposal.threadId,\n ...(context?.agentName !== undefined ? { agentName: context.agentName } : {}),\n ...(context?.uiCapabilities !== undefined\n ? { uiCapabilities: context.uiCapabilities }\n : {}),\n },\n deps.resolveUiCatalog,\n );\n const output = await deps.registry.invoke(\n proposal.toolName,\n snapshotActionProposal(\n Object.hasOwn(proposal, 'preparationInput') ? proposal.preparationInput : proposal.input,\n ),\n {\n actor,\n threadId: proposal.threadId,\n runId: proposal.originRunId,\n requestId: context?.requestId ?? proposal.originRunId,\n toolCallId: proposal.originToolCallId,\n idempotencyKey: proposal.idempotencyKey,\n ...(context?.agentName !== undefined ? { agentName: context.agentName } : {}),\n ...(context?.persona !== undefined ? { persona: context.persona } : {}),\n ...(context?.pageContext !== undefined ? { pageContext: context.pageContext } : {}),\n ...(context?.uiCapabilities !== undefined\n ? { uiCapabilities: context.uiCapabilities }\n : {}),\n ...(deps.host !== undefined ? { host: deps.host } : {}),\n emitUi: ui.emit,\n },\n deps.rolesPolicy,\n {\n approvedInput: proposal.input,\n ...(deps.allowedTools !== undefined ? { allowedTools: deps.allowedTools } : {}),\n },\n );\n return snapshotActionProposal({\n status: 'succeeded',\n ...(output !== undefined ? { result: output } : {}),\n ui: ui.components(),\n ...(ui.text() ? { text: ui.text() } : {}),\n });\n } catch (error) {\n return {\n status: 'failed',\n error: error instanceof Error ? error.message : String(error),\n ui: ui.components(),\n ...(ui.text() ? { text: ui.text() } : {}),\n };\n }\n }\n}\n","import type { ActionProposalExecutor } from './action-proposal-executor.js';\nimport type { ActionProposalOutcomeStore } from './spi/action-proposal-outcome-store.js';\nimport type { ActionProposal, ActionProposalStore } from './spi/action-proposal-store.js';\nimport type { ActionProposalWorkerStore } from './spi/action-proposal-worker-store.js';\nexport interface ActionProposalWorkerOptions {\n store: ActionProposalStore & ActionProposalWorkerStore & ActionProposalOutcomeStore;\n executor: ActionProposalExecutor;\n workerId: string;\n pollIntervalMs?: number;\n leaseMs?: number;\n maxConcurrency?: number;\n onError?(error: unknown): void;\n onSettled?(proposal: ActionProposal): Promise<void>;\n}\nexport class ActionProposalWorker {\n private readonly leaseMs: number;\n private readonly pollIntervalMs: number;\n private readonly maxConcurrency: number;\n private timer?: ReturnType<typeof setTimeout>;\n private stopped = false;\n private readonly renewals = new Set<ReturnType<typeof setInterval>>();\n private active: Promise<void> | undefined;\n constructor(private readonly options: ActionProposalWorkerOptions) {\n this.leaseMs = options.leaseMs ?? 30000;\n this.pollIntervalMs = options.pollIntervalMs ?? 1000;\n this.maxConcurrency = options.maxConcurrency ?? 1;\n for (const value of [this.leaseMs, this.pollIntervalMs, this.maxConcurrency])\n if (!Number.isSafeInteger(value) || value <= 0)\n throw new RangeError('Worker configuration must be positive safe integers');\n if (this.pollIntervalMs >= this.leaseMs / 3)\n throw new RangeError('Worker poll interval must be below one third of lease');\n if (!options.workerId) throw new TypeError('workerId is required');\n }\n start(): void {\n if (this.timer !== undefined || this.stopped) return;\n const tick = async () => {\n if (this.stopped) return;\n try {\n await this.runOnce();\n } catch (error) {\n this.options.onError?.(error);\n }\n if (!this.stopped) this.timer = setTimeout(tick, this.pollIntervalMs);\n };\n this.timer = setTimeout(tick, 0);\n }\n async stop(): Promise<void> {\n this.stopped = true;\n for (const timer of this.renewals) clearInterval(timer);\n this.renewals.clear();\n if (this.timer !== undefined) clearTimeout(this.timer);\n await this.active;\n }\n runOnce(): Promise<void> {\n if (this.active) return this.active;\n if (this.stopped) return Promise.resolve();\n const task = this.tick();\n this.active = task;\n return task.finally(() => {\n if (this.active === task) this.active = undefined;\n });\n }\n private async tick(): Promise<void> {\n await this.options.store.expireActionProposals({ limit: 100 });\n const work: Promise<void>[] = [];\n for (let index = 0; index < this.maxConcurrency && !this.stopped; index++) {\n const proposal = await this.options.store.claimNextActionProposal({\n workerId: this.options.workerId,\n leaseMs: this.leaseMs,\n });\n if (!proposal) break;\n work.push(this.execute(proposal));\n }\n await Promise.all(work);\n for (let index = 0; index < 32 && !this.stopped; index++) {\n const delivery = await this.options.store.claimNextActionProposalOutcome({\n workerId: this.options.workerId,\n leaseMs: this.leaseMs,\n });\n if (!delivery) break;\n await this.options.store.admitActionProposalOutcome(delivery.lease);\n }\n }\n private async execute(proposal: ActionProposal): Promise<void> {\n const lease = proposal.execution?.lease;\n if (!lease) throw new Error('Claimed action lacks execution lease');\n let fenced = true;\n let renewing: Promise<void> | undefined;\n const renew = () => {\n if (renewing || !fenced) return;\n renewing = this.options.store\n .extendActionProposalLease(proposal, proposal.id, {\n token: lease.token,\n generation: lease.generation,\n leaseMs: this.leaseMs,\n })\n .then(\n (result) => {\n if (result.status !== 'applied') fenced = false;\n },\n (error) => {\n fenced = false;\n this.options.onError?.(error);\n },\n )\n .finally(() => {\n renewing = undefined;\n });\n };\n const timer = setInterval(renew, this.leaseMs / 3);\n this.renewals.add(timer);\n try {\n const result = await this.options.executor.execute(proposal);\n clearInterval(timer);\n await renewing;\n if (!fenced) return;\n const settled = await this.options.store.settleActionProposal(proposal, proposal.id, {\n ...result,\n token: lease.token,\n generation: lease.generation,\n });\n if (settled.status === 'applied' && settled.proposal)\n await this.options.onSettled?.(settled.proposal);\n } finally {\n clearInterval(timer);\n this.renewals.delete(timer);\n await renewing;\n }\n }\n}\n","import type { ActionProposalOutcomeStore } from './spi/action-proposal-outcome-store.js';\nimport type {\n ActionProposalStore,\n ActionProposalSupersessionStore,\n} from './spi/action-proposal-store.js';\nimport type { ActionProposalWorkerStore } from './spi/action-proposal-worker-store.js';\nimport type { AgentStore } from './spi/agent-store.js';\nimport type { BackgroundActorResolver } from './spi/background-actor-resolver.js';\nimport { isChatQueueStore } from './spi/chat-queue.js';\nexport type ActionProposalRuntimeStore = AgentStore &\n ActionProposalStore &\n ActionProposalWorkerStore &\n ActionProposalOutcomeStore &\n ActionProposalSupersessionStore;\nexport function assertIndependentActionCapabilities(\n store: AgentStore,\n resolver: BackgroundActorResolver | undefined,\n): asserts store is ActionProposalRuntimeStore {\n const candidate = store as unknown as Record<string, unknown>;\n if (!resolver || typeof resolver.resolve !== 'function')\n throw new Error('Independent action mode requires a BackgroundActorResolver');\n if (!isChatQueueStore(store) || candidate.actionProposalAdmissionSupported === false)\n throw new Error('Independent action mode requires transactional thread admission');\n const required = [\n 'createActionProposal',\n 'getActionProposal',\n 'listActionProposals',\n 'decideActionProposal',\n 'claimActionProposal',\n 'extendActionProposalLease',\n 'settleActionProposal',\n 'claimNextActionProposal',\n 'expireActionProposals',\n 'getThreadActionProposalScope',\n 'claimNextActionProposalOutcome',\n 'admitActionProposalOutcome',\n 'createReplacingActionProposal',\n 'supersedeActionProposal',\n ];\n if (required.some((method) => typeof candidate[method] !== 'function'))\n throw new Error(\n 'Independent action mode requires proposal, worker, outcome and admission capabilities on the conversation store',\n );\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport type { ToolHandler } from './spi/tool.js';\nimport type { ToolSpec } from './types.js';\n\nexport interface FunctionalTool<I = unknown, O = unknown> {\n spec: ToolSpec;\n handler: ToolHandler<I, O>;\n}\n\nexport type FunctionalToolDefinition<I, O> = Omit<ToolSpec, 'inputSchema' | 'kind'> & {\n input: StandardSchemaV1<unknown, I>;\n kind?: ToolSpec['kind'];\n} & ToolHandler<I, O>;\n\n/** Framework-independent authoring; every method keeps the author's object as its receiver. */\nexport function createFunctionalTool<I, O>(\n definition: FunctionalToolDefinition<I, O>,\n): FunctionalTool<I, O> {\n const { input, execute, present, preflight, isEnabled, canUse, describe, kind, ...metadata } =\n definition;\n return {\n spec: { ...metadata, kind: kind ?? 'read', inputSchema: input },\n handler: {\n execute: execute.bind(definition),\n ...(present === undefined ? {} : { present: present.bind(definition) }),\n ...(preflight === undefined ? {} : { preflight: preflight.bind(definition) }),\n ...(isEnabled === undefined ? {} : { isEnabled: isEnabled.bind(definition) }),\n ...(canUse === undefined ? {} : { canUse: canUse.bind(definition) }),\n ...(describe === undefined ? {} : { describe: describe.bind(definition) }),\n },\n };\n}\n"],"mappings":"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","names":["AGENT_OPTIONS","Symbol","for","AGENT_STORE","AGENT_RUNNER","AGENT_DURABLE_RUNNER","AGENT_SINK","AGENT_MODEL","AGENT_ROLES_POLICY","AGENT_QUOTA_STORE","AGENT_TOOL_REGISTRY","AGENT_REGISTRY","AGENT_ACTOR_RESOLVER","AGENT_GOVERNANCE_QUERIES","AGENT_QUOTA_PROVIDER","AGENT_MODEL_CATALOG","AGENT_PRICING_STORE","AGENT_RETRIEVER","AGENT_EMBEDDING_PROVIDER","AGENT_DEPS_FACTORY","AGENT_PROMPT_CONTRIBUTORS","AGENT_ACTOR_DIRECTORY","AGENT_ATTACHMENT_STAGING","AGENT_APPROVAL_PORT","AGENT_SKILLS","AGENT_MEMORY","AGENT_SKILL_SOURCES","AGENT_CONFIRM_TOKEN_STORE","AGENT_CHANNEL_STORE","staticModelCatalog","view","list","findCatalogModel","id","group","providers","found","models","find","model","undefined","withSelectedModel","provider","runTurn","args","AgentStreamError","Error","code","error","message","name","encoder","TextEncoder","encodeStreamEvent","event","encode","JSON","stringify","decodeStreamEvent","line","parsed","parse","kind","observeTurnFrames","writer","now","Date","decoder","TextDecoder","pending","reasoning","reasoningMs","burstStartedAt","ui","Map","closeBurst","undefined","Math","max","observeLine","line","trim","length","event","decodeStreamEvent","kind","text","set","id","component","props","version","observe","chunk","decode","stream","newline","indexOf","slice","write","end","fail","error","summary","round","size","values","withTurnFrames","result","frames","TOOL_STEP_UI","wrapToolStepOutput","output","ui","text","reserved","length","wrapped","wrapToolPreflightDenied","reason","preflightDenied","unwrapToolStepOutput","raw","Array","isArray","createNoopEmitUi","scope","next","_component","_props","options","id","undefined","createUiCollector","toolCallId","write","pushed","Map","emit","component","props","Error","entry","JSON","parse","stringify","version","fallbackText","componentVersions","set","kind","components","values","restart","mergeUi","lists","merged","list","escapeUnsafeToolUiText","replaceAll","replace","unit","charCodeAt","toString","padStart","ALL_AGENTS","CHAT_QUEUE_METHODS","isChatQueueStore","store","candidate","every","method","releaseThreadRun","threadId","runId","releaseActiveStream","setActiveStream","queuedMessageView","message","id","content","attachments","undefined","length","agentName","persona","model","interrupt","createdAt","updatedAt","exhaustedWindow","windows","window","tokensOut","limitTokens","undefined","usedTokens","spendOut","limitUsd","usedUsd","period","reason","quotaUsedRatio","ratios","push","length","Math","max","quotaWarning","fullest","warnAt","ratio","quotaPeriodRange","now","year","getUTCFullYear","month","getUTCMonth","day","toISOString","slice","next","Date","UTC","getUTCDate","fromDay","toDay","resetsAt","first","last","seedModelPrices","store","prices","price","upsertModelPrice","DEFAULT_INCREMENTAL_LOOKBACK_CHARS","OutputRejectedError","Error","processor","reason","name","ProcessorFailedError","phase","cause","message","String","THREAD_DETAIL_CONTENT_CHARS","truncateDetailContent","content","length","truncated","slice","REQUESTER_APPROVER","DefaultApprovalPolicy","requirementFor","tool","required","kind","approver","defaultCanDecide","actor","decision","id","requesterRef","roles","includes","mayDecideApproval","policy","canDecide","undefined","toolCallApprovalFromRow","row","status","expiresAt","Date","toISOString","decided","toolCallId","proposalId","confirmation","remember","executedByRef","decidedBy","decidedVia","error","reason","estimateCost","usage","price","undefined","cacheWriteTokens","cacheReadTokens","uncachedInputTokens","inputTokens","inputPricePer1m","cacheWritePricePer1m","cacheReadPricePer1m","outputTokens","outputPricePer1m","rowCost","row","prices","costUsd","get","modelId","bucketByModel","rows","byModel","Map","bucket","requests","set","result","push","sort","left","right","localeCompare","bucketByActor","byActor","actorRef","totalTokens","threadIds","Set","add","threadId","threadCount","size","bucketByThread","threads","options","byThread","thread","includeUnknownThreads","title","slice","limit","rollupThreadUsage","rollup","bucketUsageTrend","byDay","day","dayBoundsUtc","range","start","Date","fromDay","end","toDay","isToolEnabled","spec","handler","declared","enabled","isEnabled","undefined","filterToolsByEnabled","entries","checked","Promise","all","map","entry","filter","row","canActorUseTool","actor","canUse","filterToolsByCanUse","allowed","filterToolsByRole","tools","policy","tool","can","filterToolsByAllowList","allowedTools","Set","has","name","intersectAllowLists","first","second","undefined","allowed","Set","filter","name","has","findPersona","definition","id","personas","find","persona","personaCatalogEntry","label","description","resolvePersonaAlias","definitions","aliases","includes","agent","estimateMessageTokens","message","extras","toolCalls","undefined","JSON","stringify","length","toolResults","Math","ceil","content","windowHistory","options","estimate","policy","maxMessages","select","messages","cut","max","maxTokens","tokenCut","min","keep","slice","drop","summarize","index","total","cost","DEFAULT_HISTORY_SUMMARY_INSTRUCTION","summarizeWithModel","model","instruction","dropped","discard","write","end","fail","turn","runTurn","system","tools","sink","text","usage","modelId","decoder","TextDecoder","createFrameBuffer","frames","writer","write","chunk","line","decode","split","length","push","end","fail","releaseGatedFrames","text","released","emitted","frame","event","decodeStreamEvent","kind","encodeStreamEvent","runInputProcessors","processors","prompt","ctx","current","processor","process","error","ProcessorFailedError","name","runOutputProcessors","answer","verdict","toolCalls","action","rejection","reason","gateFollowUps","followUps","kept","followUp","settled","undefined","resolveOutputGateMode","every","incremental","resolveGateLookback","lookback","Math","max","lookbackChars","DEFAULT_INCREMENTAL_LOOKBACK_CHARS","createIncrementalGate","options","raw","stalled","queue","Promise","resolve","advance","candidate","slice","startsWith","delta","handle","id","input","then","gateTail","map","join","Error","StructuredOutputError","Error","issues","text","attempts","detail","length","map","issue","message","join","name","extractJson","candidates","match","candidate","undefined","JSON","parse","validateStructured","schema","reported","ok","result","validate","value","DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION","repairInstruction","instruction","path","ELICITATION_INPUT_TYPES","questionOptions","question","options","isTypedQuestion","input","undefined","type","DATE_PATTERN","EMAIL_PATTERN","NUMBER_PATTERN","isDate","value","match","exec","year","month","day","date","Date","UTC","Number","getUTCFullYear","getUTCMonth","getUTCDate","isHttpUrl","url","URL","protocol","fullMatch","pattern","RegExp","test","asNumber","bound","isFinite","trim","validateElicitationValue","allowFreeText","some","option","number","min","max","length","validateElicitationAnswer","values","present","filter","required","multiple","problem","readElicitationInput","raw","candidate","includes","placeholder","readElicitationQuestions","questions","Array","isArray","item","id","prompt","flatMap","label","typed","defaults","push","normalizeElicitationReply","reply","answers","candidate","answeredByRef","executedByRef","answeredVia","decidedVia","approved","skipped","undefined","resolveElicitation","request","raw","defaulted","question","questions","submitted","id","defaults","push","valid","filter","value","validateElicitationValue","multiple","slice","answeredBy","settleElicitation","outcome","summary","renderElicitationAnswers","lines","map","chosen","labels","questionOptions","find","option","label","prompt","length","join","preface","ASK_TOOL_NAME","MAX_ASK_QUESTIONS","issue","path","message","parseOption","issues","hotkey","parseQuestion","input","readElicitationInput","ELICITATION_INPUT_TYPES","described","description","typed","type","Array","isArray","options","index","rawOption","entries","offered","Set","has","allowFreeText","ASK_JSON_SCHEMA","additionalProperties","properties","preamble","minItems","maxItems","items","required","enum","placeholder","min","max","pattern","maxLength","askInputSchema","version","vendor","validate","jsonSchema","ASK_TOOL_DESCRIPTION","askToolDefinition","name","kind","inputSchema","DEFAULT_INTAKE_PREAMBLE","GLOBAL_SCOPE","actorScope","actor","id","tenantScope","tenantRef","defaultScopeResolver","resolve","undefined","staticSkillProvider","skills","list","scopes","filter","skill","includes","scope","load","name","find","body","compositeSkillProvider","providers","ctx","seen","Set","merged","provider","summary","key","has","add","push","DEFAULT_MAX_SKILLS","resolveSkillCatalog","summaries","maxSkills","rank","Map","map","index","byName","existing","get","set","resolved","candidates","values","ordered","sort","a","b","winner","shadows","slice","candidate","description","length","byScope","compare","entries","omitted","Math","max","offerSkills","config","buildSkillsBlock","lines","entry","join","SKILL_TOOL_NAME","SKILL_JSON_SCHEMA","type","additionalProperties","required","properties","issue","path","message","skillInputSchema","version","vendor","validate","value","issues","jsonSchema","input","SKILL_TOOL_DESCRIPTION","skillToolDefinition","kind","inputSchema","withSkillTool","tools","enabled","loadSkill","offer","available","ok","error","skillWriteVerdict","request","author","allowed","reason","own","elevated","DEFAULT_MAX_MEMORIES","DEFAULT_MAX_FACT_CHARS","resolveMemoryDigest","records","scopes","maxMemories","ranked","rank","Map","map","scope","index","byKey","entry","has","existing","get","key","undefined","set","push","resolved","candidates","values","ordered","sort","a","b","winner","overrides","slice","beaten","text","author","origin","pinned","some","candidate","length","byPrecedence","compare","updatedAt","selected","pinRank","pinnedOmitted","filter","entries","omitted","Math","max","offerMemories","config","ctx","query","defaultScopeResolver","resolve","trimmed","trim","search","provider","bind","limit","list","recalled","ASSERTED_FRAMING","CONCLUDED_FRAMING","PARTIAL_FRAMING","memorySection","framing","flatMap","buildMemoryBlock","writable","partial","writeLine","REMEMBER_TOOL_NAME","body","join","REMEMBER_JSON_SCHEMA","type","additionalProperties","required","properties","description","fact","issue","path","message","rememberInputSchema","version","vendor","validate","value","issues","jsonSchema","input","REMEMBER_TOOL_DESCRIPTION","rememberToolDefinition","name","kind","inputSchema","withMemoryTool","tools","enabled","memoryWriteVerdict","request","actor","includes","allowed","reason","own","actorScope","elevated","memoryForgetVerdict","record","writeMemory","digest","call","runId","write","ok","error","maxFactChars","verdict","actorRef","id","threadId","AgentRegistry","definitions","Map","register","definition","set","name","get","has","list","values","isReplayIntegrityError","error","Error","name","toLowerCase","endsWith","CONTROL_FLOW_SIGNAL","Symbol","for","isControlFlowSignal","error","UNFINISHED_TOOL_CALL","RUN_ENDED_BEFORE_TOOL_CALL","DECLINED","EXPIRED","danglingToolCallIds","messages","ids","message","calls","toolCalls","role","length","settled","Set","toolResults","map","result","id","call","has","push","resultFor","outcome","base","name","status","output","error","rejected","denied","expired","settleDanglingToolCalls","outcomes","known","Map","results","missing","filter","get","RUN_NOT_ACTIVE_CODE","RUN_NOT_ACTIVE_MESSAGE","RUN_NO_LONGER_RUNNING","settleDeadRun","store","input","failure","undefined","Promise","resolve","recordRunEnd","runId","status","errorCode","code","errorMessage","message","catch","failUnsettledToolCalls","RUN_ENDED_BEFORE_TOOL_CALL","threadId","releaseThreadRun","normalizeDelegation","entry","agent","detached","detachedStarted","args","status","runId","note","detachedDelivered","text","detachedUnsettled","error","undefined","settleUnsettledDelegation","store","delivery","thread","getThread","threadId","messages","some","message","appendMessage","role","content","agentName","updateToolCall","toolCallId","output","validateActionProposalWorkerClaim","command","now","Number","isSafeInteger","RangeError","workerId","length","TypeError","leaseMs","validateActionProposalExpiryBatch","validateActionProposalDiscoveryIndexBatch","isInteger","limit","attachActionProposalOutcome","row","now","ui","text","outcome","execution","id","proposalId","outcomeVersion","tenantRef","actorRef","threadId","originRunId","originToolCallId","toolName","decision","createdAt","undefined","status","executionStatus","Object","hasOwn","result","error","decisionAudit","reason","snapshotActionProposal","outcomeDelivery","generation","lease","claimActionProposalOutcome","command","token","validateActionProposalWorkerClaim","delivery","expiresAt","workerId","leaseMs","actionProposalOutcomeFenceValid","Number","isSafeInteger","RangeError","outcomeId","TypeError","outcomeSummary","JSON","stringify","actionProposalOutcomeScope","actionProposalOutcomeText","isStandardSchema","schema","validate","toJsonSchema","standard","converter","jsonSchema","undefined","input","target","validateProps","value","validator","result","issues","ok","toGenuiIssues","length","validatePropsSync","Promise","catch","map","issue","path","segment","key","message","formatIssues","formatPath","join","index","builtinJsonSchemaValidator","validate","schema","value","issues","check","MAX_DEPTH","typeOf","Array","isArray","matchesType","type","Number","isInteger","isFinite","resolveRef","root","ref","startsWith","undefined","current","raw","slice","split","key","replace","deepEqual","a","b","keysA","Object","keys","keysB","length","every","path","depth","push","message","s","$ref","target","types","some","join","enum","option","map","JSON","stringify","const","minLength","maxLength","pattern","RegExp","test","minimum","maximum","minItems","maxItems","items","forEach","item","index","record","properties","required","entry","entries","additionalProperties","allOf","sub","anyOf","oneOf","options","passing","filter","nested","not","COMPONENT_NAME","defineComponent","definition","test","name","Error","version","undefined","Number","isSafeInteger","RangeError","fallbackText","TypeError","defineCatalog","components","options","byName","Map","component","defineComponent","has","name","Error","set","buildCatalog","jsonSchemaValidator","builtinJsonSchemaValidator","validator","list","Object","freeze","values","get","modelComponents","filter","internal","validate","props","definition","undefined","ok","issues","path","message","result","validateProps","outputProps","validateSync","validatePropsSync","jsonSchemaFor","toJsonSchema","extend","more","next","GENUI_TREE_COMPONENT","validateTree","catalog","tree","limits","phase","maxDepth","maxNodes","issues","nodes","visit","node","path","depth","push","message","undefined","Array","isArray","element","type","definition","get","internal","modelComponents","map","component","name","join","validated","validateProps","props","validator","validate","ok","issue","value","rawChildren","parseChildrenIfStringified","children","length","index","child","entries","next","root","parseChildrenIfStringified","value","trimmed","trim","startsWith","leadingJsonArray","text","depth","inString","escaped","index","length","char","parsed","JSON","parse","slice","Array","isArray","undefined","componentToText","catalog","component","props","GENUI_TREE_COMPONENT","root","undefined","treeToText","ownText","definition","get","fallback","fallbackText","failed","text","trim","length","children","jsonBlock","out","visit","node","depth","type","push","child","filter","line","join","title","JSON","stringify","validateUiCapabilities","value","record","Object","keys","some","key","Array","isArray","components","TypeError","seen","Set","map","component","name","COMPONENT_NAME","test","Number","isSafeInteger","version","has","add","negotiateCatalog","catalog","capabilities","undefined","supported","defineCatalog","filter","entry","jsonSchemaValidator","validator","prepareUiEmission","props","drawable","GENUI_TREE_COMPONENT","Error","validated","validateTree","root","ok","formatIssues","issues","node","type","children","every","versions","Map","collectVersions","set","get","child","kind","fallbackText","treeToText","componentVersions","fromEntries","text","definition","currentVersion","validate","componentToText","checkTime","value","Number","isSafeInteger","RangeError","checkString","length","TypeError","validateActionProposalCreation","input","allowed","Object","keys","some","key","includes","tenantRef","id","actorRef","threadId","replacementKey","undefined","hasOwn","context","executionContext","Array","isArray","allowedContext","requestId","validateUiCapabilities","uiCapabilities","agentName","persona","page","pageContext","kind","expiresAt","confirmation","title","verb","canonicalActionProposalJson","validateActionProposalListQuery","query","limit","isInteger","decision","after","createdAt","ancestors","Set","sort","item","isFinite","has","prototype","getPrototypeOf","add","sorted","from","fromEntries","map","delete","JSON","stringify","snapshotActionProposal","parse","actionProposalScopeMatches","row","scope","initialActionProposal","now","decisionAudit","execution","updatedAt","actionProposalCreationMatches","_decision","_audit","_execution","_created","_updated","supersededBy","_supersededBy","outcome","_outcome","outcomeDelivery","_delivery","original","result","status","proposal","transitionActionProposalDecision","command","via","reason","remember","next","at","attachActionProposalOutcome","audit","generation","lease","checkLeaseMs","leaseMs","transitionActionProposalClaim","token","workerId","leaseStatus","work","transitionActionProposalLease","Math","max","transitionActionProposalSettlement","error","ui","text","transitionActionProposalSupersession","replacement","replacementProposalId","toolName","str","description","extra","type","undefined","obj","properties","required","additionalProperties","arr","items","cell","row","s","value","String","heading","props","title","textTable","columns","rows","max","shown","slice","widths","map","column","Math","min","label","length","r","key","format","values","index","padEnd","join","lines","width","repeat","push","lineDiff","before","after","a","split","b","text","op","dp","Array","from","fill","at","i","j","out","bar","n","round","abs","DataTable","defineComponent","name","align","enum","minItems","maxItems","fallbackText","Chart","xKey","series","data","unit","chartText","filter","each","labelOf","flatMap","point","Number","KpiCards","delta","trend","hint","item","SourceCards","url","snippet","source","Checklist","done","note","Timeline","events","date","event","CodeBlock","language","code","Diff","line","Callout","tone","Stack","direction","gap","children","Card","subtitle","Heading","Text","muted","Badge","Link","pattern","Image","alt","snapshotComponentPresentation","value","seen","Set","check","entry","Number","isFinite","TypeError","has","Array","isArray","Object","getPrototypeOf","prototype","add","item","values","delete","JSON","parse","stringify","createComponent","definition","options","defineComponent","catalog","defineCatalog","factory","props","result","validateProps","validator","ok","Error","name","formatIssues","issues","normalized","portable","validate","canonicalJson","component","version","fallbackText","componentToText","assign","table","createComponent","DataTable","chart","Chart","validatePresentationBatch","presentations","batch","Array","isArray","map","item","presentation","snapshotComponentPresentation","component","test","Number","isSafeInteger","version","fallbackText","props","TypeError","canonicalJson","value","join","record","Object","keys","sort","key","JSON","stringify","emitToolPresentations","handler","output","ctx","toolName","present","undefined","result","batch","validatePresentationBatch","presentation","emitUi","component","props","version","fallbackText","error","onPresentationError","reportError","console","warn","ToolForbiddenError","Error","toolName","name","ToolDisabledError","ToolNotFoundError","ToolInputInvalidError","issues","map","issue","message","join","ToolPreflightDeniedError","reason","ToolInputDriftError","assertTrustedInput","value","approved","canonicalActionProposalJson","ToolRegistry","entries","Map","register","spec","handler","set","hasPresentation","get","present","presentOutput","output","ctx","entry","undefined","emitToolPresentations","has","unregister","delete","allSpecs","values","definitionsFor","actor","policy","allowedTools","scope","visible","visibleEntries","definitions","Promise","all","override","describe","available","kind","description","inputSchema","filter","definition","visibleSpecs","pinnedNames","Set","filterToolsByAllowList","pinned","live","filterToolsByEnabled","allowedByRole","filterToolsByRole","roleScoped","filterToolsByCanUse","invoke","input","options","withEmit","validated","trusted","Object","hasOwn","approvedInput","executionInput","snapshotActionProposal","hookInput","result","preflight","phase","status","execute","prepare","prepareValidated","normalized","snapshotInput","isToolEnabled","can","canActorUseTool","includes","validation","validate","emitUi","createNoopEmitUi","requestId","DefaultRolesPolicy","emptyRoles","defaultRoles","tool","ability","roles","allowed","length","some","role","ClosedRolesPolicy","closeEmptyRoles","inner","defaults","createHash","trace","resolveActionProposalApproval","input","policy","DefaultApprovalPolicy","requirement","requirementFor","tool","actor","thread","required","mode","remembered","store","rememberedApprovals","threadId","includes","name","approver","roundedTtl","ttlMs","undefined","Number","isFinite","Math","floor","now","clock","Date","isSafeInteger","RangeError","expiresAt","toISOString","prepareActionProposal","registry","name","input","ctx","policy","options","preparationInput","snapshotActionProposal","prepared","prepareValidated","snapshotInput","replacementKey","replacement","spec","preflight","status","undefined","length","TypeError","actionProposalReceipt","proposalId","status","executed","emit","publishAgentRunStarted","payload","emit","publishAgentMessage","publishAgentToolCall","publishAgentQuotaExceeded","publishAgentRunFinished","publishAgentRunFailed","publishAgentDelegated","publishAgentRetrieved","publishAgentToolRetry","publishAgentSkillsResolved","publishAgentMemoryResolved","publishAgentMemoryWritten","AGENT_SPAN_EVENTS","AGENT_DIAGNOSTIC_EVENTS","agentDiagnosticKey","event","createNegotiatedUiCollector","toolCallId","scope","resolveCatalog","write","collector","createUiCollector","texts","Map","next","components","text","values","join","restart","clear","emit","component","props","options","declared","uiCapabilities","undefined","some","entry","name","version","id","fallbackText","length","set","kind","capturedProps","snapshotActionProposal","capturedOptions","catalog","prepared","prepareUiEmission","componentVersions","hasTransientShape","error","code","undefined","errno","sqlState","message","test","isTransientToolError","ToolPreflightDeniedError","cause","DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS","DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS","resolveToolTransientRetryNumbers","setting","attempts","backoffMs","delay","ms","Promise","resolve","setTimeout","invokeWithTransientRetry","fn","options","classify","attempt","isControlFlowSignal","isControlFlowError","attemptsRemain","onRetry","resolveCostUsd","usage","reportedCostUsd","price","undefined","estimateCost","buildContextBlock","passages","items","map","passage","index","label","source","text","join","buildSummaryBlock","summary","settleAll","tasks","started","task","Promise","all","work","then","value","ok","error","QuotaExceededError","Error","name","RunCancelledError","agentFailureCode","OutputRejectedError","StructuredOutputError","isReplayIntegrityError","isNoOutputError","message","startsWith","RUN_FAILED_MESSAGE","streamErrorDetails","exposeStreamErrorDetails","expose","WORDED_CODES","Set","streamFailure","detail","String","code","has","exposed","process","env","NODE_ENV","MAX_DELEGATION_DEPTH","DEFAULT_MAX_AGENT_APPEARANCES","delegationRefusal","args","deps","input","targetAgent","ancestry","delegationPath","agentName","appearances","filter","length","maxAppearances","maxAgentAppearances","chain","times","maxDepth","maxDelegationDepth","delegationDepth","resolvePrompt","prompt","ctx","resolveSystemPrompt","persona","promptContext","sections","systemPrompt","contribute","promptContributors","section","push","withoutPersona","_dropped","rest","actor","pageContext","uiCapabilities","id","resolveTurnPersona","findPersona","ref","basePrompt","allowedTools","personaRefusal","toolName","includes","extractTask","JSON","stringify","deriveTitle","userText","trimmed","trim","replace","slice","ToolTimeoutError","ms","withToolTimeout","resolve","reject","timer","setTimeout","clearTimeout","parseFollowUps","count","match","parsed","parse","Array","isArray","item","generateFollowUps","model","messages","discard","write","end","fail","turn","runTurn","system","tools","sink","followUps","modelId","spanned","event","runId","payload","run","summarize","trace","traceId","traceLlmTurn","step","inputTokens","outputTokens","textLength","toolCalls","traceToolExecution","call","toModelMessages","role","content","toolResults","attachments","historyContext","threadId","splitHistory","policy","keep","drop","select","loadSelectedHistory","hooks","recorded","thread","readThreadForTurn","historyPolicy","settleHistory","dropped","title","hasAssistantMessage","actionApprovalMode","settleDanglingToolCalls","dangling","danglingToolCallIds","outcomes","store","toolCallOutcomes","catch","windowing","loadThreadForTurn","messageLimit","turnMessageLimit","page","getThread","stored","some","maxMessages","loadWholeThread","foldDroppedHistory","history","recordUsage","actorRef","purpose","processorContext","restatementPrompt","answer","fromTranscript","restated","structureAnswer","schema","instruction","outputInstruction","DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION","maxAttempts","outputRepairAttempts","outputProcessors","issues","attempt","repairInstruction","reply","outputSchema","object","result","gate","runOutputProcessors","rejection","processor","reason","reported","outcome","validateStructured","stampToolKinds","preflight","_untrusted","prepared","_untrustedPrepared","actionApproval","_untrustedApproval","trusted","kind","declaredKind","ask","ASK_TOOL_NAME","skills","SKILL_TOOL_NAME","memoryIsWritable","REMEMBER_TOOL_NAME","registry","spec","memory","provider","withAskTool","askToolDefinition","awaitElicitation","request","awaitAnswers","normalizeElicitationReply","awaitApproval","toolCallContext","toolCallId","idempotencyKey","toolContext","requestId","host","emitUi","createNoopEmitUi","intakeApplies","intake","threadHasAssistant","when","runIntake","writer","preamble","DEFAULT_INTAKE_PREAMBLE","questions","asked","appendMessage","recordToolCall","messageId","toolType","status","encodeStreamEvent","settleElicitation","updateToolCall","skipped","output","answeredByRef","executedByRef","setMessageToolResults","PARALLEL_TOOLS_PATCH","CANCELLATION_PATCH","SELECTED_HISTORY_PATCH","PROMPT_STAGES_PATCH","resolvePromptStages","configured","retriever","patched","UNSERVED_MEMORY","scopes","entries","omitted","pinnedOmitted","UNSERVED_SKILLS","haltIfCancelled","cancellable","observe","cancelled","claimToolCall","persisted","awaitsHuman","independentApproval","dispatchLlm","resolveActionProposalApproval","tool","approvalPolicy","toolAllowList","intersectAllowLists","mode","prepareActionProposal","rolesPolicy","prepare","isControlFlowError","isControlFlowSignal","confirmation","approval","claimApproval","proposalId","proposalStore","createActionProposal","createHash","update","digest","display","presentation","confirm","verb","fill","_match","path","current","part","split","create","replacementKey","bind","createReplacingActionProposal","created","tenantRef","originRunId","originMessageId","originToolCallId","preparationInput","executionContext","approver","expiresAt","Date","proposal","parks","target","detached","terminal","hasPresentation","presentCompletedPreflight","resolvedCall","DefaultApprovalPolicy","requirement","requirementFor","required","remembered","rememberedApprovals","ttlMs","Number","isFinite","Math","floor","now","toISOString","loadSkillIntoTurn","claimed","startedAt","config","offer","skillInputSchema","validate","each","loaded","loadSkill","skillContext","skill","scope","body","shadows","executionMs","rememberIntoTurn","rememberInputSchema","writeMemory","publishAgentMemoryWritten","record","chars","invokeClaimedTool","invokeAllowList","raw","dispatchTool","stepCtx","envelope","toolTimeoutMs","timeoutMs","transientRetry","resolveToolTransientRetryNumbers","toolTransientRetry","collectUi","invocation","ui","createNegotiatedUiCollector","resolveUiCatalog","invokeWithTransientRetry","restart","invoke","emit","onRetry","retryError","publishAgentToolRetry","wrapToolPreflightDenied","wrapToolStepOutput","components","preflightDenied","unwrapToolStepOutput","toolText","set","toolUi","halt","recordToolOutcome","deciderRef","meta","decided","decidedBy","decidedVia","remember","settle","streamed","rejected","denied","publishAgentToolCall","durationMs","delegateToolCall","refusal","start","startAgent","publishAgentDelegated","toAgent","fromAgent","sub","detachedStarted","agent","runAgent","elicitToolCall","askInputSchema","runClaimedToolCall","independentProposal","actionProposalReceipt","presentOutput","presented","decision","streamsSettlement","expired","expireToolCall","approved","DEFAULT_REFUSAL_REASON","refusalNarrative","APPROVAL_EXPIRED_REASON","expiryNarrative","outputFrame","refusalReason","base","invokeClaimedToolsTogether","parallel","settled","entry","results","runAgentLoop","boundDeps","requested","withSelectedModel","maxSteps","inputProcessors","gateMode","resolveOutputGateMode","gated","gateLookback","resolveGateLookback","structured","quota","state","check","day","withinLimit","publishAgentQuotaExceeded","actorId","usedTokens","limitTokens","regenerate","existing","lastUserIndex","firstDropped","truncateFrom","modelMessages","openSink","lastText","steps","totalInput","totalOutput","publishAgentRunStarted","stages","promptHash","recordRunStart","parentRunId","memoryDigest","offerMemories","query","block","buildMemoryBlock","writable","partial","recalled","publishAgentMemoryResolved","offered","promptChars","injectedPassages","topK","retrievalTopK","queryLength","retrieve","retrieved","publishAgentRetrieved","skillOffer","offerSkills","buildSkillsBlock","publishAgentSkillsResolved","prices","pricingStore","listCurrentPrices","priceByModel","Map","i","runInputProcessors","preflightContext","bufferOutput","personaAllowedTools","withMemoryTool","withSkillTool","definitionsFor","enabled","incremental","createIncrementalGate","processors","lookbackChars","buffer","createFrameBuffer","frames","observeTurnFrames","withTurnFrames","releasedText","released","gateRejection","bufferedFrames","chunk","releaseGatedFrames","tail","gateTail","resolvedModelId","stepModel","costUsd","get","toolCallsWithKind","bump","publishAgentMessage","isFinalTurn","outputFromTranscript","followUpsCount","generated","suggestions","gateFollowUps","synthetic","messageCalls","syntheticResults","assistant","reasoning","reasoningMs","assistantMessage","toolKind","turnCalls","every","settledResults","escapeUnsafeToolUiText","flatMap","setMessageUi","mergeUi","setTitle","delivery","deliverTo","detachedDelivered","recordRunEnd","publishAgentRunFinished","randomUUID","InMemoryActionProposalStore","rows","Map","clock","options","Date","now","createActionProposal","input","validateActionProposalCreation","row","get","id","actionProposalScopeMatches","status","actionProposalCreationMatches","proposal","snapshotActionProposal","initialActionProposal","set","getActionProposal","scope","listActionProposals","query","limit","validateActionProposalListQuery","values","filter","decision","undefined","after","createdAt","sort","a","b","slice","map","mutate","transition","result","decideActionProposal","command","transitionActionProposalDecision","claimActionProposal","transitionActionProposalClaim","randomUUID","extendActionProposalLease","transitionActionProposalLease","settleActionProposal","transitionActionProposalSettlement","claimNextActionProposal","validateActionProposalWorkerClaim","candidates","execution","lease","expiresAt","candidate","claimed","expireActionProposals","validateActionProposalExpiryBatch","expired","actorRef","via","claimNextActionProposalOutcome","outcomeDelivery","next","claimActionProposalOutcome","outcome","outcomeId","token","generation","createReplacingActionProposal","existing","replacements","replacementKey","toolName","transitionActionProposalSupersession","replacementProposalId","push","supersedeActionProposal","replacement","InMemoryAgentStore","InMemoryActionProposalStore","threads","Map","queues","pauses","toolCalls","usage","runs","now","Date","toISOString","createThread","input","id","crypto","randomUUID","has","Error","ts","row","actorRef","actor","tenantRef","title","transient","createdAt","updatedAt","messages","persona","undefined","set","toSummary","getThread","threadId","get","map","message","withApprovals","activeStreamId","activeRunId","approvals","call","values","messageId","approval","toolCallApprovalFromRow","toolCallId","proposalId","status","approver","confirmation","expiresAt","remember","executedByRef","decidedVia","error","push","length","rememberedApprovals","names","Set","add","toolName","thread","proposal","rows","decisionAudit","execution","toolCallInput","toolCallApproval","listThreads","limit","filter","sort","a","b","localeCompare","slice","softDeleteThread","delete","forkThread","fromMessageId","source","cutoff","findIndex","kept","feedback","_feedback","defaultAgent","model","ownerOfThread","ownerOfToolCall","runForToolCall","runId","ownerOfActiveStream","setTitle","updateThread","patch","activeRunForThread","defaultAgentForThread","personaForThread","modelForThread","recordRunStart","run","retries","startedAt","agentName","parentRunId","promptHash","recordRunEnd","end","settledAt","durationMs","errorCode","errorMessage","bumpRunRetries","promoteThread","setActiveStream","claimActiveStream","options","holder","replacing","releaseActiveStream","enqueueMessage","content","attachments","pageContext","uiCapabilities","hostContext","interrupt","queue","at","unshift","listQueue","getQueuedMessage","found","findQueued","updateQueuedMessage","moveQueuedMessage","index","position","splice","target","Math","max","min","trunc","removeQueuedMessage","clearQueue","count","queuePause","setQueuePause","pause","getThreadActionProposalScope","admitActionProposalOutcome","command","find","outcome","outcomeId","outcomeDelivery","actionProposalOutcomeFenceValid","clock","snapshotActionProposal","lease","role","actionProposalOutcomeText","actionProposalOutcome","ui","next","appendMessage","toolResults","followUps","reasoning","reasoningMs","setMessageToolResults","results","candidate","setMessageUi","_previous","rest","threadOfMessage","threadIdForMessage","setMessageFeedback","truncateFrom","referencedMediaIds","mediaIds","wanted","queued","attachment","mediaId","recordToolCall","toolType","structuredClone","toolCallOutcomes","toolCallIds","outcomes","output","failUnsettledToolCalls","settled","updateToolCall","executionMs","recordUsage","modelId","inputTokens","outputTokens","day","cacheWriteTokens","cacheReadTokens","costUsd","quotaToday","usageBetween","fromDay","toDay","usedTokens","reduce","sum","usageRows","tokens","governanceUsage","governanceToolCalls","governanceMessages","governancePendingApprovals","threadTitle","requestedAt","governanceThreads","messageCount","governanceRuns","some","toolCallRows","last","lastMessagePreview","createHash","createHmac","timingSafeEqual","DEFAULT_CONFIRM_TTL_MS","canonicalJson","value","undefined","JSON","stringify","Array","isArray","map","join","toJSON","entries","Object","filter","entry","sort","a","b","key","signature","subject","expiresAt","secret","Error","createHmac","update","tool","actorId","tenantRef","args","digest","signConfirmToken","options","confirmTokenExpiry","token","separator","indexOf","Number","slice","isSafeInteger","verifyConfirmToken","now","Date","expected","Buffer","from","given","length","timingSafeEqual","hashConfirmToken","createHash","InMemoryConfirmTokenStore","claims","Map","claim","input","purgeExpired","has","hash","set","release","delete","purged","size","InMemoryChannelStore","Map","maxEntries","key","entry","get","undefined","expiresAt","Date","now","delete","value","ttlMs","set","size","stored","claim","purgeExpired","purged","DEFAULT_MESSAGES","confirm","invalid","used","ConfirmTokenError","Error","reason","message","name","CONFIRM_JSON_SCHEMA_PROPERTIES","type","description","confirmToken","SCHEMA_EXTENSION","Symbol","for","schemaExtensionOf","schema","extension","undefined","isRecord","value","Array","isArray","splitConfirm","input","args","fields","jsonSchemaInputOf","standard","jsonSchema","options","call","withConfirmFields","inner","innerJsonSchema","describe","base","additionalProperties","properties","wrapped","version","vendor","validate","issues","push","path","result","length","output","defineConfirmedTool","steps","secret","ttlMs","DEFAULT_CONFIRM_TTL_MS","store","messages","specFields","text","howToConfirm","replaceAll","String","Math","round","secretNow","handler","execute","ctx","subject","tool","actorId","actor","id","tenantRef","confirming","token","verifyConfirmToken","prepared","prepare","preview","expiresAt","Date","now","status","summary","data","signConfirmToken","toISOString","hash","hashConfirmToken","claimed","claim","actorRef","confirmTokenExpiry","done","commit","error","release","catch","spec","kind","inputSchema","DEFAULT_TTL_SECONDS","DEFAULT_POLL_INTERVAL_MS","DEFAULT_IDLE_POLL_INTERVAL_MS","IDLE_AFTER_MS","DEFAULT_FLUSH_MS","READ_PAGE","PURGE_CHUNK","AUTO_PURGE_EVERY_MS","APPEND_ATTEMPTS","decoder","TextDecoder","encoder","TextEncoder","sleep","ms","Promise","resolve","setTimeout","textOf","line","startsWith","parsed","JSON","parse","Object","keys","length","kind","text","SqlTokenStreamSink","pollIntervalMs","idlePollIntervalMs","flushMs","ttlSeconds","autoPurge","writes","Map","lastAutoPurge","table","options","Math","max","runWrites","runId","state","get","undefined","timer","tail","pending","failure","set","release","delete","enqueue","work","next","then","flushText","clearTimeout","decode","encodeStreamEvent","append","raiseFailure","error","frame","attempt","createdAt","Date","now","caught","isUniqueViolation","terminate","flushed","ended","all","purgeInBackground","open","write","chunk","trimEnd","catch","appended","flush","end","fail","stringify","code","message","subscribe","cursor","quietSince","rows","read","row","seq","AgentStreamError","encode","has","close","remove","purgeExpired","lapsed","lapsedRuns","index","slice","resolveTextActionProposalDecision","text","proposals","vocabulary","command","parseTextActionProposalCommand","status","decision","remember","pending","filter","proposal","explicitId","proposalId","undefined","some","id","length","proposalIds","map","candidate","DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY","approve","reject","DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES","approved","rejected","expired","unchanged","ambiguous","ids","join","tooMany","textActionProposalReply","result","replies","escapeRegExp","word","replace","alternatives","words","trim","fold","toLowerCase","test","verbs","match","RegExp","exec","verb","remembers","ptBrActionProposalText","toActionProposalView","proposal","execution","outcomeDelivery","idempotencyKey","_idempotencyKey","preparationInput","_preparationInput","executionContext","_executionContext","rest","withoutLease","undefined","toActionProposalMutationView","result","value","lease","_lease","ActionProposalExecutor","options","execute","proposal","ui","createNegotiatedUiCollector","originToolCallId","actor","id","actorRef","threadId","resolver","resolve","tenantRef","Error","deps","resolveExecution","registry","spec","toolName","kind","context","executionContext","agentName","undefined","uiCapabilities","resolveUiCatalog","output","invoke","snapshotActionProposal","Object","hasOwn","preparationInput","input","runId","originRunId","requestId","toolCallId","idempotencyKey","persona","pageContext","host","emitUi","emit","rolesPolicy","approvedInput","allowedTools","status","result","components","text","error","message","String","ActionProposalWorker","leaseMs","pollIntervalMs","maxConcurrency","timer","stopped","renewals","Set","active","options","value","Number","isSafeInteger","RangeError","workerId","TypeError","start","undefined","tick","runOnce","error","onError","setTimeout","stop","clearInterval","clear","clearTimeout","Promise","resolve","task","finally","store","expireActionProposals","limit","work","index","proposal","claimNextActionProposal","push","execute","all","delivery","claimNextActionProposalOutcome","admitActionProposalOutcome","lease","execution","Error","fenced","renewing","renew","extendActionProposalLease","id","token","generation","then","result","status","setInterval","add","executor","settled","settleActionProposal","onSettled","delete","assertIndependentActionCapabilities","store","resolver","candidate","resolve","Error","isChatQueueStore","actionProposalAdmissionSupported","required","some","method","createFunctionalTool","definition","input","execute","present","preflight","isEnabled","canUse","describe","kind","metadata","spec","inputSchema","handler","bind","undefined"]}
|
|
1
|
+
{"version":3,"sources":["../src/tokens.ts","../src/spi/model-catalog.ts","../src/spi/token-stream-sink.ts","../src/stream-events.ts","../src/turn-frames.ts","../src/tool-ui.ts","../src/tool-presentation.ts","../src/spi/chat-queue.ts","../src/spi/quota-provider.ts","../src/spi/pricing-store.ts","../src/spi/processors.ts","../src/spi/governance-queries.ts","../src/spi/approval-policy.ts","../src/governance/compute.ts","../src/tool-filters.ts","../src/personas.ts","../src/history.ts","../src/processors.ts","../src/structured-output.ts","../src/elicitation-input.ts","../src/elicitation.ts","../src/skills.ts","../src/memory.ts","../src/agent-registry.ts","../src/replay-integrity.ts","../src/control-flow.ts","../src/dangling-tool-calls.ts","../src/dead-run.ts","../src/delegation.ts","../src/action-proposal-discovery.ts","../src/action-proposal-outcome.ts","../src/genui/schema.ts","../src/genui/catalog.ts","../src/genui/tree.ts","../src/genui/text.ts","../src/genui/capabilities.ts","../src/action-proposal-transitions.ts","../src/genui/builtins.ts","../src/genui/registry.ts","../src/tool-presentations.ts","../src/tool-registry.ts","../src/agent-loop.ts","../src/action-proposal-approval.ts","../src/action-proposal-preparation.ts","../src/action-proposal-receipt.ts","../src/diagnostics.ts","../src/negotiated-tool-ui.ts","../src/tool-retry.ts","../src/in-memory-action-proposal-store.ts","../src/in-memory-store.ts","../src/confirm-token.ts","../src/channel-store.ts","../src/confirmed-tool.ts","../src/sql-token-stream-sink.ts","../src/action-proposal-text.ts","../src/action-proposal-view.ts","../src/action-proposal-executor.ts","../src/action-proposal-worker.ts","../src/action-proposal-capabilities.ts","../src/functional-tool.ts"],"sourcesContent":["/**\n * Public, cross-lib-discoverable DI tokens.\n *\n * These use `Symbol.for(...)` (the global symbol registry) on purpose: pnpm peer\n * multiplexing + dual ESM/CJS can load `core` more than once, and a plain `Symbol()`\n * would mint a distinct token per copy and break DI across package boundaries. A\n * registered symbol collapses every copy onto the same token, and lets a sibling lib\n * resolve our injectables by name without importing our internals.\n *\n * Naming convention (ecosystem-wide): `@dudousxd/nestjs-<lib>:<name>`.\n */\nexport const AGENT_OPTIONS = Symbol.for('@dudousxd/nestjs-agent:options');\nexport const AGENT_STORE = Symbol.for('@dudousxd/nestjs-agent:store');\nexport const AGENT_RUNNER = Symbol.for('@dudousxd/nestjs-agent:runner');\n/**\n * The durable runner, provided ONLY by `AgentDurableModule`. When `durable: true`, the module\n * binds `AGENT_RUNNER` to this via an optional injection, so a missing `AgentDurableModule`\n * fails with a clear error instead of a cryptic unresolved-dependency one.\n */\nexport const AGENT_DURABLE_RUNNER = Symbol.for('@dudousxd/nestjs-agent:durable-runner');\nexport const AGENT_SINK = Symbol.for('@dudousxd/nestjs-agent:sink');\nexport const AGENT_MODEL = Symbol.for('@dudousxd/nestjs-agent:model');\nexport const AGENT_ROLES_POLICY = Symbol.for('@dudousxd/nestjs-agent:roles-policy');\n/**\n * @deprecated Nothing binds or injects this token since the quota rework (#230): `AgentModule`\n * enforces and reports the budget through {@link AGENT_QUOTA_PROVIDER}, configured with\n * `AgentModule.forRoot({ quota })`. Inject `AGENT_QUOTA_PROVIDER` instead. Removed in the next major.\n */\nexport const AGENT_QUOTA_STORE = Symbol.for('@dudousxd/nestjs-agent:quota-store');\nexport const AGENT_TOOL_REGISTRY = Symbol.for('@dudousxd/nestjs-agent:tool-registry');\nexport const AGENT_REGISTRY = Symbol.for('@dudousxd/nestjs-agent:agent-registry');\nexport const AGENT_ACTOR_RESOLVER = Symbol.for('@dudousxd/nestjs-agent:actor-resolver');\n/** The governance read-model (usage/spend/threads), consumed by the dashboard + telescope surfaces. */\nexport const AGENT_GOVERNANCE_QUERIES = Symbol.for('@dudousxd/nestjs-agent:governance-queries');\n/** The `QuotaProvider` behind `GET <base>/quota` (and, when the host binds one, the send gate). */\nexport const AGENT_QUOTA_PROVIDER = Symbol.for('@dudousxd/nestjs-agent:quota-provider');\n/** The `ModelCatalog` behind `GET <base>/models` and the model a send may name. Optional. */\nexport const AGENT_MODEL_CATALOG = Symbol.for('@dudousxd/nestjs-agent:model-catalog');\n/** The pricing WRITE side (`AgentPricingStore`) — seeds/updates the per-model rates cost is priced against. */\nexport const AGENT_PRICING_STORE = Symbol.for('@dudousxd/nestjs-agent:pricing-store');\n/** The RAG retrieval seam (`Retriever`) — vector/keyword search behind the agentic tool or inject mode. */\nexport const AGENT_RETRIEVER = Symbol.for('@dudousxd/nestjs-agent:retriever');\n/** The embedding provider (`EmbeddingProvider`) — text→vector for retrieval + ingestion. */\nexport const AGENT_EMBEDDING_PROVIDER = Symbol.for('@dudousxd/nestjs-agent:embedding-provider');\n// Per-agent deps factory. A Symbol.for token (not the class) so DI survives tsup's dual\n// index/durable bundles, which each get their own copy of the AgentDepsFactory class.\nexport const AGENT_DEPS_FACTORY = Symbol.for('@dudousxd/nestjs-agent:deps-factory');\n/** App-wide, ordered `@SystemPromptContributor()` functions the loop appends after the agent base. */\nexport const AGENT_PROMPT_CONTRIBUTORS = Symbol.for('@dudousxd/nestjs-agent:prompt-contributors');\n/**\n * Resolves opaque store `actorRef`s to human display labels for governance/dashboard read surfaces.\n * Optional — see {@link import('./spi/actor-directory.js').ActorDirectory}.\n */\nexport const AGENT_ACTOR_DIRECTORY = Symbol.for('@dudousxd/nestjs-agent:actor-directory');\n/**\n * Persists an uploaded attachment somewhere the model can fetch it from and returns a\n * `MessageAttachment`. Optional — see\n * {@link import('./spi/attachment-staging.js').AttachmentStagingStore}.\n */\nexport const AGENT_ATTACHMENT_STAGING = Symbol.for('@dudousxd/nestjs-agent:attachment-staging');\n/**\n * Console-side HITL approve/reject for the cross-thread approvals inbox. Optional — see\n * {@link import('./spi/approval-port.js').AgentApprovalPort}.\n */\nexport const AGENT_APPROVAL_PORT = Symbol.for('@dudousxd/nestjs-agent:approval-port');\n/**\n * The resolved `SkillsConfig` (provider + scope resolver + ceiling), or `undefined` where the host\n * configured no skills. Bound once and read by BOTH the loop's deps and the listing endpoint, so\n * what a user can invoke and what the model can reach are the same resolution.\n */\nexport const AGENT_SKILLS = Symbol.for('@dudousxd/nestjs-agent:skills');\n/**\n * The resolved `MemoryConfig` (provider + scope resolver + ceilings), or `undefined` where the host\n * configured no memory. Bound once and read by BOTH the loop's deps and the read-back endpoint, so\n * what a person is shown and what the model was shown are the same resolution.\n */\nexport const AGENT_MEMORY = Symbol.for('@dudousxd/nestjs-agent:memory');\n/**\n * A shared, mutable list `SkillDiscoveryService` fills with `@Skill`-decorated providers. Read\n * lazily by the bound {@link AGENT_SKILLS} provider — discovery runs after DI has built it.\n */\nexport const AGENT_SKILL_SOURCES = Symbol.for('@dudousxd/nestjs-agent:skill-sources');\n/**\n * The `ConfirmTokenStore` that makes a `defineConfirmedTool` confirmation single use. Bound by the\n * store modules (`DrizzleAgentStoreModule`, `MikroOrmAgentStoreModule`); inject it into the factory\n * that builds the tool (`provideAgentTool(factory, [AGENT_CONFIRM_TOKEN_STORE])`).\n */\nexport const AGENT_CONFIRM_TOKEN_STORE = Symbol.for('@dudousxd/nestjs-agent:confirm-token-store');\n/**\n * The `ChannelStore` text channels (`@dudousxd/nestjs-agent-channels`) keep their short-lived state\n * in: message ids already answered, questions waiting for an answer, outcomes already relayed. Bound\n * by the store modules (`DrizzleAgentStoreModule`, `MikroOrmAgentStoreModule`) on the\n * `agent_channel_state` table; unbound, `AgentChannelsModule` keeps it in memory.\n */\nexport const AGENT_CHANNEL_STORE = Symbol.for('@dudousxd/nestjs-agent:channel-store');\n","import type { Actor } from '../types.js';\nimport type { ModelProvider, ModelTurnArgs } from './model-provider.js';\n\n/** One model a caller may pick. */\nexport interface ModelCatalogEntry {\n /** What a client sends as `model` — and what the {@link ModelProvider} receives as `args.model`. */\n id: string;\n label: string;\n description?: string;\n /** Short tags a picker can render as chips — `'fast'`, `'reasoning'`, `'vision'`, `'new'`, … */\n badges?: string[];\n /** `false` → listed but not selectable right now (plan, quota, outage); a send naming it is refused. */\n available: boolean;\n /** Why it is unavailable, in words a picker can show. */\n unavailableReason?: string;\n /** Context window, in tokens, when the host knows it. */\n contextWindow?: number;\n}\n\n/** Models grouped under the provider that serves them. */\nexport interface ModelCatalogProviderGroup {\n id: string;\n label: string;\n models: ModelCatalogEntry[];\n}\n\n/** The agent always runs on one model: the picker shows it and offers no choice. */\nexport interface ModelCatalogLock {\n /** The catalog id every turn runs on. */\n model: string;\n /** Why, in words a picker can show (\"This assistant always uses GPT-5\"). */\n reason?: string;\n}\n\n/** What `GET <base>/models` answers. */\nexport interface ModelCatalogView {\n providers: ModelCatalogProviderGroup[];\n /**\n * Present when the agent is locked to one model. Every turn runs on `locked.model` — a send's own\n * `model` and a thread's pin included — and a send naming another model is refused (`400`). List\n * the other models as unavailable too, so an older client that ignores the lock cannot pick them.\n */\n locked?: ModelCatalogLock;\n /** The model a turn runs on when nobody picked one; `null` when the provider decides. */\n default: string | null;\n}\n\nexport interface ModelCatalogQuery {\n actor: Actor;\n /** The agent the picker is for; omitted → the default agent. */\n agent?: string;\n}\n\n/**\n * Which models a caller may run a turn on — the picker's data and the send's gate. The server\n * refuses a `model` (on a send, or pinned on a thread) that this does not list as `available` for\n * the actor and agent, so a client cannot pick a model the host did not offer it.\n *\n * Bind with `AgentModule.forRoot({ models })`. Without one, `GET <base>/models` answers an empty\n * catalog and a request naming a model is refused.\n */\nexport interface ModelCatalog {\n list(query: ModelCatalogQuery): ModelCatalogView | Promise<ModelCatalogView>;\n}\n\n/** A catalog that answers the same view to everyone — for a fixed list of models. */\nexport function staticModelCatalog(view: ModelCatalogView): ModelCatalog {\n return { list: () => view };\n}\n\n/** The entry `id` names in `view`, or `undefined`. */\nexport function findCatalogModel(\n view: ModelCatalogView,\n id: string,\n): ModelCatalogEntry | undefined {\n for (const group of view.providers) {\n const found = group.models.find((model) => model.id === id);\n if (found !== undefined) return found;\n }\n return undefined;\n}\n\n/**\n * A provider that runs every turn on `model` — what the loop wraps the bound provider in when a\n * turn has a selected model, so every call it makes (the answer, a structured-output pass, the\n * follow-up suggestions) goes to the same one. A provider that does not read `args.model` runs its\n * own default, unchanged.\n */\nexport function withSelectedModel(provider: ModelProvider, model: string): ModelProvider {\n return {\n runTurn: (args: ModelTurnArgs) => provider.runTurn({ ...args, model }),\n };\n}\n","/**\n * The \"data plane\": live token transport, decoupled from the durable control plane.\n *\n * The model turn writes deltas to a `SinkWriter` keyed by runId; the HTTP layer\n * `subscribe`s by runId and pipes the chunks to the browser as SSE. A late subscriber\n * (reconnect/resume) replays buffered chunks first, then follows live — which is what\n * makes streaming survive a dropped connection or a pod restart.\n */\nexport interface SinkWriter {\n write(chunk: Uint8Array): void | Promise<void>;\n /** Mark the run's stream finished (no more chunks). */\n end(): void | Promise<void>;\n /**\n * Terminate the run's stream with an error instead of a normal end. Subscribers replay any\n * buffered chunks first, then throw an {@link AgentStreamError} carrying this `code`/`message`\n * — so the transport can surface a typed failure frame instead of leaking it as assistant text.\n */\n fail(error: StreamError): void | Promise<void>;\n /**\n * OPTIONAL: write out anything this writer is still holding back, without ending the stream. Only\n * a sink that gathers frames before writing them (the SQL sink coalesces text) has anything to do\n * here; a delegated run's child writer calls it where it would have ended the stream, so nothing\n * of the delegate's is still held back when its parent — possibly on another replica — writes next.\n */\n flush?(): void | Promise<void>;\n}\n\n/** A machine-readable stream failure. `code` is a stable slug; `message` is human-facing. */\nexport interface StreamError {\n code: string;\n message: string;\n}\n\n/**\n * Thrown out of {@link TokenStreamSink.subscribe} when a run ended via {@link SinkWriter.fail}.\n * Carries the structured {@link StreamError} so the HTTP layer can emit an `event: error` frame.\n */\nexport class AgentStreamError extends Error {\n readonly code: string;\n constructor(error: StreamError) {\n super(error.message);\n this.name = 'AgentStreamError';\n this.code = error.code;\n }\n}\n\nexport interface TokenStreamSink {\n /** Open (or reopen) the writer for a run. */\n open(runId: string): SinkWriter | Promise<SinkWriter>;\n /**\n * Replay buffered chunks for the run, then yield live ones until `end()`. Throws\n * {@link AgentStreamError} if the run was terminated with {@link SinkWriter.fail}.\n */\n subscribe(runId: string): AsyncIterable<Uint8Array>;\n /** Drop any buffer/resources for the run. */\n close(runId: string): void | Promise<void>;\n}\n","/**\n * The structured live-stream vocabulary carried over the {@link SinkWriter} byte channel.\n *\n * The model turn (via the AI-SDK adapter) and the agent loop write these events as NDJSON — one\n * `JSON.stringify(event)\\n` per {@link SinkWriter.write}. The HTTP layer forwards each line as an\n * SSE `data:` frame, and the client transport maps them back to the AI SDK UI-message chunk\n * protocol so the browser renders text, reasoning, and tool cards (input + output) LIVE — the same\n * rich rendering a raw `streamText().toUIMessageStream()` would give, but reconstructed on the\n * client so the sink stays a format-agnostic byte buffer (durable buffering/replay is untouched).\n *\n * Keeping this vocabulary neutral (not AI-SDK `UIMessageChunk`) means core never depends on `ai`:\n * the adapter owns model-parts → event, the transport owns event → UI-chunk.\n *\n * The vocabulary is also a CONTRACT for runners that are not this library's loop: anything that\n * writes these frames (one JSON object per SSE `data:` line) gets the React transport, transcript\n * model and hooks for free. Two rules keep it evolvable:\n * - every frame is a JSON object with a string `kind`; a reader MUST tolerate kinds it does not\n * know (the React transport forwards them as `data-<kind>` parts rather than dropping them);\n * - fields are only ever added, and new fields are optional.\n */\nimport type { ElicitationRequest } from './elicitation.js';\nimport type { ChatQueueState } from './spi/chat-queue.js';\nimport type { ToolConfirmation } from './tool-presentation.js';\nimport type { MessageUsage } from './types.js';\n\n/**\n * A component the server pushed into the conversation: generative UI that is NOT a tool call's\n * rendering. It is addressed by `component` (a key in the client's own component registry), never\n * by a tool name, so a runner can emit one from anywhere — a tool body, a post-processing step, a\n * sandboxed agent that renders through its own protocol.\n *\n * `id` is the component's identity within the message: a second frame with the same `id` REPLACES\n * the first (streaming props into a chart, flipping a card from \"loading\" to \"ready\"), it never\n * adds a second component.\n */\nexport interface AgentUiComponent {\n id: string;\n /** Registry key the client resolves to its own renderer, e.g. `data-table`. */\n component: string;\n props: Record<string, unknown>;\n /** Schema version of `props`, so a client can keep rendering components persisted by an older server. */\n version?: number;\n /** Validated readable fallback retained for clients without this renderer. */\n fallbackText?: string;\n /** Trusted schema versions for every component in a persisted tree. */\n componentVersions?: Record<string, number>;\n /**\n * The tool call that pushed the component (`ctx.emitUi`), when one did. Lets a client place it\n * with that call — a reloaded message puts it right after the call's tool part, where the live\n * stream showed it. Absent for a component pushed outside a tool.\n */\n toolCallId?: string;\n}\n\n/**\n * Who has to settle an action tool call, and until when. Metadata only: the call itself is still\n * settled through the tool-call approve/reject routes, by its `toolCallId`.\n */\nexport interface AgentApprovalRequest {\n target?: { kind: 'proposal'; proposalId: string };\n /** Resolved confirmation from the action preflight; overrides presentation templates. */\n confirmation?: ToolConfirmation;\n /** The tool call awaiting the decision — the `id` of a call already announced on this stream. */\n id: string;\n /**\n * Who may decide. Open vocabulary the host defines — `'requester'` (the person chatting),\n * `'admin'`, a role name, a team. A client uses it to say \"waiting on an admin\" instead of\n * offering buttons the viewer cannot use.\n */\n approver: string;\n /** ISO-8601 instant after which the request lapses. Absent → it never expires. */\n expiresAt?: string;\n /** Why this call needs a person, in words for that person. */\n reason?: string;\n}\n\n/**\n * How an approval settled — the other half of {@link AgentApprovalRequest}, under the same `id`.\n * Metadata again: the call's own outcome still arrives as `tool-output` (approved and ran),\n * `tool-output-error` (approved and failed) or `tool-output-denied` (rejected or expired).\n */\nexport interface AgentApprovalSettlement {\n id: string;\n status: 'approved' | 'rejected' | 'expired';\n /** Repeated from the request, for a call approved without one being streamed (a remembered approval). */\n approver?: string;\n /** Opaque ref of who decided. Absent on an expiry. */\n decidedBy?: string;\n /** The surface the decision came through: `'web'`, `'slack'`, `'remembered'`, … */\n decidedVia?: string;\n /** The approval also covers later calls of this tool in this thread. */\n remember?: boolean;\n /** What the person said when declining. */\n reason?: string;\n}\n\nexport type AgentStreamEvent =\n | { kind: 'step-start' }\n /**\n * Closes the step opened by the matching `step-start`. Carries the model call's token usage and\n * `costUsd` (an estimate from the bound pricing store, or `null` when unpriced/unbound — never a\n * fabricated `0`) so a live client can render running cost without waiting for a thread re-fetch.\n */\n | {\n kind: 'step-finish';\n usage?: MessageUsage;\n costUsd?: number | null;\n /**\n * How long the model spent thinking in this step, in ms — the same number persisted as\n * `StoredMessage.reasoningMs`, so a live thread and a reloaded one read the same duration.\n * Absent when the step had no reasoning.\n */\n reasoningMs?: number;\n /**\n * The model the step ran on: the one the provider reported, else the configured `modelId`.\n * What a per-model usage report keys on (the AG-UI producer's `RUN_FINISHED.usage`). Absent\n * when neither is known; a reader that does not know the field ignores it.\n */\n model?: string;\n }\n | { kind: 'text'; text: string }\n | { kind: 'reasoning'; text: string }\n /**\n * `toolKind` collapses `ToolKind`'s `'agent'` into `'read'` — delegation tools auto-execute like a read tool.\n *\n * `parentId` nests this call under another call on the same stream: the inner calls a code-mode\n * `execute` makes, the tools a delegated sub-agent runs. The parent must be announced first. A\n * call's parent is fixed by its first frame that names one; later frames may omit it.\n */\n | {\n kind: 'tool-input-start';\n id: string;\n name: string;\n toolKind: 'read' | 'action';\n parentId?: string;\n }\n | { kind: 'tool-input-delta'; id: string; delta: string }\n | {\n kind: 'tool-input-available';\n id: string;\n name: string;\n input: unknown;\n toolKind: 'read' | 'action';\n /** Same as on `tool-input-start`, for a runner that announces a call without streaming its input. */\n parentId?: string;\n }\n | { kind: 'tool-output'; id: string; output: unknown }\n | { kind: 'tool-output-error'; id: string; error: string }\n /**\n * A person was asked to approve an action tool and declined it. Its own frame, NOT\n * `tool-output-error`: a refusal is a decision with a known outcome — nothing ran — while a\n * failure is an outcome nobody chose and whose effects are unknown. Rendering them the same way\n * tells an operator their own \"no\" was a malfunction. Maps onto the SDK's `output-denied` tool\n * part state, which a client reads without knowing any tool's name.\n */\n | { kind: 'tool-output-denied'; id: string; reason?: string }\n /**\n * The run has put a question set to the user and is parked until someone answers it (or skips).\n * Written by the LOOP for both elicitation surfaces — the configured intake and the model's `ask`\n * tool — so a client renders one form either way rather than learning to recognise a tool name.\n * The matching `tool-output` frame, under the same `id`, carries the settled answers.\n */\n | { kind: 'elicitation'; id: string; request: ElicitationRequest }\n /**\n * An action tool call (already announced by `tool-input-start`/`tool-input-available` under the\n * same `id`) is parked on a person. Optional: a client still treats an `action` call stuck at\n * its input as pending — this frame adds WHO has to decide and UNTIL WHEN, and moves the call\n * into the AI SDK's native `approval-requested` state.\n */\n | ({ kind: 'approval-requested' } & AgentApprovalRequest)\n /**\n * A parked action call was decided (or lapsed). Optional, like `approval-requested`: it adds WHO\n * decided, THROUGH WHAT and whether the approval is REMEMBERED; the outcome itself rides the\n * call's own output frame. See {@link AgentApprovalSettlement}.\n */\n | ({ kind: 'approval-settled' } & AgentApprovalSettlement)\n /**\n * Server-pushed generative UI, positioned in the message where it arrives. Not tied to a tool\n * call. See {@link AgentUiComponent}.\n */\n | ({ kind: 'ui' } & AgentUiComponent)\n /**\n * The thread's title was set or changed while this run streamed (typically derived from the\n * first exchange). Thread-level, not message content: a client updates its header/sidebar and\n * does not render it in the transcript.\n */\n | { kind: 'title'; title: string }\n /**\n * Host-defined facts about the message being streamed (the model that answered, how long it took,\n * the error it ended with), merged into the client message's `metadata`. The persisted\n * counterpart is `StoredMessage.metadata`, so a reload reads the same values. The library's own\n * loop never writes it; a runner that is not this library's loop uses it for what its store keeps\n * per message.\n */\n | { kind: 'message-metadata'; metadata: Record<string, unknown> }\n /**\n * Someone stopped this run. The stream's LAST frame, written by the runner that settled the\n * cancel, immediately before a normal `end()` — never a `fail()`, because a cancel is not an\n * error and a client that retries on a failed stream must not retry this.\n *\n * A run that simply ends wrote everything it had; one that ends after this frame did not, and the\n * difference is the whole point: without it a reader cannot tell a truncated answer from a\n * complete one. Consumers that predate the frame ignore it and see the `end()` they always saw.\n */\n | { kind: 'cancelled' }\n /**\n * The thread's message queue changed — a snapshot of the whole queue, never a delta, so a client\n * that missed one frame is corrected by the next. Written into the stream of the run that is\n * holding the thread: when someone queues, edits, reorders or removes a waiting message, and, just\n * before this run's own terminal frame, with what happens next — `started` names the queued\n * message that became the next turn and that turn's run id (attach to it with\n * `GET <base>/chat/:runId/stream`), `queue.paused` says why nothing starts.\n */\n | { kind: 'queue'; queue: ChatQueueState; started?: { messageId: string; runId: string } };\n\nconst encoder = new TextEncoder();\n\n/** Encode one event as an NDJSON line (`{...}\\n`) for {@link SinkWriter.write}. */\nexport function encodeStreamEvent(event: AgentStreamEvent): Uint8Array {\n return encoder.encode(`${JSON.stringify(event)}\\n`);\n}\n\n/**\n * Read one NDJSON line back, or `null` when the line is not a stream event at all.\n *\n * `null` covers a genuinely opaque chunk, not just malformed JSON: the sink is a byte channel, so a\n * model provider is free to write anything into it and some write bare text. A caller that has to\n * CLASSIFY a chunk — the output gate, which may only forward what it can prove is not the answer —\n * treats an unreadable frame as unclassifiable rather than guessing.\n */\nexport function decodeStreamEvent(line: string): AgentStreamEvent | null {\n try {\n const parsed: unknown = JSON.parse(line);\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n typeof (parsed as AgentStreamEvent).kind === 'string'\n ) {\n return parsed as AgentStreamEvent;\n }\n } catch {\n /* not a stream event — the caller decides what an opaque chunk means */\n }\n return null;\n}\n\n/**\n * The `code` of a failed run's `event: error` frame — what a client branches on, and translates.\n * `quota_exceeded`, `output_rejected` and `structured_output_invalid` are outcomes the library words\n * itself (their `message` is safe to show as it is); the rest are crashes, whose `message` is a\n * generic sentence in production. Open-ended on purpose: a host's own runner may send other codes.\n */\nexport type AgentStreamErrorCode =\n | 'quota_exceeded'\n | 'output_rejected'\n | 'structured_output_invalid'\n /** The durable runtime refused a checkpoint position: the run's journal and its code disagree. */\n | 'replay_diverged'\n /** A model call ended without producing anything. */\n | 'model_no_output'\n | 'run_failed';\n","import type { ModelTurnResult } from './spi/model-provider.js';\nimport type { SinkWriter } from './spi/token-stream-sink.js';\nimport { type AgentUiComponent, decodeStreamEvent } from './stream-events.js';\n\n/** What a model turn streamed that the persisted message keeps, beyond its text and tool calls. */\nexport interface TurnFrameSummary {\n reasoning?: string;\n reasoningMs?: number;\n ui?: AgentUiComponent[];\n}\n\nexport interface ObservedTurnFrames {\n /** Hand THIS to the provider: every write passes through to the wrapped writer unchanged. */\n writer: SinkWriter;\n /** What was seen so far. Closes an open thinking burst at the moment it is called. */\n summary(): TurnFrameSummary;\n}\n\n/**\n * Watch the frames a model turn writes, to learn what the stream showed that the provider's result\n * does not carry: the model's thinking (text and how long it took) and any pushed UI components.\n *\n * Derived from the FRAMES rather than asked of each provider, so every provider that streams the\n * vocabulary gets reasoning persisted without implementing anything. Thinking time is the sum of\n * each burst of consecutive `reasoning` frames — from the first one to the next frame that is not\n * reasoning (or the end of the turn) — which is what a reader watched as \"thinking\".\n *\n * Call it inside the step that runs the model, so the summary rides that step's journaled result\n * and a replay reads the same numbers back instead of re-measuring a turn that is not happening.\n */\nexport function observeTurnFrames(\n writer: SinkWriter,\n now: () => number = Date.now,\n): ObservedTurnFrames {\n const decoder = new TextDecoder();\n let pending = '';\n let reasoning = '';\n let reasoningMs = 0;\n let burstStartedAt: number | undefined;\n const ui = new Map<string, AgentUiComponent>();\n\n function closeBurst(): void {\n if (burstStartedAt !== undefined) {\n reasoningMs += Math.max(0, now() - burstStartedAt);\n burstStartedAt = undefined;\n }\n }\n\n function observeLine(line: string): void {\n if (line.trim().length === 0) {\n return;\n }\n const event = decodeStreamEvent(line);\n if (event === null) {\n return;\n }\n if (event.kind === 'reasoning') {\n burstStartedAt ??= now();\n reasoning += event.text;\n return;\n }\n closeBurst();\n if (event.kind === 'ui') {\n // A repeat id replaces the props but keeps the component where it first appeared, exactly as\n // the client's data part does.\n ui.set(event.id, {\n id: event.id,\n component: event.component,\n props: event.props,\n ...(event.version !== undefined ? { version: event.version } : {}),\n });\n }\n }\n\n function observe(chunk: Uint8Array): void {\n pending += decoder.decode(chunk, { stream: true });\n let newline = pending.indexOf('\\n');\n while (newline !== -1) {\n observeLine(pending.slice(0, newline));\n pending = pending.slice(newline + 1);\n newline = pending.indexOf('\\n');\n }\n }\n\n return {\n writer: {\n write(chunk) {\n // Observed before it is forwarded, so a burst closes at the moment the next frame was\n // produced rather than whenever a slow sink got round to accepting it.\n observe(chunk);\n return writer.write(chunk);\n },\n end: () => writer.end(),\n fail: (error) => writer.fail(error),\n },\n summary() {\n if (pending.length > 0) {\n observeLine(pending);\n pending = '';\n }\n closeBurst();\n return {\n ...(reasoning.length > 0 ? { reasoning, reasoningMs: Math.round(reasoningMs) } : {}),\n ...(ui.size > 0 ? { ui: [...ui.values()] } : {}),\n };\n },\n };\n}\n\n/** Fill what a provider did not report from what its frames showed. A provider's own value wins. */\nexport function withTurnFrames<T extends ModelTurnResult>(result: T, frames: TurnFrameSummary): T {\n return {\n ...result,\n ...(result.reasoning === undefined && frames.reasoning !== undefined\n ? { reasoning: frames.reasoning }\n : {}),\n ...(result.reasoningMs === undefined && frames.reasoningMs !== undefined\n ? { reasoningMs: frames.reasoningMs }\n : {}),\n ...(result.ui === undefined && frames.ui !== undefined ? { ui: frames.ui } : {}),\n };\n}\n","import type { AiToolCtx } from './spi/tool.js';\nimport { type AgentStreamEvent, type AgentUiComponent } from './stream-events.js';\n\n/**\n * Components a tool pushes through `ctx.emitUi` have to survive a durable replay without being\n * streamed or persisted twice. They do it by riding the tool step's RESULT: the step that ran the\n * tool (`tool:<callId>` in-process, or the dispatched `AgentRunSteps.tool`) returns its output\n * wrapped together with the components, the runtime journals that, and a replay reads both back\n * without running anything. The loop then persists them once, from the step that already persists\n * the step's tool results.\n *\n * The wrapper is used ONLY when a tool pushed something, so every other tool journals exactly the\n * bytes it always did, and a run recorded before this existed replays unchanged.\n */\nconst TOOL_STEP_UI = '@@nestjs-agent/tool-step-ui';\n\ninterface ToolStepOutputWithUi {\n [TOOL_STEP_UI]: 1;\n output: unknown;\n ui: AgentUiComponent[];\n preflightDenied?: string;\n text?: string;\n}\n\n/** The tool step's journaled result: the bare output, or the output plus the components it pushed. */\nexport function wrapToolStepOutput(\n output: unknown,\n ui: readonly AgentUiComponent[],\n text?: string,\n): unknown {\n // Escape ordinary output that happens to match our envelope: unwrap exactly one layer.\n const reserved = typeof output === 'object' && output !== null && TOOL_STEP_UI in output;\n if (ui.length === 0 && !reserved && !text) {\n return output;\n }\n const wrapped: ToolStepOutputWithUi = {\n [TOOL_STEP_UI]: 1,\n output,\n ui: [...ui],\n ...(text ? { text } : {}),\n };\n return wrapped;\n}\n\n/** Carry domain refusal across a remote step without losing its type in error serialization. */\nexport function wrapToolPreflightDenied(reason: string): unknown {\n const wrapped: ToolStepOutputWithUi = {\n [TOOL_STEP_UI]: 1,\n output: null,\n ui: [],\n preflightDenied: reason,\n };\n return wrapped;\n}\n\n/** Read a tool step's result back — either shape. */\nexport function unwrapToolStepOutput(raw: unknown): {\n output: unknown;\n ui: AgentUiComponent[];\n preflightDenied?: string;\n text?: string;\n} {\n if (\n typeof raw === 'object' &&\n raw !== null &&\n (raw as Partial<ToolStepOutputWithUi>)[TOOL_STEP_UI] === 1\n ) {\n const wrapped = raw as ToolStepOutputWithUi;\n return {\n output: wrapped.output,\n ui: Array.isArray(wrapped.ui) ? wrapped.ui : [],\n ...(typeof wrapped.text === 'string' ? { text: wrapped.text } : {}),\n ...(typeof wrapped.preflightDenied === 'string'\n ? { preflightDenied: wrapped.preflightDenied }\n : {}),\n };\n }\n return { output: raw, ui: [] };\n}\n\nexport type EmitUi = AiToolCtx['emitUi'];\n\n/**\n * `ctx.emitUi` where there is no conversation to push into (the MCP server, a direct\n * `registry.invoke`): nothing is streamed or persisted, but the call resolves to an id — the one it\n * was given, else `<scope>:ui:<n>` — so a tool never has to test for the capability.\n */\nexport function createNoopEmitUi(scope = 'noop'): EmitUi {\n let next = 0;\n return async (_component, _props, options = {}) => {\n if (options.id !== undefined) {\n return { id: options.id };\n }\n const id = `${scope}:ui:${next}`;\n next += 1;\n return { id };\n };\n}\n\n/** Collects what one tool invocation pushes, streaming each push as it happens. */\nexport interface UiCollector {\n emit: EmitUi;\n /** Everything pushed so far: first-seen order, last props per id. */\n components(): AgentUiComponent[];\n /**\n * A new ATTEMPT of the same call (a transient retry): numbering restarts, so the retry's pushes\n * reuse — and replace — the ids the failed attempt used.\n */\n restart(): void;\n}\n\n/**\n * `write` streams one frame; omit it where there is no live stream (the component is still\n * collected and persisted).\n */\nexport function createUiCollector(\n toolCallId: string,\n write?: (event: AgentStreamEvent) => void | Promise<void>,\n): UiCollector {\n const pushed = new Map<string, AgentUiComponent>();\n let next = 0;\n const emit: EmitUi = async (component, props, options = {}) => {\n if (typeof component !== 'string' || component.length === 0) {\n throw new Error('emitUi: component must be a non-empty string');\n }\n if (typeof props !== 'object' || props === null || Array.isArray(props)) {\n throw new Error('emitUi: props must be a JSON object');\n }\n let id = options.id;\n if (id === undefined) {\n id = `${toolCallId}:ui:${next}`;\n next += 1;\n }\n const entry: AgentUiComponent = {\n id,\n component,\n // Snapshot: the frame and the persisted value are what the tool pushed at THIS moment, not\n // whatever the object it handed over looks like when the step settles.\n props: JSON.parse(JSON.stringify(props)) as Record<string, unknown>,\n ...(options.version !== undefined ? { version: options.version } : {}),\n ...(options.fallbackText !== undefined ? { fallbackText: options.fallbackText } : {}),\n ...(options.componentVersions !== undefined\n ? { componentVersions: { ...options.componentVersions } }\n : {}),\n toolCallId,\n };\n // Delete-then-set would move it; a repeat id keeps its first position, like the client's part.\n pushed.set(id, entry);\n await write?.({ kind: 'ui', ...entry });\n return { id };\n };\n return {\n emit,\n components: () => [...pushed.values()],\n restart: () => {\n next = 0;\n },\n };\n}\n\n/** Merge component lists: first-seen order, the last props for each id. */\nexport function mergeUi(\n ...lists: readonly (readonly AgentUiComponent[] | undefined)[]\n): AgentUiComponent[] {\n const merged = new Map<string, AgentUiComponent>();\n for (const list of lists) {\n for (const component of list ?? []) {\n merged.set(component.id, component);\n }\n }\n return [...merged.values()];\n}\n\n/** Escape code units native PostgreSQL/MySQL TEXT cannot store; retain ordinary prose and emoji. */\nexport function escapeUnsafeToolUiText(text: string): string {\n return text\n .replaceAll('\\u0000', '\\\\u0000')\n .replace(\n /[\\uD800-\\uDFFF]/gu,\n (unit) => `\\\\u${unit.charCodeAt(0).toString(16).padStart(4, '0')}`,\n );\n}\n","import type { ToolKind } from './types.js';\n\n/**\n * How a person-facing surface talks about a tool WITHOUT ever naming it. Declared on the server,\n * beside the tool's input schema, because whoever changes the input is the one who has to re-word\n * the sentence that mentions it — and a client that shipped its own name-to-sentence map would go\n * stale the moment a tool was renamed. A tool name is an identifier, never copy.\n *\n * `running` / `done` (and `confirm.title`, `confirm.detail`, `result.text`) are templates:\n * `{dotted.path}` placeholders are filled from the call's INPUT (or, for `result`, its OUTPUT), so one\n * declaration covers every call the tool will ever receive and replays identically from history.\n * A placeholder with nothing behind it collapses along with the space before it.\n */\nexport interface ToolPresentation {\n /** Noun phrase, for counts and headings: \"Database query\", \"Knowledge base\". */\n label: string;\n /** Present progressive, while the call is in flight: \"Reading {bucket}\". */\n running: string;\n /** Settled, once the output is in: \"Read {bucket}\". */\n done: string;\n /** A key into the client's own glyph map (`database`, `search`, …). Unknown keys fall back to a generic glyph there. */\n icon?: string;\n /** One line naming what the tool reaches, for when the activity line is opened. */\n detail?: string;\n /** `destructive` earns the warning treatment on an approval prompt. */\n tone?: ToolPresentationTone;\n /** What a person is being asked to allow when an `action` call parks for approval. */\n confirm?: ToolConfirmation;\n /** How the call's OUTPUT reads as content. */\n result?: ToolResultView;\n}\n\nexport type ToolPresentationTone = 'neutral' | 'destructive';\n\nexport interface ToolConfirmation {\n /** \"Delete {count} files?\" */\n title: string;\n /** The button: \"Delete\". */\n verb: string;\n /** A sentence under the title, when the title alone does not say what changes. */\n detail?: string;\n}\n\n/** A value read out of a tool's output by dotted path, with the words to put next to it. */\nexport interface ToolResultField {\n path: string;\n label: string;\n unit?: string;\n}\n\n/**\n * How a tool's output reads as content. Every variant names dotted paths into the output rather\n * than shapes, so a renderer never has to recognise which tool it is drawing: it receives\n * `{ view, output }` and draws it.\n */\nexport type ToolResultView =\n /** A row of labelled readings — one result, several facets. */\n | { kind: 'metrics'; fields: ToolResultField[] }\n /** `rows` is a path to an array; each column's `path` is read WITHIN a row. */\n | { kind: 'table'; columns: ToolResultField[]; rows: string; empty?: string }\n /** `lines` is a path to an array of strings, drawn as a log tail. */\n | { kind: 'log'; lines: string }\n /** One sentence, templated over the output. */\n | { kind: 'note'; text: string }\n /** The output is drawn somewhere else on the screen already (a pushed component, a side panel). */\n | { kind: 'elsewhere' };\n\n/**\n * `GET <base>/tools?agent=*` (and `useToolCatalog({ agent: ALL_AGENTS })`): every tool the actor\n * reaches through ANY agent, each once — for a surface that shows several agents' conversations.\n */\nexport const ALL_AGENTS = '*';\n\n/**\n * One tool as `GET <base>/tools` reports it: the tools THIS actor may be offered by the chosen agent,\n * with how each is spoken about. `presentation` is absent for a tool that declared none — a client\n * then narrates it generically rather than falling back to its name.\n */\nexport interface ToolCatalogEntry {\n /** The wire name tool parts carry (`tool-<name>`) — the key a client looks a call up by. */\n name: string;\n kind: ToolKind;\n presentation?: ToolPresentation;\n}\n","import type { UiCapabilities } from '../genui/capabilities.js';\nimport type { Actor, AgentHostContext, MessageAttachment, PageContext } from '../types.js';\nimport type { AgentStore } from './agent-store.js';\n\n/**\n * Why a thread's queue stopped draining. A paused queue keeps its messages; nothing starts until\n * someone resumes it (`POST <base>/threads/:id/queue/resume`, `chat.queue.resume()`).\n *\n * - `run_failed` the turn before it failed — the next message would likely fail the same way,\n * and the person should see the error before more of their messages are spent.\n * - `cancelled` someone pressed Stop. Stop means stop: the queue does not start behind it.\n * An interrupt (`mode: 'interrupt'`) is the exception — its message starts.\n * - `quota_exceeded` the next message's actor is over budget; resuming later retries the check.\n * - `start_failed` the next message could not be started (the runner refused it).\n */\nexport type QueuePauseReason = 'run_failed' | 'cancelled' | 'quota_exceeded' | 'start_failed';\n\nexport interface QueuePause {\n reason: QueuePauseReason;\n /** Human-facing detail (the failure, the quota window), when there is one. */\n message?: string;\n /** ISO-8601 instant the queue paused. */\n at: string;\n}\n\n/**\n * A message a person sent while a turn was still running on the thread, waiting its turn. It is not\n * part of the transcript until it starts: the loop appends it as the turn's user message, exactly as\n * if it had been sent then. Everything a send carries is captured at enqueue time, resolved and\n * checked there (agent, model, attachments), so a queued message starts with no request around it.\n */\nexport interface QueuedMessage {\n id: string;\n threadId: string;\n /** Who queued it. The turn it starts runs as this actor. */\n actor: Actor;\n content: string;\n attachments?: MessageAttachment[];\n agentName?: string;\n /** The persona the send resolved (explicit, the thread's, or the agent's default) — what it starts under. */\n persona?: string;\n model?: string;\n pageContext?: PageContext;\n uiCapabilities?: UiCapabilities;\n /** The send's {@link AgentRunInput.hostContext}, carried to the turn it starts. Never on the wire view. */\n hostContext?: AgentHostContext;\n /**\n * Queued by an interrupt (`POST chat { mode: 'interrupt' }`): the running turn was cancelled to\n * make room for it, so the cancel starts it instead of pausing the queue.\n */\n interrupt?: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\n/** A queued message as the wire shows it — {@link QueuedMessage} without the actor or thread. */\nexport interface QueuedMessageView {\n id: string;\n content: string;\n attachments?: MessageAttachment[];\n agentName?: string;\n persona?: string;\n model?: string;\n interrupt?: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\n/**\n * A thread's queue: its waiting messages in the order they will run, and whether it is draining.\n * What `GET <base>/threads/:id/queue` answers, what `ThreadDetail.queue` carries, and what every\n * `queue` stream frame snapshots.\n */\nexport interface ChatQueueState {\n items: QueuedMessageView[];\n paused: QueuePause | null;\n}\n\nexport interface EnqueueMessageInput {\n threadId: string;\n actor: Actor;\n content: string;\n attachments?: MessageAttachment[];\n agentName?: string;\n persona?: string;\n model?: string;\n pageContext?: PageContext;\n uiCapabilities?: UiCapabilities;\n hostContext?: AgentHostContext;\n interrupt?: boolean;\n /** `'tail'` (default) runs it after everything already waiting; `'head'` runs it next. */\n at?: 'tail' | 'head';\n}\n\n/**\n * What a store may change on a waiting message (`PATCH <base>/queue/:messageId` sets the text and\n * attachments). An omitted key leaves the field as it is.\n */\nexport interface QueuedMessagePatch {\n content?: string;\n /** `null` drops every attachment. */\n attachments?: MessageAttachment[] | null;\n /**\n * Mark (or unmark) the message as an interrupt — what `POST <base>/queue/:messageId/interrupt`\n * does to a message that is already waiting, before it cancels the running turn for it.\n */\n interrupt?: boolean;\n}\n\n/**\n * A store that can hold a thread's queue of waiting messages, and admit ONE run per thread at a time.\n *\n * Probed STRUCTURALLY ({@link isChatQueueStore}), like `ThreadTurnReader`: a store that predates it\n * keeps the old behaviour (a send on a busy thread starts a second, concurrent run). All members or\n * none — a queue without the admission primitives cannot be drained safely across processes.\n *\n * Admission is the thread's `activeStreamId`, compare-and-set:\n * - {@link claimActiveStream} sets it to `runId` only when it is free, already `runId` (a retried\n * claim is idempotent), or held by `replacing` (a handoff from the run that is settling, or a\n * takeover from a holder the runner reports dead). Exactly one of two racing claims wins.\n * - {@link releaseActiveStream} clears it only when `runId` still holds it — so a run that settles\n * after it handed the thread to the next one cannot clear the next one's claim.\n */\nexport interface ChatQueueStore {\n enqueueMessage(input: EnqueueMessageInput): Promise<QueuedMessage>;\n /** The thread's waiting messages, in run order (the head first). */\n listQueue(threadId: string): Promise<QueuedMessage[]>;\n getQueuedMessage(id: string): Promise<QueuedMessage | null>;\n /** `null` when there is no such message (it started, or was removed). */\n updateQueuedMessage(id: string, patch: QueuedMessagePatch): Promise<QueuedMessage | null>;\n /** Move a message to `index` (clamped) in its thread's run order. `false` when it is gone. */\n moveQueuedMessage(id: string, index: number): Promise<boolean>;\n /**\n * Remove a message. `false` when it was already gone — which is also how a drain learns that the\n * head it was about to start was deleted under it, so it must be a real conditional delete.\n */\n removeQueuedMessage(id: string): Promise<boolean>;\n /** Remove every waiting message on the thread; answers how many there were. */\n clearQueue(threadId: string): Promise<number>;\n queuePause(threadId: string): Promise<QueuePause | null>;\n setQueuePause(threadId: string, pause: QueuePause | null): Promise<void>;\n /** The run currently holding the thread, or `null`. */\n activeRunForThread(threadId: string): Promise<string | null>;\n claimActiveStream(\n threadId: string,\n runId: string,\n options?: { replacing?: string },\n ): Promise<boolean>;\n releaseActiveStream(threadId: string, runId: string): Promise<boolean>;\n}\n\nconst CHAT_QUEUE_METHODS = [\n 'enqueueMessage',\n 'listQueue',\n 'getQueuedMessage',\n 'updateQueuedMessage',\n 'moveQueuedMessage',\n 'removeQueuedMessage',\n 'clearQueue',\n 'queuePause',\n 'setQueuePause',\n 'activeRunForThread',\n 'claimActiveStream',\n 'releaseActiveStream',\n] as const satisfies readonly (keyof ChatQueueStore)[];\n\n/** Whether `store` implements every {@link ChatQueueStore} member. */\nexport function isChatQueueStore(store: AgentStore): store is AgentStore & ChatQueueStore {\n const candidate = store as unknown as Record<string, unknown>;\n return CHAT_QUEUE_METHODS.every((method) => typeof candidate[method] === 'function');\n}\n\n/**\n * Release the thread `runId` was streaming — conditionally when the store can compare, so a run\n * that already handed the thread to the next queued turn does not clear that turn's claim; the old\n * unconditional clear on a store that cannot.\n */\nexport async function releaseThreadRun(\n store: AgentStore,\n threadId: string,\n runId: string,\n): Promise<void> {\n if (isChatQueueStore(store)) {\n await store.releaseActiveStream(threadId, runId);\n return;\n }\n await store.setActiveStream(threadId, null);\n}\n\n/** The wire view of a queued message. */\nexport function queuedMessageView(message: QueuedMessage): QueuedMessageView {\n return {\n id: message.id,\n content: message.content,\n ...(message.attachments !== undefined && message.attachments.length > 0\n ? { attachments: message.attachments }\n : {}),\n ...(message.agentName !== undefined ? { agentName: message.agentName } : {}),\n ...(message.persona !== undefined ? { persona: message.persona } : {}),\n ...(message.model !== undefined ? { model: message.model } : {}),\n ...(message.interrupt === true ? { interrupt: true } : {}),\n createdAt: message.createdAt,\n updatedAt: message.updatedAt,\n };\n}\n","import type { Actor } from '../types.js';\n\n/** The span a quota window counts over, in UTC. */\nexport type QuotaPeriod = 'day' | 'month';\n\n/** One budget window: what was spent in it, and the ceiling when there is one. */\nexport interface QuotaWindow {\n period: QuotaPeriod;\n /**\n * Tokens used in the window. Absent → the budget does not count tokens (a USD-only spend cap, such\n * as an AI gateway's) — never a fabricated `0`.\n */\n usedTokens?: number;\n /** Absent → no token ceiling on this window. */\n limitTokens?: number;\n usedUsd: number;\n /** Absent → no spend ceiling on this window. */\n limitUsd?: number;\n /** ISO-8601 instant the window starts over (next UTC midnight, first of next month). */\n resetsAt?: string;\n /**\n * The soft limit: the share of a ceiling (`0..1`, e.g. `0.8`) past which a client should warn\n * that the budget is running out. Absent → no warning for this window.\n */\n warnAt?: number;\n}\n\n/** Which window stopped the actor, when one did. */\nexport interface QuotaBlock {\n period: QuotaPeriod;\n /** Words a client can show (\"Monthly AI budget reached\"). */\n reason?: string;\n}\n\n/** A window past its soft limit ({@link QuotaWindow.warnAt}) but not exhausted. */\nexport interface QuotaWarning {\n period: QuotaPeriod;\n /** How much of the window's ceiling is used, `0..1` (the larger of spend and tokens). */\n ratio: number;\n /** Words a client can show (\"80% of your monthly AI budget used\"). */\n reason?: string;\n}\n\n/** What `GET <base>/quota` answers. */\nexport interface QuotaReport {\n windows: QuotaWindow[];\n /** Present when a window is exhausted — a send will be refused until it resets. */\n blocked?: QuotaBlock;\n /**\n * Present when a window crossed its `warnAt` and none is exhausted — the fullest one. A client\n * may also derive it from the windows ({@link quotaWarning}); the server's wins.\n */\n warning?: QuotaWarning;\n}\n\nexport interface QuotaQuery {\n actor: Actor;\n /** The instant to report for; defaults to now. */\n now?: Date;\n}\n\n/**\n * The actor's budget across windows — the read behind `GET <base>/quota` and, when the host binds\n * one (`AgentModule.forRoot({ quota })`), the gate a send passes: a report with `blocked`\n * refuses the turn with `429` before it starts.\n *\n * The default reads the usage ledger (`LedgerQuotaProvider` in `@dudousxd/nestjs-agent`); a host\n * with its own budget (an AI-gateway spend cap, a plan's monthly allowance) implements this.\n */\nexport interface QuotaProvider {\n report(query: QuotaQuery): Promise<QuotaReport>;\n}\n\n/** The first window whose token or spend ceiling is reached, as a {@link QuotaBlock}. */\nexport function exhaustedWindow(windows: readonly QuotaWindow[]): QuotaBlock | undefined {\n for (const window of windows) {\n const tokensOut =\n window.limitTokens !== undefined && (window.usedTokens ?? 0) >= window.limitTokens;\n const spendOut = window.limitUsd !== undefined && window.usedUsd >= window.limitUsd;\n if (tokensOut || spendOut) {\n return {\n period: window.period,\n reason: `${window.period === 'day' ? 'Daily' : 'Monthly'} ${spendOut ? 'spend' : 'token'} limit reached`,\n };\n }\n }\n return undefined;\n}\n\n/** How much of `window`'s ceilings is used, `0..1+` (the larger of spend and tokens), or `null`. */\nexport function quotaUsedRatio(window: QuotaWindow): number | null {\n const ratios: number[] = [];\n if (window.limitUsd !== undefined && window.limitUsd > 0) {\n ratios.push(window.usedUsd / window.limitUsd);\n }\n if (\n window.limitTokens !== undefined &&\n window.limitTokens > 0 &&\n window.usedTokens !== undefined\n ) {\n ratios.push(window.usedTokens / window.limitTokens);\n }\n return ratios.length === 0 ? null : Math.max(...ratios);\n}\n\n/**\n * The fullest window past its `warnAt`, as a {@link QuotaWarning} — `undefined` when none is, or\n * when one is exhausted (that is `blocked`, not a warning).\n */\nexport function quotaWarning(windows: readonly QuotaWindow[]): QuotaWarning | undefined {\n if (exhaustedWindow(windows) !== undefined) return undefined;\n let fullest: QuotaWarning | undefined;\n for (const window of windows) {\n if (window.warnAt === undefined) continue;\n const ratio = quotaUsedRatio(window);\n if (ratio === null || ratio < window.warnAt) continue;\n if (fullest === undefined || ratio > fullest.ratio) {\n fullest = { period: window.period, ratio };\n }\n }\n return fullest;\n}\n\n/** The UTC day range (`YYYY-MM-DD`, inclusive) and reset instant of `period` around `now`. */\nexport function quotaPeriodRange(\n period: QuotaPeriod,\n now: Date,\n): { fromDay: string; toDay: string; resetsAt: string } {\n const year = now.getUTCFullYear();\n const month = now.getUTCMonth();\n const day = now.toISOString().slice(0, 10);\n if (period === 'day') {\n const next = new Date(Date.UTC(year, month, now.getUTCDate() + 1));\n return { fromDay: day, toDay: day, resetsAt: next.toISOString() };\n }\n const first = new Date(Date.UTC(year, month, 1));\n const last = new Date(Date.UTC(year, month + 1, 0));\n return {\n fromDay: first.toISOString().slice(0, 10),\n toDay: last.toISOString().slice(0, 10),\n resetsAt: new Date(Date.UTC(year, month + 1, 1)).toISOString(),\n };\n}\n","/**\n * The WRITE side of the pricing table the {@link import('./governance-queries.js').AgentGovernanceQueries}\n * read-model prices usage against. Cost is $0 for an unpriced model, so an app seeds its models'\n * per-1M rates once (and re-`upsert`s when a provider changes prices). A store adapter implements\n * this; consumers inject via `AGENT_PRICING_STORE`. Use `seedModelPrices` for a one-shot batch.\n */\n\n/** A per-1M-token price for one model. Cache rates fall back to the input rate when omitted. */\nexport interface ModelPriceInput {\n modelId: string;\n inputPricePer1m: number;\n outputPricePer1m: number;\n /** Per-1M price for cache-write (prompt-cache) input tokens. Omit → priced at the input rate. */\n cacheWritePricePer1m?: number;\n /** Per-1M price for cache-read (prompt-cache) input tokens. Omit → priced at the input rate. */\n cacheReadPricePer1m?: number;\n}\n\n/** A current price row as read back, with the timestamp it took effect. */\nexport interface CurrentModelPrice extends ModelPriceInput {\n effectiveFrom: string;\n}\n\nexport interface AgentPricingStore {\n /**\n * Set the current price for a model. Atomic supersede: the model's prior `isCurrent` row (if any)\n * is retired and this one is inserted as current, effective now — so the read-model always joins\n * to exactly one live price per model, with no window where two rows race for `isCurrent`.\n */\n upsertModelPrice(input: ModelPriceInput): Promise<void>;\n /** The current price row per model (`isCurrent`), for a pricing admin view. */\n listCurrentPrices(): Promise<CurrentModelPrice[]>;\n}\n\n/** Seed (or refresh) a batch of model prices — one `upsertModelPrice` per row, in order. */\nexport async function seedModelPrices(\n store: AgentPricingStore,\n prices: ModelPriceInput[],\n): Promise<void> {\n for (const price of prices) {\n await store.upsertModelPrice(price);\n }\n}\n","/**\n * The two seams that see a turn's traffic to and from the model: an {@link InputProcessor} rewrites\n * the prompt on its way out, an {@link OutputProcessor} inspects the answer on its way back and may\n * redact, replace or refuse it. Wire them as `AgentLoopDeps.inputProcessors` /\n * `outputProcessors`, or via `AgentModule.forRoot({ inputProcessors, outputProcessors })`.\n *\n * WHAT THESE ARE NOT: a second way to decide what enters the context. `HistoryPolicy` owns\n * SELECTION — which of the thread's messages ride into the turn, and what stands in for the rest.\n * Processors run on whatever selection produced and own TRANSFORMATION — what those messages say.\n * The distinction is load-bearing rather than stylistic: selection is contractually pure and is what\n * the `load:thread` checkpoint records, so it bounds the journal as well as the prompt, while a\n * processor is allowed to call a model, runs in a checkpoint of its own per step, and rewrites a\n * DERIVED prompt that never becomes the thread's own memory of what was said. Splitting the same\n * decision across both means neither can be reasoned about alone, and the cheap one stops being the\n * whole answer to \"why did this turn cost that much\".\n */\n\nimport type { Actor, ModelMessage, ToolCallRequest } from '../types.js';\n\n/** Which turn, and which model step of it, a processor is looking at. */\nexport interface ProcessorContext {\n threadId: string;\n actor: Actor;\n /** The agent running this turn. Undefined → the default agent. */\n agentName?: string;\n /** The persona the turn runs under, when it runs under one. */\n persona?: string;\n /** 0-based model step within the run — the same index the `llm:<step>` checkpoint carries. */\n step: number;\n}\n\n/** Everything the model is about to be sent, as the previous processor in the chain left it. */\nexport interface ProcessedPrompt {\n /** The composed system prompt (agent base + contributors + any injected retrieval block). */\n system: string;\n /** The turn's messages, oldest-first, already through the history ceiling. */\n messages: ModelMessage[];\n}\n\n/**\n * Rewrites the prompt before each model call of a turn — masking identifiers, stamping a policy\n * preamble, collapsing an oversized tool result. Runs on EVERY step, not once per run, because the\n * transcript grows between steps: a redactor that only saw the opening prompt would wave through\n * whatever a tool result carried back.\n *\n * Runs inside the loop's `process:input:<step>` checkpoint and its result is journaled, so a\n * processor may call a model or hit the network — a resumed run reads back the prompt the suspended\n * attempt built rather than composing a different one.\n */\nexport interface InputProcessor {\n /** Identifies this processor in a failure. Keep it stable — it is user-visible on an error. */\n readonly name: string;\n process(\n prompt: ProcessedPrompt,\n ctx: ProcessorContext,\n ): ProcessedPrompt | Promise<ProcessedPrompt>;\n}\n\n/** One model step's answer, as the previous processor in the chain left it. */\nexport interface ModelAnswer {\n /** The assembled assistant text for this step. */\n text: string;\n /** The tool calls the same step asked for. Read-only context — a processor cannot change them. */\n toolCalls: readonly ToolCallRequest[];\n}\n\n/**\n * What an {@link OutputProcessor} decided. `pass` hands the text to the next processor unchanged;\n * `replace` hands it on rewritten (a redaction is a replacement); `reject` ends the chain AND the\n * run — the text is never streamed, never persisted, and the caller gets an\n * {@link OutputRejectedError} rather than an answer.\n */\nexport type OutputVerdict =\n | { action: 'pass' }\n | { action: 'replace'; text: string }\n | { action: 'reject'; reason: string };\n\n/**\n * Characters an incremental gate keeps holding at the end of the transformed answer, when a\n * processor declares {@link IncrementalGating} without naming its own window. Wide enough for the\n * patterns a redactor is usually written against — an SSN, an email address, a card number — and\n * deliberately not wider: the window IS the answer's minimum latency tail, since those characters\n * are only released once the whole-answer pass runs.\n */\nexport const DEFAULT_INCREMENTAL_LOOKBACK_CHARS = 64;\n\n/**\n * A processor's statement that its verdict on a PREFIX of an answer is worth acting on, which is\n * what lets the loop release that prefix to the reader instead of holding the whole answer.\n *\n * Declaring it is a promise about every prefix `P` of the final answer, and the loop takes it at\n * face value on the streaming path:\n *\n * 1. REJECTION IS PREFIX-DECIDABLE. The refusal this processor would return for the whole answer is\n * already returned for the first prefix that contains the reason. A refusal that only emerges\n * from the complete answer still fails the run, but by then the reader has seen a prefix — there\n * is no un-sending bytes, and that is the cost of opting in.\n * 2. REPLACEMENT IS PREFIX-STABLE UP TO THE WINDOW. Once a character of `process(P)`'s output is\n * more than {@link lookbackChars} from the end of that output, it never changes as `P` grows.\n *\n * A broken second promise is caught, not tolerated: the whole-answer pass stays authoritative, and\n * the loop raises a `ProcessorFailedError` when its result is not an extension of what the chain\n * already released. So a window too short for a pattern fails loudly rather than streaming the text\n * it was supposed to redact.\n */\nexport interface IncrementalGating {\n /**\n * How many characters of this processor's own output stay held back. Undefined →\n * {@link DEFAULT_INCREMENTAL_LOOKBACK_CHARS}. Set it to the length of the longest pattern the\n * processor can act on — anything shorter is a run that fails on the pattern it was written for.\n */\n readonly lookbackChars?: number;\n}\n\n/**\n * Inspects each model step's answer before anything downstream sees it — before it reaches the live\n * stream, before it is persisted, before it becomes the next step's context.\n *\n * Gating an answer and streaming it as it is generated are mutually exclusive, so registering ANY\n * output processor switches the turn's model call off the run's sink: nothing reaches the\n * subscriber until this chain has ruled on it — see `AgentLoopDeps.outputProcessors`. How much of\n * that costs the reader is what {@link incremental} decides.\n *\n * Runs inside the loop's `process:output:<step>` checkpoint (which also performs the release), so a\n * processor may call a model — a moderation pass is the motivating case — and a replay reads the\n * verdict back instead of re-deciding it.\n */\nexport interface OutputProcessor {\n /** Identifies this processor in a rejection or a failure. User-visible; keep it stable. */\n readonly name: string;\n /**\n * Opt this processor into gating a PREFIX, so the turn keeps streaming — see\n * {@link IncrementalGating} for what declaring it promises. Undefined means the whole answer,\n * which is what a processor written against the complete text needs and therefore the only safe\n * default; a chain is incremental only when EVERY member of it declares this, so a neighbour can\n * never downgrade what another author was given.\n */\n readonly incremental?: IncrementalGating;\n process(answer: ModelAnswer, ctx: ProcessorContext): OutputVerdict | Promise<OutputVerdict>;\n}\n\n/**\n * The run ended because an output processor refused the answer — NOT because the model failed. The\n * two must stay distinguishable: a model failure is worth retrying and worth paging someone about,\n * a refusal is the control doing its job. Both runners map this to the `output_rejected` stream\n * error code.\n */\nexport class OutputRejectedError extends Error {\n /** {@link OutputProcessor.name} of the processor that refused. */\n readonly processor: string;\n /** The reason it gave, verbatim. */\n readonly reason: string;\n\n constructor(processor: string, reason: string) {\n super(`Output rejected by \"${processor}\": ${reason}`);\n this.name = 'OutputRejectedError';\n this.processor = processor;\n this.reason = reason;\n }\n}\n\n/**\n * A processor threw. Wrapped so it can never be mistaken for the model call failing — the loop's\n * only other source of failure at that point in the turn — and so the failure names the processor\n * that produced it instead of surfacing a bare `TypeError` from someone else's code.\n */\nexport class ProcessorFailedError extends Error {\n /** Which seam it was on, so a reader knows whether the prompt or the answer was in flight. */\n readonly phase: 'input' | 'output';\n /** The processor's `name`. */\n readonly processor: string;\n\n constructor(phase: 'input' | 'output', processor: string, cause: unknown) {\n super(\n `${phase} processor \"${processor}\" failed: ${cause instanceof Error ? cause.message : String(cause)}`,\n );\n this.name = 'ProcessorFailedError';\n this.phase = phase;\n this.processor = processor;\n this.cause = cause;\n }\n}\n","/**\n * A read-model over the persisted agent data (usage ⋈ pricing, tool calls, threads) for the\n * governance surfaces — the standalone `-dashboard` SPA and the `-telescope` \"Agent\" tab both\n * consume this ONE interface, so cost/usage aggregation lives in a single place.\n *\n * Separate from {@link AgentStore} on purpose: that SPI owns the write/thread path, this owns the\n * read/analytics path. A store adapter implements both. Consumers inject via\n * `AGENT_GOVERNANCE_QUERIES`.\n *\n * Live activity (in-flight runs, streaming tool calls, delegations, forbidden attempts) is NOT here\n * — that comes off the `aviary:agent:*` diagnostics channel. This interface is the durable, restart-\n * surviving history.\n */\n\n/** Inclusive UTC day range, each `YYYY-MM-DD`. */\nexport interface GovernanceRange {\n fromDay: string;\n toDay: string;\n}\n\n/** Spend + token totals for one model over a range. */\nexport interface ModelSpendRow {\n modelId: string;\n requests: number;\n inputTokens: number;\n outputTokens: number;\n costUsd: number;\n}\n\n/** Spend + token totals for one acting ref (user/tenant) over a range. */\nexport interface ActorSpendRow {\n actorRef: string;\n requests: number;\n totalTokens: number;\n costUsd: number;\n /** Distinct threads the actor used in the range. */\n threadCount: number;\n}\n\n/** Spend + token totals for one thread over a range. */\nexport interface ThreadSpendRow {\n threadId: string;\n title: string;\n actorRef: string;\n requests: number;\n totalTokens: number;\n costUsd: number;\n}\n\n/** One point on the daily usage/cost trend. */\nexport interface UsageTrendPoint {\n day: string;\n totalTokens: number;\n costUsd: number;\n}\n\n/** A recent tool-call for the activity feed. */\nexport interface ToolCallActivityRow {\n toolCallId: string;\n toolName: string;\n toolType: string;\n status: string;\n threadId: string;\n createdAt: string;\n /** The run this call belongs to, for a trace deep-link; `null` for a call recorded before this shipped. */\n runId: string | null;\n}\n\n/** A recent thread with rolled-up activity. */\nexport interface ThreadActivityRow {\n threadId: string;\n title: string;\n actorRef: string;\n messageCount: number;\n totalTokens: number;\n lastActivityAt: string;\n}\n\n/** Aggregated run reliability over a range. */\nexport interface RunMetrics {\n runs: number;\n completed: number;\n failed: number;\n /** completed / runs, 0 when runs = 0. */\n successRate: number;\n /** Total llm-step retries across the range's runs. */\n retries: number;\n durationP50Ms: number | null;\n durationP95Ms: number | null;\n}\n\n/** Run/failure/retry rollup for one agent over a range. */\nexport interface RunAgentBreakdownRow {\n /** '(default)' when the run had none. */\n agentName: string;\n runs: number;\n failed: number;\n retries: number;\n}\n\n/** Failed-run count for one error code over a range. */\nexport interface RunErrorBreakdownRow {\n errorCode: string;\n count: number;\n}\n\n/** One point on the daily run/failure trend. */\nexport interface RunTrendPoint {\n day: string;\n runs: number;\n failed: number;\n}\n\n/** A recent run for the reliability feed. */\nexport interface RecentRunRow {\n runId: string;\n threadId: string;\n actorRef: string;\n agentName: string | null;\n /**\n * `'running'` | `'completed'` | `'failed'` | `'cancelled'`. `cancelled` is a terminal of its own —\n * someone asked the run to stop and it did — so a consumer computing a failure rate over these\n * rows has to be able to leave it out rather than fold it into `failed`.\n */\n status: string;\n durationMs: number | null;\n errorCode: string | null;\n errorMessage: string | null;\n retries: number;\n /** ISO timestamp. */\n startedAt: string;\n /** sha256 hex of the run's resolved (pre-RAG) system prompt; `null` for a run recorded before this shipped. */\n promptHash: string | null;\n /**\n * The run that delegated this one; `null` for a turn nobody delegated, and for any run recorded\n * before the column existed. Pairing a child with its parent is what lets a console draw the\n * delegation tree and roll a child's cost up to the turn that asked for it — and for a DETACHED\n * child it is the only pairing there is, since it outlives its parent's turn and the transcript\n * holds no other link.\n */\n parentRunId: string | null;\n}\n\n/** One tool call awaiting a HITL decision, for the cross-thread approvals inbox. */\nexport interface PendingApprovalRow {\n toolCallId: string;\n toolName: string;\n input: unknown;\n threadId: string;\n threadTitle: string;\n /** Who asked — the run's actor. */\n actorRef: string;\n agentName: string | null;\n /** ISO timestamp. */\n requestedAt: string;\n /** The run this call belongs to, for a trace deep-link; `null` for a call recorded before this shipped. */\n runId: string | null;\n}\n\n/** Governance rollup for one tool over a range. */\nexport interface ToolStatRow {\n toolName: string;\n toolType: string;\n calls: number;\n failed: number;\n rejected: number;\n /**\n * p50 (median) of executionMs across calls that recorded one; null when none carry it. Reported\n * alongside p95 rather than a mean: tool latency is long-tailed (a retry or a slow upstream drags\n * an average somewhere no single call ever was), so the pair \"typical / tail\" is what an operator\n * can actually act on.\n */\n p50ExecutionMs: number | null;\n /** p95 of executionMs across executed calls; null when none carry it. */\n p95ExecutionMs: number | null;\n}\n\n/**\n * Neutral paged query for the governance list reads (`toolCallsPage`/`threadsPage`/`runsPage`). The\n * WIRE format a host exposes over HTTP mirrors `@dudousxd/nestjs-filter`'s conventions (`page`,\n * `limit`, `where[field][op]`) so consumers see one grammar across the ecosystem, but this SPI stays\n * neutral/typed — no filter-builder or ORM coupling here.\n */\nexport interface GovernancePageQuery<TWhere> {\n /** 1-based. */\n page: number;\n /** Rows per page, already clamped by the caller (the dashboard clamps to 200). */\n pageSize: number;\n /** Equality/range filters; absent field = no constraint. */\n where?: TWhere;\n}\n\n/** One page of a governance list read, with the total row count for prev/next + \"page X of Y\" UI. */\nexport interface GovernancePage<TRow> {\n rows: TRow[];\n total: number;\n page: number;\n pageSize: number;\n}\n\n/** Filters for {@link AgentGovernanceQueries.toolCallsPage}. */\nexport interface ToolCallWhere {\n toolName?: string;\n toolType?: string;\n status?: string;\n threadId?: string;\n /** Inclusive UTC day bounds, `YYYY-MM-DD`. */\n fromDay?: string;\n toDay?: string;\n}\n\n/** Filters for {@link AgentGovernanceQueries.threadsPage}. */\nexport interface ThreadWhere {\n actorRef?: string;\n /** Substring match on the title (case-insensitive). */\n title?: string;\n fromDay?: string;\n toDay?: string;\n}\n\n/** Filters for {@link AgentGovernanceQueries.runsPage}. */\nexport interface RunWhere {\n agentName?: string;\n status?: string;\n errorCode?: string;\n threadId?: string;\n fromDay?: string;\n toDay?: string;\n}\n\n/** Filters for {@link AgentGovernanceQueries.approvalsPage}. */\nexport interface ApprovalWhere {\n toolName?: string;\n threadId?: string;\n /** The requesting thread's owner. */\n actorRef?: string;\n agentName?: string;\n /** Inclusive UTC day bounds on when the approval was requested, `YYYY-MM-DD`. */\n fromDay?: string;\n toDay?: string;\n}\n\n// ─── Drill-down details ──────────────────────────────────────────────────────\n//\n// The list reads above answer \"what happened\"; these two answer \"what happened HERE\". Each is ONE\n// call returning everything the corresponding drill-down renders, so a console never fans out a\n// query per row it just drew. Both return `null` for an id that doesn't exist — the caller decides\n// whether that's a 404 or an empty panel.\n\n/** One tool call inside a {@link GovernanceRunDetail}, with the execution outcome a list row can't afford to carry. */\nexport interface RunToolCallRow {\n toolCallId: string;\n toolName: string;\n toolType: string;\n status: string;\n /** Wall time of the execution; null for a call that never executed (rejected/still pending). */\n executionMs: number | null;\n /** Who executed/decided it, when the store recorded an attribution. */\n executedByRef: string | null;\n /** The failure text for a `failed` call; null otherwise. */\n error: string | null;\n /** ISO timestamp. */\n createdAt: string;\n}\n\n/** The owning thread's headline, carried on a drill-down so it can be named without a second read. */\nexport interface DetailThreadRef {\n threadId: string;\n title: string;\n actorRef: string;\n /** True when the thread is soft-deleted — its history is still readable, the thread is not. */\n deleted: boolean;\n}\n\n/**\n * Everything a run drill-down renders: the run row itself, its owning thread's headline, and the\n * tool calls attributed to it.\n *\n * `toolCalls` is empty for a run recorded before tool calls carried a `runId` (the column is\n * nullable and pre-rollout rows have none) — indistinguishable, from here, from a run that called\n * no tools. There is deliberately no cost figure: the token ledger has no run column, so per-run\n * spend is not attributable without a store migration.\n */\nexport interface GovernanceRunDetail {\n run: RecentRunRow;\n thread: DetailThreadRef;\n /** The run's tool calls, oldest first — the order they were requested in. */\n toolCalls: RunToolCallRow[];\n}\n\n/** One message inside a {@link GovernanceThreadDetail}. `content` is capped server-side. */\nexport interface ThreadMessageRow {\n messageId: string;\n role: string;\n /** Message text, cut to {@link THREAD_DETAIL_CONTENT_CHARS}; see `truncated`. */\n content: string;\n /** True when `content` was cut — the console shows an explicit \"…\" rather than implying the tail. */\n truncated: boolean;\n agentName: string | null;\n /** How many tool calls this message requested. */\n toolCallCount: number;\n /** ISO timestamp. */\n createdAt: string;\n}\n\n/** Token/cost rollup across a thread's whole ledger (not range-scoped — a thread's lifetime). */\nexport interface ThreadUsageRollup {\n /** Ledger rows, i.e. billed turns. */\n requests: number;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n costUsd: number;\n}\n\n/** Everything a thread drill-down renders, in one call. */\nexport interface GovernanceThreadDetail {\n /** The thread's own activity row (`messageCount` is the thread total, not the page below). */\n thread: ThreadActivityRow;\n /** True when the thread is soft-deleted. */\n deleted: boolean;\n usage: ThreadUsageRollup;\n /** The thread's runs, newest first, capped at the query's `runLimit`. */\n runs: RecentRunRow[];\n /** Runs on this thread in total — `runs.length < runTotal` means the cap bit. */\n runTotal: number;\n /** The thread's messages, newest first, capped at the query's `messageLimit`. */\n messages: ThreadMessageRow[];\n}\n\n/** Row caps for {@link AgentGovernanceQueries.threadDetail}, already clamped by the caller. */\nexport interface GovernanceThreadDetailQuery {\n threadId: string;\n /** Max messages returned, newest first. */\n messageLimit: number;\n /** Max runs returned, newest first. */\n runLimit: number;\n}\n\n/**\n * Per-message content cap for {@link ThreadMessageRow.content}. A drill-down is a triage view, not a\n * transcript reader: capping here keeps one response bounded regardless of how long an assistant\n * turn ran. Shared by every adapter so the cut is identical wherever the console is served from.\n */\nexport const THREAD_DETAIL_CONTENT_CHARS = 2000;\n\n/**\n * Cut a message body to {@link THREAD_DETAIL_CONTENT_CHARS}, reporting whether it was cut. Lives\n * next to the cap so every adapter truncates at the same boundary — a console comparing two stores\n * must not see two different \"…\".\n */\nexport function truncateDetailContent(content: string): {\n content: string;\n truncated: boolean;\n} {\n if (content.length <= THREAD_DETAIL_CONTENT_CHARS) {\n return { content, truncated: false };\n }\n return { content: content.slice(0, THREAD_DETAIL_CONTENT_CHARS), truncated: true };\n}\n\n/**\n * The governance read-model. Cost is `inputTokens/1e6 * inputPricePer1m + outputTokens/1e6 *\n * outputPricePer1m` against the current pricing row per model; an unpriced model contributes 0 cost\n * (its tokens still count).\n */\nexport interface AgentGovernanceQueries {\n spendByModel(range: GovernanceRange): Promise<ModelSpendRow[]>;\n spendByActor(range: GovernanceRange): Promise<ActorSpendRow[]>;\n /** Top threads by spend within the range, highest cost first, capped at `limit`. */\n spendByThread(range: GovernanceRange, limit: number): Promise<ThreadSpendRow[]>;\n usageTrend(range: GovernanceRange): Promise<UsageTrendPoint[]>;\n recentToolCalls(limit: number): Promise<ToolCallActivityRow[]>;\n recentThreads(limit: number): Promise<ThreadActivityRow[]>;\n // Run reliability. An adapter backed by a store without run recording (no `recordRunStart`)\n // returns zeros/empty from all five (plus `runsPage`, below) — the dashboard renders an empty\n // reliability surface.\n runMetrics(range: GovernanceRange): Promise<RunMetrics>;\n runsByAgent(range: GovernanceRange): Promise<RunAgentBreakdownRow[]>;\n runErrors(range: GovernanceRange): Promise<RunErrorBreakdownRow[]>;\n runTrend(range: GovernanceRange): Promise<RunTrendPoint[]>;\n recentRuns(limit: number): Promise<RecentRunRow[]>;\n /**\n * Tool calls sitting `pending_approval`, oldest first — an inbox drains from the back. Capped at\n * `limit`, with NO total: a caller that needs to know whether the cap hid anything wants\n * {@link approvalsPage} instead.\n */\n pendingApprovals(limit: number): Promise<PendingApprovalRow[]>;\n /**\n * Paged, filterable approvals inbox, oldest first (same ordering as `pendingApprovals`). Unlike\n * that method this reports `total`, so a console can page a backlog and say how much of it is\n * off-screen — the one failure this surface cannot afford is a pending approval nobody sees.\n * An adapter without the backing data returns an empty page (`total: 0`) rather than throwing.\n */\n approvalsPage(\n query: GovernancePageQuery<ApprovalWhere>,\n ): Promise<GovernancePage<PendingApprovalRow>>;\n /** Per-tool call/failure/rejection/latency rollup over the range, highest call count first. */\n toolStats(range: GovernanceRange): Promise<ToolStatRow[]>;\n /**\n * Paged, filterable tool-call activity, newest-first (same ordering as `recentToolCalls`). An\n * adapter without the backing data returns an empty page (`total: 0`) rather than throwing.\n */\n toolCallsPage(\n query: GovernancePageQuery<ToolCallWhere>,\n ): Promise<GovernancePage<ToolCallActivityRow>>;\n /**\n * Paged, filterable thread activity, newest-first (same ordering as `recentThreads`). An adapter\n * without the backing data returns an empty page (`total: 0`) rather than throwing.\n */\n threadsPage(query: GovernancePageQuery<ThreadWhere>): Promise<GovernancePage<ThreadActivityRow>>;\n /**\n * Paged, filterable run activity, newest-first (same ordering as `recentRuns`). An adapter backed\n * by a store without run recording (no `recordRunStart`) returns an empty page (`total: 0`).\n */\n runsPage(query: GovernancePageQuery<RunWhere>): Promise<GovernancePage<RecentRunRow>>;\n /**\n * One run with its owning thread and its tool calls — the drill-down behind a row in the runs\n * table. `null` when no run has that id. ONE call, not one per tool call: a failed run is the\n * thing an operator opens first and it should not cost a query per step.\n *\n * An adapter backed by a store without run recording returns `null` for every id.\n */\n runDetail(runId: string): Promise<GovernanceRunDetail | null>;\n /**\n * One thread with its lifetime usage rollup, its recent runs and its recent messages — the\n * drill-down behind a row in the threads table. `null` when no thread has that id; a soft-deleted\n * thread IS returned (with `deleted: true`), because \"what did the thread we just deleted do\" is\n * exactly the question an audit asks.\n */\n threadDetail(query: GovernanceThreadDetailQuery): Promise<GovernanceThreadDetail | null>;\n}\n","import type { ToolConfirmation } from '../tool-presentation.js';\nimport type {\n Actor,\n ToolCallApproval,\n ToolCallApprovalStatus,\n ToolCallStatus,\n ToolKind,\n ToolSpec,\n} from '../types.js';\n\n/** The approver that means \"the person the run is acting for\" — the thread's own actor. */\nexport const REQUESTER_APPROVER = 'requester';\n\n/** The tool a requirement is asked about. `spec` is absent where this process cannot resolve it. */\nexport interface ApprovalToolRef {\n name: string;\n kind: ToolKind;\n spec?: ToolSpec;\n}\n\n/** Where the call is being made. */\nexport interface ApprovalThreadRef {\n threadId: string;\n runId: string;\n agentName?: string;\n}\n\n/**\n * What an action tool call needs before it runs.\n *\n * - `required: false` → the call runs without asking anyone (it is still recorded as an action).\n * - `approver` → who may decide: {@link REQUESTER_APPROVER} (the thread's own actor — the default)\n * or any other string, which the default {@link ApprovalPolicy.canDecide} reads as a ROLE the\n * decider must hold. Streamed on `approval-requested` and persisted on the call.\n * - `ttlMs` → how long the request stays open. When it lapses the call settles `expired` and the\n * model is told nobody approved it. Absent → it waits indefinitely.\n */\nexport interface ApprovalRequirement {\n required: boolean;\n approver: string;\n ttlMs?: number;\n}\n\n/** A decision about to be taken on a call, as {@link ApprovalPolicy.canDecide} sees it. */\nexport interface ApprovalDecisionRef {\n toolCallId: string;\n /** The approver recorded on the call when it was put to a person. */\n approver: string;\n /** The actorRef the run is acting for — the owner of the call's thread. */\n requesterRef: string;\n}\n\n/**\n * Who has to approve an action tool call, and for how long the request stays open.\n *\n * Consulted by the LOOP once per `action` call, inside the call's `persist:toolcall` checkpoint — so\n * a durable run reads the answer back on every replay instead of re-deciding it against a policy\n * that may have changed while it was parked. Only `action` calls are asked about: a policy cannot\n * put a `read` behind an approval, and an `ask` (a question set) is always the requester's.\n */\nexport interface ApprovalPolicy {\n requirementFor(\n tool: ApprovalToolRef,\n actor: Actor,\n thread: ApprovalThreadRef,\n ): ApprovalRequirement | Promise<ApprovalRequirement>;\n /**\n * May `actor` settle this call? Checked by the approve/reject routes before a decision is\n * signalled. Absent → {@link defaultCanDecide}: the requester approver means the thread's own\n * actor, anything else is a role the actor must hold. Plug an authz Gate here for abilities.\n */\n canDecide?(actor: Actor, decision: ApprovalDecisionRef): boolean | Promise<boolean>;\n}\n\n/**\n * The behaviour the lib always had: every `action` call waits on the person who asked, with no\n * expiry.\n */\nexport class DefaultApprovalPolicy implements ApprovalPolicy {\n requirementFor(tool: ApprovalToolRef): ApprovalRequirement {\n return { required: tool.kind === 'action', approver: REQUESTER_APPROVER };\n }\n}\n\n/** The default decider rule — see {@link ApprovalPolicy.canDecide}. */\nexport function defaultCanDecide(actor: Actor, decision: ApprovalDecisionRef): boolean {\n if (decision.approver === REQUESTER_APPROVER) {\n return actor.id === decision.requesterRef;\n }\n return actor.roles?.includes(decision.approver) === true;\n}\n\n/** Resolve whether `actor` may decide, through the policy's own rule when it has one. */\nexport async function mayDecideApproval(\n policy: ApprovalPolicy | undefined,\n actor: Actor,\n decision: ApprovalDecisionRef,\n): Promise<boolean> {\n if (policy?.canDecide !== undefined) {\n return policy.canDecide(actor, decision);\n }\n return defaultCanDecide(actor, decision);\n}\n\n/** The columns a store keeps for one call's approval, however it names them. */\nexport interface ToolCallApprovalColumns {\n proposalId?: string | null;\n confirmation?: ToolConfirmation | null | undefined;\n toolCallId: string;\n status: ToolCallStatus;\n approver: string | null | undefined;\n expiresAt: string | Date | null | undefined;\n remember: boolean | null | undefined;\n executedByRef: string | null | undefined;\n decidedVia: string | null | undefined;\n error: string | null | undefined;\n}\n\n/**\n * Read a tool-call row back as the {@link ToolCallApproval} a thread carries, or `null` for a call\n * no policy put to anyone (no approver recorded). Shared by every store so they agree on the\n * status mapping: a call that ran — or ran and failed — after a decision was APPROVED.\n */\nexport function toolCallApprovalFromRow(row: ToolCallApprovalColumns): ToolCallApproval | null {\n if (row.approver === null || row.approver === undefined) {\n return null;\n }\n const status: ToolCallApprovalStatus =\n row.status === 'pending_approval' || row.status === 'proposed'\n ? 'pending'\n : row.status === 'rejected'\n ? 'rejected'\n : row.status === 'expired'\n ? 'expired'\n : 'approved';\n const expiresAt =\n row.expiresAt instanceof Date\n ? row.expiresAt.toISOString()\n : typeof row.expiresAt === 'string'\n ? row.expiresAt\n : undefined;\n const decided = status === 'approved' || status === 'rejected';\n return {\n toolCallId: row.toolCallId,\n ...(row.proposalId != null ? { proposalId: row.proposalId } : {}),\n approver: row.approver,\n ...(row.confirmation != null ? { confirmation: row.confirmation } : {}),\n status,\n ...(expiresAt !== undefined ? { expiresAt } : {}),\n ...(row.remember === true ? { remember: true } : {}),\n ...(decided && typeof row.executedByRef === 'string' ? { decidedBy: row.executedByRef } : {}),\n ...(decided && typeof row.decidedVia === 'string' ? { decidedVia: row.decidedVia } : {}),\n ...(status === 'rejected' && typeof row.error === 'string' ? { reason: row.error } : {}),\n };\n}\n","import type {\n ActorSpendRow,\n GovernanceRange,\n ModelSpendRow,\n ThreadSpendRow,\n ThreadUsageRollup,\n UsageTrendPoint,\n} from '../spi/governance-queries.js';\n\n/**\n * The pure aggregation core shared by every {@link import('../spi/governance-queries.js').AgentGovernanceQueries}\n * adapter (MikroORM, Drizzle, in-memory). An adapter's only job is the DB-specific row fetch; the\n * cost formula, the group→sort bucketing, and the day-bounds math live here so all three surfaces\n * report identical numbers.\n */\n\n/** The current per-1M token prices for one model; cache rates fall back to the input rate. */\nexport interface ModelPrice {\n inputPricePer1m: number;\n outputPricePer1m: number;\n cacheWritePricePer1m?: number | null;\n cacheReadPricePer1m?: number | null;\n}\n\n/** The token split of one turn needed to estimate its cost. */\nexport interface CostUsage {\n inputTokens: number;\n outputTokens: number;\n cacheWriteTokens?: number | null | undefined;\n cacheReadTokens?: number | null | undefined;\n}\n\n/**\n * A normalized usage row the bucketers consume. Each adapter maps its raw DB row into this shape\n * (MikroORM reads `thread.id` + `createdAt`, Drizzle/in-memory read the flat `threadId` + `day`).\n */\nexport interface GovernanceUsageInput extends CostUsage {\n modelId: string;\n actorRef: string;\n threadId: string;\n /** The `YYYY-MM-DD` UTC day the row belongs to (its trend bucket). */\n day: string;\n /** Provider-reported spend for the row; wins over the token estimate when present. */\n costUsd?: number | null | undefined;\n}\n\n/** Thread metadata joined onto a spend bucket. */\nexport interface ThreadMeta {\n title: string;\n actorRef: string;\n}\n\n/**\n * Token-ledger estimate for one turn against a pricing row: the uncached input at the input rate,\n * cache-write/cache-read tokens at their own rates (falling back to the input rate when unpriced),\n * plus output at the output rate. An unpriced model (`price === undefined`) contributes 0 — its\n * tokens still count. Cache token counts are subsets of `inputTokens`, so the uncached remainder is\n * the difference.\n */\nexport function estimateCost(usage: CostUsage, price: ModelPrice | undefined): number {\n if (price === undefined) {\n return 0;\n }\n const cacheWriteTokens = usage.cacheWriteTokens ?? 0;\n const cacheReadTokens = usage.cacheReadTokens ?? 0;\n const uncachedInputTokens = usage.inputTokens - cacheWriteTokens - cacheReadTokens;\n return (\n (uncachedInputTokens / 1_000_000) * price.inputPricePer1m +\n (cacheWriteTokens / 1_000_000) * (price.cacheWritePricePer1m ?? price.inputPricePer1m) +\n (cacheReadTokens / 1_000_000) * (price.cacheReadPricePer1m ?? price.inputPricePer1m) +\n (usage.outputTokens / 1_000_000) * price.outputPricePer1m\n );\n}\n\n/** Provider-reported cost wins per row; otherwise the cache-aware token estimate. */\nfunction rowCost(row: GovernanceUsageInput, prices: ReadonlyMap<string, ModelPrice>): number {\n return row.costUsd ?? estimateCost(row, prices.get(row.modelId));\n}\n\n/** Aggregate usage rows into per-model spend, highest cost first then modelId ascending. */\nexport function bucketByModel(\n rows: GovernanceUsageInput[],\n prices: ReadonlyMap<string, ModelPrice>,\n): ModelSpendRow[] {\n const byModel = new Map<\n string,\n { requests: number; inputTokens: number; outputTokens: number; costUsd: number }\n >();\n for (const row of rows) {\n const bucket = byModel.get(row.modelId) ?? {\n requests: 0,\n inputTokens: 0,\n outputTokens: 0,\n costUsd: 0,\n };\n bucket.requests += 1;\n bucket.inputTokens += row.inputTokens;\n bucket.outputTokens += row.outputTokens;\n bucket.costUsd += rowCost(row, prices);\n byModel.set(row.modelId, bucket);\n }\n const result: ModelSpendRow[] = [];\n for (const [modelId, bucket] of byModel) {\n result.push({\n modelId,\n requests: bucket.requests,\n inputTokens: bucket.inputTokens,\n outputTokens: bucket.outputTokens,\n costUsd: bucket.costUsd,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.modelId.localeCompare(right.modelId),\n );\n return result;\n}\n\n/** Aggregate usage rows into per-actor spend (with distinct thread counts), highest cost first. */\nexport function bucketByActor(\n rows: GovernanceUsageInput[],\n prices: ReadonlyMap<string, ModelPrice>,\n): ActorSpendRow[] {\n const byActor = new Map<\n string,\n { requests: number; totalTokens: number; costUsd: number; threadIds: Set<string> }\n >();\n for (const row of rows) {\n const bucket = byActor.get(row.actorRef) ?? {\n requests: 0,\n totalTokens: 0,\n costUsd: 0,\n threadIds: new Set<string>(),\n };\n bucket.requests += 1;\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(row, prices);\n bucket.threadIds.add(row.threadId);\n byActor.set(row.actorRef, bucket);\n }\n const result: ActorSpendRow[] = [];\n for (const [actorRef, bucket] of byActor) {\n result.push({\n actorRef,\n requests: bucket.requests,\n totalTokens: bucket.totalTokens,\n costUsd: bucket.costUsd,\n threadCount: bucket.threadIds.size,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.actorRef.localeCompare(right.actorRef),\n );\n return result;\n}\n\n/**\n * Aggregate usage rows into per-thread spend, highest cost first then threadId ascending, capped at\n * `limit`. A thread absent from `threads` is dropped when `includeUnknownThreads` is false (the SQL\n * adapters fetch only non-deleted threads, so a soft-deleted thread's rows vanish from the ranking);\n * when true it is kept with blank title/actor (the in-memory adapter's semantics).\n */\nexport function bucketByThread(\n rows: GovernanceUsageInput[],\n prices: ReadonlyMap<string, ModelPrice>,\n threads: ReadonlyMap<string, ThreadMeta>,\n options: { limit: number; includeUnknownThreads: boolean },\n): ThreadSpendRow[] {\n const byThread = new Map<string, { requests: number; totalTokens: number; costUsd: number }>();\n for (const row of rows) {\n const bucket = byThread.get(row.threadId) ?? { requests: 0, totalTokens: 0, costUsd: 0 };\n bucket.requests += 1;\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(row, prices);\n byThread.set(row.threadId, bucket);\n }\n const result: ThreadSpendRow[] = [];\n for (const [threadId, bucket] of byThread) {\n const thread = threads.get(threadId);\n if (thread === undefined && !options.includeUnknownThreads) {\n continue;\n }\n result.push({\n threadId,\n title: thread?.title ?? '',\n actorRef: thread?.actorRef ?? '',\n requests: bucket.requests,\n totalTokens: bucket.totalTokens,\n costUsd: bucket.costUsd,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.threadId.localeCompare(right.threadId),\n );\n return result.slice(0, options.limit);\n}\n\n/**\n * Sum an already-scoped set of usage rows into one rollup — the thread drill-down's headline. Same\n * `rowCost` as every bucketer above (provider-reported cost wins, else the cache-aware estimate), so\n * a thread's detail cost and its row in the by-thread ranking can never disagree.\n */\nexport function rollupThreadUsage(\n rows: GovernanceUsageInput[],\n prices: ReadonlyMap<string, ModelPrice>,\n): ThreadUsageRollup {\n const rollup: ThreadUsageRollup = {\n requests: 0,\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n costUsd: 0,\n };\n for (const row of rows) {\n rollup.requests += 1;\n rollup.inputTokens += row.inputTokens;\n rollup.outputTokens += row.outputTokens;\n rollup.totalTokens += row.inputTokens + row.outputTokens;\n rollup.costUsd += rowCost(row, prices);\n }\n return rollup;\n}\n\n/** Aggregate usage rows into a daily token/cost trend, ascending by day. */\nexport function bucketUsageTrend(\n rows: GovernanceUsageInput[],\n prices: ReadonlyMap<string, ModelPrice>,\n): UsageTrendPoint[] {\n const byDay = new Map<string, { totalTokens: number; costUsd: number }>();\n for (const row of rows) {\n const bucket = byDay.get(row.day) ?? { totalTokens: 0, costUsd: 0 };\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(row, prices);\n byDay.set(row.day, bucket);\n }\n const result: UsageTrendPoint[] = [];\n for (const [day, bucket] of byDay) {\n result.push({ day, totalTokens: bucket.totalTokens, costUsd: bucket.costUsd });\n }\n result.sort((left, right) => left.day.localeCompare(right.day));\n return result;\n}\n\n/** Turn an inclusive `YYYY-MM-DD` day range into the UTC datetime bounds used to filter usage rows. */\nexport function dayBoundsUtc(range: GovernanceRange): { start: Date; end: Date } {\n return {\n start: new Date(`${range.fromDay}T00:00:00.000Z`),\n end: new Date(`${range.toDay}T23:59:59.999Z`),\n };\n}\n","import type { RolesPolicy } from './spi/roles-policy.js';\nimport type { ToolHandler } from './spi/tool.js';\nimport type { Actor, ToolSpec } from './types.js';\n\n/**\n * Is this tool part of this deployment right now? `ToolSpec.enabled` and the handler's\n * `isEnabled()` are ANDed — either one saying no is enough — and both default to yes.\n *\n * Resolved per turn rather than at registration, so the answer can come from configuration that\n * did not exist when the module was built.\n */\nexport async function isToolEnabled(spec: ToolSpec, handler?: ToolHandler): Promise<boolean> {\n const declared =\n typeof spec.enabled === 'function' ? await spec.enabled() : (spec.enabled ?? true);\n if (!declared) {\n return false;\n }\n return handler?.isEnabled === undefined ? true : await handler.isEnabled();\n}\n\n/**\n * Second filter layer: drop tools this deployment has turned off, before anyone asks who may call\n * them. A disabled tool is absent, not forbidden — the difference matters, because \"forbidden\"\n * tells the model (and the user reading a refusal) that the capability exists.\n */\nexport async function filterToolsByEnabled<T extends { spec: ToolSpec; handler?: ToolHandler }>(\n entries: T[],\n): Promise<T[]> {\n const checked = await Promise.all(\n entries.map(async (entry) => ({\n entry,\n enabled: await isToolEnabled(entry.spec, entry.handler),\n })),\n );\n return checked.filter((row) => row.enabled).map((row) => row.entry);\n}\n\n/**\n * May this actor use this tool, per the tool's OWN gate? Tools without a `canUse` say yes and are\n * governed by the `RolesPolicy` alone.\n */\nexport async function canActorUseTool(actor: Actor, handler?: ToolHandler): Promise<boolean> {\n return handler?.canUse === undefined ? true : await handler.canUse(actor);\n}\n\n/**\n * Fourth filter layer: drop tools whose own `canUse` refuses this actor. Runs after the app-wide\n * `RolesPolicy`, and is additive to it — a tool can narrow who reaches it, never widen.\n */\nexport async function filterToolsByCanUse<T extends { spec: ToolSpec; handler?: ToolHandler }>(\n entries: T[],\n actor: Actor,\n): Promise<T[]> {\n const checked = await Promise.all(\n entries.map(async (entry) => ({\n entry,\n allowed: await canActorUseTool(actor, entry.handler),\n })),\n );\n return checked.filter((row) => row.allowed).map((row) => row.entry);\n}\n\n/** Third filter layer: drop tools the actor's role may not invoke. `can` may be async (authz). */\nexport async function filterToolsByRole(\n tools: ToolSpec[],\n actor: Actor,\n policy: RolesPolicy,\n): Promise<ToolSpec[]> {\n const checked = await Promise.all(\n tools.map(async (tool) => ({ tool, allowed: await policy.can(actor, tool) })),\n );\n return checked.filter((entry) => entry.allowed).map((entry) => entry.tool);\n}\n\n/**\n * First filter layer: if the agent pins an allow-list, keep only those tool names. Pure and\n * synchronous, which is why it runs ahead of the three gates that may do I/O — see\n * `ToolRegistry.definitionsFor`.\n */\nexport function filterToolsByAllowList(\n tools: ToolSpec[],\n allowedTools: string[] | undefined,\n): ToolSpec[] {\n if (allowedTools === undefined) {\n return tools;\n }\n const allowed = new Set(allowedTools);\n return tools.filter((tool) => allowed.has(tool.name));\n}\n","import type { AgentDefinition, Persona, PersonaCatalogEntry } from './types.js';\n\n/**\n * The narrower of two tool allow-lists. `undefined` is \"no restriction\", so it yields the other;\n * two lists yield the names on both, in the order of the first.\n */\nexport function intersectAllowLists(\n first: readonly string[] | undefined,\n second: readonly string[] | undefined,\n): string[] | undefined {\n if (first === undefined) {\n return second === undefined ? undefined : [...second];\n }\n if (second === undefined) {\n return [...first];\n }\n const allowed = new Set(second);\n return first.filter((name) => allowed.has(name));\n}\n\n/** The persona `id` of `definition`, or `undefined` when it declares none by that id. */\nexport function findPersona(\n definition: Pick<AgentDefinition, 'personas'> | undefined,\n id: string | undefined,\n): Persona | undefined {\n if (id === undefined) {\n return undefined;\n }\n return definition?.personas?.find((persona) => persona.id === id);\n}\n\n/** A persona as a picker reads it — never its prompt or its allow-list. */\nexport function personaCatalogEntry(persona: Persona): PersonaCatalogEntry {\n return {\n id: persona.id,\n label: persona.label,\n ...(persona.description !== undefined ? { description: persona.description } : {}),\n };\n}\n\n/** Where a former agent name now lives: an agent, and the persona of it the name stands for. */\nexport interface PersonaAlias {\n agent: string;\n persona: string;\n}\n\n/**\n * Resolve `name` through the {@link Persona.aliases} of `definitions`: the agent and persona that\n * answer for it, or `undefined` when no persona claims it. A name that IS a registered agent is\n * never an alias — the caller checks that first, so a real agent always wins.\n */\nexport function resolvePersonaAlias(\n definitions: readonly AgentDefinition[],\n name: string,\n): PersonaAlias | undefined {\n for (const definition of definitions) {\n for (const persona of definition.personas ?? []) {\n if (persona.aliases?.includes(name) === true) {\n return { agent: definition.name, persona: persona.id };\n }\n }\n }\n return undefined;\n}\n","/**\n * The built-in {@link HistoryPolicy}: keep the newest messages that fit a count and/or a token\n * budget, and (optionally) fold the rest into a summary. See `./spi/history-policy.ts` for the seam\n * itself and the determinism contract `select` has to hold to.\n */\n\nimport type { HistoryPolicy, HistorySelection, HistorySummary } from './spi/history-policy.js';\nimport type { ModelProvider } from './spi/model-provider.js';\nimport type { SinkWriter } from './spi/token-stream-sink.js';\nimport type { ModelMessage } from './types.js';\n\n/**\n * Rough token count for one message: ~4 characters per token over its content and its serialized\n * tool calls/results, plus a small per-message envelope allowance for the role and part framing.\n *\n * A heuristic on purpose. A real tokenizer is model-specific and would drag a provider dependency\n * into core, while a budget only has to be approximately right to keep a thread clear of the\n * provider's hard limit — and it must be a pure function, because it runs inside `select`. Pass\n * `estimate` to {@link windowHistory} to substitute a real one.\n */\nexport function estimateMessageTokens(message: ModelMessage): number {\n const extras =\n (message.toolCalls !== undefined ? JSON.stringify(message.toolCalls).length : 0) +\n (message.toolResults !== undefined ? JSON.stringify(message.toolResults).length : 0);\n return Math.ceil((message.content.length + extras) / 4) + 4;\n}\n\nexport interface WindowHistoryOptions {\n /** Keep at most this many of the newest messages. Omit → no count limit. */\n maxMessages?: number;\n /** Keep the newest messages whose estimated tokens fit this budget. Omit → no token limit. */\n maxTokens?: number;\n /** Substitute for {@link estimateMessageTokens}. Must be pure — it runs inside `select`. */\n estimate?: (message: ModelMessage) => number;\n /** Folds the dropped messages into a leading summary. Omit → they are simply gone. */\n summarize?: HistoryPolicy['summarize'];\n}\n\n/**\n * Keep the newest messages that fit. Both limits apply when both are set — whichever cuts more wins.\n * Neither set is a policy that keeps everything, which is what an unconfigured loop already does.\n *\n * A naive slice is safe here because a tool exchange is ONE message: the loop persists a call's\n * results onto the same assistant message that made them (`toolCalls` + `toolResults`), and each\n * model adapter expands that into the assistant/tool pair the provider wants. So a cut can't orphan\n * a tool result from its call, the way it could against a provider-shaped transcript.\n */\nexport function windowHistory(options: WindowHistoryOptions): HistoryPolicy {\n const estimate = options.estimate ?? estimateMessageTokens;\n const policy: HistoryPolicy = {\n // A suffix selection of at most `maxMessages` rows, which is exactly what `HistoryPolicy`'s row\n // hint promises — so the store can bound its read to that many of the thread's newest messages.\n // A token-only window declares nothing: its budget names no row count.\n ...(options.maxMessages !== undefined ? { maxMessages: options.maxMessages } : {}),\n select(messages: ModelMessage[]): HistorySelection {\n let cut = 0;\n if (options.maxMessages !== undefined) {\n cut = Math.max(cut, messages.length - options.maxMessages);\n }\n if (options.maxTokens !== undefined) {\n cut = Math.max(cut, tokenCut(messages, options.maxTokens, estimate));\n }\n // The newest message always rides, whatever the limits say — a turn with nothing to answer is\n // worse than a turn slightly over budget.\n cut = Math.min(cut, Math.max(0, messages.length - 1));\n return { keep: messages.slice(cut), drop: messages.slice(0, cut) };\n },\n };\n return options.summarize !== undefined ? { ...policy, summarize: options.summarize } : policy;\n}\n\n/** Index of the oldest message that still fits `maxTokens`, walking newest-first. */\nfunction tokenCut(\n messages: ModelMessage[],\n maxTokens: number,\n estimate: (message: ModelMessage) => number,\n): number {\n let index = messages.length;\n let total = 0;\n while (index > 0) {\n const message = messages[index - 1];\n if (message === undefined) {\n break;\n }\n const cost = estimate(message);\n if (index < messages.length && total + cost > maxTokens) {\n break;\n }\n total += cost;\n index -= 1;\n }\n return index;\n}\n\n/**\n * What a summarizer is told to produce when none is supplied. Written for a reader who will continue\n * the conversation without seeing the messages themselves, so it asks for the parts a later turn\n * still has to act on rather than a readable recap.\n */\nexport const DEFAULT_HISTORY_SUMMARY_INSTRUCTION =\n 'Summarize this conversation for an assistant that will continue it without seeing these messages. Preserve decisions made, facts and constraints the user stated, identifiers and names mentioned, and anything left unresolved. Omit pleasantries. Reply with the summary only — no preamble, no headings.';\n\n/**\n * A {@link HistoryPolicy.summarize} backed by one extra, non-streamed model call — what\n * `AgentModule.forRoot({ history: { summarize: true } })` binds. Writes to a discarding sink so the\n * summary's tokens never reach the user's live stream, and reports its usage so the call lands in\n * the spend read-model like any other.\n */\nexport function summarizeWithModel(\n model: ModelProvider,\n instruction: string = DEFAULT_HISTORY_SUMMARY_INSTRUCTION,\n): NonNullable<HistoryPolicy['summarize']> {\n return async (dropped: ModelMessage[]): Promise<HistorySummary> => {\n const discard: SinkWriter = { write: () => {}, end: () => {}, fail: () => {} };\n const turn = await model.runTurn({\n system: instruction,\n messages: dropped,\n tools: [],\n sink: discard,\n });\n return {\n text: turn.text,\n usage: turn.usage,\n ...(turn.modelId !== undefined ? { modelId: turn.modelId } : {}),\n };\n };\n}\n","/**\n * Running the processor chains, and the stream buffering an output gate requires. See\n * `./spi/processors.ts` for the seams themselves and the boundary against `HistoryPolicy`.\n */\n\nimport {\n DEFAULT_INCREMENTAL_LOOKBACK_CHARS,\n type InputProcessor,\n type ModelAnswer,\n type OutputProcessor,\n type OutputVerdict,\n type ProcessedPrompt,\n type ProcessorContext,\n ProcessorFailedError,\n} from './spi/processors.js';\nimport type { SinkWriter } from './spi/token-stream-sink.js';\nimport { decodeStreamEvent, encodeStreamEvent } from './stream-events.js';\nimport type { ToolCallRequest } from './types.js';\n\n/**\n * Holds a model call's stream frames instead of letting them reach the subscriber. `end`/`fail` are\n * swallowed for the same reason `childSinkWriter` swallows them: the loop owns the run's stream\n * lifecycle across however many steps the turn takes, and the model call is one step of it.\n *\n * Frames are kept as the decoded NDJSON LINES rather than the raw `Uint8Array`s so the buffer can\n * ride a durable checkpoint — the gate has to survive a suspend between the model call and the\n * verdict, and bytes do not round-trip through JSON.\n */\nexport interface FrameBuffer {\n writer: SinkWriter;\n /** Everything written so far, one entry per NDJSON line, in write order. */\n frames(): string[];\n}\n\nconst decoder = new TextDecoder();\n\nexport function createFrameBuffer(): FrameBuffer {\n const frames: string[] = [];\n return {\n writer: {\n write: (chunk) => {\n for (const line of decoder.decode(chunk).split('\\n')) {\n if (line.length > 0) {\n frames.push(line);\n }\n }\n },\n end: () => {},\n fail: () => {},\n },\n frames: () => frames,\n };\n}\n\n/**\n * The chunks a passed gate releases to the live stream: the held frames, with every text frame\n * collapsed into ONE carrying `text` — the answer as the chain left it, which is the only version\n * anything downstream is allowed to see.\n *\n * A frame that does not decode is dropped along with them. It cannot be forwarded, because a gate\n * that forwards bytes it cannot classify is not a gate: a provider writing bare text into the sink\n * (rather than the `AgentStreamEvent` vocabulary) would otherwise stream the ungated answer past\n * the processor that was supposed to hold it. That is the cost of an output gate for a provider\n * outside the encoded vocabulary, and it is stated in `AgentLoopDeps.outputProcessors`.\n */\nexport function releaseGatedFrames(frames: readonly string[], text: string): Uint8Array[] {\n const released: Uint8Array[] = [];\n let emitted = false;\n for (const frame of frames) {\n const event = decodeStreamEvent(frame);\n if (event === null || event.kind === 'text') {\n // Substituted in place, so the answer keeps its position relative to the tool-call frames a\n // model interleaves with it.\n if (!emitted && text.length > 0) {\n released.push(encodeStreamEvent({ kind: 'text', text }));\n emitted = true;\n }\n continue;\n }\n released.push(encodeStreamEvent(event));\n }\n if (!emitted && text.length > 0) {\n released.push(encodeStreamEvent({ kind: 'text', text }));\n }\n return released;\n}\n\n/**\n * Fold the prompt through each processor in order, every one seeing what the previous one produced.\n * A throw is wrapped so it cannot read as the model call failing — see {@link ProcessorFailedError}.\n */\nexport async function runInputProcessors(\n processors: readonly InputProcessor[],\n prompt: ProcessedPrompt,\n ctx: ProcessorContext,\n): Promise<ProcessedPrompt> {\n let current = prompt;\n for (const processor of processors) {\n try {\n current = await processor.process(current, ctx);\n } catch (error) {\n throw new ProcessorFailedError('input', processor.name, error);\n }\n }\n return current;\n}\n\n/** A settled output chain: the answer as the chain left it, plus who refused it if anyone did. */\nexport interface OutputGateResult {\n /** The text every downstream consumer sees — the stream, the persisted message, the next step. */\n text: string;\n /** Set only on a refusal; the run ends with an `OutputRejectedError` naming these. */\n rejection?: { processor: string; reason: string };\n}\n\n/**\n * Fold the answer through each processor in order. The FIRST rejection ends the chain: a later\n * processor has nothing to add about text that is never going anywhere, and running it would bill\n * a moderation call for a turn already refused.\n */\nexport async function runOutputProcessors(\n processors: readonly OutputProcessor[],\n answer: ModelAnswer,\n ctx: ProcessorContext,\n): Promise<OutputGateResult> {\n let text = answer.text;\n for (const processor of processors) {\n let verdict: OutputVerdict;\n try {\n verdict = await processor.process({ text, toolCalls: answer.toolCalls }, ctx);\n } catch (error) {\n throw new ProcessorFailedError('output', processor.name, error);\n }\n if (verdict.action === 'reject') {\n return { text, rejection: { processor: processor.name, reason: verdict.reason } };\n }\n if (verdict.action === 'replace') {\n text = verdict.text;\n }\n }\n return { text };\n}\n\n/**\n * Put each suggestion through the output chain on its own, and keep what survives.\n *\n * A follow-up is model-generated text that gets persisted and rendered, so the gate has to see it.\n * What it does NOT get is the chain's usual answer to a refusal — ending the run. The suggestions\n * are produced AFTER the turn's answer has already cleared the same chain, and retracting a cleared\n * answer because a question nobody asked for was refused would make a run's outcome depend on a\n * by-product. Dropping the suggestion removes it just as completely, which is what the refusal was\n * for. A `replace` is honoured; a processor that empties one drops it too, since an empty suggestion\n * is nothing to render.\n *\n * One suggestion at a time rather than the joined list, so a refusal is confined to the one that\n * earned it and a `replace` cannot smear across a neighbour.\n */\nexport async function gateFollowUps(\n processors: readonly OutputProcessor[],\n followUps: readonly string[],\n ctx: ProcessorContext,\n): Promise<string[]> {\n const kept: string[] = [];\n for (const followUp of followUps) {\n const settled = await runOutputProcessors(processors, { text: followUp, toolCalls: [] }, ctx);\n if (settled.rejection === undefined && settled.text.length > 0) {\n kept.push(settled.text);\n }\n }\n return kept;\n}\n\n/**\n * How much of a turn's stream an output chain costs the reader.\n *\n * `off` — nothing registered, the model writes straight to the run's sink.\n * `whole` — at least one processor needs the complete answer, so every frame is held until the\n * chain has passed and the answer arrives as one `text` frame.\n * `incremental` — every processor declared {@link IncrementalGating}, so a lookback-bounded prefix\n * is released while the call streams.\n */\nexport type OutputGateMode = 'off' | 'whole' | 'incremental';\n\n/**\n * ALL or nothing: one undeclared processor puts the whole chain on the whole-answer path. Its\n * author wrote `process` against the complete text, and a chain that ran it on a prefix because a\n * neighbour opted in would be handing it an input it never agreed to read.\n */\nexport function resolveOutputGateMode(processors: readonly OutputProcessor[]): OutputGateMode {\n if (processors.length === 0) {\n return 'off';\n }\n return processors.every((processor) => processor.incremental !== undefined)\n ? 'incremental'\n : 'whole';\n}\n\n/**\n * The chain's window is the WIDEST any member asked for: a release safe for the shortest-sighted\n * processor is not safe for the one that matches longer patterns, and the gate makes one release\n * decision for all of them.\n *\n * An undeclared processor contributes nothing rather than the default — it has no window, because a\n * chain containing one never reaches the incremental path at all.\n */\nexport function resolveGateLookback(processors: readonly OutputProcessor[]): number {\n let lookback = 0;\n for (const processor of processors) {\n if (processor.incremental !== undefined) {\n lookback = Math.max(\n lookback,\n processor.incremental.lookbackChars ?? DEFAULT_INCREMENTAL_LOOKBACK_CHARS,\n );\n }\n }\n return lookback;\n}\n\n/** A live gate over one model call: the sink the model writes to, plus what it let through. */\nexport interface IncrementalGate {\n /** Hand this to the model instead of the run's writer. */\n writer: SinkWriter;\n /** Resolves once every chunk handed to {@link writer} has been ruled on. */\n settled(): Promise<void>;\n /** The transformed prefix already written to the run's sink. */\n released(): string;\n /** Set once a prefix was refused; nothing further was released after that. */\n rejection(): OutputGateResult['rejection'];\n}\n\n/**\n * Releases a model call's answer to `writer` as it arrives, holding back the last `lookbackChars`\n * characters of what the chain produces so a processor can still change them.\n *\n * The chain runs over the whole PREFIX accumulated so far rather than over each new chunk, so a\n * processor always sees well-formed text and never has to reassemble a pattern split across\n * frames — which is what makes {@link IncrementalGating}'s promise a claim about prefixes. It runs\n * once per streamed `text` frame.\n *\n * Only an EXTENSION of what the reader already has is ever written: a chain whose output stops\n * agreeing with its earlier output has broken its promise, and the loop's whole-answer pass reports\n * that rather than this gate papering over it by re-sending a different answer.\n *\n * Frames that are not text are forwarded live, in arrival order. They are not the answer, so the\n * gate does not own them — but it does drop any frame it cannot decode, for the same reason\n * {@link releaseGatedFrames} does: a gate that forwards bytes it cannot classify is not a gate.\n */\nexport function createIncrementalGate(options: {\n processors: readonly OutputProcessor[];\n ctx: ProcessorContext;\n lookbackChars: number;\n writer: SinkWriter;\n}): IncrementalGate {\n const { processors, ctx, lookbackChars, writer } = options;\n let raw = '';\n let released = '';\n let rejection: OutputGateResult['rejection'];\n /** A prefix the chain could not rule on. Text stops flowing; the whole-answer pass decides. */\n let stalled = false;\n const toolCalls: ToolCallRequest[] = [];\n // The model is free to write without awaiting, and a verdict is asynchronous — serialize, or two\n // prefixes race and the reader gets the answer out of order.\n let queue: Promise<void> = Promise.resolve();\n\n async function advance(): Promise<void> {\n if (raw.length === 0) {\n return;\n }\n let settled: OutputGateResult;\n try {\n settled = await runOutputProcessors(processors, { text: raw, toolCalls }, ctx);\n } catch {\n // Swallowed HERE only: a prefix pass is an early release, not the verdict. The whole-answer\n // pass runs the same chain and surfaces the failure with the processor's name on it.\n stalled = true;\n return;\n }\n if (settled.rejection !== undefined) {\n rejection = settled.rejection;\n return;\n }\n // The window is trimmed off the chain's OUTPUT, not off the text fed to it: a processor that\n // only saw `raw` minus a tail could not match a pattern straddling that cut, and would release\n // the very text it exists to rewrite.\n const candidate = settled.text.slice(0, Math.max(0, settled.text.length - lookbackChars));\n if (candidate.length <= released.length || !candidate.startsWith(released)) {\n return;\n }\n const delta = candidate.slice(released.length);\n released = candidate;\n await writer.write(encodeStreamEvent({ kind: 'text', text: delta }));\n }\n\n async function handle(chunk: Uint8Array): Promise<void> {\n for (const line of decoder.decode(chunk).split('\\n')) {\n if (line.length === 0) {\n continue;\n }\n const event = decodeStreamEvent(line);\n if (event === null || rejection !== undefined) {\n continue;\n }\n if (event.kind === 'text') {\n raw += event.text;\n if (!stalled) {\n await advance();\n }\n continue;\n }\n if (event.kind === 'tool-input-available') {\n toolCalls.push({ id: event.id, name: event.name, input: event.input });\n }\n await writer.write(encodeStreamEvent(event));\n }\n }\n\n return {\n writer: {\n write: (chunk) => {\n queue = queue.then(() => handle(chunk));\n return queue;\n },\n end: () => {},\n fail: () => {},\n },\n settled: () => queue,\n released: () => released,\n rejection: () => rejection,\n };\n}\n\n/**\n * The tail an incremental gate still owes the reader once the whole-answer pass has settled: the\n * authoritative text minus the prefix already released.\n *\n * Throws when the settled answer is not an extension of that prefix. That check is the reason the\n * final pass stays authoritative for both the stream and the store rather than the stream being\n * stitched together from per-prefix results: agreement between what was streamed and what was\n * stored becomes structural instead of assumed.\n */\nexport function gateTail(\n processors: readonly OutputProcessor[],\n released: string,\n text: string,\n): string {\n if (!text.startsWith(released)) {\n throw new ProcessorFailedError(\n 'output',\n processors.map((processor) => processor.name).join(' → '),\n new Error(\n `the gated answer is not an extension of the ${released.length} characters this chain already released — a processor that declares \"incremental\" promises its result on a prefix stays a prefix of its result on the whole answer, outside the last lookbackChars`,\n ),\n );\n }\n return text.slice(released.length);\n}\n","/**\n * Constraining a turn's ANSWER to a schema. See `AgentLoopDeps.outputSchema` for where this sits in\n * the loop and why it is a separate model call rather than a constraint on the turn's own calls.\n */\n\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\n\n/**\n * The turn produced an answer that does not satisfy `outputSchema`, and the bounded repair attempts\n * did not fix it. A DEFINED outcome of asking for structured output, not a crash: it carries the\n * validation issues and the text that failed them, so a caller can log what the model actually said\n * instead of guessing from a parse error. Both runners map it to the `structured_output_invalid`\n * stream error code.\n */\nexport class StructuredOutputError extends Error {\n /** Why it failed the schema. Empty only when the text was not JSON at all. */\n readonly issues: readonly StandardSchemaV1.Issue[];\n /** The last text the model produced, verbatim. */\n readonly text: string;\n /** How many model calls were spent trying (1 = the formatting pass, no repairs). */\n readonly attempts: number;\n\n constructor(issues: readonly StandardSchemaV1.Issue[], text: string, attempts: number) {\n const detail =\n issues.length > 0\n ? issues.map((issue) => issue.message).join('; ')\n : 'the model did not reply with JSON';\n super(`Structured output invalid after ${attempts} attempt(s): ${detail}`);\n this.name = 'StructuredOutputError';\n this.issues = issues;\n this.text = text;\n this.attempts = attempts;\n }\n}\n\n/** A validated answer, or the issues that stopped it being one. */\nexport type StructuredOutcome<T> =\n | { ok: true; value: T }\n | { ok: false; issues: readonly StandardSchemaV1.Issue[] };\n\n/**\n * Pull a JSON value out of a model reply, tolerating the code fences and lead-in prose a provider\n * that cannot constrain its own generation still emits. `undefined` when there is no JSON in there\n * at all — distinct from a JSON `null`, which is a value the schema may well accept.\n */\nexport function extractJson(text: string): unknown {\n const candidates = [text, text.match(/\\{[\\s\\S]*\\}/)?.[0], text.match(/\\[[\\s\\S]*\\]/)?.[0]];\n for (const candidate of candidates) {\n if (candidate === undefined) {\n continue;\n }\n try {\n return JSON.parse(candidate) as unknown;\n } catch {\n /* try the next shape */\n }\n }\n return undefined;\n}\n\n/**\n * Validate one attempt. The provider's own parsed `object` is preferred when it reported one (a\n * provider that constrained generation already did the parse), but it is validated all the same —\n * \"the provider says it matched\" is not the same claim as \"it matches\", and a provider that ignored\n * `outputSchema` entirely must fail here rather than downstream.\n */\nexport async function validateStructured<T>(\n schema: StandardSchemaV1<unknown, T>,\n text: string,\n reported: unknown,\n): Promise<StructuredOutcome<T>> {\n const candidate = reported !== undefined ? reported : extractJson(text);\n if (candidate === undefined) {\n return { ok: false, issues: [] };\n }\n const result = await schema['~standard'].validate(candidate);\n return result.issues !== undefined\n ? { ok: false, issues: result.issues }\n : { ok: true, value: result.value };\n}\n\n/**\n * What the formatting pass is told to do. Written for a model that is being shown a finished answer\n * and asked to restate it — never to extend or improve it, which would make the structured result\n * disagree with the prose the user already read.\n */\nexport const DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION =\n \"Restate the assistant's final answer as a single JSON value matching the required schema. Use only information already present in the conversation — add nothing, and answer nothing that was not asked. Reply with ONLY the JSON: no prose, no explanation, no code fences.\";\n\n/** Appends the previous attempt's validation issues, so a repair call knows what to fix. */\nexport function repairInstruction(\n instruction: string,\n issues: readonly StandardSchemaV1.Issue[],\n): string {\n const detail =\n issues.length > 0\n ? issues\n .map((issue) => `${(issue.path ?? []).join('.') || '(root)'}: ${issue.message}`)\n .join('\\n')\n : 'the previous reply was not valid JSON';\n return `${instruction}\\n\\nYour previous reply was rejected:\\n${detail}`;\n}\n","/**\n * Typed answers for a question set: a question that asks for a number, a date, an email or a\n * sentence instead of offering options to pick.\n *\n * Answers stay `string[]` on the wire whatever the type — the signal that carries them, the row that\n * records them and the model that reads them back all see strings — so this module fixes ONE\n * canonical string per type and validates against it:\n *\n * | `type` | canonical value |\n * |------------|----------------------------------------------|\n * | `text` | the text |\n * | `textarea` | the text (newlines kept) |\n * | `number` | a finite decimal, e.g. `\"42\"`, `\"-1.5\"` |\n * | `boolean` | `\"true\"` or `\"false\"` |\n * | `date` | `YYYY-MM-DD` |\n * | `email` | an address with one `@` and a dotted domain |\n * | `url` | an absolute `http:`/`https:` URL |\n * | `select` | one of the question's `options[].value` |\n *\n * Pure and dependency-free, so the loop (which filters what it settles on), the HTTP surface (which\n * refuses what it cannot settle) and a client (which says so before sending) all agree.\n */\nimport type { ElicitationOption, ElicitationQuestion } from './elicitation.js';\n\nexport const ELICITATION_INPUT_TYPES = [\n 'text',\n 'textarea',\n 'number',\n 'boolean',\n 'date',\n 'email',\n 'url',\n 'select',\n] as const;\n\nexport type ElicitationInputType = (typeof ELICITATION_INPUT_TYPES)[number];\n\n/** How a question takes its answer when it is not (only) a pick from `options`. */\nexport interface ElicitationInput {\n type: ElicitationInputType;\n /** Hint shown in an empty field. Advisory. */\n placeholder?: string;\n /** Submitting without a value is refused. Skipping the whole set is still allowed. */\n required?: boolean;\n /**\n * Lower bound: the smallest number for `number`, the shortest length for `text`/`textarea`, the\n * earliest `YYYY-MM-DD` for `date`. Ignored for the other types.\n */\n min?: number | string;\n /** Upper bound, read like {@link min}. */\n max?: number | string;\n /** A regular expression the WHOLE value must match (`text`, `textarea`, `email`, `url`). */\n pattern?: string;\n}\n\n/** The question's options, or none — `options` may be omitted on a typed question. */\nexport function questionOptions(question: ElicitationQuestion): ElicitationOption[] {\n return question.options ?? [];\n}\n\n/** A question answered by a typed value rather than by picking one of its options. */\nexport function isTypedQuestion(question: ElicitationQuestion): boolean {\n return question.input !== undefined && question.input.type !== 'select';\n}\n\nconst DATE_PATTERN = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\nconst EMAIL_PATTERN = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst NUMBER_PATTERN = /^-?(\\d+\\.?\\d*|\\.\\d+)(e[+-]?\\d+)?$/i;\n\nfunction isDate(value: string): boolean {\n const match = DATE_PATTERN.exec(value);\n if (match === null) {\n return false;\n }\n const [, year, month, day] = match;\n const date = new Date(Date.UTC(Number(year), Number(month) - 1, Number(day)));\n return (\n date.getUTCFullYear() === Number(year) &&\n date.getUTCMonth() === Number(month) - 1 &&\n date.getUTCDate() === Number(day)\n );\n}\n\nfunction isHttpUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\nfunction fullMatch(pattern: string, value: string): boolean | undefined {\n try {\n return new RegExp(`^(?:${pattern})$`, 'u').test(value);\n } catch {\n // An author's unreadable pattern constrains nothing rather than refusing every answer.\n return undefined;\n }\n}\n\nfunction asNumber(bound: number | string | undefined): number | undefined {\n if (typeof bound === 'number' && Number.isFinite(bound)) {\n return bound;\n }\n if (typeof bound === 'string' && NUMBER_PATTERN.test(bound.trim())) {\n return Number(bound);\n }\n return undefined;\n}\n\n/**\n * Why `value` is not an acceptable answer to `question`, or `null` when it is. Checks ONE value;\n * {@link validateElicitationAnswer} checks the list (required, single choice).\n */\nexport function validateElicitationValue(\n question: ElicitationQuestion,\n value: string,\n): string | null {\n const input = question.input;\n if (input === undefined || input.type === 'select') {\n if (question.allowFreeText === true) {\n return null;\n }\n return questionOptions(question).some((option) => option.value === value)\n ? null\n : 'must be one of the offered options';\n }\n switch (input.type) {\n case 'number': {\n if (!NUMBER_PATTERN.test(value.trim()) || !Number.isFinite(Number(value))) {\n return 'must be a number';\n }\n const number = Number(value);\n const min = asNumber(input.min);\n const max = asNumber(input.max);\n if (min !== undefined && number < min) {\n return `must be at least ${min}`;\n }\n if (max !== undefined && number > max) {\n return `must be at most ${max}`;\n }\n return null;\n }\n case 'boolean':\n return value === 'true' || value === 'false' ? null : 'must be \"true\" or \"false\"';\n case 'date': {\n if (!isDate(value)) {\n return 'must be a date as YYYY-MM-DD';\n }\n if (typeof input.min === 'string' && isDate(input.min) && value < input.min) {\n return `must be on or after ${input.min}`;\n }\n if (typeof input.max === 'string' && isDate(input.max) && value > input.max) {\n return `must be on or before ${input.max}`;\n }\n return null;\n }\n case 'email':\n if (!EMAIL_PATTERN.test(value)) {\n return 'must be an email address';\n }\n break;\n case 'url':\n if (!isHttpUrl(value)) {\n return 'must be an http(s) URL';\n }\n break;\n case 'text':\n case 'textarea': {\n const min = asNumber(input.min);\n const max = asNumber(input.max);\n if (min !== undefined && value.length < min) {\n return `must be at least ${min} characters`;\n }\n if (max !== undefined && value.length > max) {\n return `must be at most ${max} characters`;\n }\n break;\n }\n }\n if (input.pattern !== undefined && fullMatch(input.pattern, value) === false) {\n return 'does not match the expected format';\n }\n return null;\n}\n\n/**\n * Why `values` is not an acceptable answer to `question`, or `null` when it is: a `required`\n * question left empty, more than one value for a single-choice question, or any value\n * {@link validateElicitationValue} refuses. An empty string counts as no value.\n */\nexport function validateElicitationAnswer(\n question: ElicitationQuestion,\n values: readonly string[],\n): string | null {\n const present = values.filter((value) => value !== '');\n if (present.length === 0) {\n return question.input?.required === true ? 'requires an answer' : null;\n }\n if (question.multiple !== true && present.length > 1) {\n return 'takes a single value';\n }\n for (const value of present) {\n const problem = validateElicitationValue(question, value);\n if (problem !== null) {\n return problem;\n }\n }\n return null;\n}\n\n/**\n * Read an {@link ElicitationInput} from untrusted JSON, or `undefined` when it is not one. Unknown\n * keys are dropped; a malformed optional field is dropped rather than failing the input.\n */\nexport function readElicitationInput(raw: unknown): ElicitationInput | undefined {\n if (typeof raw !== 'object' || raw === null) {\n return undefined;\n }\n const candidate = raw as Record<string, unknown>;\n const type = candidate.type;\n if (typeof type !== 'string' || !(ELICITATION_INPUT_TYPES as readonly string[]).includes(type)) {\n return undefined;\n }\n const bound = (value: unknown) =>\n (typeof value === 'number' && Number.isFinite(value)) || typeof value === 'string'\n ? (value as number | string)\n : undefined;\n const min = bound(candidate.min);\n const max = bound(candidate.max);\n return {\n type: type as ElicitationInputType,\n ...(typeof candidate.placeholder === 'string' ? { placeholder: candidate.placeholder } : {}),\n ...(candidate.required === true ? { required: true } : {}),\n ...(min !== undefined ? { min } : {}),\n ...(max !== undefined ? { max } : {}),\n ...(typeof candidate.pattern === 'string' ? { pattern: candidate.pattern } : {}),\n };\n}\n\n/**\n * The questions a parked call carries, read leniently from its recorded input (`{ questions }` —\n * what both an intake and an `ask` persist). Used where a reply is checked against the questions it\n * answers; a question that cannot be read is left out rather than failing the rest.\n */\nexport function readElicitationQuestions(input: unknown): ElicitationQuestion[] {\n if (typeof input !== 'object' || input === null) {\n return [];\n }\n const raw = (input as { questions?: unknown }).questions;\n if (!Array.isArray(raw)) {\n return [];\n }\n const questions: ElicitationQuestion[] = [];\n for (const item of raw) {\n if (typeof item !== 'object' || item === null) {\n continue;\n }\n const candidate = item as Record<string, unknown>;\n if (typeof candidate.id !== 'string' || typeof candidate.prompt !== 'string') {\n continue;\n }\n const options: ElicitationOption[] = Array.isArray(candidate.options)\n ? candidate.options.flatMap((option: unknown) => {\n if (typeof option !== 'object' || option === null) {\n return [];\n }\n const { value, label } = option as Record<string, unknown>;\n return typeof value === 'string' && typeof label === 'string' ? [{ value, label }] : [];\n })\n : [];\n const typed = readElicitationInput(candidate.input);\n const defaults = Array.isArray(candidate.defaults)\n ? candidate.defaults.filter((value): value is string => typeof value === 'string')\n : [];\n questions.push({\n id: candidate.id,\n prompt: candidate.prompt,\n options,\n ...(typed !== undefined ? { input: typed } : {}),\n ...(defaults.length > 0 ? { defaults } : {}),\n ...(candidate.multiple === true ? { multiple: true } : {}),\n ...(candidate.allowFreeText === true ? { allowFreeText: true } : {}),\n });\n }\n return questions;\n}\n","/**\n * Asking the USER a structured question, and waiting for the answer.\n *\n * `awaitApproval` collects a yes/no about work already proposed; this collects the scope BEFORE the\n * work. Two surfaces produce it — a configured intake (`AgentLoopDeps.intake`) and the model-callable\n * `ask` tool (`AgentLoopDeps.ask`) — and they deliberately produce the SAME {@link\n * ElicitationRequest}, persist through the same tool-call row, and resume through the same\n * `tool:<runId>:<callId>` signal. A consumer cannot tell which one asked, and should not have to.\n */\n\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport {\n ELICITATION_INPUT_TYPES,\n type ElicitationInput,\n isTypedQuestion,\n questionOptions,\n readElicitationInput,\n validateElicitationValue,\n} from './elicitation-input.js';\nimport type { Decision, ToolDefinition } from './types.js';\n\n/** One choice a question offers. */\nexport interface ElicitationOption {\n /** Stable identifier submitted back. Never shown to the user. */\n value: string;\n /** What the user reads. */\n label: string;\n /**\n * A single character a UI may bind as a keyboard shortcut for this option. Advisory — nothing in\n * the library reads it, and a client is free to render its own.\n */\n hotkey?: string;\n}\n\n/** One question in a set. */\nexport interface ElicitationQuestion {\n /** Unique within its request; the key answers come back under. */\n id: string;\n prompt: string;\n /** A line of help under the prompt. */\n description?: string;\n /**\n * The choices. Required unless {@link input} asks for a typed value — then optional, and a UI may\n * offer them as suggestions. An `input` of type `select` still picks from these.\n */\n options?: ElicitationOption[];\n /**\n * Ask for a typed value (a number, a date, a sentence…) instead of — or, for `select`, on top of —\n * a pick from `options`. The answer is still a `string[]`, in the type's canonical form; see\n * `elicitation-input.ts`.\n */\n input?: ElicitationInput;\n /** More than one option may be chosen. Omit → single choice. */\n multiple?: boolean;\n /**\n * The options already picked for the user. The claim this whole surface makes is that confirming\n * is enough, so a question with no defaults is a question the user must stop and think about —\n * which is the case the design is trying to avoid. Empty/omitted is allowed and means exactly\n * that: submitting without answering leaves this question unanswered.\n */\n defaults?: string[];\n /** Accept values that are not among `options` (a typed-in answer). Omit → options only. */\n allowFreeText?: boolean;\n}\n\n/**\n * A question set awaiting a human. Identical in shape whether an `@Agent`'s configured intake or\n * the model's `ask` tool authored it — `source` records which, for audit, not for control flow.\n *\n * `questions.length` is known when the request is written, which is what lets a client render\n * \"Question 1 of 3\" without guessing whether a fourth is coming.\n */\nexport interface ElicitationRequest {\n /** The tool-call id this request is persisted under, and the signal it is answered through. */\n id: string;\n source: 'intake' | 'ask';\n /** What the assistant says above the form. */\n preamble?: string;\n questions: ElicitationQuestion[];\n}\n\n/** What a human sent back for an {@link ElicitationRequest}. */\nexport interface ElicitationReply {\n /**\n * questionId → chosen values. A question whose id is ABSENT takes the request's own `defaults` —\n * that is what makes \"just submit\" mean \"yes, your pre-picked answers\". A present-but-empty array\n * is an explicit \"none of these\" and does NOT fall back.\n */\n answers: Record<string, string[]>;\n /**\n * The user declined to answer and told the agent to proceed on its own assumptions. Distinct from\n * confirming the defaults even though the resulting values are the same: one is a decision the\n * user made, the other is one they refused to make, and only the first is evidence of intent.\n */\n skipped?: boolean;\n /** Opaque ref of WHO answered, when it wasn't the run's own actor. */\n answeredByRef?: string;\n /**\n * The surface the answer came through — `'web'`, `'slack'`, `'console'`, … — the counterpart of\n * an approval's `decidedVia`.\n */\n answeredVia?: string;\n}\n\n/** A settled elicitation: what the agent proceeds on, and how it got there. */\nexport interface ElicitationOutcome {\n /** One entry per question, in request order — always present, so a caller never re-applies defaults. */\n answers: Record<string, string[]>;\n skipped: boolean;\n /** Question ids filled from the request's `defaults` rather than by the human. */\n defaulted: string[];\n /**\n * Who answered (or skipped) — the reply's `answeredByRef`, which a host may make a display name.\n * The counterpart of an approval's `decidedBy`. Absent when the reply did not say.\n */\n answeredBy?: string;\n /** The surface it came through (`'web'`, `'slack'`, …) — an approval's `decidedVia`. */\n answeredVia?: string;\n}\n\n/**\n * Read whatever the human channel delivered as an {@link ElicitationReply}.\n *\n * A question set is persisted as an `action` tool call in `pending_approval` — that is what puts it\n * in the approvals inbox a deployment already has, instead of needing one of its own. The cost of\n * that choice is that the thing which comes back may be a {@link Decision} someone pressed\n * Approve/Reject on rather than a set of answers, and a `Decision` carries no `answers` at all.\n *\n * Approve means every question keeps its own pre-picked `defaults`, which is exactly what \"just\n * submit\" already means on this surface; Reject is the same declining-to-answer a skip is. Neither\n * reading is a guess — a yes/no channel cannot say more than that, and saying it here is what lets\n * one inbox settle both kinds of pending work.\n *\n * Returns the reply UNCHANGED when it already carries answers, so the common path allocates nothing\n * and a caller can identity-compare.\n */\nexport function normalizeElicitationReply(reply: ElicitationReply | Decision): ElicitationReply {\n if (typeof reply !== 'object' || reply === null) {\n return { answers: {} };\n }\n const candidate = reply as Partial<ElicitationReply> & Partial<Decision>;\n if (typeof candidate.answers === 'object' && candidate.answers !== null) {\n return reply as ElicitationReply;\n }\n const answeredByRef = candidate.answeredByRef ?? candidate.executedByRef;\n const answeredVia = candidate.answeredVia ?? candidate.decidedVia;\n return {\n answers: {},\n ...(candidate.approved === false || candidate.skipped === true ? { skipped: true } : {}),\n ...(answeredByRef !== undefined ? { answeredByRef } : {}),\n ...(answeredVia !== undefined ? { answeredVia } : {}),\n };\n}\n\n/**\n * Settle a reply against the request it answers: fill every unanswered question from its own\n * `defaults`, drop submitted values that aren't on offer, and collapse a single-choice question to\n * one value.\n *\n * PURE, and deliberately so. Both of its inputs are already journaled by the time the loop calls it\n * — the request came from module config or from an `llm:<i>` checkpoint, the reply from the signal\n * checkpoint — so every process replaying the turn reaches the same values without a checkpoint of\n * its own. Resolving defaults in the HTTP layer instead would put them behind a store read that a\n * replay would have to repeat.\n */\nexport function resolveElicitation(\n request: ElicitationRequest,\n raw: ElicitationReply | Decision,\n): ElicitationOutcome {\n const reply = normalizeElicitationReply(raw);\n const answers: Record<string, string[]> = {};\n const defaulted: string[] = [];\n for (const question of request.questions) {\n const submitted = reply.skipped === true ? undefined : reply.answers[question.id];\n if (submitted === undefined) {\n answers[question.id] = [...(question.defaults ?? [])];\n defaulted.push(question.id);\n continue;\n }\n // What cannot be settled is dropped, never guessed at: a value off the offered options, or one a\n // typed question's own rules refuse. The HTTP surface refuses both before they are signalled; this\n // is the same rule applied where the loop settles, so a reply from anywhere reads the same.\n const valid = submitted.filter(\n (value) => value !== '' && validateElicitationValue(question, value) === null,\n );\n answers[question.id] = question.multiple === true ? valid : valid.slice(0, 1);\n }\n return {\n answers,\n skipped: reply.skipped === true,\n defaulted,\n ...(reply.answeredByRef !== undefined ? { answeredBy: reply.answeredByRef } : {}),\n ...(reply.answeredVia !== undefined ? { answeredVia: reply.answeredVia } : {}),\n };\n}\n\n/**\n * What a settled elicitation looks like to everyone downstream: the model reading it back as a tool\n * result, the thread reader rendering it, the auditor asking what the agent was told to do. One\n * shape for both surfaces — nothing here records which of them asked.\n */\nexport interface ElicitationResult extends ElicitationOutcome {\n /** The questions against the chosen LABELS, so a reader (and a model) can act on it. */\n summary: string;\n}\n\n/** {@link resolveElicitation} plus its human-readable rendering. Pure, for the same reason. */\nexport function settleElicitation(\n request: ElicitationRequest,\n reply: ElicitationReply | Decision,\n): ElicitationResult {\n const outcome = resolveElicitation(request, reply);\n return { ...outcome, summary: renderElicitationAnswers(request, outcome) };\n}\n\n/**\n * The answers as the model reads them: the question's own prompt against the chosen options' LABELS,\n * not their opaque `value`s — a model shown `{\"scope\":[\"b\"]}` has been told nothing.\n */\nexport function renderElicitationAnswers(\n request: ElicitationRequest,\n outcome: ElicitationOutcome,\n): string {\n const lines = request.questions.map((question) => {\n const chosen = outcome.answers[question.id] ?? [];\n const labels = chosen.map(\n (value) => questionOptions(question).find((option) => option.value === value)?.label ?? value,\n );\n return `${question.prompt} → ${labels.length > 0 ? labels.join(', ') : '(no answer)'}`;\n });\n const preface = outcome.skipped\n ? 'The user declined to answer and asked you to proceed on these assumptions:'\n : 'The user answered:';\n return `${preface}\\n${lines.join('\\n')}`;\n}\n\n/** The reserved tool name the model calls to ask the user something. */\nexport const ASK_TOOL_NAME = 'ask';\n\n/** What the model must supply when it calls `ask`. */\nexport interface AskToolInput {\n preamble?: string;\n questions: ElicitationQuestion[];\n}\n\n/** How many questions one `ask` may carry. A form the user has to scroll is a form they skip. */\nexport const MAX_ASK_QUESTIONS = 5;\n\nfunction issue(path: (string | number)[], message: string): StandardSchemaV1.Issue {\n return { message, path };\n}\n\nfunction parseOption(\n raw: unknown,\n path: (string | number)[],\n issues: StandardSchemaV1.Issue[],\n): ElicitationOption | undefined {\n if (typeof raw !== 'object' || raw === null) {\n issues.push(issue(path, 'must be an object'));\n return undefined;\n }\n const candidate = raw as Partial<ElicitationOption>;\n if (typeof candidate.value !== 'string' || candidate.value.length === 0) {\n issues.push(issue([...path, 'value'], 'must be a non-empty string'));\n return undefined;\n }\n if (typeof candidate.label !== 'string' || candidate.label.length === 0) {\n issues.push(issue([...path, 'label'], 'must be a non-empty string'));\n return undefined;\n }\n return {\n value: candidate.value,\n label: candidate.label,\n ...(typeof candidate.hotkey === 'string' ? { hotkey: candidate.hotkey } : {}),\n };\n}\n\nfunction parseQuestion(\n raw: unknown,\n path: (string | number)[],\n issues: StandardSchemaV1.Issue[],\n): ElicitationQuestion | undefined {\n if (typeof raw !== 'object' || raw === null) {\n issues.push(issue(path, 'must be an object'));\n return undefined;\n }\n const candidate = raw as Partial<ElicitationQuestion>;\n if (typeof candidate.id !== 'string' || candidate.id.length === 0) {\n issues.push(issue([...path, 'id'], 'must be a non-empty string'));\n return undefined;\n }\n if (typeof candidate.prompt !== 'string' || candidate.prompt.length === 0) {\n issues.push(issue([...path, 'prompt'], 'must be a non-empty string'));\n return undefined;\n }\n let input: ElicitationInput | undefined;\n if (candidate.input !== undefined) {\n input = readElicitationInput(candidate.input);\n if (input === undefined) {\n issues.push(\n issue([...path, 'input', 'type'], `must be one of ${ELICITATION_INPUT_TYPES.join(', ')}`),\n );\n return undefined;\n }\n }\n const described =\n typeof candidate.description === 'string' && candidate.description.length > 0\n ? { description: candidate.description }\n : {};\n const typed = input !== undefined && input.type !== 'select';\n if (!typed && (!Array.isArray(candidate.options) || candidate.options.length === 0)) {\n issues.push(issue([...path, 'options'], 'must be a non-empty array'));\n return undefined;\n }\n const options: ElicitationOption[] = [];\n for (const [index, rawOption] of (Array.isArray(candidate.options)\n ? candidate.options\n : []\n ).entries()) {\n const option = parseOption(rawOption, [...path, 'options', index], issues);\n if (option !== undefined) {\n options.push(option);\n }\n }\n if (typed) {\n // A typed question pre-picks when it can (a sensible date, a default count) but need not: there\n // is no honest default for \"what is your email\". What it does pre-pick has to be an answer its\n // own rules accept, or confirming would submit something the form would refuse.\n const question: ElicitationQuestion = {\n id: candidate.id,\n prompt: candidate.prompt,\n ...described,\n ...(options.length > 0 ? { options } : {}),\n input: input as ElicitationInput,\n ...(candidate.multiple === true ? { multiple: true } : {}),\n };\n const offered = Array.isArray(candidate.defaults)\n ? candidate.defaults.filter((value): value is string => typeof value === 'string')\n : [];\n const defaults = offered.filter((value) => validateElicitationValue(question, value) === null);\n if (offered.length > 0 && defaults.length === 0) {\n issues.push(\n issue([...path, 'defaults'], `must be valid ${(input as ElicitationInput).type} values`),\n );\n return undefined;\n }\n return defaults.length > 0 ? { ...question, defaults } : question;\n }\n // The one rule that carries the design: a question with no pre-picked answer is a question the\n // user has to stop and think about, and this surface exists to avoid that.\n if (!Array.isArray(candidate.defaults) || candidate.defaults.length === 0) {\n issues.push(\n issue(\n [...path, 'defaults'],\n 'must pre-pick at least one option — say what you would choose so the user can just confirm',\n ),\n );\n return undefined;\n }\n const offered = new Set(options.map((option) => option.value));\n const defaults = candidate.defaults.filter(\n (value): value is string => typeof value === 'string' && offered.has(value),\n );\n if (defaults.length === 0) {\n issues.push(\n issue([...path, 'defaults'], \"must name values that appear in this question's options\"),\n );\n return undefined;\n }\n return {\n id: candidate.id,\n prompt: candidate.prompt,\n ...described,\n options,\n ...(input !== undefined ? { input } : {}),\n defaults,\n ...(candidate.multiple === true ? { multiple: true } : {}),\n ...(candidate.allowFreeText === true ? { allowFreeText: true } : {}),\n };\n}\n\nconst ASK_JSON_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n properties: {\n preamble: {\n type: 'string',\n description:\n 'One sentence shown above the form, e.g. \"Three questions before I start. I have pre-picked what I would choose, so confirming is enough.\"',\n },\n questions: {\n type: 'array',\n minItems: 1,\n maxItems: MAX_ASK_QUESTIONS,\n items: {\n type: 'object',\n additionalProperties: false,\n required: ['id', 'prompt'],\n properties: {\n id: {\n type: 'string',\n description: 'Unique within this call; answers come back under it.',\n },\n prompt: { type: 'string' },\n description: { type: 'string', description: 'A line of help under the prompt.' },\n input: {\n type: 'object',\n additionalProperties: false,\n required: ['type'],\n description:\n 'Ask for a typed value instead of offering options. Omit for a pick from options. Answers come back as strings: numbers as decimals, booleans as \"true\"/\"false\", dates as YYYY-MM-DD.',\n properties: {\n type: { type: 'string', enum: [...ELICITATION_INPUT_TYPES] },\n placeholder: { type: 'string' },\n required: { type: 'boolean' },\n min: {\n type: ['number', 'string'],\n description: 'number: minimum; text: minimum length; date: earliest YYYY-MM-DD.',\n },\n max: {\n type: ['number', 'string'],\n description: 'number: maximum; text: maximum length; date: latest YYYY-MM-DD.',\n },\n pattern: { type: 'string', description: 'A regex the whole value must match.' },\n },\n },\n multiple: { type: 'boolean', description: 'Allow more than one option to be chosen.' },\n allowFreeText: {\n type: 'boolean',\n description: 'Accept an answer that is not an option.',\n },\n defaults: {\n type: 'array',\n minItems: 1,\n items: { type: 'string' },\n description:\n 'REQUIRED for a pick from options: the option values you would pick yourself, so the user can confirm rather than decide. For a typed input, the value you would enter, when there is a sensible one.',\n },\n options: {\n type: 'array',\n minItems: 2,\n items: {\n type: 'object',\n additionalProperties: false,\n required: ['value', 'label'],\n properties: {\n value: { type: 'string' },\n label: { type: 'string' },\n hotkey: { type: 'string', maxLength: 1 },\n },\n },\n },\n },\n },\n },\n },\n required: ['questions'],\n} as const;\n\n/**\n * The `ask` tool's input schema, hand-written rather than borrowed from a validation library: core\n * depends on no validator, and the schema has to carry a JSON Schema a provider can constrain\n * generation against. It publishes one through the Standard JSON Schema extension\n * (`~standard.jsonSchema.input`), which is the path the AI SDK adapter already recognises for\n * Valibot / ArkType / Zod 4.\n */\nexport const askInputSchema: StandardSchemaV1<unknown, AskToolInput> = {\n '~standard': {\n version: 1,\n vendor: 'nestjs-agent',\n validate: (value: unknown) => {\n const issues: StandardSchemaV1.Issue[] = [];\n if (typeof value !== 'object' || value === null) {\n return { issues: [issue([], 'must be an object')] };\n }\n const candidate = value as Partial<AskToolInput>;\n if (!Array.isArray(candidate.questions) || candidate.questions.length === 0) {\n return { issues: [issue(['questions'], 'must be a non-empty array')] };\n }\n if (candidate.questions.length > MAX_ASK_QUESTIONS) {\n return {\n issues: [issue(['questions'], `must hold at most ${MAX_ASK_QUESTIONS} questions`)],\n };\n }\n const questions: ElicitationQuestion[] = [];\n for (const [index, raw] of candidate.questions.entries()) {\n const question = parseQuestion(raw, ['questions', index], issues);\n if (question !== undefined) {\n questions.push(question);\n }\n }\n if (issues.length > 0) {\n return { issues };\n }\n return {\n value: {\n questions,\n ...(typeof candidate.preamble === 'string' ? { preamble: candidate.preamble } : {}),\n },\n };\n },\n jsonSchema: { input: () => ASK_JSON_SCHEMA },\n },\n} as StandardSchemaV1<unknown, AskToolInput>;\n\n/**\n * What the model is told the `ask` tool is for. Written to discourage the two failure modes that\n * make a clarifying question worse than a guess: asking about something the conversation already\n * settled, and asking without saying what you would have done.\n */\nexport const ASK_TOOL_DESCRIPTION =\n 'Ask the user to settle the scope of the work before you do it. Use it when a reasonable person would produce a materially different result depending on the answer — not to confirm something the conversation already says. Every question must pre-pick the answer you would choose, so the user can confirm instead of deciding. The user may decline, in which case you proceed on those pre-picked answers.';\n\n/**\n * The `ask` tool as the model sees it. NOT a `ToolSpec` and never registered: `ask` has no handler,\n * because the loop settles it against a human instead of invoking anything. Keeping it out of the\n * `ToolRegistry` is also what keeps the kind decision off a process-local lookup — see\n * `claimToolCall`.\n */\nexport function askToolDefinition(): ToolDefinition {\n return {\n name: ASK_TOOL_NAME,\n kind: 'ask',\n description: ASK_TOOL_DESCRIPTION,\n inputSchema: askInputSchema,\n };\n}\n\n/** A question set an `@Agent` asks before it starts working. See `AgentLoopDeps.intake`. */\nexport interface AgentIntake {\n questions: ElicitationQuestion[];\n /** What the assistant says above the form. Omit → {@link DEFAULT_INTAKE_PREAMBLE}. */\n preamble?: string;\n /**\n * `'thread-start'` (default) asks once, on the first turn of a thread; `'every-turn'` asks before\n * every turn. Both are decided from what `load:thread` recorded about the thread when the turn\n * began, never from anything this process happens to know — by the time a replay reaches the\n * question, the thread already holds the assistant message the first attempt wrote.\n */\n when?: 'thread-start' | 'every-turn';\n}\n\nexport const DEFAULT_INTAKE_PREAMBLE =\n 'A few questions before I start. I have pre-picked what I would choose, so confirming is enough.';\n","/**\n * Skills: an authored procedure the model pulls in when a task calls for it, instead of every\n * instruction living in the system prompt.\n *\n * WHAT A SKILL IS NOT: an agent. An `@Agent` is WHO is answering — its persona, its tools, its\n * history ceiling, its output schema. A skill is HOW one particular task is done, and any agent may\n * pull one in. That is why a skill carries no model, no tool list and no schema: the moment it did,\n * the two would be the same thing wearing different names, and a consumer would have to choose\n * between them for reasons nobody could state.\n *\n * WHAT IT COSTS THE PROMPT: one line per skill. The catalog block below carries names, scopes and\n * descriptions only; a BODY reaches the model as a tool result, on the transcript, where the\n * `HistoryPolicy` ceiling already governs it. So skills are not a fourth thing competing for the\n * system block with the agent's own prompt, its contributors and injected retrieval — see\n * `AgentLoopDeps.skills` for how the four compose.\n */\n\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport type { Actor, PageContext, ToolDefinition } from './types.js';\n\n/** How a skill is identified in the catalog, to the model and to a `/`-autocomplete alike. */\nexport interface SkillSummary {\n /** Unique within a scope. The handle the model passes to the `skill` tool. */\n name: string;\n /** One line: what task this covers, and therefore when to load it. Read by the MODEL to choose. */\n description: string;\n /** The opaque scope token this skill is published at — see {@link ScopeResolver}. */\n scope: string;\n}\n\n/** A skill with the instructions themselves. Only ever materialized when something loads it. */\nexport interface Skill extends SkillSummary {\n body: string;\n}\n\n/** Whose turn is asking, and therefore which scopes apply. */\nexport interface ScopeContext {\n actor: Actor;\n threadId: string;\n /** The agent running this turn. Undefined → the default agent. */\n agentName?: string;\n pageContext?: PageContext;\n}\n\n/**\n * The skills-facing name for {@link ScopeContext}, so a `SkillProvider`'s signature reads in its own\n * vocabulary. Deliberately the SAME type rather than a parallel one: skills and memory resolve\n * scopes through one `ScopeResolver`, and a deployment that could answer \"which scopes does this\n * actor have\" twice would eventually answer it differently.\n */\nexport type SkillContext = ScopeContext;\n\n/** The scope token every deployment has: skills nobody narrowed. */\nexport const GLOBAL_SCOPE = 'global';\n\n/** The token for one actor's own skills. */\nexport function actorScope(actor: Actor): string {\n return `actor:${actor.id}`;\n}\n\n/** The token for a tenant's skills — `Actor.tenantRef` is the only tenant key this library knows. */\nexport function tenantScope(tenantRef: string): string {\n return `tenant:${tenantRef}`;\n}\n\n/**\n * Which scopes a turn may draw skills from, MOST SPECIFIC FIRST. Precedence is the order: a skill\n * from an earlier token outranks a same-named one from a later token, and the model is shown which\n * of them won.\n *\n * A HOST-SUPPLIED FUNCTION rather than an enum this library owns, because the axes a deployment\n * scopes by are the deployment's own. `Actor` gives an id and a tenant; it does not give a sector, a\n * region, a warehouse, a shift — and every one of those is a real axis in some consumer. An enum here\n * would make each of them a schema change in a library that has no business knowing they exist,\n * while a token is a string a host mints for itself. Return `['sector:logistics', 'tenant:berlin',\n * 'global']` and precedence follows, with nothing in this package edited.\n *\n * MUST be a pure function of its context. It runs inside the `skills:catalog` checkpoint and its\n * result is journaled, so a resumed run reads back the scopes the first attempt resolved rather than\n * asking a membership table that may have changed since — which would otherwise let a run's prompt\n * differ from the one its journal records. Read a database here at your peril; read it in the\n * provider, whose answer is journaled at the same position.\n */\nexport interface ScopeResolver {\n resolve(ctx: SkillContext): string[] | Promise<string[]>;\n}\n\n/**\n * The scopes derivable from an {@link Actor} alone — the common case, so a consumer wiring skills\n * for the first time supplies no resolver at all: the actor's own, their tenant's (when they have\n * one), and the deployment's. A host adding an axis of its own replaces this rather than extending\n * it, since the ORDER is the precedence and only the host knows where its axis belongs.\n */\nexport const defaultScopeResolver: ScopeResolver = {\n resolve: ({ actor }: SkillContext): string[] => [\n actorScope(actor),\n ...(actor.tenantRef !== undefined ? [tenantScope(actor.tenantRef)] : []),\n GLOBAL_SCOPE,\n ],\n};\n\n/**\n * Where skills come from. Deliberately two calls rather than one: `list` is asked on EVERY turn and\n * must stay cheap, while a body is read only when the model decides it needs that procedure — the\n * whole point of the surface. A provider over a table selects name/description/scope for the first\n * and one row for the second.\n *\n * This library owns no skill table. A skill's real scoping axes, its authoring UI and its audit\n * trail are all the host's, and a host that related its own `Sector` entity into a table this\n * package created at boot would be writing migrations against a schema the boot-time heal also\n * edits. Tokens split it the other way round: the library owns the contract (what a scope means, how\n * precedence works, what is journaled), the host owns the rows.\n */\n/** Arguments to {@link SkillProvider.list}. */\nexport interface ListSkillsInput {\n scopes: readonly string[];\n ctx: SkillContext;\n}\n\n/**\n * Arguments to {@link SkillProvider.load}. An object rather than positional arguments because\n * `name` and `scope` are both strings: transposed, a positional call compiles clean, returns `null`,\n * and the skill silently fails to load.\n */\nexport interface LoadSkillInput {\n name: string;\n scope: string;\n ctx: SkillContext;\n}\n\nexport interface SkillProvider {\n /**\n * Every skill visible at `scopes`, in any order — this library sorts and resolves precedence. A\n * provider MAY return skills outside `scopes`; they are dropped rather than trusted, so a filter\n * bug in a host cannot widen what an actor is offered.\n */\n list(input: ListSkillsInput): SkillSummary[] | Promise<SkillSummary[]>;\n /**\n * The instructions for one skill, or `null` when it is gone. Called only from inside the loading\n * checkpoint, so the body it returns is journaled and every replay reads THAT text back — an\n * edited skill never rewrites the prompt of a run already in flight.\n */\n load(input: LoadSkillInput): string | null | Promise<string | null>;\n}\n\n/** A source of skills that is a fixed list — `@Skill()`-decorated classes, or plain config. */\nexport function staticSkillProvider(skills: readonly Skill[]): SkillProvider {\n return {\n list: ({ scopes }) => skills.filter((skill) => scopes.includes(skill.scope)),\n load: ({ name, scope }) =>\n skills.find((skill) => skill.name === name && skill.scope === scope)?.body ?? null,\n };\n}\n\n/**\n * Read several sources as one. The order is the tie-break and nothing else: precedence between\n * skills is by SCOPE, so two sources only ever compete when they publish the same name at the same\n * scope, and then the earlier source wins. Wire the host's own provider first — a row it can edit is\n * a better answer than a body that needs a deploy to change.\n */\nexport function compositeSkillProvider(providers: readonly SkillProvider[]): SkillProvider {\n return {\n list: async ({ scopes, ctx }) => {\n const seen = new Set<string>();\n const merged: SkillSummary[] = [];\n for (const provider of providers) {\n for (const summary of await provider.list({ scopes, ctx })) {\n const key = `${summary.scope}\\u0000${summary.name}`;\n if (!seen.has(key)) {\n seen.add(key);\n merged.push(summary);\n }\n }\n }\n return merged;\n },\n load: async ({ name, scope, ctx }) => {\n for (const provider of providers) {\n const body = await provider.load({ name, scope, ctx });\n if (body !== null) {\n return body;\n }\n }\n return null;\n },\n };\n}\n\n/**\n * One skill as it is offered — to the model in the catalog block, and to a client over\n * `GET /agent/skills`. Both read the same list, built by the same call, so what a user can type\n * after a `/` and what the model can reach cannot drift apart.\n */\nexport interface SkillCatalogEntry {\n name: string;\n description: string;\n /** The scope token it resolved from — the provenance a user is entitled to see. */\n scope: string;\n /**\n * Scope tokens of same-named skills this one outranks, widest last. Present ONLY when something\n * was shadowed, so a reader can tell \"there is no org default\" from \"there is one and yours wins\".\n * The model is shown it for the same reason: a silent override is indistinguishable from an\n * instruction nobody wrote, and the user can only be told \"your setting differs from the org\n * default\" by something that knows both existed.\n */\n shadows?: string[];\n}\n\n/** What a turn resolved — journaled whole, so the prompt is reconstructible from the journal alone. */\nexport interface SkillOffer {\n /** The scope tokens this turn drew from, most specific first. */\n scopes: string[];\n /** The skills offered, most specific first then by name. */\n entries: SkillCatalogEntry[];\n /** Applicable skills `maxSkills` left out. Non-zero means the catalog is not the whole truth. */\n omitted: number;\n}\n\n/**\n * How many skills a catalog offers before it starts leaving some out. A ceiling on the SYSTEM\n * PROMPT's share, not on how many a deployment may have: the block costs one line each, and a\n * hundred lines of \"here is something you could load\" crowds out the agent's own instructions while\n * making the choice harder rather than easier.\n */\nexport const DEFAULT_MAX_SKILLS = 20;\n\n/** How a turn reaches its skills. See `AgentLoopDeps.skills`. */\nexport interface SkillsConfig {\n provider: SkillProvider;\n /** Undefined → {@link defaultScopeResolver}: the actor's own, their tenant's, the deployment's. */\n scopes?: ScopeResolver;\n /** Undefined → {@link DEFAULT_MAX_SKILLS}. */\n maxSkills?: number;\n}\n\n/**\n * Resolve a provider's skills against an ordered scope list: most specific wins, and the loser's\n * scope is recorded rather than discarded.\n *\n * Pure, and separately exported, because two callers must reach the identical answer — the loop, so\n * the model is offered it, and the listing endpoint, so a user is. A second implementation of\n * \"which skills apply\" is a second answer, and the two diverge the first time either is edited.\n */\nexport function resolveSkillCatalog(\n summaries: readonly SkillSummary[],\n scopes: readonly string[],\n maxSkills: number = DEFAULT_MAX_SKILLS,\n): Omit<SkillOffer, 'scopes'> {\n const rank = new Map(scopes.map((scope, index) => [scope, index]));\n const byName = new Map<string, SkillSummary[]>();\n for (const summary of summaries) {\n // A scope the resolver did not return is one this actor has no claim on, whatever the provider\n // thinks. Dropping it here is what makes over-returning a performance mistake instead of a leak.\n if (!rank.has(summary.scope)) {\n continue;\n }\n const existing = byName.get(summary.name);\n if (existing === undefined) {\n byName.set(summary.name, [summary]);\n } else {\n existing.push(summary);\n }\n }\n const resolved: SkillCatalogEntry[] = [];\n for (const candidates of byName.values()) {\n const ordered = [...candidates].sort(\n (a, b) => (rank.get(a.scope) ?? 0) - (rank.get(b.scope) ?? 0),\n );\n const winner = ordered[0];\n if (winner === undefined) {\n continue;\n }\n const shadows = ordered.slice(1).map((candidate) => candidate.scope);\n resolved.push({\n name: winner.name,\n description: winner.description,\n scope: winner.scope,\n ...(shadows.length > 0 ? { shadows } : {}),\n });\n }\n // Most specific first, then alphabetical: an order a reader can predict, and one where trimming\n // the tail to `maxSkills` drops the WIDEST skills — an org default is the one a deployment can\n // best afford to lose, and the actor's own is the one it can least.\n resolved.sort((a, b) => {\n const byScope = (rank.get(a.scope) ?? 0) - (rank.get(b.scope) ?? 0);\n return byScope !== 0 ? byScope : compare(a.name, b.name);\n });\n return {\n entries: resolved.slice(0, maxSkills),\n omitted: Math.max(0, resolved.length - maxSkills),\n };\n}\n\nfunction compare(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/** Resolve the scopes and the catalog for one turn. Called INSIDE the loop's `skills:catalog` step. */\nexport async function offerSkills(config: SkillsConfig, ctx: SkillContext): Promise<SkillOffer> {\n const scopes = await (config.scopes ?? defaultScopeResolver).resolve(ctx);\n const summaries = await config.provider.list({ scopes, ctx });\n return { scopes, ...resolveSkillCatalog(summaries, scopes, config.maxSkills) };\n}\n\n/**\n * The catalog as the model reads it. One line per skill — name, scope, description, and what it\n * overrides — because the entire claim of progressive disclosure is that choosing what to read costs\n * far less than reading everything.\n */\nexport function buildSkillsBlock(entries: readonly SkillCatalogEntry[]): string {\n const lines = entries.map((entry) => {\n const shadows =\n entry.shadows === undefined ? '' : ` (overrides the one from ${entry.shadows.join(', ')})`;\n return `- ${entry.name} [${entry.scope}] — ${entry.description}${shadows}`;\n });\n return `<skills>\nProcedures available to you. Each line is a name, the scope it came from, and what it covers — not the procedure itself.\nCall the \\`${SKILL_TOOL_NAME}\\` tool with a name from this list to read one BEFORE doing the task it covers, and follow what it says; never guess its contents from the description.\nA skill from a narrower scope overrides a same-named one from a wider scope. When you follow one that overrides another, say which scope it came from, so the user knows their setting differs from the wider default.\n${lines.join('\\n')}\n</skills>`;\n}\n\n/** The reserved name of the built-in skill-loading tool. */\nexport const SKILL_TOOL_NAME = 'skill';\n\n/** What the model passes to the `skill` tool. */\nexport interface SkillToolInput {\n name: string;\n}\n\nconst SKILL_JSON_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['name'],\n properties: {\n name: {\n type: 'string',\n description: 'The name of a skill from the <skills> list, exactly as written there.',\n },\n },\n} as const;\n\nfunction issue(path: (string | number)[], message: string) {\n return { message, path };\n}\n\n/**\n * The `skill` tool's input schema. Hand-written for the same reason `askInputSchema` is: core\n * depends on no validator and the schema has to publish a JSON Schema a provider can constrain\n * generation against.\n *\n * The available names are deliberately NOT an enum here. A per-turn enum would make the tool's\n * definition depend on the catalog — and the dispatched llm step re-derives the tool list on\n * whichever worker serves it, from ITS OWN provider, which is exactly the process-local lookup this\n * design keeps off the turn's decisions. The names live in the prompt, where the journal holds them;\n * a name that is not in the catalog comes back as an ordinary tool failure listing the ones that are.\n */\nexport const skillInputSchema = {\n '~standard': {\n version: 1,\n vendor: 'nestjs-agent',\n validate: (value: unknown) => {\n if (typeof value !== 'object' || value === null) {\n return { issues: [issue([], 'must be an object')] };\n }\n const candidate = value as Partial<SkillToolInput>;\n if (typeof candidate.name !== 'string' || candidate.name.length === 0) {\n return { issues: [issue(['name'], 'must be a non-empty string')] };\n }\n return { value: { name: candidate.name } };\n },\n jsonSchema: { input: () => SKILL_JSON_SCHEMA },\n },\n} as unknown as StandardSchemaV1<unknown, SkillToolInput>;\n\nexport const SKILL_TOOL_DESCRIPTION =\n 'Read one of the procedures listed in <skills>. Call it before doing a task a listed skill covers, and follow what it returns. It performs nothing and changes nothing — it only gives you instructions you do not yet have.';\n\n/**\n * The `skill` tool as the model sees it. NOT a `ToolSpec` and never registered, exactly like `ask`:\n * it has no handler, because the loop serves it from the catalog the journal holds. Keeping it out\n * of the `ToolRegistry` is also what keeps its kind off a process-local lookup — see `claimToolCall`.\n */\nexport function skillToolDefinition(): ToolDefinition {\n return {\n name: SKILL_TOOL_NAME,\n kind: 'skill',\n description: SKILL_TOOL_DESCRIPTION,\n inputSchema: skillInputSchema,\n };\n}\n\n/**\n * Append the built-in `skill` definition to a turn's tool list. Exported because the dispatched llm\n * step re-derives the tool list on a worker and has to reach the same list the loop would have.\n */\nexport function withSkillTool({\n tools,\n enabled,\n}: { tools: ToolDefinition[]; enabled: boolean }): ToolDefinition[] {\n return enabled ? [...tools, skillToolDefinition()] : tools;\n}\n\n/** What a `skill` call resolved to — the body, or why it did not. */\nexport type SkillLoadOutcome =\n | { ok: true; skill: Skill; shadows?: string[] }\n | { ok: false; error: string };\n\n/**\n * Serve one `skill` call against the catalog THIS TURN was offered.\n *\n * The catalog is the authorization boundary, not just a menu: a name the turn was never offered is\n * refused here, so a model that invents one (or repeats one it saw in another actor's thread) cannot\n * reach a body through a provider that would happily serve it. Because the catalog came out of the\n * `skills:catalog` checkpoint, that boundary is the one the journal records rather than the one this\n * process's provider currently believes in.\n */\nexport async function loadSkill(\n config: SkillsConfig,\n offer: SkillOffer,\n name: string,\n ctx: SkillContext,\n): Promise<SkillLoadOutcome> {\n const entry = offer.entries.find((candidate) => candidate.name === name);\n if (entry === undefined) {\n const available = offer.entries.map((candidate) => candidate.name).join(', ');\n return {\n ok: false,\n error:\n available.length === 0\n ? `No skill named \"${name}\" is available to you, and no others are either.`\n : `No skill named \"${name}\" is available to you. Available: ${available}.`,\n };\n }\n const body = await config.provider.load({ name: entry.name, scope: entry.scope, ctx });\n if (body === null) {\n return { ok: false, error: `Skill \"${name}\" is listed but its body could not be read.` };\n }\n return {\n ok: true,\n skill: { name: entry.name, description: entry.description, scope: entry.scope, body },\n ...(entry.shadows !== undefined ? { shadows: entry.shadows } : {}),\n };\n}\n\n/** Who is trying to write a skill. */\nexport interface SkillAuthor {\n /**\n * `'human'` is a person acting through a UI; `'agent'` is anything else — a tool, a turn, a\n * batch job. The distinction is the whole of the rule below, so it is not inferable and has to\n * be stated by the caller.\n */\n kind: 'human' | 'agent';\n actorRef?: string;\n}\n\n/** A request to author a skill at a scope. */\nexport interface SkillWriteRequest {\n /** The scope token the skill would be published at. */\n scope: string;\n actor: Actor;\n /** The actor's resolved scopes, most specific first — the same list a turn draws from. */\n scopes: readonly string[];\n author: SkillAuthor;\n /**\n * The host's own answer to \"may this person administer that scope\" — a sector lead editing their\n * sector's skills, an operator editing the deployment's. This library cannot know it: it has no\n * notion of who administers `sector:logistics`, and inventing one would be a second, weaker\n * authorization model next to the host's real one. Undefined/false → a wider scope is refused.\n */\n elevated?: boolean;\n}\n\nexport type SkillWriteVerdict = { allowed: true } | { allowed: false; reason: string };\n\n/**\n * May this author publish a skill at this scope?\n *\n * A skill's body is instructions the model follows, which makes writing one at a scope an edit to\n * everyone in that scope's system prompt. The rules follow from that, and only the third is\n * interesting:\n *\n * 1. You may only write into a scope you are yourself in. Writing into a scope you are not in is\n * authoring for people you have no relationship with.\n * 2. Your OWN scope is yours. A per-actor skill affects exactly one prompt — the author's.\n * 3. NOTHING BUT A HUMAN MAY WRITE ABOVE ITS OWN SCOPE, whatever `elevated` says. An agent that can\n * write a `tenant:` skill is an agent whose prompt anyone in the tenant can edit by talking to\n * it: the user asks for something, the turn writes the instruction, and every later turn for\n * every other user follows it. That is prompt injection with persistence, and no elevation a\n * host could grant makes it a different shape. An agent that has genuinely learned something\n * worth sharing proposes it; a person publishes it.\n * 4. A human writing above their own scope needs the host to say so (`elevated`).\n */\nexport function skillWriteVerdict(request: SkillWriteRequest): SkillWriteVerdict {\n const { scope, scopes, author, actor } = request;\n if (!scopes.includes(scope)) {\n return { allowed: false, reason: `\"${scope}\" is not a scope this actor belongs to` };\n }\n const own = actorScope(actor);\n if (scope === own) {\n return { allowed: true };\n }\n if (author.kind !== 'human') {\n return {\n allowed: false,\n reason: `only a human may author a skill at \"${scope}\"; an agent may write only at \"${own}\"`,\n };\n }\n return request.elevated === true\n ? { allowed: true }\n : { allowed: false, reason: `authoring at \"${scope}\" requires an elevated human author` };\n}\n","/**\n * Memory: what the assistant has concluded about a person or an organisation, carried across turns\n * and across threads.\n *\n * HOW A READER TELLS IT FROM RAG. Retrieval answers \"what do the documents say\"; memory answers\n * \"what did I decide about you\". A passage is content a person authored and can correct at its\n * source, and it is cited. A memory has no source to go and fix: it is the agent's own inference,\n * which is why every record carries an {@link MemoryOrigin} (who wrote it, in which conversation),\n * why the block tells the model to treat it as fallible, and why `forget` is a REQUIRED method on\n * the provider rather than an optional one. A wrong document is a content problem. A wrong memory is\n * the assistant being confidently wrong about someone with nobody aware it is there, so the whole\n * design is arranged around making it visible and removable.\n *\n * WHAT IT COSTS THE PROMPT. One line per memory, capped by `maxMemories`, and each line capped by\n * `maxFactChars` at WRITE time — so the block a turn can carry is the product of two numbers an\n * operator sets, rather than however much the model felt like writing down. Unlike a skill, a memory\n * has no body/catalog split: a fact that cannot be stated in a line is not a memory, it is a\n * document, and documents are retrieval's job.\n *\n * WHAT IT IS NOT: recall over a TRANSCRIPT. Searching what was said earlier is retrieval, and this\n * library already has `Retriever`/`Reranker` for that.\n *\n * RECALL OVER THE MEMORIES THEMSELVES IS A DIFFERENT QUESTION, and it is answered here. The prompt\n * budget must be bounded; the store has no reason to be. A person accumulates preferences over\n * months and an organisation publishes facts for everyone in it, so the applicable set outgrows\n * `maxMemories` quickly — and once it does, WHICH of them the block carries is a decision somebody\n * has to make. Making it by scope starves the widest scopes first, which is precisely backwards: the\n * facts that apply to the most people are the ones nobody sees. So a provider MAY supply\n * {@link MemoryProvider.search}, and where it does, the block is filled by relevance to the turn\n * (see {@link resolveMemoryDigest}) with scope still a hard filter and never a ranking signal.\n * `maxMemories` then means \"how many matter right now\" rather than \"how many a person may have\".\n */\n\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport {\n type ScopeContext,\n type ScopeResolver,\n actorScope,\n defaultScopeResolver,\n} from './skills.js';\nimport type { Actor, ToolDefinition } from './types.js';\n\n/** Who wrote a memory, and out of what. Kept so a person reading it back can ask \"says who?\". */\nexport interface MemoryOrigin {\n /** `'agent'` — a turn concluded it. `'human'` — a person wrote it in the host's own console. */\n author: 'agent' | 'human';\n /**\n * The conversation the conclusion was drawn in. MAY name a thread whose messages the history\n * ceiling has since dropped: a memory deliberately outlives its source, so this is a pointer that\n * is allowed to dangle, and a read-back that cannot resolve it says so rather than hiding the row.\n */\n threadId?: string;\n runId?: string;\n actorRef?: string;\n}\n\n/** One thing the assistant believes, at one scope. */\nexport interface MemoryRecord {\n /** The host's row id — what `forget` takes and what a read-back offers a delete button for. */\n id: string;\n /**\n * What the fact is ABOUT. The handle that makes a conflict mechanically detectable: two memories\n * sharing a key at different scopes are one question answered twice, and the narrower wins. A\n * keyless store could only ever hope its facts did not contradict each other.\n */\n key: string;\n /** The fact itself, as the model reads it. */\n text: string;\n /** The opaque scope token it is held at — see `ScopeResolver` in `skills.ts`. */\n scope: string;\n origin: MemoryOrigin;\n /** ISO-8601, so the ceiling can keep the newest with a string comparison it can do purely. */\n updatedAt: string;\n /**\n * Always-on: this fact is in the block whether or not the turn is about it. The difference between\n * working memory and recall, drawn per record — \"they report on the calendar year\" must not depend\n * on the turn mentioning dates, while \"they prefer the kerbside dock\" can wait until it comes up.\n *\n * A PROPERTY OF THE ROW, NOT OF A WRITE. This library reads it and never sets it, the same way it\n * never mints an `id`: an agent deciding its own conclusions are always-on is an agent deciding\n * how much of every future prompt it gets, so pinning is an operator's act in the host's console.\n * That is also why {@link StoreMemoryInput} carries no `pinned` — the `remember` tool has no\n * parameter to refuse. A host whose upsert drops the flag has silently unpinned the row; preserve\n * it across an upsert on (`scope`, `key`).\n */\n pinned?: boolean;\n}\n\n/** A same-key memory a narrower scope outranked, with the value it holds. */\nexport interface OverriddenMemory {\n scope: string;\n text: string;\n /**\n * Who asserted the beaten value. Travels because precedence is blind to it: an agent's own\n * inference at `actor:` outranks an administrator's published policy at `global`, and an agent\n * that knew only that a wider value existed could not tell the two apart — one is a stale guess,\n * the other is what the organisation decided.\n */\n author: MemoryOrigin['author'];\n}\n\n/** One memory as the model and a read-back both meet it. */\nexport interface MemoryDigestEntry extends MemoryRecord {\n /**\n * Same-key memories this one outranks, widest last. Present ONLY where something was outranked.\n *\n * Carries the beaten TEXT, which is where memory departs from a skill's `shadows`. A skill only\n * has to say which scope it beat — the agent follows one procedure either way. A memory is a\n * VALUE, and an agent that knows only that a wider value existed cannot tell the user what the\n * difference is; it can only choose, silently, which is the thing this is meant to prevent.\n */\n overrides?: OverriddenMemory[];\n}\n\n/** What a turn resolved — journaled whole, so its prompt is reconstructible from its journal alone. */\nexport interface MemoryDigest {\n /** The scope tokens this turn drew from, most specific first. */\n scopes: string[];\n /** The memories in the block, most specific first then by key. */\n entries: MemoryDigestEntry[];\n /**\n * Applicable memories `maxMemories` left out. Non-zero means the block is not the whole truth —\n * and under {@link recalled} it counts what the SEARCH offered and the ceiling dropped, not what\n * the store holds, because nothing asked the store for a total.\n */\n omitted: number;\n /**\n * Of {@link omitted}, how many were ALWAYS-ON. Reported separately because it means something else\n * entirely: ordinary omission is the budget doing its job, while an always-on memory the ceiling\n * dropped is a deployment's own standing policies having silently stopped reaching any prompt.\n * Non-zero is a misconfiguration — more was pinned than the block holds — and the fix is to unpin\n * something or raise `maxMemories`, not to wait for it to come back.\n */\n pinnedOmitted: number;\n /**\n * Whether the entries were selected by relevance to this turn rather than read whole. The model is\n * told (see {@link buildMemoryBlock}), because a partial set read as a whole one turns an absence\n * into evidence: \"you never told me that\" about a fact it simply was not shown.\n *\n * Optional so a digest journaled before recall existed reads back as the plain scoped read it was.\n */\n recalled?: boolean;\n}\n\n/** What a write asks the host to store. `id` and `updatedAt` are the host's to mint. */\nexport interface MemoryFact {\n key: string;\n text: string;\n scope: string;\n origin: MemoryOrigin;\n}\n\n/** Arguments to {@link MemoryProvider.list}. */\nexport interface ListMemoriesInput {\n /** The scope tokens that apply to this turn, most specific first. */\n scopes: readonly string[];\n ctx: ScopeContext;\n}\n\n/**\n * Arguments to {@link MemoryProvider.search}.\n *\n * `scopes` GATES, AND IT GATES FIRST. A search that ranks before it filters is a cross-tenant leak\n * wearing a relevance score: the nearest neighbour to \"what is our rollback policy\" is another\n * tenant's rollback policy. Filter in the query, not after it. Records returned outside `scopes` are\n * dropped rather than trusted, so a mistake here costs throughput rather than privacy — but the\n * drop is a backstop, not the boundary.\n */\nexport interface SearchMemoriesInput {\n /** The scope tokens that apply to this turn, most specific first. A HARD FILTER. */\n scopes: readonly string[];\n /** What this turn is about. Never blank — a blank query is served by `list` instead. */\n query: string;\n /**\n * At most this many distinct KEYS may be ranked in, which is the block's own unit: precedence\n * resolves a key to one line, so `limit` keys is `limit` lines. Pinned records are returned in\n * addition and do not count against it.\n */\n limit: number;\n ctx: ScopeContext;\n}\n\n/** Arguments to {@link MemoryProvider.forget}. */\nexport interface ForgetMemoryInput {\n id: string;\n ctx: ScopeContext;\n}\n\n/**\n * Arguments to {@link MemoryProvider.write}. An object rather than positional arguments because\n * `key`, `text` and `scope` are all strings: transposed, a positional call compiles clean and writes\n * a fact whose key is its value, at a scope nobody meant.\n */\nexport interface StoreMemoryInput extends MemoryFact {\n ctx: ScopeContext;\n}\n\n/**\n * Where memories live. The host owns the rows, for the same reason it owns skill rows: the axes a\n * deployment scopes by, the console that edits them and the audit trail are all the host's, and a\n * table this package created at boot would put a consumer's migrations in the path of the schema\n * heal that manages the `agent_*` tables.\n *\n * `forget` is REQUIRED, unlike `write`. A deployment may reasonably populate memory from its own\n * pipeline and offer the agent no write tool; no deployment may reasonably hold conclusions about a\n * person that the person cannot have deleted. Making it optional would make forgetting a wiring\n * choice, and it is not one.\n */\nexport interface MemoryProvider {\n /**\n * Every memory visible at `scopes`, in any order — this library resolves precedence and the\n * ceiling. Asked on EVERY turn, so keep it cheap. A provider MAY return records outside `scopes`;\n * they are dropped rather than trusted, so a filter bug in a host cannot widen what an actor sees.\n */\n list(input: ListMemoriesInput): MemoryRecord[] | Promise<MemoryRecord[]>;\n /** Delete one record by id. `false` where there was nothing by that id to delete. */\n forget(input: ForgetMemoryInput): boolean | Promise<boolean>;\n /**\n * Upsert on (`scope`, `key`) and return the stored record. Omit to serve memory read-only — the\n * `remember` tool is then never offered, and a turn's tool list is the same on every pod.\n */\n write?(input: StoreMemoryInput): MemoryRecord | Promise<MemoryRecord>;\n /**\n * The memories worth putting in front of a turn about `query`, MOST RELEVANT FIRST. Omit and every\n * turn is served by {@link list} — a deployment with twenty memories must not have to stand up an\n * index to keep working, and one with two thousand uses whatever it already runs (pgvector, a\n * full-text index, a hybrid service). The host owns the index for the same reason it owns the\n * rows.\n *\n * THREE CLAUSES, and the third is the one that is easy to miss:\n *\n * 1. Filter to `scopes` before ranking — see {@link SearchMemoriesInput}.\n * 2. Rank the KEYS visible at those scopes and take the best `limit` of them.\n * 3. Return EVERY record sharing a returned key, plus every `pinned` record at those scopes.\n *\n * Clause three is what keeps precedence intact. Precedence resolves a conflict between two records\n * at one key, narrower winning and the beaten value riding along; a search that returned the\n * `global` half of a conflict and not the `actor:` half would render the org default as the answer\n * — the exact failure memory exists to prevent, and one nothing downstream can detect. It is one\n * query either way:\n *\n * ```sql\n * SELECT * FROM agent_memory\n * WHERE scope IN (:scopes)\n * AND (pinned OR key IN (SELECT key FROM agent_memory\n * WHERE scope IN (:scopes)\n * ORDER BY embedding <=> :queryVector\n * LIMIT :limit))\n * ```\n */\n search?(input: SearchMemoriesInput): MemoryRecord[] | Promise<MemoryRecord[]>;\n}\n\n/**\n * How many memories the block carries. The same ceiling shape as `maxSkills`, and for the same\n * reason: a prompt that grows with how much the agent has written down is a prompt whose cost nobody\n * set. A budget on the PROMPT and never on the store — with a provider that can\n * {@link MemoryProvider.search}, it is how many matter right now rather than how many a person may\n * have.\n */\nexport const DEFAULT_MAX_MEMORIES = 20;\n\n/**\n * How long one memory may be, enforced when it is WRITTEN rather than when it is rendered. Enforcing\n * it at render time would make the prompt disagree with the store; enforcing it at write time makes\n * the block's whole ceiling a multiplication an operator can do — `maxMemories × maxFactChars` — and\n * pushes back on the model at the moment it is writing an essay instead of a fact.\n */\nexport const DEFAULT_MAX_FACT_CHARS = 240;\n\n/** How a turn reaches its memory. See `AgentLoopDeps.memory`. */\nexport interface MemoryConfig {\n provider: MemoryProvider;\n /** Undefined → `defaultScopeResolver`: the actor's own, their tenant's, the deployment's. */\n scopes?: ScopeResolver;\n /** Undefined → {@link DEFAULT_MAX_MEMORIES}. Always-on memories are taken from it first. */\n maxMemories?: number;\n /** Undefined → {@link DEFAULT_MAX_FACT_CHARS}. */\n maxFactChars?: number;\n}\n\n/**\n * Resolve a provider's records against an ordered scope list: most specific wins a key, and the\n * losers' values are carried rather than discarded.\n *\n * Pure, and separately exported, because the loop and the read-back endpoint must reach the same\n * answer — a person has to be shown what the model was shown, or \"see what it believes about you\"\n * means nothing.\n */\n/** Arguments to {@link resolveMemoryDigest}. */\nexport interface ResolveMemoryDigestInput {\n records: readonly MemoryRecord[];\n /** The scope tokens that apply, most specific first — the precedence order. */\n scopes: readonly string[];\n /** Undefined → {@link DEFAULT_MAX_MEMORIES}. */\n maxMemories?: number;\n /**\n * Whether `records` arrived most-relevant-first, from {@link MemoryProvider.search}. A key's rank\n * is its best-placed record's. Undefined/false → the ceiling selects by scope and recency, which\n * is the right order only while nothing is being starved.\n */\n ranked?: boolean;\n}\n\nexport function resolveMemoryDigest({\n records,\n scopes,\n maxMemories = DEFAULT_MAX_MEMORIES,\n ranked = false,\n}: ResolveMemoryDigestInput): Omit<MemoryDigest, 'scopes' | 'recalled'> {\n const rank = new Map(scopes.map((scope, index) => [scope, index]));\n const byKey = new Map<string, MemoryRecord[]>();\n for (const entry of records) {\n // A scope the resolver did not return is one this actor has no claim on, whatever the provider\n // thinks. Dropping it here is what makes over-returning a performance mistake, not a leak.\n if (!rank.has(entry.scope)) {\n continue;\n }\n const existing = byKey.get(entry.key);\n if (existing === undefined) {\n byKey.set(entry.key, [entry]);\n } else {\n existing.push(entry);\n }\n }\n const resolved: MemoryDigestEntry[] = [];\n for (const candidates of byKey.values()) {\n const ordered = [...candidates].sort(\n (a, b) => (rank.get(a.scope) ?? 0) - (rank.get(b.scope) ?? 0),\n );\n const winner = ordered[0];\n if (winner === undefined) {\n continue;\n }\n const overrides = ordered.slice(1).map((beaten) => ({\n scope: beaten.scope,\n text: beaten.text,\n author: beaten.origin.author,\n }));\n // A pin belongs to the QUESTION, not to the record that currently answers it: pinning \"which\n // fiscal year\" and then letting a personal override of it fall out of the block would make\n // always-on mean \"always-on until someone disagrees with it\".\n const pinned = ordered.some((candidate) => candidate.pinned === true);\n resolved.push({\n ...winner,\n ...(pinned ? { pinned: true } : {}),\n ...(overrides.length > 0 ? { overrides } : {}),\n });\n }\n // Three orders, answering three different questions.\n //\n // ALWAYS-ON FIRST, whatever else is true: a pinned fact is in the block whether or not the turn is\n // about it. It spends the same budget as everything else, so the ceiling stays a product of two\n // numbers an operator set rather than growing with how much got pinned.\n //\n // Then SELECTION among the rest — by relevance where the candidates were ranked, else by narrowest\n // scope and newest within it. That second rule is right only while nothing is being starved, which\n // is the case a host running no index is in: `list` returns the whole applicable set, so a ceiling\n // that bites is dropping what the deployment can best afford to lose. Once the set outgrows the\n // block it is exactly wrong, because the scopes it drops first are the ones shared by the most\n // people — one person's twentieth note would end every chance their organisation's facts had.\n //\n // RENDERING is by scope then key, stable between turns: ordering the block by recency or by score\n // would reshuffle it on every write and throw away the provider's prompt cache. Pinned entries\n // lead, because they are the part of the block that does not move from turn to turn.\n const byPrecedence = (a: MemoryDigestEntry, b: MemoryDigestEntry): number =>\n (rank.get(a.scope) ?? 0) - (rank.get(b.scope) ?? 0) ||\n compare(b.updatedAt, a.updatedAt) ||\n compare(a.key, b.key);\n const selected = resolved\n .map((entry, index) => ({ entry, index }))\n .sort(\n (a, b) =>\n pinRank(a.entry) - pinRank(b.entry) ||\n (ranked && a.entry.pinned !== true ? a.index - b.index : byPrecedence(a.entry, b.entry)),\n )\n .slice(0, maxMemories)\n .map((candidate) => candidate.entry);\n const pinnedOmitted =\n resolved.filter((entry) => entry.pinned === true).length -\n selected.filter((entry) => entry.pinned === true).length;\n selected.sort(\n (a, b) =>\n pinRank(a) - pinRank(b) ||\n (rank.get(a.scope) ?? 0) - (rank.get(b.scope) ?? 0) ||\n compare(a.key, b.key),\n );\n return {\n entries: selected,\n omitted: Math.max(0, resolved.length - maxMemories),\n pinnedOmitted,\n };\n}\n\nfunction pinRank(entry: MemoryDigestEntry): number {\n return entry.pinned === true ? 0 : 1;\n}\n\nfunction compare(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/** Arguments to {@link offerMemories}. */\nexport interface OfferMemoriesInput {\n config: MemoryConfig;\n ctx: ScopeContext;\n /**\n * What this turn is about — the loop passes the user's own message, and nothing else. Given, and\n * with a provider that has an index, the block is filled by relevance to it. Absent, the scope is\n * read whole: that is what the read-back endpoint wants, since a person must be shown every belief\n * held about them rather than the slice one turn happened to need.\n */\n query?: string;\n}\n\n/**\n * Resolve the scopes and the digest for one turn. Called INSIDE the loop's `memory:digest` step, and\n * that placement is the whole of its determinism: a search is the most re-derivable thing in this\n * library — the index moves, a neighbour is written, embeddings are recomputed — so its result has\n * to be part of the checkpoint every replay reads back, never something a replaying process asks\n * again.\n */\nexport async function offerMemories({\n config,\n ctx,\n query,\n}: OfferMemoriesInput): Promise<MemoryDigest> {\n const scopes = await (config.scopes ?? defaultScopeResolver).resolve(ctx);\n const maxMemories = config.maxMemories ?? DEFAULT_MAX_MEMORIES;\n // A search keyed on nothing ranks on noise, so a turn with no text to search with reads the scope\n // plainly rather than making a worse selection out of it. What carries a fact through a turn like\n // that is `pinned`, not a cleverer query.\n const trimmed = query?.trim() ?? '';\n // Bound for the same reason `writeMemory` binds its own: a provider is normally a class, and a\n // method read off it has lost the receiver its body needs.\n const search = trimmed.length > 0 ? config.provider.search?.bind(config.provider) : undefined;\n const records =\n search !== undefined\n ? await search({ scopes, query: trimmed, limit: maxMemories, ctx })\n : await config.provider.list({ scopes, ctx });\n return {\n scopes,\n recalled: search !== undefined,\n ...resolveMemoryDigest({ records, scopes, maxMemories, ranked: search !== undefined }),\n };\n}\n\n/**\n * The block as the model reads it.\n *\n * THREE THINGS IT HAS TO DO THAT A SKILLS CATALOG DOES NOT.\n *\n * It must frame each note by WHO ASSERTED IT, which is why there are two sections rather than one\n * sentence over the whole list. An unlabelled fact in a system prompt reads with the authority of an\n * instruction, and the hazard of an agent's own inference is exactly that authority — so those are\n * hedged. But a memory an administrator published for a whole organisation is not the agent's guess,\n * and telling the model to \"prefer what the user says now\" about it hands any user an override of\n * their organisation's policy by asserting the opposite. `MemoryOrigin.author` is the axis, and it\n * is the only one that matters here: scope says who a fact applies to, not who decided it.\n *\n * Where a narrower scope won, it must print the value it beat, so the model can tell the user their\n * setting differs from the org's instead of quietly applying one of them.\n *\n * And a block that is a SELECTION must say so. A model reading a partial set as a whole one turns an\n * absence into evidence — \"you never told me that\" about a fact it simply was not shown.\n */\n/** Arguments to {@link buildMemoryBlock}. */\nexport interface BuildMemoryBlockInput {\n entries: readonly MemoryDigestEntry[];\n /** Whether this deployment offers `remember` — the block names the tool only where it exists. */\n writable: boolean;\n /** Whether applicable memories are missing from `entries` — the ceiling bit, or recall selected. */\n partial: boolean;\n}\n\nconst ASSERTED_FRAMING =\n 'Stated by people. A person wrote each of these deliberately — the user about themselves, or someone administering their organisation. Treat them as you would any other instruction you were given. If the user says something that contradicts one, say which note it conflicts with and at what scope it is held, rather than quietly setting it aside.';\n\nconst CONCLUDED_FRAMING =\n 'Concluded by you. These are your own notes from earlier turns, not documents anyone wrote: they may be wrong or out of date, so prefer what the user says now, and say where a note came from if you act on it.';\n\nconst PARTIAL_FRAMING =\n 'You are being shown a selection, not everything on file. Other notes exist that are not in this list, so never read something’s absence from it as evidence that it was never recorded.';\n\nfunction memorySection(framing: string, entries: readonly MemoryDigestEntry[]): string[] {\n if (entries.length === 0) {\n return [];\n }\n return [\n framing,\n ...entries.flatMap((entry) => [\n `- [${entry.scope}] ${entry.key}: ${entry.text}`,\n ...(entry.overrides ?? []).map(\n (beaten) =>\n ` ↳ [${beaten.scope}] ${beaten.author === 'human' ? 'a person stated' : 'instead has'}: ${beaten.text}`,\n ),\n ]),\n ];\n}\n\nexport function buildMemoryBlock({ entries, writable, partial }: BuildMemoryBlockInput): string {\n const writeLine = writable\n ? [\n `When you learn something durable about this user, record it with the \\`${REMEMBER_TOOL_NAME}\\` tool; when one of these turns out to be wrong, record the corrected fact under the same key. What you record that way is one of your own notes, not something stated by a person.`,\n ]\n : [];\n const body = [\n 'What is on file about this user and their organisation, carried over from earlier conversations. Each line is a scope, a key and the fact. A narrower scope overrides a wider one; where the wider value is shown underneath, tell the user their setting differs from it rather than silently choosing one.',\n ...(partial ? [PARTIAL_FRAMING] : []),\n ...writeLine,\n // People before inferences: the model meets what it was told before what it worked out.\n ...memorySection(\n ASSERTED_FRAMING,\n entries.filter((entry) => entry.origin.author === 'human'),\n ),\n ...memorySection(\n CONCLUDED_FRAMING,\n entries.filter((entry) => entry.origin.author !== 'human'),\n ),\n ];\n return `<memory>\\n${body.join('\\n')}\\n</memory>`;\n}\n\n/** The reserved name of the built-in memory-writing tool. */\nexport const REMEMBER_TOOL_NAME = 'remember';\n\n/** What the model passes to the `remember` tool. */\nexport interface RememberToolInput {\n key: string;\n fact: string;\n}\n\nconst REMEMBER_JSON_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['key', 'fact'],\n properties: {\n key: {\n type: 'string',\n description:\n 'A short, stable handle for what this fact is ABOUT (e.g. \"fiscal-year\", \"preferred-units\"). Reusing an existing key replaces that fact rather than adding a second one.',\n },\n fact: {\n type: 'string',\n description:\n 'The fact itself, in one sentence, stated so it still makes sense in a conversation months from now.',\n },\n },\n} as const;\n\nfunction issue(path: (string | number)[], message: string) {\n return { message, path };\n}\n\n/**\n * The `remember` tool's input schema. Hand-written for the same reason `askInputSchema` and\n * `skillInputSchema` are: core depends on no validator and has to publish a JSON Schema a provider\n * can constrain generation against.\n *\n * THERE IS NO SCOPE PARAMETER, and that is the enforcement rather than a simplification. An agent\n * may only ever write the actor it is running for (see {@link memoryWriteVerdict}), so a scope\n * argument could only ever be a request that gets refused — and a refusable request is one a model\n * will keep making, and one a future reader will be tempted to make grantable.\n */\nexport const rememberInputSchema = {\n '~standard': {\n version: 1,\n vendor: 'nestjs-agent',\n validate: (value: unknown) => {\n if (typeof value !== 'object' || value === null) {\n return { issues: [issue([], 'must be an object')] };\n }\n const candidate = value as Partial<RememberToolInput>;\n if (typeof candidate.key !== 'string' || candidate.key.length === 0) {\n return { issues: [issue(['key'], 'must be a non-empty string')] };\n }\n if (typeof candidate.fact !== 'string' || candidate.fact.length === 0) {\n return { issues: [issue(['fact'], 'must be a non-empty string')] };\n }\n return { value: { key: candidate.key, fact: candidate.fact } };\n },\n jsonSchema: { input: () => REMEMBER_JSON_SCHEMA },\n },\n} as unknown as StandardSchemaV1<unknown, RememberToolInput>;\n\nexport const REMEMBER_TOOL_DESCRIPTION =\n 'Record one durable fact about this user under a key, so later conversations start knowing it. For things that will still be true another day — how they work, what their organisation requires, a correction they made. Not for what this conversation is about, and not for anything you were not told or could not reasonably infer. The user can read and delete everything you record here.';\n\n/**\n * The `remember` tool as the model sees it. NOT a `ToolSpec` and never registered, exactly like\n * `ask` and `skill`: it has no handler, because the loop serves it against the digest the journal\n * holds. Keeping it out of the `ToolRegistry` is also what keeps its kind off a process-local\n * lookup — see `claimToolCall`.\n */\nexport function rememberToolDefinition(): ToolDefinition {\n return {\n name: REMEMBER_TOOL_NAME,\n kind: 'memory',\n description: REMEMBER_TOOL_DESCRIPTION,\n inputSchema: rememberInputSchema,\n };\n}\n\n/**\n * Append the built-in `remember` definition to a turn's tool list. Exported because the dispatched\n * llm step re-derives the tool list on a worker and has to reach the same list the loop would have.\n */\n/** Arguments to {@link withMemoryTool}. */\nexport interface WithMemoryToolInput {\n tools: ToolDefinition[];\n /** Whether this deployment's provider can write at all — module config, uniform across its pods. */\n enabled: boolean;\n}\n\nexport function withMemoryTool({ tools, enabled }: WithMemoryToolInput): ToolDefinition[] {\n return enabled ? [...tools, rememberToolDefinition()] : tools;\n}\n\n/** Who is trying to write a memory. */\nexport interface MemoryAuthor {\n /**\n * `'human'` is a person acting through a UI; `'agent'` is anything else — a turn, a tool, a batch\n * job. The distinction is the whole of rule three below, so it is not inferable and has to be\n * stated by the caller.\n */\n kind: 'human' | 'agent';\n actorRef?: string;\n}\n\n/** A request to write a memory at a scope. */\nexport interface MemoryWriteRequest {\n scope: string;\n actor: Actor;\n /** The actor's resolved scopes, most specific first — the same list the turn drew its digest from. */\n scopes: readonly string[];\n author: MemoryAuthor;\n /**\n * The host's own answer to \"may this person administer that scope\". This library cannot know it,\n * and inventing an answer would be a second, weaker authorization model next to the host's real\n * one. Undefined/false → a wider scope is refused.\n */\n elevated?: boolean;\n}\n\nexport type MemoryVerdict = { allowed: true } | { allowed: false; reason: string };\n\n/**\n * May this author write a memory at this scope?\n *\n * The same four rules as `skillWriteVerdict`, deliberately duplicated rather than shared: they are\n * the same rules about two different things, and folding them into one function would mean a future\n * change to how skills are authored silently changing who may edit what the assistant believes about\n * a person. Rule three is the one that matters, and it bites harder here than it does for skills:\n *\n * 1. You may only write into a scope you are yourself in.\n * 2. Your OWN scope is yours. A memory at `actor:<you>` affects exactly one prompt — your own.\n * 3. NOTHING BUT A HUMAN MAY WRITE ABOVE ITS OWN SCOPE, whatever `elevated` says. A skill an agent\n * could publish at `tenant:` is a procedure anyone in the tenant can edit by talking to the\n * assistant; a MEMORY it could publish there is a fact everyone in the tenant is then answered\n * from, with no document to inspect and nobody aware it was written. An agent that has genuinely\n * learned something the organisation should know proposes it; a person publishes it.\n * 4. A human writing above their own scope needs the host to say so (`elevated`).\n */\nexport function memoryWriteVerdict(request: MemoryWriteRequest): MemoryVerdict {\n const { scope, scopes, author, actor } = request;\n if (!scopes.includes(scope)) {\n return { allowed: false, reason: `\"${scope}\" is not a scope this actor belongs to` };\n }\n const own = actorScope(actor);\n if (scope === own) {\n return { allowed: true };\n }\n if (author.kind !== 'human') {\n return {\n allowed: false,\n reason: `only a human may write a memory at \"${scope}\"; an agent may write only at \"${own}\"`,\n };\n }\n return request.elevated === true\n ? { allowed: true }\n : { allowed: false, reason: `writing at \"${scope}\" requires an elevated human author` };\n}\n\n/**\n * May this actor delete this memory?\n *\n * Narrower than the write rule on purpose, and it takes no `elevated` flag. Deleting what the\n * assistant believes about YOU needs no permission from anyone — that is the point of the read-back\n * — so the endpoint that serves it must not be able to ask a host a question it might answer no to.\n * Deleting what it believes about a tenant is an administrative act on shared state, which belongs\n * in the host's console with the same elevation a write there needs.\n */\n/** A request to delete one memory. */\nexport interface MemoryForgetRequest {\n record: Pick<MemoryRecord, 'scope'>;\n actor: Actor;\n}\n\nexport function memoryForgetVerdict({ record, actor }: MemoryForgetRequest): MemoryVerdict {\n return record.scope === actorScope(actor)\n ? { allowed: true }\n : {\n allowed: false,\n reason: `\"${record.scope}\" is not this actor's own scope; deleting it is an administrative action`,\n };\n}\n\n/** What a `remember` call resolved to — the stored record, or why nothing was stored. */\nexport type MemoryWriteOutcome = { ok: true; record: MemoryRecord } | { ok: false; error: string };\n\n/**\n * Serve one `remember` call against the digest THIS TURN resolved.\n *\n * The digest's `scopes` are the authorization boundary, not the resolver: they came out of the\n * `memory:digest` checkpoint, so a write is checked against the scopes the run recorded rather than\n * the ones a replaying process's resolver would produce now. A membership table edited mid-run\n * cannot retroactively widen — or narrow — what a turn already in flight is allowed to write.\n */\n/** Arguments to {@link writeMemory}. */\nexport interface WriteMemoryInput {\n config: MemoryConfig;\n /** The digest THIS TURN journaled — the authorization boundary, never a fresh resolution. */\n digest: MemoryDigest;\n /** The `remember` call as the model made it. */\n call: RememberToolInput;\n ctx: ScopeContext;\n runId: string;\n}\n\nexport async function writeMemory({\n config,\n digest,\n call,\n ctx,\n runId,\n}: WriteMemoryInput): Promise<MemoryWriteOutcome> {\n // Bound, not detached. A provider is normally a CLASS — a Nest `@Injectable()` holding a\n // repository on `this` — and `const write = provider.write` hands back a function that has lost\n // its receiver, so the first `this.` inside it throws a TypeError the tool reports as a failed\n // call. Every provider in this repo's own tests is an object literal of arrow functions, which is\n // why that went unseen: they never need a receiver.\n const write = config.provider.write?.bind(config.provider);\n if (write === undefined) {\n return { ok: false, error: 'Memory is read-only in this deployment.' };\n }\n const key = call.key.trim();\n const text = call.fact.trim();\n if (key.length === 0 || text.length === 0) {\n return { ok: false, error: 'A memory needs both a key and a fact.' };\n }\n const maxFactChars = config.maxFactChars ?? DEFAULT_MAX_FACT_CHARS;\n if (text.length > maxFactChars) {\n return {\n ok: false,\n error: `A memory must be at most ${maxFactChars} characters; that was ${text.length}. State the fact more briefly.`,\n };\n }\n const scope = actorScope(ctx.actor);\n const verdict = memoryWriteVerdict({\n scope,\n actor: ctx.actor,\n scopes: digest.scopes,\n author: { kind: 'agent', actorRef: ctx.actor.id },\n });\n if (!verdict.allowed) {\n return { ok: false, error: verdict.reason };\n }\n const record = await write({\n key,\n text,\n scope,\n origin: { author: 'agent', threadId: ctx.threadId, runId, actorRef: ctx.actor.id },\n ctx,\n });\n return { ok: true, record };\n}\n","import type { AgentDefinition } from './types.js';\n\n/** Holds the named agent definitions registered via `AgentModule.forFeature([...])`. */\nexport class AgentRegistry {\n private readonly definitions = new Map<string, AgentDefinition>();\n\n register(definition: AgentDefinition): void {\n this.definitions.set(definition.name, definition);\n }\n\n get(name: string): AgentDefinition | undefined {\n return this.definitions.get(name);\n }\n\n has(name: string): boolean {\n return this.definitions.has(name);\n }\n\n list(): AgentDefinition[] {\n return [...this.definitions.values()];\n }\n}\n","/**\n * Is this the durable runtime refusing a checkpoint position, rather than anything the agent did?\n *\n * Matched by NAME because this package cannot import either class: the in-process engine throws\n * `@dudousxd/nestjs-durable-core`'s `NonDeterminismError` and the thin BullMQ worker throws\n * `@dudousxd/nestjs-durable-worker`'s `NondeterminismError` — the same contract under two spellings\n * in two packages, neither of which core depends on. Same cross-runtime reasoning as the\n * `isControlFlowError` hook, which exists for exactly this reason on the suspend path.\n *\n * Suffix rather than equality, because a runtime is free to qualify the name: the sibling Adonis\n * stack raises a `WorkflowNondeterminismError` from its remote-replay path, which an equality check\n * would wave through as an ordinary tool failure. `replay-integrity.contract.spec.ts` pins this\n * against the real exported classes, so a rename upstream fails a test instead of quietly\n * disarming the guard.\n *\n * Callers must let these through untouched. Every `catch` in a workflow body reacts by writing more\n * checkpoints (a toolfail, a run-end, a deactivate), and on a journal that has already diverged each\n * of those asks for a position the history cannot supply — so the recovery attempt raises its own\n * refusal, and THAT is the error the operator reads: a message pointing at the wrong seq, naming\n * checkpoints from the recovery path rather than the two that actually disagreed.\n */\nexport function isReplayIntegrityError(error: unknown): boolean {\n return error instanceof Error && error.name.toLowerCase().endsWith('nondeterminismerror');\n}\n","/**\n * The durable runtime's marker for a CONTROL-FLOW signal — a suspend or a continue-as-new, thrown to\n * unwind the current turn, never a failure. Declared here as a bare `Symbol.for` rather than\n * imported, for the same reason `replay-integrity.ts` matches by name: core depends on neither\n * durable package and must not, since the inline runner has to work with neither installed. The\n * duplication is safe precisely because the key is in the GLOBAL registry — the string IS the\n * contract, and a locally-declared copy collapses onto the identical symbol across duplicate module\n * copies, dual ESM/CJS loads, and the two packages that raise these signals under different class\n * names (`@dudousxd/nestjs-durable-core`'s `WorkflowSuspended`/`ContinueAsNew`, the BullMQ thin\n * worker's `Suspend`).\n */\nconst CONTROL_FLOW_SIGNAL = Symbol.for('aviary:durable:control-flow');\n\n/**\n * Is this the runner unwinding the turn (a durable suspend / continue-as-new) rather than something\n * the agent did? Callers must rethrow it untouched: every `catch` in the loop reacts by writing more\n * checkpoints, and a suspend recorded as a tool failure leaves a journal the resumed replay cannot\n * line up with.\n *\n * Detected from the error itself so a host that never wired `AgentLoopHooks.isControlFlowError` still\n * gets its suspends through — that hook is an override for a runner whose signals carry no marker,\n * not the only line of defence. Checked as a stamped property, NOT `instanceof`: the classes differ\n * per runtime, which is why the marker exists.\n */\nexport function isControlFlowSignal(error: unknown): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n (error as { [CONTROL_FLOW_SIGNAL]?: unknown })[CONTROL_FLOW_SIGNAL] === true\n );\n}\n","import type { ModelMessage, ToolCallStatus, ToolResult } from './types.js';\n\n/**\n * What a store knows about a tool call, read back when its message carries no result for it — see\n * {@link import('./spi/agent-store.js').AgentStore.toolCallOutcomes}.\n */\nexport interface ToolCallOutcome {\n id: string;\n status: ToolCallStatus;\n output?: unknown;\n error?: string;\n}\n\n/** What the model is told about a call whose turn died before the call was settled. */\nexport const UNFINISHED_TOOL_CALL =\n 'This tool call was never completed: the turn it belonged to ended unexpectedly before it was ' +\n 'settled. Do not assume it ran, and do not assume it did not — check the current state with a ' +\n 'read tool if one exists, tell the person plainly what is and is not confirmed, and do it again ' +\n 'only if they still want it.';\n\n/** What is written on the row of a call whose run ended without settling it. */\nexport const RUN_ENDED_BEFORE_TOOL_CALL = 'the run ended before this tool call was settled';\n\nconst DECLINED =\n 'The person was asked to approve this action and declined it. Nothing ran and nothing changed.';\nconst EXPIRED =\n 'This action needed approval, and the request expired before anyone decided. Nothing ran.';\n\n/** The ids of every tool call in `messages` that the message asking for it holds no result for. */\nexport function danglingToolCallIds(messages: readonly ModelMessage[]): string[] {\n const ids: string[] = [];\n for (const message of messages) {\n const calls = message.toolCalls ?? [];\n if (message.role !== 'assistant' || calls.length === 0) {\n continue;\n }\n const settled = new Set((message.toolResults ?? []).map((result) => result.id));\n for (const call of calls) {\n if (!settled.has(call.id)) {\n ids.push(call.id);\n }\n }\n }\n return ids;\n}\n\nfunction resultFor(\n call: { id: string; name: string },\n outcome: ToolCallOutcome | undefined,\n): ToolResult {\n const base = { id: call.id, name: call.name };\n switch (outcome?.status) {\n case 'executed':\n case 'auto_executed':\n return { ...base, output: outcome.output ?? null };\n case 'failed':\n return { ...base, output: null, error: outcome.error ?? UNFINISHED_TOOL_CALL };\n case 'rejected':\n return { ...base, output: { rejected: true }, denied: true, error: DECLINED };\n case 'expired':\n return {\n ...base,\n output: { rejected: true, expired: true },\n denied: true,\n expired: true,\n error: EXPIRED,\n };\n default:\n return { ...base, output: null, error: UNFINISHED_TOOL_CALL };\n }\n}\n\n/**\n * Give every tool call in a thread's history a result.\n *\n * A turn writes its results onto the assistant message once the step's LAST tool has settled. A turn\n * that dies before that — its run failed, its worker was killed, an approval was never answered and\n * the run was abandoned — leaves an assistant message that asks for tools and is answered by\n * nothing. A provider refuses a prompt shaped like that (a tool call must be followed by its\n * result), so every LATER turn on the thread fails too, with an error about the stream rather than\n * about the history: one dead turn makes the whole conversation unusable.\n *\n * Here each such call is settled from what is actually known: the call's own row where the store\n * can read it (`outcomes` — a tool that DID run hands the model its real output, so it is not run a\n * second time), and otherwise a result saying the call was never completed. Pure: the same messages\n * and outcomes always produce the same prompt, so a replay composes what the first attempt did.\n * Messages with nothing dangling are returned as they are.\n */\nexport function settleDanglingToolCalls(\n messages: ModelMessage[],\n outcomes: readonly ToolCallOutcome[] = [],\n): ModelMessage[] {\n const known = new Map(outcomes.map((outcome) => [outcome.id, outcome]));\n return messages.map((message) => {\n const calls = message.toolCalls ?? [];\n if (message.role !== 'assistant' || calls.length === 0) {\n return message;\n }\n const results = message.toolResults ?? [];\n const settled = new Set(results.map((result) => result.id));\n const missing = calls.filter((call) => !settled.has(call.id));\n if (missing.length === 0) {\n return message;\n }\n return {\n ...message,\n toolResults: [...results, ...missing.map((call) => resultFor(call, known.get(call.id)))],\n };\n });\n}\n","import { RUN_ENDED_BEFORE_TOOL_CALL } from './dangling-tool-calls.js';\nimport type { AgentStore } from './spi/agent-store.js';\nimport { releaseThreadRun } from './spi/chat-queue.js';\n\n/** The `code` a decision answers with when the run it was for is over (`409`). */\nexport const RUN_NOT_ACTIVE_CODE = 'run_not_active';\n\n/** What a person is told when they decide on a request whose run is over. */\nexport const RUN_NOT_ACTIVE_MESSAGE =\n 'This request is no longer waiting for an answer: the turn it belonged to has ended. Send the message again.';\n\n/** What is written on the row of a run that was found over without having said so itself. */\nexport const RUN_NO_LONGER_RUNNING = 'the run is no longer running';\n\nexport interface SettleDeadRunInput {\n runId: string;\n /** Set for a thread's own turn: the thread is released if this run still holds it. */\n threadId?: string;\n /**\n * Settle the run ROW as `failed` with this. Pass it only where the caller KNOWS the run failed\n * (the run's own body, unwinding). `recordRunEnd` is last-write-wins, so a caller that only knows\n * the run is no longer running — it may have completed — must leave the row alone.\n */\n failure?: { code: string; message: string };\n}\n\n/**\n * Leave nothing waiting on a run that is over and did not say so itself.\n *\n * A run normally settles its own row, its calls and its thread from inside its body. One that is\n * refused a checkpoint position, or whose worker died, never gets there: a call it had put to a\n * person stays `pending_approval` — an approval card that takes a \"yes\" and then does nothing, for\n * ever — and its thread stays pointed at it. Everything here is written straight to the store,\n * outside any checkpoint, because the callers are exactly the paths that have no journal left to\n * write to; each write is idempotent (only still-pending calls, a release conditional on the\n * holder), so doing it twice changes nothing.\n *\n * Best-effort on purpose: this runs while something else is already failing, and must not replace\n * that failure with one of its own.\n */\nexport async function settleDeadRun(store: AgentStore, input: SettleDeadRunInput): Promise<void> {\n const failure = input.failure;\n if (failure !== undefined) {\n await Promise.resolve(\n store.recordRunEnd?.({\n runId: input.runId,\n status: 'failed',\n errorCode: failure.code,\n errorMessage: failure.message,\n }),\n ).catch(() => undefined);\n }\n await Promise.resolve(\n store.failUnsettledToolCalls?.(input.runId, RUN_ENDED_BEFORE_TOOL_CALL),\n ).catch(() => 0);\n if (input.threadId !== undefined) {\n await releaseThreadRun(store, input.threadId, input.runId).catch(() => undefined);\n }\n}\n","import type { AgentStore } from './spi/agent-store.js';\nimport type { AgentDelegation, DetachedDelivery } from './types.js';\n\n/** An agent->agent edge with its awaited-or-not resolved, whichever form it was authored in. */\nexport interface ResolvedDelegation {\n agent: string;\n detached: boolean;\n}\n\n/** Read one {@link AgentDelegation} entry in either of its forms. */\nexport function normalizeDelegation(entry: AgentDelegation): ResolvedDelegation {\n return typeof entry === 'string'\n ? { agent: entry, detached: false }\n : { agent: entry.agent, detached: entry.detached === true };\n}\n\n/**\n * What a detached delegation hands the model in place of an answer. Its `status` is the whole point:\n * a model that is given an object shaped like a result will report one, and this run has none yet.\n */\nexport interface DetachedDelegationReceipt {\n detached: true;\n status: 'started';\n /** The agent now working on it. */\n agent: string;\n /** The run doing the work — what a client subscribes to, and what stamps the delivered message. */\n runId: string;\n /**\n * The same fact in the only vocabulary the model reliably acts on: prose in a tool result. The\n * structured fields above are for a client; this is for the turn that has to explain itself to a\n * user without claiming a result it does not hold.\n */\n note: string;\n}\n\n/** How a detached delegation ended, written back onto its tool-call row once the run settles. */\nexport interface DetachedDelegationOutcome {\n detached: true;\n status: 'delivered' | 'failed' | 'cancelled';\n agent: string;\n runId: string;\n /** The delivered answer. Present on `delivered` only. */\n text?: string;\n /** Why it did not deliver. Present on `failed` only. */\n error?: string;\n}\n\n/** The receipt an `agent`-kind call returns the moment its delegate is under way. */\nexport function detachedStarted(args: { agent: string; runId: string }): DetachedDelegationReceipt {\n return {\n detached: true,\n status: 'started',\n agent: args.agent,\n runId: args.runId,\n note: `The \"${args.agent}\" agent is now working on this in the background. Its answer is NOT part of this turn and will arrive in this conversation as a separate message when it is ready. Tell the user the work has started; do not state or guess what it will find.`,\n };\n}\n\n/** The outcome written onto the delegating tool call when a detached run finishes its answer. */\nexport function detachedDelivered(args: {\n agent: string;\n runId: string;\n text: string;\n}): DetachedDelegationOutcome {\n return {\n detached: true,\n status: 'delivered',\n agent: args.agent,\n runId: args.runId,\n text: args.text,\n };\n}\n\n/**\n * The outcome written onto the delegating tool call when a detached run never produced an answer.\n * Written by the RUNNER, not the loop: a run that crashed or was stopped cannot record its own\n * ending, and a delegation card that stays \"started\" for ever is the one state a reader cannot act\n * on.\n */\nexport function detachedUnsettled(args: {\n agent: string;\n runId: string;\n status: 'failed' | 'cancelled';\n error?: string;\n}): DetachedDelegationOutcome {\n return {\n detached: true,\n status: args.status,\n agent: args.agent,\n runId: args.runId,\n ...(args.error !== undefined ? { error: args.error } : {}),\n };\n}\n\n/**\n * Settle the delegation a detached run was started for when that run ends with no answer.\n *\n * Two writes, because a reader needs both: the tool-call row so a governance surface stops counting\n * it as in flight, and a MESSAGE in the delegating thread so the person who asked finds out. A\n * delivered answer already arrives as a message; without this, the failure is the one outcome that\n * silently never does, and the conversation shows \"started\" for ever.\n *\n * Called by the RUNNER, never the loop — a run that crashed or was stopped cannot record its own\n * ending. Skipped entirely when the thread is gone, for the same reason delivery is.\n *\n * Settles ONCE: a thread that already holds a message from this run (its answer, or an earlier\n * settlement) is left alone. A Stop can be settled from two places — the run's own body when it\n * observes the cancel, and the runner for a run parked where its body never runs again — and a\n * Stop on a run that already answered must not write \"stopped\" under its answer.\n */\nexport async function settleUnsettledDelegation(args: {\n store: AgentStore;\n delivery: DetachedDelivery;\n agent: string;\n runId: string;\n status: 'failed' | 'cancelled';\n error?: string;\n}): Promise<void> {\n const { store, delivery, agent, runId, status } = args;\n const thread = await store.getThread(delivery.threadId);\n if (thread === null || thread.messages.some((message) => message.runId === runId)) {\n return;\n }\n await store.appendMessage({\n threadId: delivery.threadId,\n role: 'assistant',\n content:\n status === 'cancelled'\n ? `The \"${agent}\" agent was stopped before it could answer.`\n : `The \"${agent}\" agent stopped before it could answer: ${args.error ?? 'unknown error'}`,\n agentName: agent,\n runId,\n });\n await store.updateToolCall({\n toolCallId: delivery.toolCallId,\n status: 'executed',\n output: detachedUnsettled({\n agent,\n runId,\n status,\n ...(args.error !== undefined ? { error: args.error } : {}),\n }),\n });\n}\n","import type { ClaimActionProposal } from './spi/action-proposal-store.js';\n\nexport function validateActionProposalWorkerClaim(command: ClaimActionProposal, now: number): void {\n if (!Number.isSafeInteger(now)) throw new RangeError('Invalid action proposal clock');\n if (typeof command.workerId !== 'string' || command.workerId.length === 0)\n throw new TypeError('workerId must be a nonempty string');\n if (\n !Number.isSafeInteger(command.leaseMs) ||\n command.leaseMs <= 0 ||\n !Number.isSafeInteger(now + command.leaseMs)\n )\n throw new RangeError('leaseMs must be positive safe integer milliseconds');\n}\n\nexport function validateActionProposalExpiryBatch(command: { limit: number }, now: number): void {\n if (!Number.isSafeInteger(now)) throw new RangeError('Invalid action proposal clock');\n validateActionProposalDiscoveryIndexBatch(command);\n}\n\nexport function validateActionProposalDiscoveryIndexBatch(command: { limit: number }): void {\n if (!Number.isInteger(command.limit) || command.limit < 1 || command.limit > 1000)\n throw new RangeError('limit must be an integer from 1 to 1000');\n}\n","import { validateActionProposalWorkerClaim } from './action-proposal-discovery.js';\nimport { snapshotActionProposal } from './action-proposal-transitions.js';\nimport type {\n ActionProposalOutcome,\n ActionProposalOutcomeLease,\n} from './spi/action-proposal-outcome-store.js';\nimport type { ActionProposal, ActionProposalScope } from './spi/action-proposal-store.js';\nimport type { AgentUiComponent } from './stream-events.js';\n\nexport function attachActionProposalOutcome(\n row: ActionProposal,\n now: number,\n ui: AgentUiComponent[] = [],\n text?: string,\n): ActionProposal {\n if (row.outcome) return row;\n const execution = row.execution;\n const outcome: ActionProposalOutcome = {\n id: `${row.id}:outcome:1`,\n proposalId: row.id,\n outcomeVersion: 1,\n tenantRef: row.tenantRef,\n actorRef: row.actorRef,\n threadId: row.threadId,\n originRunId: row.originRunId,\n originToolCallId: row.originToolCallId,\n toolName: row.toolName,\n decision: row.decision,\n ui,\n createdAt: now,\n ...(text !== undefined ? { text } : {}),\n ...(execution?.status === 'succeeded' || execution?.status === 'failed'\n ? { executionStatus: execution.status }\n : {}),\n ...(execution && Object.hasOwn(execution, 'result') ? { result: execution.result } : {}),\n ...(execution?.error !== undefined\n ? { error: execution.error }\n : row.decisionAudit?.reason !== undefined\n ? { error: row.decisionAudit.reason }\n : {}),\n };\n return snapshotActionProposal({\n ...row,\n outcome,\n outcomeDelivery: { status: 'pending', generation: 0, lease: null },\n });\n}\nexport function claimActionProposalOutcome(\n row: ActionProposal,\n command: { workerId: string; leaseMs: number },\n now: number,\n token: string,\n): ActionProposal | null {\n validateActionProposalWorkerClaim(command, now);\n const delivery = row.outcomeDelivery;\n if (\n !row.outcome ||\n !delivery ||\n delivery.status !== 'pending' ||\n (delivery.lease && now < delivery.lease.expiresAt)\n )\n return null;\n const generation = delivery.generation + 1;\n return snapshotActionProposal({\n ...row,\n outcomeDelivery: {\n ...delivery,\n generation,\n lease: { token, generation, workerId: command.workerId, expiresAt: now + command.leaseMs },\n },\n });\n}\nexport function actionProposalOutcomeFenceValid(\n row: ActionProposal,\n command: ActionProposalOutcomeLease,\n now: number,\n): boolean {\n if (!Number.isSafeInteger(now)) throw new RangeError('Invalid server clock');\n if (\n typeof command.token !== 'string' ||\n !command.token ||\n !Number.isSafeInteger(command.generation) ||\n command.generation < 1 ||\n typeof command.outcomeId !== 'string' ||\n !command.outcomeId\n )\n throw new TypeError('Invalid outcome fence');\n const delivery = row.outcomeDelivery;\n return (\n row.outcome?.id === command.outcomeId &&\n delivery?.status === 'pending' &&\n delivery.generation === command.generation &&\n delivery.lease?.token === command.token &&\n delivery.lease.generation === command.generation &&\n now < delivery.lease.expiresAt\n );\n}\nfunction outcomeSummary(outcome: ActionProposalOutcome): string {\n if (outcome.executionStatus === 'succeeded')\n return `Action ${JSON.stringify(outcome.toolName)} completed (proposal ${JSON.stringify(outcome.proposalId)}).${Object.hasOwn(outcome, 'result') ? ` Result: ${JSON.stringify(outcome.result)}` : ''}`;\n if (outcome.executionStatus === 'failed')\n return `Action ${JSON.stringify(outcome.toolName)} failed (proposal ${JSON.stringify(outcome.proposalId)}): ${JSON.stringify(outcome.error ?? 'Execution failed')}`;\n return `Action ${JSON.stringify(outcome.toolName)} was ${outcome.decision} (proposal ${JSON.stringify(outcome.proposalId)}) and was not executed.${outcome.error ? ` Reason: ${JSON.stringify(outcome.error)}` : ''}`;\n}\nexport function actionProposalOutcomeScope(outcome: ActionProposalOutcome): ActionProposalScope {\n return { tenantRef: outcome.tenantRef, actorRef: outcome.actorRef, threadId: outcome.threadId };\n}\n\nexport function actionProposalOutcomeText(outcome: ActionProposalOutcome): string {\n return outcomeSummary(outcome) + (outcome.text ? ` UI: ${JSON.stringify(outcome.text)}` : '');\n}\n","import type { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec';\n\n/** A JSON Schema document (draft-07 / 2020-12 subset). Plain data, so a catalog can be stored and shipped. */\nexport type JsonSchema = Record<string, unknown>;\n\n/** One problem with a value, addressed by its path from the root of the value. */\nexport interface GenuiIssue {\n path: (string | number)[];\n message: string;\n}\n\nexport type GenuiValidation<T = unknown> =\n | { ok: true; value: T }\n | { ok: false; issues: GenuiIssue[] };\n\n/**\n * Validates a value against a JSON Schema. The package ships {@link builtinJsonSchemaValidator} (a\n * dependency-free subset that covers what component props use); pass {@link ajvValidator} to a\n * catalog for full JSON Schema.\n */\nexport interface JsonSchemaValidator {\n validate(schema: JsonSchema, value: unknown): GenuiIssue[];\n}\n\n/** A component's props schema: any Standard Schema (Zod, Valibot, ArkType) or a JSON Schema object. */\nexport type PropsSchema = StandardSchemaV1 | JsonSchema;\n\nexport function isStandardSchema(schema: unknown): schema is StandardSchemaV1 {\n return (\n typeof schema === 'object' &&\n schema !== null &&\n '~standard' in schema &&\n typeof (schema as StandardSchemaV1)['~standard']?.validate === 'function'\n );\n}\n\n/**\n * The JSON Schema a props schema presents to a model: the schema itself for a JSON Schema, the\n * Standard JSON Schema converter's output for a Standard Schema that has one (Zod 4, Valibot,\n * ArkType). `undefined` when neither is available (e.g. Zod 3) — the model then gets the\n * component's description only.\n */\nexport function toJsonSchema(schema: PropsSchema): JsonSchema | undefined {\n if (!isStandardSchema(schema)) {\n return schema;\n }\n const standard = schema['~standard'] as StandardSchemaV1['~standard'] &\n Partial<StandardJSONSchemaV1['~standard']>;\n const converter = standard.jsonSchema;\n if (converter === undefined || typeof converter.input !== 'function') {\n return undefined;\n }\n try {\n return converter.input({ target: 'draft-07' });\n } catch {\n return undefined;\n }\n}\n\n/** Validate against either kind of props schema. A Standard Schema's own (possibly transformed) output wins. */\nexport async function validateProps(\n schema: PropsSchema,\n value: unknown,\n validator: JsonSchemaValidator,\n): Promise<GenuiValidation> {\n if (isStandardSchema(schema)) {\n const result = await schema['~standard'].validate(value);\n if (result.issues !== undefined) {\n return { ok: false, issues: toGenuiIssues(result.issues) };\n }\n return { ok: true, value: result.value };\n }\n const issues = validator.validate(schema, value);\n return issues.length > 0 ? { ok: false, issues } : { ok: true, value };\n}\n\n/**\n * {@link validateProps} without waiting: the verdict when it is available synchronously (always\n * for JSON Schema, and for every Standard Schema whose `validate` does not return a promise — Zod,\n * Valibot and ArkType all answer synchronously for synchronous schemas), `undefined` otherwise. What\n * a renderer uses to decide on its first paint instead of flashing a placeholder.\n */\nexport function validatePropsSync(\n schema: PropsSchema,\n value: unknown,\n validator: JsonSchemaValidator,\n): GenuiValidation | undefined {\n if (!isStandardSchema(schema)) {\n const issues = validator.validate(schema, value);\n return issues.length > 0 ? { ok: false, issues } : { ok: true, value };\n }\n const result = schema['~standard'].validate(value);\n if (result instanceof Promise) {\n result.catch(() => undefined);\n return undefined;\n }\n return result.issues !== undefined\n ? { ok: false, issues: toGenuiIssues(result.issues) }\n : { ok: true, value: result.value };\n}\n\nfunction toGenuiIssues(issues: readonly StandardSchemaV1.Issue[]): GenuiIssue[] {\n return issues.map((issue) => ({\n path: (issue.path ?? []).map((segment) =>\n typeof segment === 'object' && segment !== null && 'key' in segment\n ? (segment.key as string | number)\n : (segment as string | number),\n ),\n message: issue.message,\n }));\n}\n\n/** `a.b[0].c: message; …` — what a model is handed back when its props were refused. */\nexport function formatIssues(issues: readonly GenuiIssue[]): string {\n return issues\n .map(\n (issue) => `${issue.path.length > 0 ? formatPath(issue.path) : '(root)'}: ${issue.message}`,\n )\n .join('; ');\n}\n\nfunction formatPath(path: readonly (string | number)[]): string {\n return path\n .map((segment, index) =>\n typeof segment === 'number' ? `[${segment}]` : index === 0 ? segment : `.${segment}`,\n )\n .join('');\n}\n\n/**\n * Structural type of an Ajv instance, so the package never imports Ajv: `new Ajv({ allErrors: true })`\n * satisfies it.\n */\nexport interface AjvLike {\n compile(schema: object): ((data: unknown) => boolean | Promise<unknown>) & {\n errors?: { instancePath?: string; message?: string }[] | null;\n };\n}\n\n/**\n * Full JSON Schema validation through the app's own Ajv instance. Compiled validators are cached\n * per schema object.\n */\nexport function ajvValidator(ajv: AjvLike): JsonSchemaValidator {\n const compiled = new WeakMap<object, ReturnType<AjvLike['compile']>>();\n return {\n validate(schema, value) {\n let fn = compiled.get(schema);\n if (fn === undefined) {\n fn = ajv.compile(schema);\n compiled.set(schema, fn);\n }\n if (fn(value) === true) {\n return [];\n }\n return (fn.errors ?? []).map((error) => ({\n path: (error.instancePath ?? '')\n .split('/')\n .filter((segment) => segment.length > 0)\n .map((segment) => {\n const decoded = segment.replace(/~1/g, '/').replace(/~0/g, '~');\n return /^\\d+$/.test(decoded) ? Number(decoded) : decoded;\n }),\n message: error.message ?? 'is invalid',\n }));\n },\n };\n}\n\n/**\n * A dependency-free JSON Schema validator for the keywords component props actually use: `type`\n * (incl. `integer`, `null`, type arrays), `enum`, `const`, `properties`, `required`,\n * `additionalProperties`, `items`, `minItems`/`maxItems`, `minLength`/`maxLength`/`pattern`,\n * `minimum`/`maximum`, `anyOf`/`oneOf`/`allOf`, `not`, and local `$ref`s (`#`, `#/$defs/…`,\n * `#/definitions/…`). Unknown keywords (e.g. `format`) are ignored. Use {@link ajvValidator} when\n * you need the rest.\n */\nexport const builtinJsonSchemaValidator: JsonSchemaValidator = {\n validate(schema, value) {\n const issues: GenuiIssue[] = [];\n check(schema, value, [], schema, issues, 0);\n return issues;\n },\n};\n\nconst MAX_DEPTH = 64;\n\nfunction typeOf(value: unknown): string {\n if (value === null) return 'null';\n if (Array.isArray(value)) return 'array';\n return typeof value;\n}\n\nfunction matchesType(type: string, value: unknown): boolean {\n switch (type) {\n case 'integer':\n return typeof value === 'number' && Number.isInteger(value);\n case 'number':\n return typeof value === 'number' && Number.isFinite(value);\n case 'object':\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n default:\n return typeOf(value) === type;\n }\n}\n\nfunction resolveRef(root: JsonSchema, ref: string): JsonSchema | undefined {\n if (ref === '#') return root;\n if (!ref.startsWith('#/')) return undefined;\n let current: unknown = root;\n for (const raw of ref.slice(2).split('/')) {\n const key = raw.replace(/~1/g, '/').replace(/~0/g, '~');\n if (typeof current !== 'object' || current === null) return undefined;\n current = (current as Record<string, unknown>)[key];\n }\n return typeof current === 'object' && current !== null ? (current as JsonSchema) : undefined;\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n return keysA.every((key) =>\n deepEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key]),\n );\n}\n\nfunction check(\n schema: unknown,\n value: unknown,\n path: (string | number)[],\n root: JsonSchema,\n issues: GenuiIssue[],\n depth: number,\n): void {\n if (schema === true || schema === undefined) return;\n if (schema === false) {\n issues.push({ path, message: 'is not allowed' });\n return;\n }\n if (typeof schema !== 'object' || schema === null) return;\n if (depth > MAX_DEPTH) {\n issues.push({ path, message: 'is nested too deeply' });\n return;\n }\n const s = schema as Record<string, unknown>;\n\n if (typeof s.$ref === 'string') {\n const target = resolveRef(root, s.$ref);\n if (target === undefined) {\n issues.push({ path, message: `references unknown schema ${s.$ref}` });\n return;\n }\n check(target, value, path, root, issues, depth + 1);\n }\n\n if (s.type !== undefined) {\n const types = Array.isArray(s.type) ? (s.type as string[]) : [s.type as string];\n if (!types.some((type) => matchesType(type, value))) {\n issues.push({ path, message: `must be ${types.join(' or ')}` });\n return;\n }\n }\n if (Array.isArray(s.enum) && !s.enum.some((option) => deepEqual(option, value))) {\n issues.push({\n path,\n message: `must be one of ${s.enum.map((option) => JSON.stringify(option)).join(', ')}`,\n });\n }\n if ('const' in s && !deepEqual(s.const, value)) {\n issues.push({ path, message: `must be ${JSON.stringify(s.const)}` });\n }\n\n if (typeof value === 'string') {\n if (typeof s.minLength === 'number' && value.length < s.minLength) {\n issues.push({ path, message: `must be at least ${s.minLength} characters` });\n }\n if (typeof s.maxLength === 'number' && value.length > s.maxLength) {\n issues.push({ path, message: `must be at most ${s.maxLength} characters` });\n }\n if (typeof s.pattern === 'string') {\n let pattern: RegExp | undefined;\n try {\n pattern = new RegExp(s.pattern, 'u');\n } catch {\n pattern = undefined;\n }\n if (pattern !== undefined && !pattern.test(value)) {\n issues.push({ path, message: `must match ${s.pattern}` });\n }\n }\n }\n if (typeof value === 'number') {\n if (typeof s.minimum === 'number' && value < s.minimum) {\n issues.push({ path, message: `must be >= ${s.minimum}` });\n }\n if (typeof s.maximum === 'number' && value > s.maximum) {\n issues.push({ path, message: `must be <= ${s.maximum}` });\n }\n }\n\n if (Array.isArray(value)) {\n if (typeof s.minItems === 'number' && value.length < s.minItems) {\n issues.push({ path, message: `must have at least ${s.minItems} items` });\n }\n if (typeof s.maxItems === 'number' && value.length > s.maxItems) {\n issues.push({ path, message: `must have at most ${s.maxItems} items` });\n }\n if (s.items !== undefined && !Array.isArray(s.items)) {\n value.forEach((item, index) => {\n check(s.items, item, [...path, index], root, issues, depth + 1);\n });\n }\n }\n\n if (matchesType('object', value)) {\n const record = value as Record<string, unknown>;\n const properties =\n typeof s.properties === 'object' && s.properties !== null\n ? (s.properties as Record<string, unknown>)\n : {};\n if (Array.isArray(s.required)) {\n for (const key of s.required as string[]) {\n if (record[key] === undefined) {\n issues.push({ path: [...path, key], message: 'is required' });\n }\n }\n }\n for (const [key, entry] of Object.entries(record)) {\n if (key in properties) {\n if (entry !== undefined) {\n check(properties[key], entry, [...path, key], root, issues, depth + 1);\n }\n } else if (s.additionalProperties === false) {\n issues.push({ path: [...path, key], message: 'is not a known property' });\n } else if (typeof s.additionalProperties === 'object' && s.additionalProperties !== null) {\n check(s.additionalProperties, entry, [...path, key], root, issues, depth + 1);\n }\n }\n }\n\n if (Array.isArray(s.allOf)) {\n for (const sub of s.allOf) check(sub, value, path, root, issues, depth + 1);\n }\n if (Array.isArray(s.anyOf) || Array.isArray(s.oneOf)) {\n const options = (Array.isArray(s.anyOf) ? s.anyOf : s.oneOf) as unknown[];\n const passing = options.filter((sub) => {\n const nested: GenuiIssue[] = [];\n check(sub, value, path, root, nested, depth + 1);\n return nested.length === 0;\n }).length;\n if (Array.isArray(s.anyOf) ? passing === 0 : passing !== 1) {\n issues.push({\n path,\n message: Array.isArray(s.anyOf)\n ? 'does not match any allowed shape'\n : 'must match exactly one allowed shape',\n });\n }\n }\n if (s.not !== undefined) {\n const nested: GenuiIssue[] = [];\n check(s.not, value, path, root, nested, depth + 1);\n if (nested.length === 0) {\n issues.push({ path, message: 'matches a shape that is not allowed' });\n }\n }\n}\n","import {\n type GenuiValidation,\n type JsonSchema,\n type JsonSchemaValidator,\n type PropsSchema,\n builtinJsonSchemaValidator,\n toJsonSchema,\n validateProps,\n validatePropsSync,\n} from './schema.js';\n\n/**\n * One component a server may push into a conversation. Data only — how it LOOKS is each app's own\n * renderer, looked up by {@link name}. The same definition serves the model (description + props\n * schema), the server (validation), text-only channels ({@link fallbackText}) and the client\n * (validation before rendering).\n */\nexport interface ComponentDefinition<P = Record<string, unknown>> {\n /** Registry key, e.g. `DataTable`. What a `ui` frame's `component` names. */\n name: string;\n /** Human label: \"Data table\". */\n title: string;\n /** Shown to the model: what the component is for and when to use it. */\n description: string;\n /** The props schema: a Standard Schema (Zod, Valibot, ArkType) or a JSON Schema object. */\n props: PropsSchema;\n /** Portable normalized props schema. Required when input transformations are not idempotent. */\n outputProps?: PropsSchema;\n /**\n * The component takes nested elements (a layout: `Stack`, `Card`). Only meaningful in tree mode,\n * where a node's `children` are validated against the catalog too. Such a component gets no\n * `ui__show_*` tool and is not offered by the show tool ({@link flatComponents}), and when its\n * {@link fallbackText} comes out empty it writes no text of its own (its children still do).\n */\n children?: boolean;\n /**\n * Plain text / Slack mrkdwn rendering of these props, for a channel that cannot draw the\n * component. Absent → {@link componentToText} prints the props as JSON.\n */\n fallbackText?: (props: P) => string;\n /**\n * Pushed by the server (e.g. an approval card), never offered to the model. Excluded from\n * {@link catalogToModelText} and from the tool factories.\n */\n internal?: boolean;\n /**\n * Schema version of {@link props}. Stamped on every `ui` frame the component is pushed with, so a\n * client can keep rendering messages persisted under an older shape.\n */\n version?: number;\n}\n\n/** Component names: an identifier a registry key, a tool name and a snake_case slug can all be derived from. */\nexport const COMPONENT_NAME = /^[A-Za-z][A-Za-z0-9]{0,63}$/;\n\n/** Declare a component. Validates the name and returns the definition unchanged (typed). */\nexport function defineComponent<P = Record<string, unknown>>(\n definition: ComponentDefinition<P>,\n): ComponentDefinition<P> {\n if (!COMPONENT_NAME.test(definition.name)) {\n throw new Error(\n `genui: component name \"${definition.name}\" must be letters and digits, starting with a letter (e.g. DataTable)`,\n );\n }\n if (\n definition.version !== undefined &&\n (!Number.isSafeInteger(definition.version) || definition.version <= 0)\n )\n throw new RangeError('genui: component version must be a positive safe integer');\n if (definition.fallbackText !== undefined && typeof definition.fallbackText !== 'function')\n throw new TypeError('genui: fallbackText must be a function');\n return definition;\n}\n\nexport interface CatalogOptions {\n /** How JSON Schema props are checked. Default: {@link builtinJsonSchemaValidator}; pass `ajvValidator(new Ajv())` for full JSON Schema. */\n jsonSchemaValidator?: JsonSchemaValidator;\n}\n\n/** An immutable set of component definitions, looked up by name. */\nexport interface Catalog {\n readonly components: readonly ComponentDefinition<any>[];\n readonly validator: JsonSchemaValidator;\n get(name: string): ComponentDefinition<any> | undefined;\n has(name: string): boolean;\n /** The components a model may be offered (every non-`internal` one). */\n modelComponents(): ComponentDefinition<any>[];\n /** Validate `props` for `component`. An unknown component is a validation failure, not a throw. */\n validate(component: string, props: unknown): Promise<GenuiValidation<Record<string, unknown>>>;\n /**\n * {@link validate} without waiting — `undefined` only when the component's Standard Schema\n * validates asynchronously. An unknown component is a failure, as in `validate`.\n */\n validateSync(\n component: string,\n props: unknown,\n ): GenuiValidation<Record<string, unknown>> | undefined;\n /** The component's props as JSON Schema, when it can be derived (see {@link toJsonSchema}). */\n jsonSchemaFor(component: string): JsonSchema | undefined;\n /** A new catalog with these components added (a later definition replaces an earlier one of the same name). */\n extend(components: readonly ComponentDefinition<any>[]): Catalog;\n}\n\n/**\n * The model components a FLAT tool can offer — one whose input is the component's props alone\n * (`ui__show_<name>`, the generic show tool). A layout component (`children: true`) is left out:\n * those tools have no way to pass it children, so it would only ever draw an empty box. Tree mode\n * offers every model component.\n */\nexport function flatComponents(catalog: Catalog): ComponentDefinition<any>[] {\n return catalog.modelComponents().filter((component) => component.children !== true);\n}\n\n/**\n * Collect component definitions into a {@link Catalog}. Names must be unique; to override a\n * definition (e.g. a builtin), use {@link Catalog.extend}.\n */\nexport function defineCatalog(\n components: readonly ComponentDefinition<any>[],\n options: CatalogOptions = {},\n): Catalog {\n const byName = new Map<string, ComponentDefinition<any>>();\n for (const component of components) {\n defineComponent(component);\n if (byName.has(component.name)) {\n throw new Error(`genui: component \"${component.name}\" is defined twice in one catalog`);\n }\n byName.set(component.name, component);\n }\n return buildCatalog(byName, options.jsonSchemaValidator ?? builtinJsonSchemaValidator);\n}\n\nfunction buildCatalog(\n byName: Map<string, ComponentDefinition<any>>,\n validator: JsonSchemaValidator,\n): Catalog {\n const list = Object.freeze([...byName.values()]);\n return {\n components: list,\n validator,\n get: (name) => byName.get(name),\n has: (name) => byName.has(name),\n modelComponents: () => list.filter((component) => component.internal !== true),\n async validate(component, props) {\n const definition = byName.get(component);\n if (definition === undefined) {\n return {\n ok: false,\n issues: [{ path: [], message: `unknown component \"${component}\"` }],\n };\n }\n const result = await validateProps(\n definition.outputProps ?? definition.props,\n props,\n validator,\n );\n return result as GenuiValidation<Record<string, unknown>>;\n },\n validateSync(component, props) {\n const definition = byName.get(component);\n if (definition === undefined) {\n return {\n ok: false,\n issues: [{ path: [], message: `unknown component \"${component}\"` }],\n };\n }\n return validatePropsSync(definition.outputProps ?? definition.props, props, validator) as\n | GenuiValidation<Record<string, unknown>>\n | undefined;\n },\n jsonSchemaFor(component) {\n const definition = byName.get(component);\n return definition === undefined\n ? undefined\n : toJsonSchema(definition.outputProps ?? definition.props);\n },\n extend(more) {\n const next = new Map(byName);\n for (const component of more) {\n defineComponent(component);\n next.set(component.name, component);\n }\n return buildCatalog(next, validator);\n },\n };\n}\n\n/** `DataTable` → `data_table`, `KPICards` → `kpi_cards`. */\nexport function toSnakeCase(name: string): string {\n return name\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')\n .replace(/[^a-zA-Z0-9]+/g, '_')\n .toLowerCase();\n}\n\n/** The per-component tool name: `ui__show_data_table` with the default prefix. */\nexport function toolNameFor(component: string, prefix = 'ui__show_'): string {\n return `${prefix}${toSnakeCase(component)}`;\n}\n","import type { Catalog } from './catalog.js';\nimport { type GenuiIssue, type GenuiValidation, type JsonSchema, validateProps } from './schema.js';\n\n/**\n * One node of a composed UI: a catalog component, its props, and — for components declared with\n * `children: true` — nested nodes. The shape json-render calls a \"nested element\", so a tree\n * converts to a json-render flat spec with {@link treeToFlatSpec}.\n */\nexport interface GenuiElement {\n type: string;\n props: Record<string, unknown>;\n children?: GenuiElement[];\n}\n\n/**\n * The `ui` frame component a tree-mode tool pushes: `{ component: GENUI_TREE_COMPONENT, props: {\n * root } }`. Not a valid component name, so it can never collide with a catalog entry.\n */\nexport const GENUI_TREE_COMPONENT = 'genui:tree';\n\n/** Props of a {@link GENUI_TREE_COMPONENT} frame. */\nexport interface GenuiTreeProps {\n root: GenuiElement;\n}\n\nexport interface TreeLimits {\n /** Deepest nesting accepted. Default 12. */\n maxDepth?: number;\n /** Most nodes accepted in one tree. Default 200. */\n maxNodes?: number;\n}\n\n/**\n * Validate a model-composed tree against the catalog: every node's `type` must be a model-facing\n * component, its props must pass that component's schema, and only components declared with\n * `children: true` may have children. Returns the tree with each node's props as its schema\n * produced them (defaults applied by a Standard Schema, for instance).\n *\n * Lenient about one thing models get wrong: a `children` array sent as a JSON STRING (sometimes\n * with a stray trailing `}`) is parsed back into the array the model plainly meant.\n */\nexport async function validateTree(\n catalog: Catalog,\n tree: unknown,\n limits: TreeLimits = {},\n phase: 'input' | 'output' = 'output',\n): Promise<GenuiValidation<GenuiElement>> {\n const maxDepth = limits.maxDepth ?? 12;\n const maxNodes = limits.maxNodes ?? 200;\n const issues: GenuiIssue[] = [];\n let nodes = 0;\n\n const visit = async (\n node: unknown,\n path: (string | number)[],\n depth: number,\n ): Promise<GenuiElement | undefined> => {\n nodes += 1;\n if (nodes > maxNodes) {\n if (nodes === maxNodes + 1) {\n issues.push({ path, message: `the tree has more than ${maxNodes} elements` });\n }\n return undefined;\n }\n if (depth > maxDepth) {\n issues.push({ path, message: `the tree is nested deeper than ${maxDepth} levels` });\n return undefined;\n }\n if (typeof node !== 'object' || node === null || Array.isArray(node)) {\n issues.push({ path, message: 'must be an element object { type, props, children? }' });\n return undefined;\n }\n const element = node as Record<string, unknown>;\n if (typeof element.type !== 'string') {\n issues.push({ path: [...path, 'type'], message: 'must be a component name' });\n return undefined;\n }\n const definition = catalog.get(element.type);\n if (definition === undefined || definition.internal === true) {\n issues.push({\n path: [...path, 'type'],\n message: `unknown component \"${element.type}\" (allowed: ${catalog\n .modelComponents()\n .map((component) => component.name)\n .join(', ')})`,\n });\n return undefined;\n }\n const validated =\n phase === 'input'\n ? ((await validateProps(\n definition.props,\n element.props ?? {},\n catalog.validator,\n )) as GenuiValidation<Record<string, unknown>>)\n : await catalog.validate(element.type, element.props ?? {});\n let props: Record<string, unknown> = {};\n if (!validated.ok) {\n for (const issue of validated.issues) {\n issues.push({ path: [...path, 'props', ...issue.path], message: issue.message });\n }\n } else {\n props = validated.value;\n }\n const rawChildren = parseChildrenIfStringified(element.children);\n if (rawChildren === undefined || rawChildren === null) {\n return { type: element.type, props };\n }\n if (!Array.isArray(rawChildren)) {\n issues.push({\n path: [...path, 'children'],\n message: 'must be an array of elements (a literal array, not a string)',\n });\n return undefined;\n }\n if (rawChildren.length > 0 && definition.children !== true) {\n issues.push({\n path: [...path, 'children'],\n message: `${element.type} does not take children`,\n });\n return undefined;\n }\n const children: GenuiElement[] = [];\n for (const [index, child] of rawChildren.entries()) {\n const next = await visit(child, [...path, 'children', index], depth + 1);\n if (next !== undefined) {\n children.push(next);\n }\n }\n return children.length > 0\n ? { type: element.type, props, children }\n : { type: element.type, props };\n };\n\n const root = await visit(tree, [], 1);\n return issues.length > 0 || root === undefined\n ? { ok: false, issues: issues.length > 0 ? issues : [{ path: [], message: 'is invalid' }] }\n : { ok: true, value: root };\n}\n\n/**\n * The JSON Schema of a tree-mode tool's input: a recursive `{ type, props, children? }` node whose\n * `type` is one of the catalog's model-facing component names. Per-component props are described\n * to the model in the tool description (see `catalogToModelText`) and checked by\n * {@link validateTree}, which keeps this schema small enough for every provider.\n */\nexport function treeJsonSchema(catalog: Catalog): JsonSchema {\n return {\n type: 'object',\n properties: {\n type: {\n type: 'string',\n enum: catalog.modelComponents().map((component) => component.name),\n description: 'Component name from the catalog',\n },\n props: {\n type: 'object',\n description: \"The component's props, as the catalog describes them\",\n },\n children: {\n type: 'array',\n items: { $ref: '#' },\n description:\n 'Nested elements, only for components that take children. A literal JSON array, never a JSON-stringified one.',\n },\n },\n required: ['type', 'props'],\n };\n}\n\n/** A json-render flat spec: `{ root, elements: { [id]: { type, props, children: id[] } } }`. */\nexport interface FlatSpec {\n root: string;\n elements: Record<string, { type: string; props: Record<string, unknown>; children: string[] }>;\n}\n\n/** Convert a tree to a json-render flat spec (ids are `el-0`, `el-1`, … in depth-first order). */\nexport function treeToFlatSpec(root: GenuiElement): FlatSpec {\n const elements: FlatSpec['elements'] = {};\n let next = 0;\n const visit = (node: GenuiElement): string => {\n const id = `el-${next++}`;\n const entry = { type: node.type, props: node.props, children: [] as string[] };\n elements[id] = entry;\n for (const child of node.children ?? []) {\n entry.children.push(visit(child));\n }\n return id;\n };\n return { root: visit(root), elements };\n}\n\nfunction parseChildrenIfStringified(value: unknown): unknown {\n if (typeof value !== 'string') return value;\n const trimmed = value.trim();\n if (!trimmed.startsWith('[')) return value;\n return leadingJsonArray(trimmed) ?? value;\n}\n\n/**\n * The array `text` opens with, ignoring what follows: a model that stringifies `children` tends to\n * carry the enclosing object's `}` along, which `JSON.parse` refuses whole.\n */\nfunction leadingJsonArray(text: string): unknown[] | undefined {\n let depth = 0;\n let inString = false;\n let escaped = false;\n for (let index = 0; index < text.length; index += 1) {\n const char = text[index];\n if (inString) {\n if (escaped) escaped = false;\n else if (char === '\\\\') escaped = true;\n else if (char === '\"') inString = false;\n continue;\n }\n if (char === '\"') inString = true;\n else if (char === '[' || char === '{') depth += 1;\n else if (char === ']' || char === '}') {\n depth -= 1;\n if (depth === 0) {\n try {\n const parsed: unknown = JSON.parse(text.slice(0, index + 1));\n return Array.isArray(parsed) ? parsed : undefined;\n } catch {\n return undefined;\n }\n }\n }\n }\n return undefined;\n}\n","import { type Catalog, flatComponents, toolNameFor } from './catalog.js';\nimport { type JsonSchema, toJsonSchema } from './schema.js';\nimport { GENUI_TREE_COMPONENT, type GenuiElement } from './tree.js';\n\n/**\n * Plain text (Slack mrkdwn compatible) for a pushed component: its definition's `fallbackText`, or\n * the props as a JSON block when the catalog has no text for it. A tree frame\n * ({@link GENUI_TREE_COMPONENT}) renders node by node. Never throws — a fallback that fails prints\n * the JSON instead. A layout component (`children: true`) whose text comes out empty writes\n * nothing: it has nothing of its own to say, and its props (`direction`, `gap`) are not content.\n */\nexport function componentToText(\n catalog: Catalog,\n component: string,\n props: Record<string, unknown>,\n): string {\n if (component === GENUI_TREE_COMPONENT) {\n const root = props.root as GenuiElement | undefined;\n return root === undefined ? '' : treeToText(catalog, root);\n }\n return ownText(catalog, component, props) ?? '';\n}\n\n/**\n * One component's own text, without its children: its fallback; `undefined` for a layout component\n * with nothing to say; the props as JSON otherwise (no fallback, an empty one, or one that threw).\n */\nfunction ownText(\n catalog: Catalog,\n component: string,\n props: Record<string, unknown>,\n): string | undefined {\n const definition = catalog.get(component);\n const fallback = definition?.fallbackText;\n let failed = false;\n if (fallback !== undefined) {\n try {\n const text = fallback(props);\n if (typeof text === 'string' && text.trim().length > 0) return text;\n } catch {\n failed = true;\n }\n }\n if (definition?.children === true && !failed) return undefined;\n return jsonBlock(props);\n}\n\n/** Plain text for a composed tree: each node's text, depth-first, blank-line free. */\nexport function treeToText(catalog: Catalog, root: GenuiElement): string {\n const out: string[] = [];\n const visit = (node: GenuiElement, depth: number) => {\n if (depth > 32) return;\n const text = ownText(catalog, node.type, node.props);\n if (text !== undefined) out.push(text);\n for (const child of node.children ?? []) visit(child, depth + 1);\n };\n visit(root, 0);\n return out.filter((line) => line.trim().length > 0).join('\\n');\n}\n\nfunction jsonBlock(props: Record<string, unknown>): string {\n const title =\n typeof props.title === 'string' && props.title.length > 0 ? `*${props.title}*\\n` : '';\n return `${title}\\`\\`\\`\\n${JSON.stringify(props, null, 2)}\\n\\`\\`\\``;\n}\n\nexport interface CatalogTextOptions {\n /**\n * `per-component`: each component is its own tool (`ui__show_<snake>`), named in the text.\n * `tree`: one tool takes a nested `{ type, props, children }` tree; the text explains the format.\n * `show`: one tool takes `{ component, props }` (the generic show tool). Default `tree`.\n */\n mode?: 'per-component' | 'tree' | 'show';\n /** Tool-name prefix for `per-component`. Default `ui__show_`. */\n namePrefix?: string;\n}\n\n/**\n * The catalog described for a model: one entry per model-facing component with its description and\n * a compact TypeScript-like signature of its props. What a tree-mode (or show) tool puts in its\n * description, and what a host can add to a system prompt.\n */\nexport function catalogToModelText(catalog: Catalog, options: CatalogTextOptions = {}): string {\n const mode = options.mode ?? 'tree';\n const lines: string[] = [];\n if (mode === 'tree') {\n lines.push(\n 'Compose the UI as ONE tree of elements: { \"type\": <component>, \"props\": { … }, \"children\"?: [ … ] }.',\n 'Only components marked \"takes children\" accept children; `children` is a literal JSON array, never a string.',\n 'Components:',\n );\n } else if (mode === 'show') {\n lines.push('Pass { \"component\": <name>, \"props\": { … } } with one of these components:');\n } else {\n lines.push('Components you can show (one tool each):');\n }\n // Flat modes cannot pass children, so a layout component is not offered there.\n const components = mode === 'tree' ? catalog.modelComponents() : flatComponents(catalog);\n for (const component of components) {\n const schema = toJsonSchema(component.props);\n const head =\n mode === 'per-component'\n ? `- ${component.name} (tool \\`${toolNameFor(component.name, options.namePrefix)}\\`)`\n : `- ${component.name}`;\n lines.push(`${head}: ${component.description}`);\n if (schema !== undefined) {\n lines.push(` props: ${summarizeSchema(schema, schema, 0)}`);\n }\n if (mode === 'tree' && component.children === true) {\n lines.push(' takes children');\n }\n }\n return lines.join('\\n');\n}\n\n/** A JSON Schema as a one-line TypeScript-like type, e.g. `{ title?: string, rows: object[] }`. */\nexport function summarizeSchema(schema: unknown, root: JsonSchema, depth: number): string {\n if (typeof schema !== 'object' || schema === null) return 'unknown';\n const s = schema as Record<string, unknown>;\n if (depth > 5) return '…';\n if (typeof s.$ref === 'string') {\n return s.$ref === '#' ? 'Self' : (s.$ref.split('/').pop() ?? 'unknown');\n }\n if (Array.isArray(s.enum)) {\n return s.enum.map((option) => JSON.stringify(option)).join(' | ');\n }\n if ('const' in s) return JSON.stringify(s.const);\n const variants = (s.anyOf ?? s.oneOf) as unknown[] | undefined;\n if (Array.isArray(variants)) {\n return variants.map((variant) => summarizeSchema(variant, root, depth + 1)).join(' | ');\n }\n const types = Array.isArray(s.type) ? (s.type as string[]) : s.type !== undefined ? [s.type] : [];\n if (types.length > 1) {\n return types.map((type) => summarizeSchema({ ...s, type }, root, depth + 1)).join(' | ');\n }\n const type = types[0] as string | undefined;\n if (type === 'array') {\n const item = s.items === undefined ? 'unknown' : summarizeSchema(s.items, root, depth + 1);\n return /[|\\s]/.test(item) && !item.startsWith('{') ? `(${item})[]` : `${item}[]`;\n }\n if (type === 'object' || (type === undefined && s.properties !== undefined)) {\n const properties = (s.properties ?? {}) as Record<string, unknown>;\n const keys = Object.keys(properties);\n if (keys.length === 0) return 'object';\n const required = new Set(Array.isArray(s.required) ? (s.required as string[]) : []);\n const fields = keys.map((key) => {\n const field = properties[key] as Record<string, unknown> | undefined;\n const note =\n typeof field?.description === 'string' && depth === 0 ? ` /* ${field.description} */` : '';\n return `${key}${required.has(key) ? '' : '?'}: ${summarizeSchema(field, root, depth + 1)}${note}`;\n });\n return `{ ${fields.join(', ')} }`;\n }\n if (type === 'integer') return 'number';\n return type ?? 'unknown';\n}\n\n/** Replace `{{path}}` placeholders with prop values (objects as JSON). */\nexport function fillTemplate(template: string, props: Record<string, unknown>): string {\n return template.replace(/\\{\\{\\s*([\\w.[\\]]+)\\s*\\}\\}/g, (_match, path: string) => {\n const value = getPath(props, path);\n if (value === null || value === undefined) return '';\n return typeof value === 'object' ? JSON.stringify(value) : String(value);\n });\n}\n\n/** Read `a.b[0].c` from a value; `undefined` when any step is missing. */\nexport function getPath(source: unknown, path: string): unknown {\n let current: any = source;\n for (const part of path\n .replace(/\\[(\\d+)\\]/g, '.$1')\n .split('.')\n .filter(Boolean)) {\n if (current === null || current === undefined) return undefined;\n current = current[part];\n }\n return current;\n}\n","import { COMPONENT_NAME, type Catalog, defineCatalog } from './catalog.js';\nimport { formatIssues } from './schema.js';\nimport { componentToText, treeToText } from './text.js';\nimport { GENUI_TREE_COMPONENT, type GenuiElement, validateTree } from './tree.js';\n\n/** Renderer support only. Component definitions and authorization remain server-owned. */\nexport interface UiCapabilities {\n components: Array<{ name: string; version: number }>;\n}\n\nexport function validateUiCapabilities(value: unknown): UiCapabilities {\n if (\n !record(value) ||\n Object.keys(value).some((key) => key !== 'components') ||\n !Array.isArray(value.components)\n )\n throw new TypeError('Invalid UI capabilities');\n const seen = new Set<string>();\n const components = value.components.map((component: unknown) => {\n if (\n !record(component) ||\n Object.keys(component).some((key) => key !== 'name' && key !== 'version') ||\n typeof component.name !== 'string' ||\n !COMPONENT_NAME.test(component.name) ||\n !Number.isSafeInteger(component.version) ||\n Number(component.version) <= 0 ||\n seen.has(component.name)\n )\n throw new TypeError('Invalid UI component capability');\n seen.add(component.name);\n return { name: component.name, version: Number(component.version) };\n });\n return { components };\n}\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function negotiateCatalog(catalog: Catalog, capabilities?: UiCapabilities): Catalog {\n if (capabilities === undefined) return catalog;\n const supported = validateUiCapabilities(capabilities).components;\n return defineCatalog(\n catalog.components.filter((component) =>\n supported.some(\n (entry) => entry.name === component.name && entry.version === (component.version ?? 1),\n ),\n ),\n { jsonSchemaValidator: catalog.validator },\n );\n}\n\nexport type PreparedUiEmission =\n | {\n kind: 'ui';\n component: string;\n props: Record<string, unknown>;\n version: number;\n fallbackText: string;\n componentVersions?: Record<string, number>;\n }\n | { kind: 'text'; text: string };\n\n/** Validate against current trusted definitions before drawing or generating complete text. */\nexport async function prepareUiEmission(\n catalog: Catalog,\n capabilities: UiCapabilities | undefined,\n component: string,\n props: Record<string, unknown>,\n version?: number,\n): Promise<PreparedUiEmission> {\n const drawable = negotiateCatalog(catalog, capabilities);\n if (component === GENUI_TREE_COMPONENT) {\n if (version !== undefined && version !== 1) throw new Error('Invalid UI tree version');\n const validated = await validateTree(catalog, props.root);\n if (!validated.ok) throw new Error(`Invalid UI tree: ${formatIssues(validated.issues)}`);\n const supported = (node: GenuiElement): boolean =>\n drawable.has(node.type) && (node.children ?? []).every(supported);\n const versions = new Map<string, number>();\n const collectVersions = (node: GenuiElement): void => {\n versions.set(node.type, catalog.get(node.type)?.version ?? 1);\n for (const child of node.children ?? []) collectVersions(child);\n };\n collectVersions(validated.value);\n return supported(validated.value)\n ? {\n kind: 'ui',\n component,\n props: { root: validated.value },\n version: 1,\n fallbackText: treeToText(catalog, validated.value),\n componentVersions: Object.fromEntries(versions),\n }\n : { kind: 'text', text: treeToText(catalog, validated.value) };\n }\n const definition = catalog.get(component);\n if (definition === undefined) throw new Error(`Unknown UI component \"${component}\"`);\n const currentVersion = definition.version ?? 1;\n if (version !== undefined && version !== currentVersion)\n throw new Error(`Invalid UI component version for \"${component}\"`);\n const validated = await catalog.validate(component, props);\n if (!validated.ok) throw new Error(`Invalid UI props: ${formatIssues(validated.issues)}`);\n return drawable.has(component)\n ? {\n kind: 'ui',\n component,\n props: validated.value,\n version: currentVersion,\n fallbackText: componentToText(catalog, component, validated.value),\n }\n : { kind: 'text', text: componentToText(catalog, component, validated.value) };\n}\n","import { attachActionProposalOutcome } from './action-proposal-outcome.js';\nimport { validateUiCapabilities } from './genui/capabilities.js';\nimport type {\n ActionProposal,\n ActionProposalDecisionCommand,\n ActionProposalMutationResult,\n ActionProposalScope,\n ClaimActionProposal,\n CreateActionProposal,\n ExtendActionProposalLease,\n ListActionProposals,\n SettleActionProposal,\n} from './spi/action-proposal-store.js';\n\nfunction checkTime(value: number): void {\n if (!Number.isSafeInteger(value))\n throw new RangeError('Action proposal timestamps must be safe integer milliseconds');\n}\nfunction checkString(value: unknown): void {\n if (typeof value !== 'string' || value.length === 0)\n throw new TypeError('Action proposal identifiers must be nonempty strings');\n}\nexport function validateActionProposalCreation(input: CreateActionProposal): void {\n const allowed = [\n 'id',\n 'tenantRef',\n 'actorRef',\n 'threadId',\n 'originRunId',\n 'originMessageId',\n 'originToolCallId',\n 'toolName',\n 'input',\n 'preparationInput',\n 'executionContext',\n 'confirmation',\n 'approver',\n 'expiresAt',\n 'idempotencyKey',\n 'replacementKey',\n ];\n if (Object.keys(input).some((key) => !allowed.includes(key)))\n throw new TypeError('Unknown action proposal creation field');\n for (const key of [\n 'id',\n 'actorRef',\n 'threadId',\n 'originRunId',\n 'originMessageId',\n 'originToolCallId',\n 'toolName',\n 'approver',\n 'idempotencyKey',\n ] as const)\n checkString(input[key]);\n if (input.tenantRef !== null && typeof input.tenantRef !== 'string')\n throw new TypeError('tenantRef must be an explicit string or null');\n for (const value of [input.id, input.actorRef, input.threadId, input.tenantRef]) {\n if (value !== null && value.length > 255)\n throw new RangeError('Action proposal id and scope must fit 255 UTF-16 code units');\n }\n if (input.replacementKey !== undefined) {\n checkString(input.replacementKey);\n if (input.replacementKey.length > 255)\n throw new RangeError('replacementKey must fit 255 UTF-16 code units');\n }\n if (Object.hasOwn(input, 'executionContext')) {\n const context = input.executionContext;\n if (context === null || typeof context !== 'object' || Array.isArray(context))\n throw new TypeError('executionContext must be a JSON object');\n const allowedContext = ['agentName', 'persona', 'requestId', 'pageContext', 'uiCapabilities'];\n if (Object.keys(context).some((key) => !allowedContext.includes(key)))\n throw new TypeError('Unknown execution context field');\n checkString(context.requestId);\n if (Object.hasOwn(context, 'uiCapabilities')) validateUiCapabilities(context.uiCapabilities);\n if (Object.hasOwn(context, 'agentName')) checkString(context.agentName);\n if (Object.hasOwn(context, 'persona')) checkString(context.persona);\n if (Object.hasOwn(context, 'pageContext')) {\n const page = context.pageContext;\n if (page === null || typeof page !== 'object' || Array.isArray(page))\n throw new TypeError('pageContext must be a JSON object');\n if (Object.hasOwn(page, 'kind') && typeof page.kind !== 'string')\n throw new TypeError('pageContext.kind must be a string');\n }\n }\n if (input.expiresAt !== null) checkTime(input.expiresAt);\n checkString(input.confirmation?.title);\n checkString(input.confirmation?.verb);\n canonicalActionProposalJson(input);\n}\n\nexport function validateActionProposalListQuery(query: ListActionProposals = {}): number {\n const limit = query.limit === undefined ? 100 : query.limit;\n if (!Number.isInteger(limit) || limit < 1 || limit > 1000)\n throw new RangeError('limit must be an integer from 1 to 1000');\n if (\n query.decision !== undefined &&\n !['pending', 'approved', 'rejected', 'expired', 'superseded'].includes(query.decision)\n )\n throw new TypeError('Unsupported action proposal list decision');\n if (query.after !== undefined) {\n const after = query.after;\n if (\n typeof after !== 'object' ||\n after === null ||\n Array.isArray(after) ||\n Object.keys(after).some((key) => key !== 'createdAt' && key !== 'id')\n )\n throw new TypeError('Invalid action proposal cursor');\n checkTime(after.createdAt);\n checkString(after.id);\n if (after.id.length > 255) throw new TypeError('Action proposal cursor id is too long');\n }\n return limit;\n}\n\n/** Canonical JSON snapshots keep replay equality independent of object key insertion order. */\nexport function canonicalActionProposalJson(value: unknown): string {\n const ancestors = new Set<object>();\n const sort = (item: unknown): unknown => {\n if (item === null || typeof item === 'string' || typeof item === 'boolean') return item;\n if (typeof item === 'number' && Number.isFinite(item)) return item;\n if (typeof item !== 'object' || item === null || ancestors.has(item))\n throw new TypeError('Action proposals require finite, acyclic JSON values');\n const prototype = Object.getPrototypeOf(item);\n if (!Array.isArray(item) && prototype !== Object.prototype && prototype !== null)\n throw new TypeError('Action proposals require plain JSON objects');\n ancestors.add(item);\n const sorted = Array.isArray(item)\n ? Array.from(item, sort)\n : Object.fromEntries(\n Object.keys(item)\n .sort()\n .map((key) => [key, sort((item as Record<string, unknown>)[key])]),\n );\n ancestors.delete(item);\n return sorted;\n };\n return JSON.stringify(sort(value));\n}\nexport function snapshotActionProposal<T>(value: T): T {\n return JSON.parse(canonicalActionProposalJson(value)) as T;\n}\nexport function actionProposalScopeMatches(\n row: ActionProposalScope,\n scope: ActionProposalScope,\n): boolean {\n return (\n row.tenantRef === scope.tenantRef &&\n row.actorRef === scope.actorRef &&\n row.threadId === scope.threadId\n );\n}\nexport function initialActionProposal(input: CreateActionProposal, now: number): ActionProposal {\n validateActionProposalCreation(input);\n checkTime(now);\n return snapshotActionProposal({\n ...input,\n decision: 'pending',\n decisionAudit: null,\n execution: null,\n createdAt: now,\n updatedAt: now,\n });\n}\nexport function actionProposalCreationMatches(\n row: ActionProposal,\n input: CreateActionProposal,\n): boolean {\n validateActionProposalCreation(input);\n const {\n decision: _decision,\n decisionAudit: _audit,\n execution: _execution,\n createdAt: _created,\n updatedAt: _updated,\n supersededBy: _supersededBy,\n outcome: _outcome,\n outcomeDelivery: _delivery,\n ...original\n } = row;\n return canonicalActionProposalJson(original) === canonicalActionProposalJson(input);\n}\nfunction result(\n status: ActionProposalMutationResult['status'],\n proposal: ActionProposal,\n): ActionProposalMutationResult {\n return { status, proposal: snapshotActionProposal(proposal) };\n}\nexport function transitionActionProposalDecision(\n row: ActionProposal,\n command: ActionProposalDecisionCommand,\n now: number,\n): ActionProposalMutationResult {\n checkTime(now);\n if (!['approved', 'rejected', 'expired'].includes(command.decision))\n throw new TypeError('Unsupported action proposal decision');\n checkString(command.actorRef);\n checkString(command.via);\n if (command.reason !== undefined && typeof command.reason !== 'string')\n throw new TypeError('reason must be a string');\n if (command.remember !== undefined && typeof command.remember !== 'boolean')\n throw new TypeError('remember must be a boolean');\n if (row.decision !== 'pending') {\n return result(\n row.decision === command.decision\n ? 'unchanged'\n : row.decision === 'expired'\n ? 'expired'\n : 'conflict',\n row,\n );\n }\n const next = snapshotActionProposal(row);\n if (row.expiresAt !== null && now >= row.expiresAt) {\n next.decision = 'expired';\n next.decisionAudit = { actorRef: 'system', via: 'expiry', at: now };\n next.updatedAt = now;\n return result(\n command.decision === 'expired' ? 'applied' : 'expired',\n attachActionProposalOutcome(next, now),\n );\n }\n if (command.decision === 'expired') return result('conflict', row);\n const { decision, ...audit } = command;\n next.decision = decision;\n next.decisionAudit = {\n actorRef: audit.actorRef,\n via: audit.via,\n at: now,\n ...(audit.reason === undefined ? {} : { reason: audit.reason }),\n ...(audit.remember === undefined ? {} : { remember: audit.remember }),\n };\n next.updatedAt = now;\n if (decision === 'approved') next.execution = { status: 'queued', generation: 0, lease: null };\n return result('applied', decision === 'approved' ? next : attachActionProposalOutcome(next, now));\n}\nfunction checkLeaseMs(leaseMs: number, now: number): void {\n checkTime(now);\n if (!Number.isSafeInteger(leaseMs) || leaseMs <= 0 || !Number.isSafeInteger(now + leaseMs))\n throw new RangeError('leaseMs must be finite and positive');\n}\nexport function transitionActionProposalClaim(\n row: ActionProposal,\n command: ClaimActionProposal,\n now: number,\n token: string,\n): ActionProposalMutationResult {\n checkLeaseMs(command.leaseMs, now);\n checkString(command.workerId);\n checkString(token);\n const execution = row.execution;\n if (\n row.decision !== 'approved' ||\n !execution ||\n (execution.status !== 'queued' &&\n !(execution.status === 'executing' && execution.lease && now >= execution.lease.expiresAt))\n )\n return result('conflict', row);\n const next = snapshotActionProposal(row);\n const generation = execution.generation + 1;\n next.execution = {\n status: 'executing',\n generation,\n lease: { token, generation, workerId: command.workerId, expiresAt: now + command.leaseMs },\n };\n next.updatedAt = now;\n return result('applied', next);\n}\nfunction leaseStatus(\n row: ActionProposal,\n command: { token: string; generation: number },\n now: number,\n): 'valid' | 'conflict' | 'expired' {\n checkTime(now);\n checkString(command.token);\n if (!Number.isSafeInteger(command.generation) || command.generation < 1)\n throw new RangeError('Invalid lease generation');\n const work = row.execution;\n if (\n row.decision !== 'approved' ||\n work?.status !== 'executing' ||\n !work.lease ||\n work.generation !== command.generation ||\n work.lease.generation !== command.generation ||\n work.lease.token !== command.token\n )\n return 'conflict';\n return now >= work.lease.expiresAt ? 'expired' : 'valid';\n}\nexport function transitionActionProposalLease(\n row: ActionProposal,\n command: ExtendActionProposalLease,\n now: number,\n): ActionProposalMutationResult {\n checkLeaseMs(command.leaseMs, now);\n const status = leaseStatus(row, command, now);\n if (status !== 'valid') return result(status, row);\n const next = snapshotActionProposal(row);\n if (next.execution?.lease)\n next.execution.lease.expiresAt = Math.max(\n next.execution.lease.expiresAt,\n now + command.leaseMs,\n );\n next.updatedAt = now;\n return result('applied', next);\n}\nexport function transitionActionProposalSettlement(\n row: ActionProposal,\n command: SettleActionProposal,\n now: number,\n): ActionProposalMutationResult {\n checkTime(now);\n if (command.status !== 'succeeded' && command.status !== 'failed')\n throw new TypeError('Unsupported settlement status');\n if (\n (command.status === 'succeeded' && command.error !== undefined) ||\n (command.status === 'failed' &&\n (typeof command.error !== 'string' || command.result !== undefined))\n )\n throw new TypeError('Ambiguous action proposal settlement');\n const status = leaseStatus(row, command, now);\n if (status !== 'valid') return result(status, row);\n const next = snapshotActionProposal(row);\n next.execution =\n command.status === 'succeeded'\n ? {\n status: 'succeeded',\n generation: command.generation,\n lease: null,\n ...(command.result === undefined ? {} : { result: command.result }),\n }\n : { status: 'failed', generation: command.generation, lease: null, error: command.error };\n if (command.ui !== undefined) canonicalActionProposalJson(command.ui);\n if (command.text !== undefined && typeof command.text !== 'string')\n throw new TypeError('Outcome text must be a string');\n next.updatedAt = now;\n return result('applied', attachActionProposalOutcome(next, now, command.ui, command.text));\n}\n\n/** Caller must obtain the replacement through the same full scope and persistence authority. */\nexport function transitionActionProposalSupersession(\n row: ActionProposal,\n replacement: ActionProposal,\n command: { replacementProposalId: string; actorRef: string; via: string },\n now: number,\n): ActionProposalMutationResult {\n checkTime(now);\n checkString(command.replacementProposalId);\n checkString(command.actorRef);\n checkString(command.via);\n if (\n replacement.id !== command.replacementProposalId ||\n row.id === replacement.id ||\n !actionProposalScopeMatches(row, replacement) ||\n row.toolName !== replacement.toolName ||\n !row.replacementKey ||\n row.replacementKey !== replacement.replacementKey\n )\n return result('conflict', row);\n if (row.decision === 'superseded')\n return result(row.supersededBy === replacement.id ? 'unchanged' : 'conflict', row);\n if (row.decision !== 'pending') return result('conflict', row);\n if (row.expiresAt !== null && now >= row.expiresAt)\n return {\n ...transitionActionProposalDecision(\n row,\n { decision: 'expired', actorRef: 'system', via: 'expiry' },\n now,\n ),\n status: 'expired',\n };\n const next = snapshotActionProposal({\n ...row,\n decision: 'superseded' as const,\n supersededBy: replacement.id,\n decisionAudit: {\n actorRef: command.actorRef,\n via: command.via,\n replacementProposalId: replacement.id,\n at: now,\n },\n updatedAt: now,\n });\n return result('applied', attachActionProposalOutcome(next, now));\n}\n","/**\n * Optional builtin component DEFINITIONS — names, props schemas, model descriptions and plain-text\n * fallbacks for the components most chat apps want. No visuals: an app renders each with its own\n * look, keyed by name. Use them as-is, pick some, or extend them:\n *\n * ```ts\n * const catalog = defineCatalog([...BUILTIN_COMPONENTS, ...LAYOUT_COMPONENTS, myDealCard]);\n * ```\n */\nimport { type ComponentDefinition, defineComponent } from './catalog.js';\nimport type { JsonSchema } from './schema.js';\n\ntype Props = Record<string, any>;\n\nconst str = (description?: string, extra: JsonSchema = {}): JsonSchema => ({\n type: 'string',\n ...(description !== undefined ? { description } : {}),\n ...extra,\n});\nconst obj = (properties: Record<string, JsonSchema>, required: string[] = []): JsonSchema => ({\n type: 'object',\n properties,\n required,\n additionalProperties: false,\n});\nconst arr = (items: JsonSchema, extra: JsonSchema = {}): JsonSchema => ({\n type: 'array',\n items,\n ...extra,\n});\nconst cell: JsonSchema = { type: ['string', 'number', 'boolean', 'null'] };\nconst row: JsonSchema = { type: 'object', additionalProperties: cell };\n\nconst s = (value: unknown): string => (value === null || value === undefined ? '' : String(value));\nconst heading = (props: Props): string => (props.title ? `*${s(props.title)}*\\n` : '');\n\n/** A fixed-width text table in a code block, at most `max` rows. */\nexport function textTable(\n columns: readonly { key: string; label: string }[],\n rows: readonly Props[],\n max = 15,\n): string {\n const shown = rows.slice(0, max);\n const widths = columns.map((column) =>\n Math.min(28, Math.max(column.label.length, ...shown.map((r) => s(r[column.key]).length))),\n );\n const format = (values: string[]) =>\n values\n .map((value, index) => value.slice(0, widths[index]).padEnd(widths[index] ?? 0))\n .join(' ');\n const lines = [\n format(columns.map((column) => column.label)),\n widths.map((width) => '-'.repeat(width)).join(' '),\n ...shown.map((r) => format(columns.map((column) => s(r[column.key])))),\n ];\n if (rows.length > max) lines.push(`… ${rows.length - max} more rows`);\n return `\\`\\`\\`\\n${lines.join('\\n')}\\n\\`\\`\\``;\n}\n\nexport interface DiffLine {\n op: 'same' | 'add' | 'del';\n text: string;\n}\n\n/** Line diff (LCS) — good enough for snippets up to a few hundred lines. */\nexport function lineDiff(before: string, after: string): DiffLine[] {\n const a = before.split('\\n');\n const b = after.split('\\n');\n if (a.length * b.length > 250_000) {\n return [\n ...a.map((text) => ({ op: 'del' as const, text })),\n ...b.map((text) => ({ op: 'add' as const, text })),\n ];\n }\n const dp: number[][] = Array.from({ length: a.length + 1 }, () =>\n new Array<number>(b.length + 1).fill(0),\n );\n const at = (i: number, j: number): number => dp[i]?.[j] ?? 0;\n for (let i = a.length - 1; i >= 0; i--) {\n for (let j = b.length - 1; j >= 0; j--) {\n (dp[i] as number[])[j] =\n a[i] === b[j] ? at(i + 1, j + 1) + 1 : Math.max(at(i + 1, j), at(i, j + 1));\n }\n }\n const out: DiffLine[] = [];\n let i = 0;\n let j = 0;\n while (i < a.length && j < b.length) {\n if (a[i] === b[j]) {\n out.push({ op: 'same', text: a[i] as string });\n i++;\n j++;\n } else if (at(i + 1, j) >= at(i, j + 1)) {\n out.push({ op: 'del', text: a[i++] as string });\n } else {\n out.push({ op: 'add', text: b[j++] as string });\n }\n }\n while (i < a.length) out.push({ op: 'del', text: a[i++] as string });\n while (j < b.length) out.push({ op: 'add', text: b[j++] as string });\n return out;\n}\n\nfunction bar(value: number, max: number, width = 20): string {\n const n = max > 0 ? Math.round((Math.abs(value) / max) * width) : 0;\n return '█'.repeat(n) || '▏';\n}\n\nexport const DataTable = defineComponent<Props>({\n name: 'DataTable',\n title: 'Data table',\n description:\n 'Tabular data (records with the same fields) as a sortable table. Prefer it over markdown tables for more than 3 rows.',\n props: obj(\n {\n title: str('Short caption'),\n columns: arr(\n obj(\n {\n key: str('Field name in each row'),\n label: str('Column header'),\n align: str(undefined, { enum: ['left', 'right', 'center'] }),\n format: str('How to format values', {\n enum: ['text', 'number', 'currency', 'percent', 'date', 'link'],\n }),\n },\n ['key', 'label'],\n ),\n { minItems: 1, maxItems: 12 },\n ),\n rows: arr(row, { maxItems: 500 }),\n },\n ['columns', 'rows'],\n ),\n fallbackText: (props) => `${heading(props)}${textTable(props.columns ?? [], props.rows ?? [])}`,\n});\n\nexport const Chart = defineComponent<Props>({\n name: 'Chart',\n title: 'Chart',\n description:\n '`bar` to compare categories, `line` for a trend over time. `data` is a list of points; `xKey` names the category/time field and each series names a numeric field.',\n props: obj(\n {\n type: str('Chart type', { enum: ['bar', 'line'] }),\n title: str(),\n xKey: str('Field of each point used for the x axis'),\n series: arr(obj({ key: str('Numeric field'), label: str() }, ['key']), {\n minItems: 1,\n maxItems: 6,\n }),\n data: arr(row, { minItems: 1, maxItems: 200 }),\n unit: str('Unit shown after values, e.g. `KB` or `%`'),\n },\n ['type', 'xKey', 'series', 'data'],\n ),\n fallbackText: (props) => chartText(props),\n});\n\n/**\n * A chart as text. `line` → a table (x, then one column per series), which keeps every value\n * readable; `bar` → one bar per point, and per series when there are several, all on one scale so\n * bars of different series compare.\n */\nfunction chartText(props: Props): string {\n const series: { key: string; label?: string }[] = (props.series ?? []).filter(\n (each: unknown) => typeof (each as { key?: unknown })?.key === 'string',\n );\n const data: Props[] = props.data ?? [];\n const unit = props.unit ? ` ${s(props.unit)}` : '';\n const labelOf = (each: { key: string; label?: string }) => s(each.label) || each.key;\n if (props.type === 'line') {\n const columns = [\n { key: s(props.xKey), label: s(props.xKey) },\n ...series.map((each) => ({ key: each.key, label: `${labelOf(each)}${unit}` })),\n ];\n return `${heading(props)}${textTable(columns, data, 20)}`;\n }\n const max = Math.max(\n 0,\n ...data.flatMap((point) => series.map((each) => Math.abs(Number(point[each.key]) || 0))),\n );\n const shown = data.slice(0, 20);\n const lines: string[] = [];\n if (series.length <= 1) {\n const key = series[0]?.key ?? '';\n for (const point of shown) {\n lines.push(\n `${s(point[props.xKey]).slice(0, 18).padEnd(18)} ${bar(Number(point[key]) || 0, max)} ${s(point[key])}${unit}`,\n );\n }\n } else {\n const width = Math.min(18, Math.max(...series.map((each) => labelOf(each).length)));\n for (const point of shown) {\n lines.push(s(point[props.xKey]).slice(0, 18));\n for (const each of series) {\n lines.push(\n ` ${labelOf(each).slice(0, width).padEnd(width)} ${bar(Number(point[each.key]) || 0, max)} ${s(point[each.key])}${unit}`,\n );\n }\n }\n }\n if (data.length > shown.length) lines.push(`… ${data.length - shown.length} more points`);\n return `${heading(props)}\\`\\`\\`\\n${lines.join('\\n')}\\n\\`\\`\\``;\n}\n\nexport const KpiCards = defineComponent<Props>({\n name: 'KpiCards',\n title: 'KPI cards',\n description: 'A few key numbers (metrics, totals, counts) as cards.',\n props: obj(\n {\n title: str(),\n items: arr(\n obj(\n {\n label: str(),\n value: { type: ['string', 'number'] },\n delta: str('Change, e.g. `+12%`'),\n trend: str(undefined, { enum: ['up', 'down', 'flat'] }),\n hint: str(),\n },\n ['label', 'value'],\n ),\n { minItems: 1, maxItems: 8 },\n ),\n },\n ['items'],\n ),\n fallbackText: (props) =>\n `${heading(props)}${(props.items ?? [])\n .map(\n (item: Props) =>\n `• *${s(item.label)}:* ${s(item.value)}${item.delta ? ` (${s(item.delta)})` : ''}`,\n )\n .join('\\n')}`,\n});\n\nexport const SourceCards = defineComponent<Props>({\n name: 'SourceCards',\n title: 'Sources',\n description: 'The documents, pages or links an answer is based on, as cards.',\n props: obj(\n {\n title: str(),\n items: arr(\n obj({ title: str(), url: str(), snippet: str(), source: str('e.g. Wiki, GitHub') }, [\n 'title',\n ]),\n { minItems: 1, maxItems: 12 },\n ),\n },\n ['items'],\n ),\n fallbackText: (props) =>\n `${heading(props)}${(props.items ?? [])\n .map(\n (item: Props) =>\n `• ${item.url ? `<${s(item.url)}|${s(item.title)}>` : s(item.title)}${item.source ? ` — ${s(item.source)}` : ''}`,\n )\n .join('\\n')}`,\n});\n\nexport const Checklist = defineComponent<Props>({\n name: 'Checklist',\n title: 'Checklist',\n description: 'Steps or a to-do list with done/not-done state.',\n props: obj(\n {\n title: str(),\n items: arr(obj({ label: str(), done: { type: 'boolean' }, note: str() }, ['label']), {\n minItems: 1,\n maxItems: 50,\n }),\n },\n ['items'],\n ),\n fallbackText: (props) =>\n `${heading(props)}${(props.items ?? [])\n .map(\n (item: Props) =>\n `${item.done ? '☑' : '☐'} ${s(item.label)}${item.note ? ` — _${s(item.note)}_` : ''}`,\n )\n .join('\\n')}`,\n});\n\nexport const Timeline = defineComponent<Props>({\n name: 'Timeline',\n title: 'Timeline',\n description: 'Events in chronological order (the history of a project, an incident, a deal).',\n props: obj(\n {\n title: str(),\n events: arr(obj({ date: str(), title: str(), description: str() }, ['title']), {\n minItems: 1,\n maxItems: 50,\n }),\n },\n ['events'],\n ),\n fallbackText: (props) =>\n `${heading(props)}${(props.events ?? [])\n .map(\n (event: Props) =>\n `• ${event.date ? `*${s(event.date)}* ` : ''}${s(event.title)}${event.description ? ` — ${s(event.description)}` : ''}`,\n )\n .join('\\n')}`,\n});\n\nexport const CodeBlock = defineComponent<Props>({\n name: 'CodeBlock',\n title: 'Code',\n description: 'A code snippet or file excerpt with syntax highlighting.',\n props: obj({ title: str(), language: str(), code: str() }, ['code']),\n fallbackText: (props) => `${heading(props)}\\`\\`\\`\\n${s(props.code)}\\n\\`\\`\\``,\n});\n\nexport const Diff = defineComponent<Props>({\n name: 'Diff',\n title: 'Diff',\n description: 'A before/after change to a text or code file, as a line diff.',\n props: obj({ title: str(), language: str(), before: str(), after: str() }, ['before', 'after']),\n fallbackText: (props) =>\n `${heading(props)}\\`\\`\\`\\n${lineDiff(s(props.before), s(props.after))\n .map((line) => `${line.op === 'add' ? '+' : line.op === 'del' ? '-' : ' '} ${line.text}`)\n .join('\\n')}\\n\\`\\`\\``,\n});\n\nexport const Callout = defineComponent<Props>({\n name: 'Callout',\n title: 'Callout',\n description: 'A short note, warning or success message, emphasized.',\n props: obj(\n {\n tone: str(undefined, { enum: ['info', 'success', 'warning', 'danger'] }),\n title: str(),\n text: str(),\n },\n ['text'],\n ),\n fallbackText: (props) =>\n `${props.tone === 'warning' || props.tone === 'danger' ? ':warning: ' : ':information_source: '}${heading(props)}${s(props.text)}`,\n});\n\nexport const Stack = defineComponent<Props>({\n name: 'Stack',\n title: 'Stack',\n description: 'Lays its children out vertically (or horizontally with direction=row).',\n props: obj({ direction: str(undefined, { enum: ['column', 'row'] }), gap: { type: 'number' } }),\n children: true,\n fallbackText: () => '',\n});\n\nexport const Card = defineComponent<Props>({\n name: 'Card',\n title: 'Card',\n description: 'A box with an optional title around its children.',\n props: obj({ title: str(), subtitle: str() }),\n children: true,\n fallbackText: (props) =>\n props.title ? `*${s(props.title)}*${props.subtitle ? ` — ${s(props.subtitle)}` : ''}` : '',\n});\n\nexport const Heading = defineComponent<Props>({\n name: 'Heading',\n title: 'Heading',\n description: 'A heading.',\n props: obj({ text: str() }, ['text']),\n fallbackText: (props) => `*${s(props.text)}*`,\n});\n\nexport const Text = defineComponent<Props>({\n name: 'Text',\n title: 'Text',\n description: 'A paragraph of plain text (no markdown).',\n props: obj({ text: str(), muted: { type: 'boolean' } }, ['text']),\n fallbackText: (props) => s(props.text),\n});\n\nexport const Badge = defineComponent<Props>({\n name: 'Badge',\n title: 'Badge',\n description: 'A small label.',\n props: obj(\n {\n text: str(),\n tone: str(undefined, { enum: ['neutral', 'brand', 'success', 'warning', 'danger'] }),\n },\n ['text'],\n ),\n fallbackText: (props) => `[${s(props.text)}]`,\n});\n\nexport const Link = defineComponent<Props>({\n name: 'Link',\n title: 'Link',\n description: 'A link to an http(s) URL.',\n props: obj({ text: str(), url: str(undefined, { pattern: '^https?://' }) }, ['text', 'url']),\n fallbackText: (props) => `<${s(props.url)}|${s(props.text || props.url)}>`,\n});\n\nexport const Image = defineComponent<Props>({\n name: 'Image',\n title: 'Image',\n description: 'An image from an https URL.',\n props: obj({ url: str(undefined, { pattern: '^https://' }), alt: str() }, ['url']),\n fallbackText: (props) => s(props.url),\n});\n\n/** Content components: data a model shows. */\nexport const BUILTIN_COMPONENTS: readonly ComponentDefinition<Props>[] = [\n DataTable,\n Chart,\n KpiCards,\n SourceCards,\n Checklist,\n Timeline,\n CodeBlock,\n Diff,\n Callout,\n];\n\n/** Layout and text primitives, mostly for composing trees (`Stack`, `Card` take children). */\nexport const LAYOUT_COMPONENTS: readonly ComponentDefinition<Props>[] = [\n Stack,\n Card,\n Heading,\n Text,\n Badge,\n Link,\n Image,\n];\n","import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { Chart, DataTable } from './builtins.js';\nimport {\n type Catalog,\n type CatalogOptions,\n type ComponentDefinition,\n defineCatalog,\n defineComponent,\n} from './catalog.js';\nimport { type JsonSchema, formatIssues, validateProps } from './schema.js';\nimport { componentToText } from './text.js';\n\n/** Plain, durable data. Renderer functions and binary attachments never enter a UI frame. */\nexport interface ComponentPresentation<P = Record<string, unknown>> {\n component: string;\n props: P;\n version: number;\n fallbackText: string;\n}\n\nexport interface ComponentFactory<Input, Output = Input> {\n (props: Input): Promise<ComponentPresentation<Output>>;\n readonly definition: ComponentDefinition<Output>;\n}\n\n/** Reject values JSON would silently discard/coerce, and detach from caller-owned objects. */\nexport function snapshotComponentPresentation<T>(value: T): T {\n const seen = new Set<object>();\n const check = (entry: unknown): void => {\n if (entry === null || typeof entry === 'string' || typeof entry === 'boolean') return;\n if (typeof entry === 'number' && Number.isFinite(entry)) return;\n if (typeof entry !== 'object' || entry === null)\n throw new TypeError('genui: presentation must contain only JSON values');\n if (seen.has(entry))\n throw new TypeError('genui: presentation must contain acyclic JSON values');\n if (\n !Array.isArray(entry) &&\n Object.getPrototypeOf(entry) !== Object.prototype &&\n Object.getPrototypeOf(entry) !== null\n )\n throw new TypeError('genui: presentation must contain plain JSON objects');\n seen.add(entry);\n for (const item of Object.values(entry)) check(item);\n seen.delete(entry);\n };\n check(value);\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nexport function createComponent<S extends StandardSchemaV1>(\n definition: Omit<ComponentDefinition<StandardSchemaV1.InferOutput<S>>, 'props'> & { props: S },\n options?: CatalogOptions,\n): ComponentFactory<StandardSchemaV1.InferInput<S>, StandardSchemaV1.InferOutput<S>>;\nexport function createComponent<P = Record<string, unknown>>(\n definition: ComponentDefinition<P>,\n options?: CatalogOptions,\n): ComponentFactory<P>;\nexport function createComponent<P>(\n definition: ComponentDefinition<P>,\n options: CatalogOptions = {},\n): unknown {\n defineComponent(definition);\n const catalog = defineCatalog([definition], options);\n const factory = async (props: unknown): Promise<ComponentPresentation> => {\n const result = await validateProps(definition.props, props, catalog.validator);\n if (!result.ok)\n throw new Error(`genui: invalid ${definition.name} props: ${formatIssues(result.issues)}`);\n const normalized = snapshotComponentPresentation(result.value);\n if (typeof normalized !== 'object' || normalized === null || Array.isArray(normalized))\n throw new TypeError('genui: component props must be a JSON object');\n const portable = await catalog.validate(definition.name, normalized);\n if (\n !portable.ok ||\n canonicalJson(snapshotComponentPresentation(portable.value)) !== canonicalJson(normalized)\n ) {\n throw new Error(\n `genui: ${definition.name} requires outputProps accepting stable normalized JSON props`,\n );\n }\n return {\n component: definition.name,\n props: normalized as Record<string, unknown>,\n version: definition.version ?? 1,\n fallbackText: componentToText(\n catalog,\n definition.name,\n normalized as Record<string, unknown>,\n ),\n };\n };\n return Object.assign(factory, { definition });\n}\n\nexport type ComponentRenderer<P = Record<string, unknown>, Context = unknown> = (\n props: P,\n context?: Context,\n) => unknown | Promise<unknown>;\n\nexport interface ComponentManifest {\n name: string;\n title: string;\n description: string;\n version: number;\n props?: JsonSchema;\n}\n\nexport interface ComponentRegistry<Context = unknown> {\n readonly catalog: Catalog;\n readonly manifest: readonly ComponentManifest[];\n register<P>(\n definition: ComponentDefinition<P>,\n renderers: Record<string, ComponentRenderer<P, Context>>,\n ): this;\n /** Revalidate against the app's authoritative definition and regenerate trusted fallback text. */\n prepare(presentation: ComponentPresentation): Promise<ComponentPresentation>;\n render(presentation: ComponentPresentation, channel: string, context?: Context): Promise<unknown>;\n}\n\n/** A registry is owned by one app/tenant; registering never mutates a shared singleton. */\nexport function createComponentRegistry<Context = unknown>(\n options: CatalogOptions = {},\n): ComponentRegistry<Context> {\n let catalog = defineCatalog([], options);\n const channels = new Map<string, Record<string, ComponentRenderer<never, Context>>>();\n const registry: ComponentRegistry<Context> = {\n get catalog() {\n return catalog;\n },\n get manifest() {\n return catalog.components.map((definition) => {\n const props = catalog.jsonSchemaFor(definition.name);\n return {\n name: definition.name,\n title: definition.title,\n description: definition.description,\n version: definition.version ?? 1,\n ...(props === undefined ? {} : { props: snapshotComponentPresentation(props) }),\n };\n });\n },\n register(definition, renderers) {\n if (catalog.has(definition.name))\n throw new Error(`genui: component \"${definition.name}\" is already registered`);\n catalog = catalog.extend([definition]);\n channels.set(definition.name, { ...renderers } as Record<\n string,\n ComponentRenderer<never, Context>\n >);\n return this;\n },\n async prepare(presentation) {\n const definition = catalog.get(presentation.component);\n if (definition === undefined)\n throw new Error(`genui: unknown component \"${presentation.component}\"`);\n if (presentation.version !== (definition.version ?? 1))\n throw new Error(`genui: component \"${presentation.component}\" version mismatch`);\n const validated = await catalog.validate(presentation.component, presentation.props);\n if (!validated.ok)\n throw new Error(\n `genui: invalid ${presentation.component} props: ${formatIssues(validated.issues)}`,\n );\n const props = snapshotComponentPresentation(validated.value);\n if (typeof props !== 'object' || props === null || Array.isArray(props))\n throw new TypeError('genui: component props must be a JSON object');\n return {\n component: definition.name,\n props,\n version: definition.version ?? 1,\n fallbackText: componentToText(catalog, definition.name, props),\n };\n },\n async render(presentation, channel, context) {\n const prepared = await this.prepare(presentation);\n const mapping = channels.get(prepared.component);\n const renderer =\n mapping === undefined\n ? undefined\n : Object.hasOwn(mapping, channel)\n ? mapping[channel]\n : Object.hasOwn(mapping, 'text')\n ? mapping.text\n : undefined;\n return renderer === undefined\n ? prepared.fallbackText\n : renderer(prepared.props as never, context);\n },\n };\n return registry;\n}\n\nexport type TableCell = string | number | boolean | null;\nexport interface TableProps {\n title?: string;\n columns: {\n key: string;\n label: string;\n align?: 'left' | 'right' | 'center';\n format?: 'text' | 'number' | 'currency' | 'percent' | 'date' | 'link';\n }[];\n rows: Record<string, TableCell>[];\n}\nexport interface ChartProps {\n type: 'bar' | 'line';\n title?: string;\n xKey: string;\n series: { key: string; label?: string }[];\n data: Record<string, TableCell>[];\n unit?: string;\n}\n\nexport const table = createComponent<TableProps>(DataTable);\nexport const chart = createComponent<ChartProps>(Chart);\n\n/** Prepare all JSON emissions before any sink receives a partial batch. Factories validate schemas. */\nexport function validatePresentationBatch(\n presentations: ComponentPresentation<object> | readonly ComponentPresentation<object>[],\n): ComponentPresentation[] {\n const batch = Array.isArray(presentations) ? presentations : [presentations];\n return batch.map((item: ComponentPresentation<object>) => {\n const presentation = snapshotComponentPresentation(item);\n if (\n typeof presentation !== 'object' ||\n presentation === null ||\n typeof presentation.component !== 'string' ||\n !/^[A-Za-z][A-Za-z0-9]{0,63}$/.test(presentation.component) ||\n !Number.isSafeInteger(presentation.version) ||\n presentation.version <= 0 ||\n typeof presentation.fallbackText !== 'string' ||\n typeof presentation.props !== 'object' ||\n presentation.props === null ||\n Array.isArray(presentation.props)\n ) {\n throw new TypeError('genui: invalid component presentation');\n }\n return presentation as ComponentPresentation;\n });\n}\n\n/** Object order is immaterial; array order remains part of the portable contract. */\nfunction canonicalJson(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(canonicalJson).join(',')}]`;\n if (typeof value === 'object' && value !== null) {\n const record = value as Record<string, unknown>;\n return `{${Object.keys(record)\n .sort()\n .map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`)\n .join(',')}}`;\n }\n return JSON.stringify(value);\n}\n","import { validatePresentationBatch } from './genui/registry.js';\nimport type { AiToolCtx, ToolHandler } from './spi/tool.js';\n\n/** Presentation failures must never cause a successful side effect to be retried. */\nexport async function emitToolPresentations<I, O>(\n handler: ToolHandler<I, O>,\n output: O,\n ctx: AiToolCtx,\n toolName: string,\n): Promise<void> {\n if (handler.present === undefined) return;\n try {\n const result = await handler.present(output, ctx);\n if (result === undefined) return;\n const batch = validatePresentationBatch(result);\n for (const presentation of batch) {\n await ctx.emitUi(presentation.component, presentation.props, {\n version: presentation.version,\n fallbackText: presentation.fallbackText,\n });\n }\n } catch (error) {\n if (ctx.onPresentationError !== undefined) {\n try {\n await ctx.onPresentationError(error, { toolName });\n return;\n } catch (reportError) {\n console.warn(`Tool \"${toolName}\" presentation error reporter failed`, reportError);\n }\n } else {\n console.warn(`Tool \"${toolName}\" presentation failed after successful execution`, error);\n }\n }\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport {\n canonicalActionProposalJson,\n snapshotActionProposal,\n} from './action-proposal-transitions.js';\nimport type { RolesPolicy } from './spi/roles-policy.js';\nimport type { AiToolCtx, ToolDescribeScope, ToolHandler, ToolPreflightResult } from './spi/tool.js';\nimport {\n canActorUseTool,\n filterToolsByAllowList,\n filterToolsByCanUse,\n filterToolsByEnabled,\n filterToolsByRole,\n isToolEnabled,\n} from './tool-filters.js';\nimport { emitToolPresentations } from './tool-presentations.js';\nimport { createNoopEmitUi } from './tool-ui.js';\nimport type { Actor, ToolDefinition, ToolSpec } from './types.js';\n\n/** Thrown when an actor invokes a tool their role is not allowed. */\nexport class ToolForbiddenError extends Error {\n constructor(public readonly toolName: string) {\n super(`Tool \"${toolName}\" is not allowed for this role`);\n this.name = 'ToolForbiddenError';\n }\n}\n\n/**\n * Thrown when a registered tool is invoked while this deployment has it turned off (`enabled` /\n * `isEnabled()`). Distinct from {@link ToolForbiddenError}, which is about the actor, and from\n * {@link ToolNotFoundError}, which is about a name nobody registered — an operator reading a log\n * needs to tell \"you flipped the flag\" apart from \"that tool does not exist in this build\".\n *\n * Reachable in normal operation, not just from a forged call: a HITL `action` approved before the\n * flag was turned off runs its tool afterwards.\n */\nexport class ToolDisabledError extends Error {\n constructor(public readonly toolName: string) {\n super(`Tool \"${toolName}\" is disabled in this deployment`);\n this.name = 'ToolDisabledError';\n }\n}\n\n/** Thrown when a tool is invoked that was never registered. */\nexport class ToolNotFoundError extends Error {\n constructor(public readonly toolName: string) {\n super(`Tool \"${toolName}\" is not registered`);\n this.name = 'ToolNotFoundError';\n }\n}\n\n/** Thrown when a tool's input fails its Standard Schema validation. */\nexport class ToolInputInvalidError extends Error {\n constructor(\n public readonly toolName: string,\n public readonly issues: readonly StandardSchemaV1.Issue[],\n ) {\n super(\n `Invalid input for tool \"${toolName}\": ${issues.map((issue) => issue.message).join('; ')}`,\n );\n this.name = 'ToolInputInvalidError';\n }\n}\n\n/** An action refused by its current domain state, rather than by a person. */\nexport class ToolPreflightDeniedError extends Error {\n constructor(\n public readonly toolName: string,\n public readonly reason: string,\n ) {\n super(reason);\n this.name = 'ToolPreflightDeniedError';\n }\n}\n\n/** Trusted preparation or a fresh schema parse changed the approved JSON input. */\nexport class ToolInputDriftError extends Error {\n constructor(public readonly toolName: string) {\n super(`Tool \"${toolName}\" input differs from its trusted snapshot`);\n this.name = 'ToolInputDriftError';\n }\n}\n\nfunction assertTrustedInput(name: string, value: unknown, approved: unknown): void {\n try {\n if (canonicalActionProposalJson(value) === canonicalActionProposalJson(approved)) return;\n } catch {\n // A non-JSON value cannot match a trusted JSON snapshot, including an explicitly undefined\n // approvedInput. Ordinary invocations never serialize the schema's parsed value.\n }\n throw new ToolInputDriftError(name);\n}\n\ninterface Entry {\n spec: ToolSpec;\n handler: ToolHandler;\n}\n\n/**\n * Holds every registered tool and gates invocation.\n *\n * Note: `definitionsFor` returns NEUTRAL definitions (no `execute`). The agent loop runs\n * each tool itself as a (durable) step — so even read tools are not auto-executed by the\n * model. `action` tools additionally require HITL approval before the loop runs them.\n */\nexport class ToolRegistry {\n private readonly entries = new Map<string, Entry>();\n\n register(spec: ToolSpec, handler: ToolHandler): void {\n this.entries.set(spec.name, { spec, handler });\n }\n\n /** Whether a successful preflight shortcut has UI to journal. */\n hasPresentation(name: string): boolean {\n return typeof this.entries.get(name)?.handler.present === 'function';\n }\n\n /** Present an already authorized successful domain result without executing its action again. */\n async presentOutput(name: string, output: unknown, ctx: AiToolCtx): Promise<void> {\n const entry = this.entries.get(name);\n if (entry !== undefined) await emitToolPresentations(entry.handler, output, ctx, name);\n }\n\n has(name: string): boolean {\n return this.entries.has(name);\n }\n\n /**\n * Give a name back, and report whether it was held. For an importer that registered tools on\n * someone else's behalf — the MCP client is the one in this repo — and has to hand back the ones\n * its source stopped offering.\n *\n * The registry cannot tell whether a caller owns a name, so it does not try: whoever registered a\n * name is responsible for tracking that it did. Unregistering a name it does not own would\n * silently take a tool away from whoever does.\n */\n unregister(name: string): boolean {\n return this.entries.delete(name);\n }\n\n spec(name: string): ToolSpec | undefined {\n return this.entries.get(name)?.spec;\n }\n\n allSpecs(): ToolSpec[] {\n return [...this.entries.values()].map((entry) => entry.spec);\n }\n\n /**\n * The tools to offer the model for this actor+agent, after the four filter layers: what this\n * agent pinned, what this deployment has enabled, what this actor's role allows, and what each\n * tool's own `canUse` allows this actor.\n *\n * Every layer only ever removes tools, so no arrangement of them can widen what a turn reaches.\n * The agent's allow-list therefore goes FIRST, even though it is the narrowest statement: it is a\n * pure name-set match, while each of the three below it may be a round trip — an authz service, a\n * feature-flag store, an MCP server — and this runs once per model step. Asking those about a\n * tool the allow-list has already excluded is a call whose answer nothing reads.\n */\n async definitionsFor(\n actor: Actor,\n policy: RolesPolicy,\n allowedTools?: string[],\n scope: Omit<ToolDescribeScope, 'actor'> = {},\n ): Promise<ToolDefinition[]> {\n const visible = await this.visibleEntries(actor, policy, allowedTools);\n const definitions = await Promise.all(\n visible.map(async ({ spec, handler }) => {\n // After every gate: a tool this actor cannot reach is never asked to describe itself.\n const override =\n handler.describe === undefined ? undefined : await handler.describe({ actor, ...scope });\n if (override?.available === false) return null;\n return {\n name: spec.name,\n kind: spec.kind,\n description: override?.description ?? spec.description,\n inputSchema: override?.inputSchema ?? spec.inputSchema,\n };\n }),\n );\n return definitions.filter((definition): definition is ToolDefinition => definition !== null);\n }\n\n /**\n * The specs {@link definitionsFor} offers the model, whole — the same four gates (allow-list,\n * enabled, role, `canUse`) in the same order. For a surface that lists what an actor can reach\n * (`GET <base>/tools`), which must never disagree with what the model is actually shown.\n */\n async visibleSpecs(\n actor: Actor,\n policy: RolesPolicy,\n allowedTools?: string[],\n ): Promise<ToolSpec[]> {\n return (await this.visibleEntries(actor, policy, allowedTools)).map(({ spec }) => spec);\n }\n\n private async visibleEntries(\n actor: Actor,\n policy: RolesPolicy,\n allowedTools?: string[],\n ): Promise<Entry[]> {\n const pinnedNames = new Set(\n filterToolsByAllowList(this.allSpecs(), allowedTools).map((spec) => spec.name),\n );\n const pinned = [...this.entries.values()].filter((entry) => pinnedNames.has(entry.spec.name));\n const live = await filterToolsByEnabled(pinned);\n const allowedByRole = new Set(\n (\n await filterToolsByRole(\n live.map((entry) => entry.spec),\n actor,\n policy,\n )\n ).map((spec) => spec.name),\n );\n const roleScoped = live.filter((entry) => allowedByRole.has(entry.spec.name));\n return filterToolsByCanUse(roleScoped, actor);\n }\n\n /**\n * Run a tool. Re-checks that the tool is enabled and that the role allows it (defense-in-depth —\n * a call can reach here from a replayed durable step or an approval granted before the flag\n * moved, neither of which went through `definitionsFor` again) and re-parses the input via Zod.\n */\n async invoke(\n name: string,\n input: unknown,\n ctx: AiToolCtx,\n policy: RolesPolicy,\n options: InvokeOptions = {},\n ): Promise<unknown> {\n const { entry, value, ctx: withEmit } = await this.validated(name, input, ctx, policy, options);\n const trusted = Object.hasOwn(options, 'approvedInput');\n if (trusted) assertTrustedInput(name, value, options.approvedInput);\n const executionInput = trusted ? snapshotActionProposal(value) : value;\n const hookInput = trusted ? snapshotActionProposal(executionInput) : value;\n const result =\n entry.spec.kind === 'action'\n ? await entry.handler.preflight?.(hookInput, withEmit, { phase: 'execute' })\n : undefined;\n // The hook receives its own snapshot, so retained references cannot alter later execution.\n if (trusted) assertTrustedInput(name, hookInput, executionInput);\n if (result?.status === 'denied') throw new ToolPreflightDeniedError(name, result.reason);\n const output =\n result?.status === 'completed'\n ? result.output\n : await entry.handler.execute(executionInput, withEmit);\n await emitToolPresentations(entry.handler, output, withEmit, name);\n return output;\n }\n\n /** Authorize and validate without executing. The caller journals this result before approval. */\n async prepare(\n name: string,\n input: unknown,\n ctx: AiToolCtx,\n policy: RolesPolicy,\n options: PrepareOptions = {},\n ): Promise<ToolPreflightResult> {\n return (await this.prepareValidated(name, input, ctx, policy, options)).preflight;\n }\n\n /** Expose the single schema parse; snapshotInput opts proposal callers into immutable JSON. */\n async prepareValidated(\n name: string,\n input: unknown,\n ctx: AiToolCtx,\n policy: RolesPolicy,\n options: PrepareOptions = {},\n ): Promise<ToolPreparationResult> {\n const { entry, value, ctx: withEmit } = await this.validated(name, input, ctx, policy, options);\n const normalized = options.snapshotInput === true ? snapshotActionProposal(value) : value;\n const hookInput = options.snapshotInput === true ? snapshotActionProposal(normalized) : value;\n const preflight: ToolPreflightResult = (entry.spec.kind === 'action'\n ? await entry.handler.preflight?.(hookInput, withEmit, { phase: 'prepare' })\n : undefined) ?? { status: 'ready' };\n // A hook can retain its input or mutate nested values after an await. Only the isolated\n // normalized snapshot can be approved; reject mutation before exposing its confirmation.\n if (options.snapshotInput === true) assertTrustedInput(name, hookInput, normalized);\n return { input: normalized, preflight };\n }\n\n private async validated(\n name: string,\n input: unknown,\n ctx: AiToolCtx,\n policy: RolesPolicy,\n options: InvokeOptions,\n ): Promise<{ entry: Entry; value: unknown; ctx: AiToolCtx }> {\n const entry = this.entries.get(name);\n if (entry === undefined) {\n throw new ToolNotFoundError(name);\n }\n if (!(await isToolEnabled(entry.spec, entry.handler))) {\n throw new ToolDisabledError(name);\n }\n if (!(await policy.can(ctx.actor, entry.spec))) {\n throw new ToolForbiddenError(name);\n }\n if (!(await canActorUseTool(ctx.actor, entry.handler))) {\n throw new ToolForbiddenError(name);\n }\n // Last, like the persona filter on the offer: the same layers in the same order, so a call the\n // model was never offered under this persona cannot run because the model named it anyway.\n if (options.allowedTools !== undefined && !options.allowedTools.includes(name)) {\n throw new ToolForbiddenError(name);\n }\n const validation = await entry.spec.inputSchema['~standard'].validate(input);\n if (validation.issues !== undefined) {\n throw new ToolInputInvalidError(name, validation.issues);\n }\n // `emitUi` is part of the context's contract; a caller without a conversation (a test, a script,\n // a JavaScript host) gets the no-op rather than a tool that crashes calling it.\n const withEmit: AiToolCtx =\n typeof ctx.emitUi === 'function' ? ctx : { ...ctx, emitUi: createNoopEmitUi(ctx.requestId) };\n return { entry, value: validation.value, ctx: withEmit };\n }\n}\n\n/** Per-call narrowing for {@link ToolRegistry.invoke}. */\nexport interface InvokeOptions {\n /**\n * Only these tool names may run — the turn's persona allow-list. Checked after `enabled`, the\n * roles policy and `canUse`. Undefined → no such check (every caller predating personas).\n */\n allowedTools?: readonly string[];\n /** Trusted normalized JSON input. Own-property presence requires comparison even if undefined. */\n approvedInput?: unknown;\n}\n\nexport interface PrepareOptions extends InvokeOptions {\n /** Preserve a detached normalized JSON snapshot and refuse mutation by the prepare hook. */\n snapshotInput?: boolean;\n}\n\nexport interface ToolPreparationResult {\n input: unknown;\n preflight: ToolPreflightResult;\n}\n\n/**\n * Default gate: a tool that names `roles` is callable by an actor holding one of them; a tool that\n * names none falls back to `defaultRoles`, and an empty list — the default — restricts nobody. So\n * out of the box every tool is callable by whoever the `ActorResolver` resolved (an anonymous\n * visitor included, when no resolver is configured); restrict with `@AiTool({ roles })` per tool,\n * `AgentModule.forRoot({ defaultRoles })` module-wide, or a `rolesPolicy` of your own. `action`\n * tools still park on approval either way.\n *\n * A tool gated by an `ability` and naming no `roles` is refused: this policy cannot evaluate an\n * ability, and falling through to the open default would hand the tool to everyone. Bind an\n * ability-aware policy (`AgentAuthzModule`) to reach it — or give the tool `roles` as well.\n */\nexport class DefaultRolesPolicy implements RolesPolicy {\n /** What an empty roles list means here — see {@link EmptyRoles}. */\n readonly emptyRoles: EmptyRoles;\n\n constructor(\n readonly defaultRoles: string[] = [],\n options: RolesPolicyOptions = {},\n ) {\n this.emptyRoles = options.emptyRoles ?? 'allow';\n }\n\n can(actor: Actor, tool: ToolSpec): boolean {\n if (tool.ability !== undefined && tool.roles === undefined) return false;\n const allowed = tool.roles ?? this.defaultRoles;\n if (allowed.length === 0) return this.emptyRoles === 'allow';\n return (actor.roles ?? []).some((role) => allowed.includes(role));\n }\n}\n\n/**\n * What an empty roles list means to {@link DefaultRolesPolicy}: `'allow'` (the default) — no\n * restriction; `'deny'` — nobody.\n *\n * The open default is what makes a one-line `AgentModule.forRoot({ model })` a working chat. It is\n * also why an app that used `[]` to DENY — a `roles` computed from permissions that can come out\n * empty, `defaultRoles: []` on a multi-tenant MCP surface — reaches everyone instead, silently.\n * `'deny'` keeps such an app closed.\n */\nexport type EmptyRoles = 'allow' | 'deny';\n\nexport interface RolesPolicyOptions {\n /** What an empty roles list means. Default `'allow'`. */\n emptyRoles?: EmptyRoles;\n}\n\n/**\n * The closed gate — {@link DefaultRolesPolicy} with `emptyRoles: 'deny'`: the actor needs a role the\n * tool declares (else one of the default roles). A tool with no `roles` and no default roles, or with\n * an explicitly empty list, reaches nobody. What `AgentModule.forRoot({ emptyRoles: 'deny' })` binds.\n */\nexport class ClosedRolesPolicy extends DefaultRolesPolicy {\n constructor(defaultRoles: string[] = []) {\n super(defaultRoles, { emptyRoles: 'deny' });\n }\n}\n\n/**\n * Close a policy you did not build: a tool whose roles come out empty — declared `[]`, or undeclared\n * with no default roles to fall back on — reaches nobody; anything else is the inner policy's call.\n *\n * The default roles are read off a {@link DefaultRolesPolicy}; any other inner policy keeps its own\n * defaults to itself, so for it an undeclared list counts as empty. A tool gated by `ability` has\n * nothing to do with roles and is always left to the inner policy. What the MCP server's\n * `emptyRoles: 'deny'` wraps the agent's shared policy in.\n */\nexport function closeEmptyRoles(inner: RolesPolicy): RolesPolicy {\n const defaults = inner instanceof DefaultRolesPolicy ? inner.defaultRoles : [];\n return {\n can(actor: Actor, tool: ToolSpec): boolean | Promise<boolean> {\n if (tool.ability === undefined && (tool.roles ?? defaults).length === 0) {\n return false;\n }\n return inner.can(actor, tool);\n },\n };\n}\n","import { createHash } from 'node:crypto';\nimport { trace } from '@dudousxd/nestjs-diagnostics';\nimport type { PayloadOf } from '@dudousxd/nestjs-diagnostics';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { resolveActionProposalApproval } from './action-proposal-approval.js';\nimport { prepareActionProposal } from './action-proposal-preparation.js';\nimport { type ActionApprovalMode, actionProposalReceipt } from './action-proposal-receipt.js';\nimport { isControlFlowSignal } from './control-flow.js';\nimport {\n type ToolCallOutcome,\n danglingToolCallIds,\n settleDanglingToolCalls,\n} from './dangling-tool-calls.js';\nimport {\n type DetachedDelegationReceipt,\n detachedDelivered,\n detachedStarted,\n} from './delegation.js';\nimport {\n type AgentSpanEvent,\n publishAgentDelegated,\n publishAgentMemoryResolved,\n publishAgentMemoryWritten,\n publishAgentMessage,\n publishAgentQuotaExceeded,\n publishAgentRetrieved,\n publishAgentRunFinished,\n publishAgentRunStarted,\n publishAgentSkillsResolved,\n publishAgentToolCall,\n publishAgentToolRetry,\n} from './diagnostics.js';\nimport {\n ASK_TOOL_NAME,\n type AgentIntake,\n DEFAULT_INTAKE_PREAMBLE,\n type ElicitationReply,\n type ElicitationRequest,\n type ElicitationResult,\n askInputSchema,\n askToolDefinition,\n normalizeElicitationReply,\n settleElicitation,\n} from './elicitation.js';\nimport { estimateCost } from './governance/compute.js';\nimport {\n type MemoryConfig,\n type MemoryDigest,\n type MemoryRecord,\n REMEMBER_TOOL_NAME,\n buildMemoryBlock,\n offerMemories,\n rememberInputSchema,\n withMemoryTool,\n writeMemory,\n} from './memory.js';\nimport { type ResolveToolUiCatalog, createNegotiatedUiCollector } from './negotiated-tool-ui.js';\nimport { findPersona, intersectAllowLists } from './personas.js';\nimport {\n createFrameBuffer,\n createIncrementalGate,\n gateFollowUps,\n gateTail,\n releaseGatedFrames,\n resolveGateLookback,\n resolveOutputGateMode,\n runInputProcessors,\n runOutputProcessors,\n} from './processors.js';\nimport { isReplayIntegrityError } from './replay-integrity.js';\nimport {\n SKILL_TOOL_NAME,\n type SkillContext,\n type SkillOffer,\n type SkillsConfig,\n buildSkillsBlock,\n loadSkill,\n offerSkills,\n skillInputSchema,\n withSkillTool,\n} from './skills.js';\nimport type {\n ActionProposalStore,\n ActionProposalSupersessionStore,\n} from './spi/action-proposal-store.js';\nimport type { AgentStore, ThreadTurnReader } from './spi/agent-store.js';\nimport {\n type ApprovalPolicy,\n type ApprovalRequirement,\n DefaultApprovalPolicy,\n} from './spi/approval-policy.js';\nimport type {\n HistoryPolicy,\n HistoryPolicyContext,\n HistorySelection,\n} from './spi/history-policy.js';\nimport { withSelectedModel } from './spi/model-catalog.js';\nimport type {\n BufferedModelTurnResult,\n ModelProvider,\n ModelTurnResult,\n} from './spi/model-provider.js';\nimport type { AgentPricingStore, CurrentModelPrice } from './spi/pricing-store.js';\nimport {\n type InputProcessor,\n type OutputProcessor,\n OutputRejectedError,\n type ProcessedPrompt,\n type ProcessorContext,\n} from './spi/processors.js';\nimport type { QuotaStore } from './spi/quota-store.js';\nimport type { Passage, Retriever } from './spi/retriever.js';\nimport type { RolesPolicy } from './spi/roles-policy.js';\nimport type { SinkWriter, StreamError } from './spi/token-stream-sink.js';\nimport type { AiToolCtx, ToolPreflightResult } from './spi/tool.js';\nimport {\n type AgentStreamEvent,\n type AgentUiComponent,\n encodeStreamEvent,\n} from './stream-events.js';\nimport {\n DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION,\n StructuredOutputError,\n repairInstruction,\n validateStructured,\n} from './structured-output.js';\nimport type { ToolRegistry } from './tool-registry.js';\nimport { invokeWithTransientRetry, resolveToolTransientRetryNumbers } from './tool-retry.js';\nimport type { ToolTransientRetrySetting } from './tool-retry.js';\nimport {\n createNoopEmitUi,\n createUiCollector,\n escapeUnsafeToolUiText,\n mergeUi,\n unwrapToolStepOutput,\n wrapToolPreflightDenied,\n wrapToolStepOutput,\n} from './tool-ui.js';\nimport { observeTurnFrames, withTurnFrames } from './turn-frames.js';\nimport type {\n AgentRunInput,\n Decision,\n HumanReply,\n LlmStepEnvelope,\n MessageUsage,\n ModelMessage,\n Persona,\n PromptBuilder,\n PromptContext,\n PromptContributor,\n StoredMessage,\n ToolCallRequest,\n ToolDefinition,\n ToolKind,\n ToolResult,\n ToolSpec,\n ToolStepCtx,\n ToolStepEnvelope,\n TurnPersona,\n} from './types.js';\n\nexport interface AgentLoopDeps<TOutput = unknown> {\n actionApprovalMode?: ActionApprovalMode;\n resolveUiCatalog?: ResolveToolUiCatalog;\n model: ModelProvider;\n store: AgentStore;\n registry: ToolRegistry;\n rolesPolicy: RolesPolicy;\n /**\n * Who has to approve an `action` call, and for how long the request stays open. Undefined →\n * {@link DefaultApprovalPolicy}: the requester, with no expiry — the behaviour before the SPI.\n */\n approvalPolicy?: ApprovalPolicy;\n quota?: QuotaStore;\n /**\n * Fallback accounting label when the provider's turn result doesn't report a `modelId`.\n * Optional — a provider that reports its own model makes this unnecessary.\n */\n modelId?: string;\n /** Pre-computed (YYYY-MM-DD) so the loop body stays deterministic under durable replay. */\n day: string;\n /** The agent's base prompt. A flat string, or a {@link PromptBuilder} resolved per turn. */\n systemPrompt: string | PromptBuilder;\n /**\n * Cross-agent system-prompt contributors, applied in order AFTER the agent's base prompt. Each\n * returns a section to append (or `null` to skip this turn). The app registers them via\n * `@SystemPromptContributor()`; the loop composes base + contributors into the effective prompt.\n */\n promptContributors?: PromptContributor[];\n maxSteps?: number;\n /**\n * How deep agent→agent delegation may nest before the loop refuses further hops.\n * Defaults to {@link MAX_DELEGATION_DEPTH}.\n *\n * It bounds NESTING, never fan-out: how many agents a turn delegates to is the model's, one tool\n * call each, and nothing here caps that. What it guards is a hop the model cannot see — a\n * `delegatesTo` cycle (A→B→A), where each agent is making one reasonable call and the recursion\n * is a property of the wiring rather than of any decision.\n */\n maxDelegationDepth?: number;\n /**\n * How many times one agent may appear on a single delegation chain.\n * Defaults to {@link DEFAULT_MAX_AGENT_APPEARANCES}.\n *\n * This is the guard the depth ceiling was a proxy for, made exact: the loop compares the target\n * against {@link AgentRunInput.delegationPath} and knows whether the chain has been here before,\n * and how often. A chain of eight DISTINCT agents is long, not looping, and no longer refused for\n * resembling one.\n */\n maxAgentAppearances?: number;\n /** Optional host handle threaded to tool ctx (e.g. an ORM EntityManager). */\n host?: unknown;\n /** Agent-level tool allow-list. Undefined → all tools (after role filtering). */\n toolAllowList?: string[];\n /**\n * The agent's personas. Read ONLY when the run names one (`AgentRunInput.persona`), and then only\n * once, inside the `persona:resolve` checkpoint — so a replay runs under the persona the turn\n * started with even after this list changed. Undefined → no personas.\n */\n personas?: Persona[];\n /**\n * Per-tool execution timeout in ms. A tool that runs longer is aborted and recorded as failed\n * (the model gets the timeout as its result and can adapt) rather than hanging the turn.\n * Undefined → no timeout.\n */\n toolTimeoutMs?: number;\n /**\n * Retries a tool's own invocation, in place, when it throws a classified-transient error (a DB\n * deadlock, a lock-wait timeout, a serialization failure — see `isTransientToolError`) — never a\n * new durable step/checkpoint, just repeated attempts inside the same `tool:<call.id>` step body.\n * Default ON (`{ attempts: 2, backoffMs: 150 }` with the default classifier) when undefined; set\n * `{ classify }` to widen/narrow which errors count as transient, or `false` to disable entirely.\n * A tool's other (non-transient) failures are unaffected — they remain a one-shot business\n * outcome, exactly as before.\n */\n toolTransientRetry?: ToolTransientRetrySetting;\n /**\n * When set, after the final turn the loop makes one extra model call to propose up to this many\n * short follow-up questions, stored on the assistant message's `followUps`. Costs an extra call\n * (recorded as `follow_ups` usage). Undefined/0 → disabled.\n */\n followUpsCount?: number;\n /**\n * Enables always-on (\"inject\") RAG: before the turn, retrieve passages for the user message and\n * augment the system prompt with them. Its presence IS inject mode — agentic (tool) retrieval sets\n * no retriever here (it rides a normal `read` tool). Undefined → no injection, and no `retrieve`\n * position: which answer a RUN got is journaled (see {@link PromptStages}), so wiring one does not\n * move the checkpoints of a turn already in flight.\n */\n retriever?: Retriever;\n /** How many passages inject-mode retrieval requests. Undefined → 5. */\n retrievalTopK?: number;\n /**\n * Prices each step's token usage into `costUsd` (on the `step-finish` stream frame and the\n * persisted assistant message's `usage`). The current price list is fetched ONCE per run (not per\n * message/step) and reused for every step's estimate. Undefined → `costUsd` is always `null`.\n */\n pricingStore?: AgentPricingStore;\n /**\n * Bounds how much of the thread rides into the turn. Undefined → the WHOLE thread, every message\n * the store holds, which is unbounded: a long-lived thread eventually exceeds the provider's\n * context limit, and pays for the full transcript on every turn up to that point. See\n * `windowHistory` for the built-in.\n */\n historyPolicy?: HistoryPolicy;\n /**\n * Rewrites the prompt before EACH model call of the turn, in order (see {@link InputProcessor}).\n * Transformation only — `historyPolicy` owns which messages are there in the first place. Adds\n * one `process:input:<step>` checkpoint per step; empty/undefined adds none.\n */\n inputProcessors?: InputProcessor[];\n /**\n * Inspects each model step's answer before the stream, the store or the next step sees it, and\n * may redact, replace or refuse it (see {@link OutputProcessor}).\n *\n * REGISTERING ONE TAKES THE MODEL CALL OFF THE RUN'S SINK for the turn — a gate cannot run after\n * the answer has already reached the reader. What the chain costs the subscriber depends on what\n * it declares:\n *\n * - Any processor WITHOUT `incremental` → the whole answer is buffered and released as one `text`\n * frame once the chain has passed. No token-by-token text, and (for a provider that writes bytes\n * outside the `AgentStreamEvent` vocabulary) no frame the gate cannot classify.\n * - EVERY processor with `incremental` → the chain runs over the growing prefix and releases it as\n * it arrives, holding back the widest `lookbackChars` any of them asked for. The whole-answer\n * pass still runs and is still authoritative for the stream and the store.\n *\n * Both add one `process:output:<step>` checkpoint per step, in the same position, so a chain can\n * change its declaration without moving a checkpoint. Empty/undefined adds none, and the turn\n * streams exactly as it always did.\n */\n outputProcessors?: OutputProcessor[];\n /**\n * Constrain the turn's answer to a schema, returned validated as `object` on the loop's result and\n * recorded on the assistant message as a synthetic `structured_output` tool call (the same shape\n * inject-mode retrieval uses, so no store gains a column for it).\n *\n * HOW IT COMPOSES WITH TOOL CALLING: as a separate formatting pass, ALWAYS. The turn runs its\n * model→tools iteration exactly as it would without a schema; once a step comes back with no tool\n * calls, one extra non-streamed call (`structured:<step>`, `tools: []`, `outputSchema` set)\n * restates that answer as the schema. Most providers cannot serve a response format and a tool set\n * in one request, and skipping the pass for an agent that happens to have no tools would make the\n * checkpoint sequence depend on a tool-registry lookup — the registry of whichever process is\n * replaying — which is exactly how a run ends up asking for a position its history has no room\n * for. So the pass is unconditional, and it costs one model call per turn (recorded as\n * `structured_output` usage).\n */\n outputSchema?: StandardSchemaV1<unknown, TOutput>;\n /** Overrides the formatting pass's system prompt. Undefined → `DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION`. */\n outputInstruction?: string;\n /**\n * How many extra model calls may try to fix an answer that failed `outputSchema`, each shown the\n * previous attempt's validation issues. Undefined → 1; `0` → fail on the first invalid reply.\n * Bounded because a model that cannot satisfy a schema usually cannot satisfy it on the fourth\n * try either, and every attempt is billed.\n */\n outputRepairAttempts?: number;\n /**\n * Show the formatting pass the turn's whole transcript instead of just the question and the\n * answer. For an agent whose answer cannot be restated from its own words — one that reports on\n * rows a tool returned and names only their total in the prose, say.\n *\n * OFF by default because the pass is a translation, and a translation needs the thing being\n * translated. The transcript it would otherwise carry is the turn's entire prompt a second time,\n * at no discount: the pass swaps the system block for the schema instruction, and the system block\n * is the prompt cache's prefix, so nothing of the first call's cache survives into it.\n */\n outputFromTranscript?: boolean;\n /**\n * A question set the agent puts to the user BEFORE it starts working — collecting the scope, as\n * against `awaitApproval`, which sanctions work already proposed. The questions are AUTHORED, so\n * the turn spends no model call producing them and a client knows the total (\"Question 1 of 3\")\n * the moment the form appears.\n *\n * The turn parks on the answers exactly as it parks on an approval, and the request persists as\n * the same tool-call row the model's `ask` writes — see {@link ask}. Undefined → no intake, and a\n * turn's checkpoint sequence is byte-identical to one that never had the option.\n */\n intake?: AgentIntake;\n /**\n * Offer the model the built-in `ask` tool, so it can put its own question set to the user when it\n * judges the scope is missing — the same surface as {@link intake}, minus the \"known in advance\".\n *\n * `ask` is NOT a registered tool: it has no handler (the loop settles it against a human), and\n * keeping it out of the `ToolRegistry` is what keeps its kind out of a process-local lookup. The\n * loop appends its definition to the turn's tool list from THIS flag, which is module config and\n * therefore uniform across a deployment. Undefined/false → the model never sees it.\n */\n ask?: boolean;\n /**\n * Authored procedures the model may pull in when a task calls for one, resolved per turn against\n * the actor's scopes — see `skills.ts`. Undefined → no catalog block, no `skill` tool, and a\n * turn's checkpoint sequence is byte-identical to one that never had the option — including for a\n * turn that was already in flight when this was wired, because which answer a RUN got is journaled\n * (see {@link PromptStages}).\n *\n * HOW IT COMPOSES WITH THE OTHER FOUR THINGS THAT WRITE THE PROMPT. The system block is assembled\n * in one fixed order — the agent's base prompt, then each `promptContributors` section, then\n * {@link memory}, then the injected retrieval block, then the skills CATALOG — and skills are the\n * cheapest of the five by construction: the catalog is one line per skill and nothing else. The\n * instructions themselves arrive as a tool RESULT, on the transcript, which means the budget they\n * draw on is the one `historyPolicy` already governs rather than a private allowance of their own.\n *\n * A BODY IS NOT LIKE A MEMORY, which does ride the system block. A body is read BECAUSE the model\n * went and asked for it, so the transcript — what this conversation happened to pull in — is where\n * it belongs. A memory is worthless unless it is in front of the model on the turn nobody thought\n * to look for it, and it is affordable there only because it has no body to carry.\n */\n skills?: SkillsConfig;\n /**\n * What the assistant has previously concluded about the actor and their organisation, resolved per\n * turn against the same scope tokens skills use — see `memory.ts`. Undefined → no memory block, no\n * `remember` tool, and a turn's checkpoint sequence is byte-identical to one that never had the\n * option — including for a turn that was already in flight when this was wired, because which\n * answer a RUN got is journaled (see {@link PromptStages}).\n *\n * WHERE IT SITS IN THE PROMPT. The system block is assembled most-durable-first: the agent's base\n * prompt (the same for everyone, every turn), then `promptContributors`, then MEMORY (the same for\n * this person, every turn), then the injected retrieval block (this question only), then the\n * skills catalog (a menu rather than an instruction, so a reader meets instructions before\n * options).\n *\n * WHY IT IS IN THE SYSTEM BLOCK AT ALL, when a skill's body deliberately is not. A body is read\n * BECAUSE the model went and asked for it; a memory is worthless unless it is in front of the\n * model on the turn nobody thought to look for it — \"they report in nautical miles\" only works\n * unprompted. What makes that affordable is that a memory has no body: `maxMemories` lines, each\n * capped at `maxFactChars` when it is written, so the block's ceiling is a product of two numbers\n * an operator set rather than however much the model felt like writing down.\n */\n memory?: MemoryConfig;\n}\n\n/**\n * A step's cost: the provider's own reported figure when it has one (a gateway), else an estimate\n * from `price` when the model has one, else `null` — never a fabricated `0` for \"we don't know\".\n */\nfunction resolveCostUsd(\n usage: MessageUsage,\n reportedCostUsd: number | undefined,\n price: CurrentModelPrice | undefined,\n): number | null {\n if (reportedCostUsd !== undefined) {\n return reportedCostUsd;\n }\n return price === undefined ? null : estimateCost(usage, price);\n}\n\n/** Renders retrieved passages as a numbered, citable context block for the system prompt. */\nfunction buildContextBlock(passages: Passage[]): string {\n const items = passages\n .map((passage, index) => {\n const label = passage.source !== undefined ? ` (${passage.source})` : '';\n return `[${index + 1}]${label} ${passage.text}`;\n })\n .join('\\n\\n');\n return `<retrieved_context>\\n${items}\\n</retrieved_context>\\nUse the retrieved context above to answer when relevant, and cite sources by their bracket number.`;\n}\n\n/** Renders a folded-history summary as the leading `system` message of a windowed turn. */\nfunction buildSummaryBlock(summary: string): string {\n return `<conversation_summary>\\n${summary}\\n</conversation_summary>\\nEarlier messages in this thread are no longer included verbatim. Treat the summary above as an accurate record of them.`;\n}\n\n/** One task's outcome under {@link AgentLoopHooks.parallel}, reported instead of thrown. */\nexport type SettledTask<T> = { ok: true; value: T } | { ok: false; error: unknown };\n\n/**\n * The {@link AgentLoopHooks.parallel} implementation for a runner whose checkpoint positions are\n * handed out on the CALL (both durable primitives are: `ctx.localStep` and `ctx.step` take their\n * position before their first `await`). Every task is invoked here, synchronously and in list\n * order, before any of them is awaited — which is what fixes the block of positions the tasks\n * occupy, whatever order they then settle in. Nothing rejects: the caller decides what an\n * individual failure means.\n */\nexport function settleAll<T>(tasks: readonly (() => Promise<T>)[]): Promise<SettledTask<T>[]> {\n const started = tasks.map((task) => task());\n return Promise.all(\n started.map((work) =>\n work.then<SettledTask<T>, SettledTask<T>>(\n (value) => ({ ok: true, value }),\n (error: unknown) => ({ ok: false, error }),\n ),\n ),\n );\n}\n\nexport interface AgentLoopHooks {\n runId: string;\n /** A writer for this run's live token stream (data plane). */\n openSink(): SinkWriter | Promise<SinkWriter>;\n /**\n * HITL gate for an action tool. Inline resolves a pending promise; durable awaits a signal.\n *\n * `opts.timeoutMs` is the request's time to live, from the turn's `ApprovalPolicy`. When it\n * elapses with no decision the runner resolves `{ approved: false, expired: true }` — it must not\n * throw — and the loop settles the call `expired`. The value comes out of the call's\n * `persist:toolcall` checkpoint, so it is the same on every replay; a durable runner hands it to\n * its own timed wait (whose deadline the runtime journals), an inline one arms a timer.\n */\n awaitApproval(\n call: ToolCallRequest,\n ctx: AiToolCtx,\n opts?: { timeoutMs?: number },\n ): Promise<Decision>;\n /**\n * Park the run on a question set and resolve with what the human sent back. The SAME wait\n * `awaitApproval` is — the durable runner maps both to `ctx.waitForSignal` on\n * `tool:<runId>:<callId>`, so an answer and an approval reach a parked run through one path.\n *\n * Optional, and its absence changes no checkpoint: the loop falls back to `awaitApproval` and\n * reads the decision as \"the user confirmed the pre-picked answers\" (approved) or \"the user\n * skipped\" (rejected). That is the honest reduction of a yes/no channel, and it means a host that\n * only ever implemented approval still runs an elicitation to completion instead of hanging.\n *\n * Declared as `HumanReply` rather than `ElicitationReply` because that is what the channel really\n * carries: a question set is parked as a `pending_approval` action, so a `Decision` can arrive on\n * this wait from the approvals inbox even where the host implements it. The loop reduces one to\n * the other — see {@link normalizeElicitationReply} — so an implementer never has to.\n */\n awaitAnswers?(request: ElicitationRequest, ctx: AiToolCtx): Promise<HumanReply>;\n /**\n * Run another named agent and return its answer. Provided only when the host wired multi-agent\n * support (durable → child workflow, inline → nested loop). Exposed to tools as `ctx.runAgent`.\n */\n runAgent?(agentName: string, task: string): Promise<{ text: string }>;\n /**\n * Start another named agent and return its run id WITHOUT waiting for it, so the calling turn can\n * finish while the delegate is still working. The durable runner maps this to `ctx.startChild`\n * (checkpointed as `spawn:<id>`; no suspend, unlike the `ctx.child` behind {@link runAgent}); the\n * inline runner to a nested loop nobody awaits.\n *\n * `toolCallId` is the delegation's own call, which the started run carries as its delivery\n * address: it posts its answer back into the calling thread against that row.\n *\n * Absent -> a delegation the journal declares detached is AWAITED instead. The loop writes the\n * same checkpoint names either way (see {@link delegateToolCall}), so a runner that cannot detach\n * still answers the user; only the runner's own positions differ, and a given runner always makes\n * the same choice for the same call.\n */\n startAgent?(args: {\n agentName: string;\n task: string;\n toolCallId: string;\n }): Promise<{ runId: string }>;\n /**\n * Checkpoint wrapper. Inline = call fn directly; durable = ctx.localStep(name, fn) — the\n * in-process checkpointed primitive (`name` is a checkpoint identity, not a worker group).\n * EVERY side-effect and control-flow read goes through this so durable replay returns\n * cached results (stable ids, no double-write, no re-streaming).\n */\n step<T>(name: string, fn: () => Promise<T>): Promise<T>;\n /**\n * Dispatch the model turn as a routed remote step. When present the loop uses it INSTEAD of\n * running the model inline under hooks.step. Must resolve to exactly what deps.model.runTurn\n * resolves, plus `bufferedFrames` when (and only when) the envelope set `bufferOutput` — the\n * handler streams to a worker-side sink the loop cannot wrap, so an output gate depends on it\n * honouring that flag. The durable runner enriches the envelope with sink routing\n * (sinkRunId/childSink) on its side — core stays sink-topology-agnostic.\n */\n dispatchLlm?(index: number, envelope: LlmStepEnvelope): Promise<BufferedModelTurnResult>;\n /**\n * Dispatch one tool execution as a routed remote step. Replaces ONLY the registry.invoke call\n * (+ its timeout, applied handler-side); all persist steps around it stay local.\n */\n dispatchTool?(call: ToolCallRequest, envelope: ToolStepEnvelope): Promise<unknown>;\n /**\n * Recognizes the runner's control-flow signals (durable suspend / continue-as-new) so the loop\n * rethrows them untouched instead of recording a failure. An OVERRIDE, not the gate: the loop\n * already recognizes any signal carrying the durable runtime's `Symbol.for` marker on its own (see\n * {@link isControlFlowSignal}), so a host that omits this — an inline runner with no control-flow\n * exceptions, or one that simply forgot — never turns a suspend into a persisted tool failure.\n * Supply it for a runner whose signals carry no marker.\n */\n isControlFlowError?(error: unknown): boolean;\n /**\n * Run `tasks` concurrently, resolving once EVERY one has settled — one outcome per task, in INPUT\n * order, never rejecting. Supplying it is a statement about the runner's checkpointing: each task\n * MUST be invoked synchronously, in list order, before any is awaited, so a runner that hands out\n * positions on the call assigns them in that order regardless of which task finishes first.\n * {@link settleAll} is exactly that, and is what both bundled runners pass.\n *\n * Waiting for ALL of them is the other half of the contract. A durable runner unwinds a turn by\n * THROWING (a dispatched step suspends), and a sibling abandoned part-way through its own dispatch\n * is a tool nobody ever runs.\n *\n * Absent → the loop runs a turn's tool calls one at a time. That is the honest answer for a runner\n * whose positions are assigned anywhere other than the call, and it is the only behaviour that\n * existed before, so nothing gains concurrency without saying so.\n */\n parallel?<T>(tasks: readonly (() => Promise<T>)[]): Promise<SettledTask<T>[]>;\n /**\n * Has someone asked this run to stop?\n *\n * Answered at the points where stopping is safe and cheap — between steps, before the next model\n * call, before the turn's tools are dispatched — and NEVER consulted anywhere else. Two properties\n * make it safe to ask a live question inside a replayed loop body:\n *\n * 1. THE ANSWER IS JOURNALED. The loop only ever calls this inside a checkpoint, so the first\n * process to reach a given position writes the answer there and every later replay reads it\n * back. A cancel that arrives between two replays is therefore seen at the first position the\n * history does NOT yet hold, and cannot change the branch a replayed position already took.\n * 2. THE POSITIONS ARE PATCHED IN. They exist only for a run that {@link patched} admits to the\n * `agent:cancellation` shape, so a run already in flight when a deployment gained this keeps\n * replaying against the sequence it recorded.\n *\n * Undefined → the run cannot be cancelled and takes not one extra checkpoint, which is the honest\n * answer for a host with nowhere to record the request.\n *\n * WHAT IT CANNOT REACH: a turn parked on a human (`awaitApproval`/`awaitAnswers`) is suspended\n * INSIDE a position the journal already holds, so no observation of any kind fires there. Stopping\n * a parked run is the runner's job, through whatever hard cancel its runtime has.\n */\n cancelled?(): Promise<boolean>;\n /**\n * Does this run take the loop shape guarded by `id`? A runner replaying against recorded\n * checkpoints answers `false` for a run that started before the shape changed, so that run keeps\n * replaying the shape its history holds (the durable runtime's `ctx.patched`, which consumes a\n * position for a new run and gives it back to an old one). Absent → `true`: a runner that records\n * no positions has no older shape to preserve.\n */\n patched?(id: string): Promise<boolean>;\n}\n\nexport class QuotaExceededError extends Error {\n constructor() {\n super('Daily token quota exceeded');\n this.name = 'QuotaExceededError';\n }\n}\n\n/**\n * Someone asked this run to stop, and it did. NOT a failure — it is the outcome a user pressing Stop\n * is entitled to, and a consumer whose reliability numbers count `failed` runs must be able to leave\n * it out. Thrown by the loop at the point it observed the cancel, and settled by the runner, which\n * records the run `cancelled` and ends the stream with a `cancelled` frame rather than failing it.\n *\n * Carries no message detail on purpose: there is nothing to diagnose, and a cancel reads the same\n * whether it came from a Stop button, an operator console, or a deployment draining.\n */\nexport class RunCancelledError extends Error {\n constructor() {\n super('Run cancelled');\n this.name = 'RunCancelledError';\n }\n}\n\n/**\n * The stream error code a failed run surfaces to its subscriber. A refusal by an output processor\n * and an answer that never satisfied `outputSchema` are the CONTROLS working, not the model\n * breaking: a client that retries on `run_failed` must not retry either of them, and neither should\n * page whoever is on call for model failures.\n */\nexport function agentFailureCode(error: unknown): string {\n // A cancel is not a failure at all — both runners settle it on its own path and never reach here.\n // It is answered anyway so that a host which does route it through the failure machinery cannot\n // end up reporting a user's Stop as `run_failed`.\n if (error instanceof RunCancelledError) {\n return 'cancelled';\n }\n if (error instanceof QuotaExceededError) {\n return 'quota_exceeded';\n }\n if (error instanceof OutputRejectedError) {\n return 'output_rejected';\n }\n if (error instanceof StructuredOutputError) {\n return 'structured_output_invalid';\n }\n if (isReplayIntegrityError(error)) {\n return 'replay_diverged';\n }\n return isNoOutputError(error) ? 'model_no_output' : 'run_failed';\n}\n\n/**\n * A model call that ended without producing anything — the AI SDK's `NoOutputGeneratedError`.\n * Matched by name, and by its message as well: an error that crossed a dispatched step comes back\n * rebuilt by the runtime, which keeps the message and not always the class name.\n */\nfunction isNoOutputError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n return (\n error.name === 'AI_NoOutputGeneratedError' ||\n error.name === 'NoOutputGeneratedError' ||\n error.message.startsWith('No output generated')\n );\n}\n\n/**\n * What a person is told when a run fails for a reason that is ours rather than theirs. The error's\n * own text is for whoever operates the deployment: it names run ids, checkpoint positions and\n * provider internals (\"non-determinism at <uuid>#41 …\", \"No output generated. Check the stream for\n * errors.\"), which mean nothing to the person reading the chat and are not theirs to see.\n */\nexport const RUN_FAILED_MESSAGE = 'The assistant could not finish this answer. Please try again.';\n\nlet streamErrorDetails: boolean | undefined;\n\n/**\n * Whether an error frame carries the error's own message. Unset → only outside production\n * (`NODE_ENV !== 'production'`), where the person reading the stream is the one debugging it.\n * `true`/`false` decides it outright; `undefined` returns to the default.\n */\nexport function exposeStreamErrorDetails(expose: boolean | undefined): void {\n streamErrorDetails = expose;\n}\n\n/** The codes whose message the library wrote for the person, and is therefore safe to show. */\nconst WORDED_CODES = new Set(['quota_exceeded', 'output_rejected', 'structured_output_invalid']);\n\n/**\n * The terminal a failed run closes its stream with — what `SinkWriter.fail` takes, and what the\n * transport sends as the `event: error` frame.\n *\n * The frame is what the PERSON sees. For a crash it carries a stable `code` (what a client branches\n * on, and translates) and {@link RUN_FAILED_MESSAGE}; the error itself belongs in the log and on the\n * run row, which is where the runners put it. Outside production the raw message rides the frame as\n * it always did (see {@link exposeStreamErrorDetails}). A message the library words itself\n * (`quota_exceeded`, `output_rejected`, `structured_output_invalid`) is sent as it is.\n */\nexport function streamFailure(error: unknown): StreamError {\n const detail = error instanceof Error ? error.message : String(error);\n const code = agentFailureCode(error);\n if (WORDED_CODES.has(code)) {\n return { code, message: detail };\n }\n const exposed = streamErrorDetails ?? process.env.NODE_ENV !== 'production';\n return { code, message: exposed ? detail : RUN_FAILED_MESSAGE };\n}\n\n/**\n * The default depth at which agent→agent delegation stops nesting, when the host names none.\n * Override with {@link AgentLoopDeps.maxDelegationDepth}.\n *\n * A backstop for a chain that is merely LONG. The cycle it used to stand in for is now detected\n * directly — see {@link DEFAULT_MAX_AGENT_APPEARANCES}.\n *\n * WHEN IT ACTUALLY BINDS. At one appearance per agent, a chain cannot be longer than the number of\n * registered agents, so a deployment with fewer agents than this number never reaches it: the cycle\n * guard always fires first. It starts mattering with a larger fleet of agents than the ceiling, or\n * once a host raises {@link AgentLoopDeps.maxAgentAppearances}, which is what lets a chain revisit\n * an agent and therefore grow past the fleet's size.\n */\nexport const MAX_DELEGATION_DEPTH = 5;\n\n/**\n * How many times one agent may appear on a single delegation chain, when the host names no other\n * number. Once: a chain that reaches an agent it has already passed through is going in circles.\n *\n * Override with {@link AgentLoopDeps.maxAgentAppearances} — a supervisor that genuinely hands work\n * back to an earlier agent needs a larger number, and it is the count of APPEARANCES, so 2 admits\n * exactly one return.\n */\nexport const DEFAULT_MAX_AGENT_APPEARANCES = 1;\n\n/**\n * Why this delegation must not happen, or `null` to let it through.\n *\n * Two different refusals, and the order matters: a CYCLE is named before a depth, because they\n * describe different faults and the depth is the vaguer of the two. \"A→B→A\" points at the wiring;\n * \"depth limit of 5 reached\" leaves a reader to work out whether the chain was looping or merely\n * long, which is exactly the question a count cannot answer.\n */\nfunction delegationRefusal(args: {\n deps: Pick<AgentLoopDeps, 'maxAgentAppearances' | 'maxDelegationDepth'>;\n input: Pick<AgentRunInput, 'agentName' | 'delegationDepth' | 'delegationPath'>;\n targetAgent: string;\n}): string | null {\n const { deps, input, targetAgent } = args;\n // `delegationPath` is the chain that REACHED this run, so it stops short of the agent running\n // now — a runner appends its own name only on the way into a child. Both the count and the named\n // chain want the hop being taken, so this run's agent joins the end of the ancestry: without it a\n // mutual handoff is refused as `alpha → alpha`, an edge no deployment declares, and an agent\n // delegating to ITSELF from a top-level turn is not caught at all until one hop later.\n const ancestry = [\n ...(input.delegationPath ?? []),\n ...(input.agentName !== undefined ? [input.agentName] : []),\n ];\n const appearances = ancestry.filter((name) => name === targetAgent).length;\n const maxAppearances = deps.maxAgentAppearances ?? DEFAULT_MAX_AGENT_APPEARANCES;\n if (appearances >= maxAppearances) {\n const chain = [...ancestry, targetAgent].join(' → ');\n const times = appearances + 1;\n return `(delegation cycle: ${chain} — ${targetAgent} ${times} times on one chain)`;\n }\n const maxDepth = deps.maxDelegationDepth ?? MAX_DELEGATION_DEPTH;\n if ((input.delegationDepth ?? 0) >= maxDepth) {\n return `(delegation depth limit of ${maxDepth} reached)`;\n }\n return null;\n}\n\n/** Resolve a prompt that may be a flat string or a {@link PromptBuilder}. */\nasync function resolvePrompt(prompt: string | PromptBuilder, ctx: PromptContext): Promise<string> {\n return typeof prompt === 'function' ? prompt(ctx) : prompt;\n}\n\n/**\n * The effective system prompt for a turn: the agent's own base prompt, then each cross-agent\n * contributor's section appended in order (skipping any that return `null`/empty this turn). This is\n * resolved from stable inputs (actor / agent / pageContext) once per turn; contributors should be\n * derived from those rather than from uncached I/O so it stays replay-safe.\n */\nasync function resolveSystemPrompt(\n deps: AgentLoopDeps,\n input: AgentRunInput,\n persona: TurnPersona | undefined,\n): Promise<string> {\n const ctx = promptContext(input, persona);\n // A persona that carries a prompt stands in for the base — resolved, with the base it may wrap,\n // inside `persona:resolve`, so a replay reads back the exact text the turn started with.\n const sections = [persona?.prompt ?? (await resolvePrompt(deps.systemPrompt, ctx))];\n for (const contribute of deps.promptContributors ?? []) {\n const section = await contribute(ctx);\n if (section !== null && section.length > 0) {\n sections.push(section);\n }\n }\n return sections.join('\\n\\n');\n}\n\n/** The run's input with no persona — what a turn whose persona did not resolve runs as. */\nfunction withoutPersona(input: AgentRunInput): AgentRunInput {\n const { persona: _dropped, ...rest } = input;\n return rest;\n}\n\n/** What every prompt builder of a turn is handed. */\nfunction promptContext(input: AgentRunInput, persona: TurnPersona | undefined): PromptContext {\n return {\n actor: input.actor,\n agentName: input.agentName ?? 'default',\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(input.uiCapabilities !== undefined ? { uiCapabilities: input.uiCapabilities } : {}),\n ...(persona !== undefined ? { persona: { id: persona.id, label: persona.label } } : {}),\n };\n}\n\n/**\n * The `persona:resolve` checkpoint's body: the persona the run names, looked up in this process's\n * config and FROZEN — its id, label and allow-list, and its prompt resolved against the agent's base\n * prompt. `null` when the agent no longer declares it, which the turn runs as no persona at all.\n *\n * Reached only for a run whose input names a persona, and every such run was started by a release\n * that has this checkpoint; a run started before personas existed names none, spends no position\n * here, and replays on the sequence it recorded.\n */\nasync function resolveTurnPersona(\n deps: AgentLoopDeps,\n input: AgentRunInput,\n): Promise<TurnPersona | null> {\n const persona = findPersona(deps, input.persona);\n if (persona === undefined) {\n return null;\n }\n const ref = { id: persona.id, label: persona.label };\n let prompt: string | undefined;\n if (persona.systemPrompt !== undefined) {\n const ctx = promptContext(input, ref);\n const basePrompt =\n typeof persona.systemPrompt === 'function'\n ? await resolvePrompt(deps.systemPrompt, ctx)\n : undefined;\n prompt = await resolvePrompt(persona.systemPrompt, {\n ...ctx,\n ...(basePrompt !== undefined ? { basePrompt } : {}),\n });\n }\n return {\n ...ref,\n ...(persona.allowedTools !== undefined ? { allowedTools: [...persona.allowedTools] } : {}),\n ...(prompt !== undefined ? { prompt } : {}),\n };\n}\n\n/**\n * Why a delegation must not happen under this persona, or `null`. A delegate tool is a tool like any\n * other to the persona's allow-list: one it was not offered is refused, even if the model names it.\n */\nfunction personaRefusal(persona: TurnPersona | undefined, toolName: string): string | null {\n if (persona?.allowedTools === undefined || persona.allowedTools.includes(toolName)) {\n return null;\n }\n return `(tool \"${toolName}\" is not available to the \"${persona.id}\" persona)`;\n}\n\n/** An `agent`-kind tool's input is `{ task }` by convention; fall back to a JSON dump. */\nfunction extractTask(input: unknown): string {\n if (typeof input === 'object' && input !== null && 'task' in input) {\n const task = (input as { task: unknown }).task;\n if (typeof task === 'string') {\n return task;\n }\n }\n return JSON.stringify(input);\n}\n\nfunction deriveTitle(userText: string): string {\n const trimmed = userText.trim().replace(/\\s+/g, ' ');\n return trimmed.length > 60 ? `${trimmed.slice(0, 57)}...` : trimmed || 'New chat';\n}\n\n/** Thrown when a tool exceeds `toolTimeoutMs`; caught by the loop and recorded as a failed call. */\nclass ToolTimeoutError extends Error {\n constructor(toolName: string, ms: number) {\n super(`Tool \"${toolName}\" exceeded its ${ms}ms timeout`);\n this.name = 'ToolTimeoutError';\n }\n}\n\n/** Reject if `work` doesn't settle within `ms`. The underlying work is left to finish on its own. */\nexport function withToolTimeout<T>(work: Promise<T>, ms: number, toolName: string): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => reject(new ToolTimeoutError(toolName, ms)), ms);\n work.then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n}\n\n/** Best-effort parse of the follow-ups model reply: a bare JSON array, tolerating code fences/prose. */\nfunction parseFollowUps(text: string, count: number): string[] {\n const source = text.match(/\\[[\\s\\S]*\\]/)?.[0] ?? text;\n try {\n const parsed: unknown = JSON.parse(source);\n if (Array.isArray(parsed)) {\n return parsed.filter((item): item is string => typeof item === 'string').slice(0, count);\n }\n } catch {\n /* not JSON — no follow-ups this turn */\n }\n return [];\n}\n\n/**\n * One extra, non-streamed model call that proposes short follow-up questions. Writes to a discarding\n * sink so its tokens never reach the user's live stream; the reply is parsed as a JSON string array.\n */\nasync function generateFollowUps(\n model: ModelProvider,\n messages: ModelMessage[],\n count: number,\n): Promise<{ followUps: string[]; usage: MessageUsage; modelId?: string }> {\n const discard: SinkWriter = { write: () => {}, end: () => {}, fail: () => {} };\n const turn = await model.runTurn({\n system: `Based on the conversation so far, propose up to ${count} short, distinct follow-up questions the user is likely to ask next. Respond with ONLY a JSON array of strings — no prose, no code fences.`,\n messages,\n tools: [],\n sink: discard,\n });\n return {\n followUps: parseFollowUps(turn.text, count),\n usage: turn.usage,\n ...(turn.modelId !== undefined ? { modelId: turn.modelId } : {}),\n };\n}\n\n/**\n * Wrap a genuinely-executing operation in an `aviary:agent:<event>` span (the diagnostics\n * `trace()` API — five `:start`/`:end`/`:asyncStart`/`:asyncEnd`/`:error` sub-channels),\n * correlated to its run by `traceId = runId`, WITHOUT letting the operation's raw return value\n * ride the span envelope: `trace` publishes the traced fn's return as the span's `result`, so the\n * traced fn returns only `summarize`d metadata (token counts / lengths / names — never prompt or\n * output text, the point events' redaction posture) while the real value is handed back to the\n * caller through the closure. Zero-cost when no span sub-channel has a subscriber.\n *\n * REPLAY SAFETY: call sites MUST sit INSIDE a `hooks.step` body (or another genuinely-executed\n * path). Durable replay skips step bodies and returns checkpoints, which is exactly what keeps a\n * replayed run from re-emitting spans. Never wrap a `hooks.step(...)`/`hooks.dispatch*(...)`\n * CALL — those run (and resolve from cache) on every replay.\n */\nasync function spanned<TEvent extends AgentSpanEvent, T>(\n event: TEvent,\n runId: string,\n payload: PayloadOf<'agent', TEvent>,\n run: () => Promise<T>,\n summarize: (value: T) => Record<string, unknown>,\n): Promise<T> {\n let value!: T;\n await trace(\n 'agent',\n event,\n async () => {\n value = await run();\n return summarize(value);\n },\n payload,\n { traceId: runId },\n );\n return value;\n}\n\n/**\n * Span-wrap one model call (`aviary:agent:llm.turn`). Exported so the durable dispatched-step\n * handler (which executes the genuine remote llm step) can emit the same span — core cannot wrap\n * `hooks.dispatchLlm` itself, because that call also runs (from cache) on replay.\n */\nexport function traceLlmTurn(\n runId: string,\n step: number,\n run: () => Promise<ModelTurnResult>,\n): Promise<ModelTurnResult> {\n return spanned('llm.turn', runId, { runId, step }, run, (turn) => ({\n ...(turn.modelId !== undefined ? { modelId: turn.modelId } : {}),\n inputTokens: turn.usage.inputTokens,\n outputTokens: turn.usage.outputTokens,\n textLength: turn.text.length,\n toolCalls: turn.toolCalls.length,\n }));\n}\n\n/**\n * Span-wrap one tool invocation (`aviary:agent:tool.execution`). The tool's raw output never\n * rides the span (only the start payload's name/type metadata + duration). Exported for the\n * durable dispatched-step handler, like {@link traceLlmTurn}.\n */\nexport function traceToolExecution<T>(\n runId: string,\n call: { toolCallId: string; toolName: string; toolType: 'read' | 'action' },\n run: () => Promise<T>,\n): Promise<T> {\n return spanned('tool.execution', runId, { runId, ...call }, run, () => ({}));\n}\n\n/** Everything a turn needs off its thread, with the history ceiling already applied. */\ninterface TurnHistory {\n actionApprovalMode?: ActionApprovalMode;\n /** What rides into the turn, oldest-first — already through {@link HistoryPolicy.select}. */\n messages: ModelMessage[];\n /**\n * What the ceiling left out. Carried ONLY where a summarizer is configured to fold them back in:\n * `history:summarize` can run in a later process than the one that loaded the thread, so the\n * journal is the only place it can read them from. Everywhere else they are exactly the half of\n * the transcript the ceiling exists to leave behind.\n */\n dropped: ModelMessage[];\n /** The thread's title, or `null` where the store has no such thread. */\n title: string | null;\n /** Does the thread already hold an assistant message? Decides a `thread-start` intake. */\n hasAssistantMessage: boolean;\n}\n\n/** The thread's stored rows as the model sees them — the store's own bookkeeping left behind. */\nfunction toModelMessages(messages: StoredMessage[]): ModelMessage[] {\n return messages.map((message) => ({\n role: message.role,\n content: message.content,\n ...(message.toolCalls !== undefined ? { toolCalls: message.toolCalls } : {}),\n ...(message.toolResults !== undefined ? { toolResults: message.toolResults } : {}),\n ...(message.attachments !== undefined ? { attachments: message.attachments } : {}),\n }));\n}\n\n/** Whose history this is, as the policy's two halves both see it. */\nfunction historyContext(input: AgentRunInput): HistoryPolicyContext {\n return {\n threadId: input.threadId,\n actor: input.actor,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n };\n}\n\n/** The configured ceiling's split, or the whole transcript where no policy is configured. */\nfunction splitHistory(\n policy: HistoryPolicy | undefined,\n input: AgentRunInput,\n messages: ModelMessage[],\n): HistorySelection {\n return policy === undefined\n ? { keep: messages, drop: [] }\n : policy.select(messages, historyContext(input));\n}\n\n/**\n * Load the thread and journal the messages the turn is going to send.\n *\n * `select` runs INSIDE the checkpoint, so what the position holds is the ceiling's RESULT. It is\n * contractually pure and takes no position of its own. `hooks.step` checkpoints its body's output,\n * and a `ThreadDetail` is the store's entire transcript — every message row, its id and timestamp,\n * and every tool result the thread ever recorded — written to a JSON column once and then re-read\n * and re-parsed by every process that resumes the run. Recording the selection makes the bound the\n * model's prompt respects the bound that payload respects too.\n *\n * The title and the assistant-message flag ride along because they are the only other things the\n * turn reads off the thread, and re-reading the store for them would put the row back.\n */\nasync function loadSelectedHistory(\n deps: AgentLoopDeps,\n input: AgentRunInput,\n hooks: AgentLoopHooks,\n): Promise<TurnHistory> {\n const recorded = await hooks.step('load:thread', async (): Promise<TurnHistory> => {\n const thread = await readThreadForTurn(deps, input.threadId);\n // Settled BEFORE the ceiling sees it and inside the checkpoint: what the calls' rows said is\n // part of the recorded payload, so a replay composes the same prompt without asking again.\n const { keep, drop } = splitHistory(\n deps.historyPolicy,\n input,\n await settleHistory(deps, toModelMessages(thread.messages)),\n );\n return {\n messages: keep,\n dropped: deps.historyPolicy?.summarize === undefined ? [] : drop,\n title: thread.title,\n hasAssistantMessage: thread.hasAssistantMessage,\n actionApprovalMode: deps.actionApprovalMode ?? 'blocking',\n };\n });\n // Settled once more on the way out of the journal: a payload recorded before the read settled\n // dangling calls itself still has to reach the model as a prompt a provider accepts. A no-op —\n // the same array elements — on a payload that is already whole.\n return { ...recorded, messages: settleDanglingToolCalls(recorded.messages) };\n}\n\n/**\n * Settle the history's dangling tool calls (see {@link settleDanglingToolCalls}) from the calls' own\n * rows where the store can read them. A store that cannot answer, or fails to, leaves the calls to\n * be put to the model as never completed.\n */\nasync function settleHistory(\n deps: AgentLoopDeps,\n messages: ModelMessage[],\n): Promise<ModelMessage[]> {\n const dangling = danglingToolCallIds(messages);\n if (dangling.length === 0) {\n return messages;\n }\n const outcomes = await Promise.resolve(deps.store.toolCallOutcomes?.(dangling) ?? []).catch(\n (): ToolCallOutcome[] => [],\n );\n return settleDanglingToolCalls(messages, outcomes);\n}\n\n/** The three things a turn reads off its thread, however the store was able to answer them. */\ninterface ThreadForTurn {\n /** Oldest-first, and at most what the ceiling was going to keep. */\n messages: StoredMessage[];\n title: string | null;\n hasAssistantMessage: boolean;\n}\n\n/**\n * Read the thread: the store's bounded WINDOW where it offers one, else its whole transcript.\n *\n * Probed structurally, the same seam as `defaultAgentForThread` — the window is an optimization a\n * store either offers or does not, and one that predates it still answers correctly through\n * `getThread`. Which branch runs is invisible to the journal on purpose: both produce the same three\n * answers, so the payload this checkpoint records is identical either way and a deployment's choice\n * of store can never decide a run's checkpoints. That is also why the probe lives INSIDE\n * `load:thread` rather than around it — it adds no position, and a replaying process reads the\n * recorded payload back without calling the store at all.\n *\n * `hasAssistantMessage` is taken from the page's own flag rather than scanned out of its messages,\n * because the page's flag answers over the whole thread. It decides a `thread-start` intake, and a\n * window that happens to hold only the user's last questions belongs to a conversation that has\n * still been answered — scanned off the window, such a thread re-introduces itself every turn.\n */\nasync function readThreadForTurn(deps: AgentLoopDeps, threadId: string): Promise<ThreadForTurn> {\n const windowing = deps.store as Partial<ThreadTurnReader>;\n if (typeof windowing.loadThreadForTurn === 'function') {\n const messageLimit = turnMessageLimit(deps.historyPolicy);\n const page = await windowing.loadThreadForTurn({\n threadId,\n ...(messageLimit !== undefined ? { messageLimit } : {}),\n });\n return page === null\n ? { messages: [], title: null, hasAssistantMessage: false }\n : {\n messages: page.messages,\n title: page.title,\n hasAssistantMessage: page.hasAssistantMessage,\n };\n }\n const thread = await deps.store.getThread(threadId);\n const stored = thread?.messages ?? [];\n return {\n messages: stored,\n title: thread?.title ?? null,\n hasAssistantMessage: stored.some((message) => message.role === 'assistant'),\n };\n}\n\n/**\n * How many of the thread's newest rows to ask the store for — the policy's own row ceiling, or\n * nothing at all, which asks for the transcript.\n *\n * A policy that SUMMARIZES gets no limit. `summarize` is handed what `select` dropped, and a read\n * bounded to what `select` keeps drops nothing: the turn would fold an empty summary into a prompt\n * that is missing the messages it stands in for, with no error anywhere.\n *\n * A ceiling expressed only in TOKENS gets no limit either, and none can be derived from it: one\n * message can be four tokens or forty thousand, so no row count follows from a token budget. Naming\n * one too low reads fewer rows than `select` would have kept, which changes the prompt itself;\n * leaving it out only costs the read. A policy that wants its bound to reach the database states\n * {@link HistoryPolicy.maxMessages} alongside the token budget.\n */\nfunction turnMessageLimit(policy: HistoryPolicy | undefined): number | undefined {\n if (policy === undefined || policy.summarize !== undefined) {\n return undefined;\n }\n return policy.maxMessages;\n}\n\n/**\n * The load a run recorded before the selection moved inside the checkpoint has to keep replaying\n * against: the whole `ThreadDetail` journaled, the split taken outside it. Reachable only through\n * {@link SELECTED_HISTORY_PATCH} answering false, and deletable once no such run is still in flight.\n */\nasync function loadWholeThread(\n deps: AgentLoopDeps,\n input: AgentRunInput,\n hooks: AgentLoopHooks,\n): Promise<TurnHistory> {\n const thread = await hooks.step('load:thread', () => deps.store.getThread(input.threadId));\n const stored = thread?.messages ?? [];\n // Outside the checkpoint (this shape journals the store's whole `ThreadDetail`), so it is settled\n // from the messages alone: a pure function of the recorded payload, the same on every replay.\n const { keep, drop } = splitHistory(\n deps.historyPolicy,\n input,\n settleDanglingToolCalls(toModelMessages(stored)),\n );\n return {\n messages: keep,\n dropped: drop,\n title: thread?.title ?? null,\n hasAssistantMessage: stored.some((message) => message.role === 'assistant'),\n };\n}\n\n/**\n * Fold what the ceiling dropped into a leading `system` message the model reads in their place.\n *\n * Summarizing calls a model, so it is journaled under `history:summarize`: a resumed run reads back\n * the summary the suspended attempt produced instead of writing a different one into the prompt.\n * This checkpoint and the usage row below are reachable ONLY through a configured summarizer, so no\n * run that predates one can land on either.\n */\nasync function foldDroppedHistory(\n summarize: NonNullable<HistoryPolicy['summarize']>,\n deps: AgentLoopDeps,\n input: AgentRunInput,\n hooks: AgentLoopHooks,\n history: TurnHistory,\n): Promise<ModelMessage[]> {\n const summary = await hooks.step('history:summarize', () =>\n summarize(history.dropped, historyContext(input)),\n );\n if (summary.usage !== undefined) {\n const usage = summary.usage;\n await hooks.step('persist:usage:history', () =>\n deps.store.recordUsage({\n threadId: input.threadId,\n actorRef: input.actor.id,\n modelId: summary.modelId ?? deps.modelId ?? 'unknown',\n purpose: 'history_summary',\n usage,\n }),\n );\n }\n return [{ role: 'system', content: buildSummaryBlock(summary.text) }, ...history.messages];\n}\n\n/** One turn's identity, as both processor chains see it. */\nfunction processorContext(input: AgentRunInput, step: number): ProcessorContext {\n return {\n threadId: input.threadId,\n actor: input.actor,\n step,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n };\n}\n\n/**\n * What the formatting pass is shown: the question, then the answer it has to restate.\n *\n * The question comes off the PROCESSED prompt rather than `AgentRunInput.userText`, because the pass\n * is a second route out of the model and has to stand behind the same input chain the streamed turn\n * did — a question a processor masked must not reappear in the clear here. Falls back to the answer\n * alone where the chain left no user message to point at.\n *\n * See {@link AgentLoopDeps.outputFromTranscript} for the agent that needs more than this, and why it\n * is the opt-in rather than the default.\n */\nfunction restatementPrompt(\n messages: ModelMessage[],\n answer: string,\n fromTranscript: boolean,\n): ModelMessage[] {\n const restated: ModelMessage = { role: 'assistant', content: answer };\n if (fromTranscript) {\n return [...messages, restated];\n }\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index];\n if (message?.role === 'user') {\n return [message, restated];\n }\n }\n return [restated];\n}\n\n/** One attempt of the formatting pass: what the model replied, and what it cost. */\ninterface StructuredAttempt {\n text: string;\n object?: unknown;\n usage: MessageUsage;\n modelId?: string;\n}\n\n/**\n * Restate a finished answer as `deps.outputSchema`, repairing a rejected reply up to\n * `outputRepairAttempts` times. Every model call is its own checkpoint (`structured:<step>:<n>`)\n * with its own usage row, so a suspend between two attempts resumes on the reply the first one got\n * rather than paying for a third.\n *\n * Validation itself sits OUTSIDE the checkpoints, on the same footing as `HistoryPolicy.select`: its\n * inputs are the schema (module config, identical on every process of a deployment) and the reply\n * a checkpoint already holds, so every replay reaches the same verdict — and therefore the same\n * number of attempts — without a checkpoint of its own.\n *\n * THE OUTPUT CHAIN RULES ON EACH ATTEMPT, before the schema does. This pass is a second route out of\n * the model: it is handed the finished answer and asked to restate it, so anything the chain held\n * back from the prose can be restated into the schema and leave through here. It is gated on the\n * WHOLE reply regardless of what the chain declared, because nothing here is streamed — there is no\n * prefix for an `incremental` processor to release, and the release path it buys does not exist.\n */\nasync function structureAnswer<TOutput>(\n schema: StandardSchemaV1<unknown, TOutput>,\n deps: AgentLoopDeps<TOutput>,\n input: AgentRunInput,\n hooks: AgentLoopHooks,\n messages: ModelMessage[],\n step: number,\n): Promise<TOutput> {\n const instruction = deps.outputInstruction ?? DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION;\n const maxAttempts = 1 + (deps.outputRepairAttempts ?? 1);\n const outputProcessors = deps.outputProcessors ?? [];\n let issues: readonly StandardSchemaV1.Issue[] = [];\n let text = '';\n for (let attempt = 0; attempt < maxAttempts; attempt += 1) {\n const system = attempt === 0 ? instruction : repairInstruction(instruction, issues);\n const reply = await hooks.step(`structured:${step}:${attempt}`, () =>\n spanned(\n 'structured-output',\n hooks.runId,\n { runId: hooks.runId, step, attempt },\n async (): Promise<StructuredAttempt> => {\n const discard: SinkWriter = { write: () => {}, end: () => {}, fail: () => {} };\n const turn = await deps.model.runTurn({\n system,\n messages,\n tools: [],\n sink: discard,\n outputSchema: schema,\n });\n return {\n text: turn.text,\n usage: turn.usage,\n ...(turn.object !== undefined ? { object: turn.object } : {}),\n ...(turn.modelId !== undefined ? { modelId: turn.modelId } : {}),\n };\n },\n (result) => ({\n inputTokens: result.usage.inputTokens,\n outputTokens: result.usage.outputTokens,\n textLength: result.text.length,\n }),\n ),\n );\n await hooks.step(`persist:usage:structured:${step}:${attempt}`, () =>\n deps.store.recordUsage({\n threadId: input.threadId,\n actorRef: input.actor.id,\n modelId: reply.modelId ?? deps.modelId ?? 'unknown',\n purpose: 'structured_output',\n usage: reply.usage,\n }),\n );\n text = reply.text;\n if (outputProcessors.length > 0) {\n // Its own checkpoint, after the usage row: the tokens were spent either way, and a refusal\n // that also hid its own cost would let a mis-tuned gate burn a budget invisibly — the same\n // ordering the streamed answer's gate takes.\n const gate = await hooks.step(`process:output:structured:${step}:${attempt}`, () =>\n runOutputProcessors(\n outputProcessors,\n { text: reply.text, toolCalls: [] },\n processorContext(input, step),\n ),\n );\n if (gate.rejection !== undefined) {\n throw new OutputRejectedError(gate.rejection.processor, gate.rejection.reason);\n }\n text = gate.text;\n }\n // A provider that constrained its own generation reports a parsed `object`, but that object\n // describes the reply the chain has just rewritten. Once the two disagree, the gated text is the\n // only version anything downstream may see, so it is re-parsed rather than trusted.\n const reported = text === reply.text ? reply.object : undefined;\n const outcome = await validateStructured(schema, text, reported);\n if (outcome.ok) {\n return outcome.value;\n }\n issues = outcome.issues;\n }\n throw new StructuredOutputError(issues, text, maxAttempts);\n}\n\n/**\n * What resolving a call's kind needs: the registry, plus the three config flags whose reserved names\n * have no `ToolSpec` to look up. Narrow on purpose — {@link stampToolKinds} is called from a\n * dispatched step handler, which holds the host's own deps rather than a loop's.\n */\nexport type ToolKindDeps = Pick<AgentLoopDeps, 'registry' | 'ask' | 'skills' | 'memory'>;\n\n/**\n * Stamp each of a model turn's calls with the kind declared WHERE THE TOOL WAS OFFERED.\n *\n * A call exists only because some process put that tool's definition in front of the model, so that\n * process is the one that certainly knows the tool. Another process might not: a deployment that\n * splits its pods by role has one that serves HTTP and replays run bodies without registering the\n * tool classes, and its registry answers `undefined`. Stamping here, INSIDE the llm checkpoint, is\n * what puts the kind in the journal — so the branch a call takes is a fact about the turn rather\n * than about whichever process happened to replay it (see {@link claimToolCall}).\n *\n * Only unstamped calls are touched: a kind already on a call was settled upstream, and a process\n * further down never second-guesses it.\n */\nexport function stampToolKinds<T extends { toolCalls: ToolCallRequest[] }>(\n result: T,\n deps: ToolKindDeps,\n): T {\n return {\n ...result,\n toolCalls: result.toolCalls.map((call) => {\n // Preflight is a worker fact, never a field the model may supply.\n const {\n preflight: _untrusted,\n prepared: _untrustedPrepared,\n actionApproval: _untrustedApproval,\n ...trusted\n } = call;\n return trusted.kind === undefined\n ? { ...trusted, kind: declaredKind(deps, trusted.name) }\n : trusted;\n }),\n };\n}\n\n/**\n * A call's declared kind, as settled inside `persist:toolcall` and journaled from there.\n *\n * The reserved `ask` name resolves from module CONFIG, never from the registry: `ask` has no handler\n * to register, and grounding its branch in config is what keeps a process with a partial registry\n * from disagreeing about it — the same property the registry lookup below has only because its\n * answer is written into the journal. Every other name is the registry's `ToolSpec`, exactly as\n * before.\n */\nfunction declaredKind(deps: ToolKindDeps, name: string): ToolKind {\n if (deps.ask === true && name === ASK_TOOL_NAME) {\n return 'ask';\n }\n // Same reserved-name reasoning as `ask`: `skill` has no handler either, and it is the JOURNALED\n // value below — not this config — that every replay reads the branch back from.\n if (deps.skills !== undefined && name === SKILL_TOOL_NAME) {\n return 'skill';\n }\n if (memoryIsWritable(deps) && name === REMEMBER_TOOL_NAME) {\n return 'memory';\n }\n return deps.registry.spec(name)?.kind ?? 'read';\n}\n\n/**\n * Does this deployment offer the `remember` tool at all? Memory a host serves read-only (a provider\n * with no `write`) still writes its block into the prompt and still spends `memory:digest`, but the\n * model is never shown a tool it would only be refused by. Module config either way, so the worker\n * re-deriving a dispatched turn's tool list reaches the same answer as the loop.\n */\nfunction memoryIsWritable(deps: Pick<AgentLoopDeps, 'memory'>): boolean {\n return deps.memory?.provider.write !== undefined;\n}\n\n/**\n * Append the built-in `ask` definition to a turn's tool list. Exported because the dispatched llm\n * step re-derives the tool list on a worker and has to reach the same list the loop would have.\n */\nexport function withAskTool({\n tools,\n ask,\n}: { tools: ToolDefinition[]; ask: boolean | undefined }): ToolDefinition[] {\n return ask === true ? [...tools, askToolDefinition()] : tools;\n}\n\n/**\n * Park on a question set, through whichever wait the host implemented, and read back whatever that\n * wait delivered as answers.\n *\n * The reduction of a yes/no channel — approve is \"confirmed the pre-picked answers\", reject is\n * \"skipped\" — applies to BOTH branches, because the shape of the reply is decided by whoever settled\n * the tool call, not by which hook the host wired. The question set sits in the approvals inbox as a\n * `pending_approval` action, so an operator pressing Approve there sends a `Decision` into a run\n * whose host implements `awaitAnswers` perfectly well. See {@link normalizeElicitationReply}.\n *\n * Neither branch moves a checkpoint: the wait sits at the same position either way, so the choice of\n * hook cannot change the sequence a replay lines up with.\n */\nasync function awaitElicitation(\n hooks: AgentLoopHooks,\n request: ElicitationRequest,\n ctx: AiToolCtx,\n): Promise<ElicitationReply> {\n if (hooks.awaitAnswers !== undefined) {\n return normalizeElicitationReply(await hooks.awaitAnswers(request, ctx));\n }\n return normalizeElicitationReply(\n await hooks.awaitApproval(\n { id: request.id, name: ASK_TOOL_NAME, input: request, kind: 'ask' },\n ctx,\n ),\n );\n}\n\n/**\n * The per-CALL half of a tool's context: which call this is, and the key that stays the same for\n * every execution of it (see {@link AiToolCtx.idempotencyKey}).\n */\nexport function toolCallContext<T extends { runId: string }>(\n ctx: T,\n toolCallId: string,\n): T & { toolCallId: string; idempotencyKey: string } {\n return { ...ctx, toolCallId, idempotencyKey: `${ctx.runId}:${toolCallId}` };\n}\n\n/** The tool context a turn hands to a handler — and to the wait an elicitation parks on. */\nfunction toolContext(deps: AgentLoopDeps, input: AgentRunInput, hooks: AgentLoopHooks): AiToolCtx {\n return {\n actor: input.actor,\n threadId: input.threadId,\n runId: hooks.runId,\n requestId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(input.uiCapabilities !== undefined ? { uiCapabilities: input.uiCapabilities } : {}),\n ...(deps.host !== undefined ? { host: deps.host } : {}),\n // Replaced per tool call by the call's own collector (see the tool step); this one only serves\n // what runs outside a call — the elicitation wait.\n emitUi: createNoopEmitUi(hooks.runId),\n };\n}\n\n/**\n * Does the configured intake run this turn? Both inputs are facts the journal already holds — the\n * config, and `load:thread`'s record of whether the thread had an assistant message when the turn\n * began. Neither is re-read from the store here, and that is the point: by the time a replay reaches\n * this line the first attempt has already appended the intake's own assistant message to the thread,\n * so a fresh read would answer differently on the resume than it did on the way in, and the answer\n * decides how many checkpoints follow it.\n */\nfunction intakeApplies(intake: AgentIntake, threadHasAssistant: boolean): boolean {\n return intake.when === 'every-turn' || !threadHasAssistant;\n}\n\n/**\n * The configured intake: post the authored question set, park until a human settles it, and leave\n * the exchange on the transcript as an ordinary tool round-trip so the model reads the answers the\n * same way it reads its own `ask`'s.\n *\n * COSTS NO MODEL CALL. The questions, their options and their pre-picked defaults are all authored\n * on the `@Agent`, so nothing here is generated and nothing here is billed — which is also why the\n * total is knowable before the first question is shown.\n *\n * One checkpoint whenever an `intake` is configured, plus two more on the turns it actually asks —\n * all of them reachable only through that config, so a run that predates the option cannot land on\n * any of them and no marker is spent keeping the sequence stable for it. See\n * {@link AgentLoopHooks.patched} for the case that does need one.\n */\nasync function runIntake(\n intake: AgentIntake,\n deps: AgentLoopDeps,\n input: AgentRunInput,\n hooks: AgentLoopHooks,\n writer: SinkWriter,\n threadHasAssistant: boolean,\n): Promise<ModelMessage | null> {\n const preamble = intake.preamble ?? DEFAULT_INTAKE_PREAMBLE;\n // Derived from the run, so a replay rebuilds the same id without minting one — the id is a\n // checkpoint name's suffix and the signal's own key, so it cannot come from a random source.\n const request: ElicitationRequest = {\n id: `intake-${hooks.runId}`,\n source: 'intake',\n preamble,\n questions: intake.questions,\n };\n const call: ToolCallRequest = {\n id: request.id,\n name: ASK_TOOL_NAME,\n input: { preamble, questions: intake.questions },\n kind: 'ask',\n };\n // The message id rides the checkpoint because the answers land on the SAME message the questions\n // did, and the step that settles them runs after a wait that can outlive the process.\n const asked = await hooks.step('intake:ask', async (): Promise<{ messageId: string } | null> => {\n if (!intakeApplies(intake, threadHasAssistant)) {\n return null;\n }\n const message = await deps.store.appendMessage({\n threadId: input.threadId,\n role: 'assistant',\n content: preamble,\n runId: hooks.runId,\n toolCalls: [call],\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n });\n await deps.store.recordToolCall({\n toolCallId: request.id,\n messageId: message.id,\n toolName: ASK_TOOL_NAME,\n // The store knows read/action only. An unanswered question is work waiting on a human, which\n // is what `action` + `pending_approval` already mean — so it surfaces in an approvals inbox\n // rather than needing one of its own.\n toolType: 'action',\n input: call.input,\n status: 'pending_approval',\n runId: hooks.runId,\n });\n await writer.write(encodeStreamEvent({ kind: 'elicitation', id: request.id, request }));\n return { messageId: message.id };\n });\n if (asked === null) {\n return null;\n }\n const messageId = asked.messageId;\n const reply = await awaitElicitation(hooks, request, toolContext(deps, input, hooks));\n const result = settleElicitation(request, reply);\n await hooks.step('intake:answers', async () => {\n await deps.store.updateToolCall({\n toolCallId: request.id,\n // A skip is not an answer. Both leave the agent holding the same values, but only one of them\n // is evidence the user chose them, and a reader auditing what the agent was told has to be\n // able to tell those apart.\n status: result.skipped ? 'rejected' : 'executed',\n output: result,\n ...(result.skipped ? { error: 'skipped by the user' } : {}),\n ...(reply.answeredByRef !== undefined ? { executedByRef: reply.answeredByRef } : {}),\n });\n await deps.store.setMessageToolResults(messageId, [\n { id: request.id, name: ASK_TOOL_NAME, output: result },\n ]);\n await writer.write(encodeStreamEvent({ kind: 'tool-output', id: request.id, output: result }));\n });\n return {\n role: 'assistant',\n content: preamble,\n toolCalls: [call],\n toolResults: [{ id: request.id, name: ASK_TOOL_NAME, output: result }],\n };\n}\n\n/**\n * Identifies the batched tool-call shape to {@link AgentLoopHooks.patched}. Batching hoists the\n * turn's `persist:toolcall` checkpoints ahead of its first tool execution, so a run that suspended\n * mid-turn under the one-call-at-a-time shape must keep replaying against THAT one.\n */\nconst PARALLEL_TOOLS_PATCH = 'agent:parallel-tools';\n\n/**\n * Identifies the cancellable loop shape to {@link AgentLoopHooks.patched}. The observation points it\n * guards are new positions in the middle of the sequence, so a run that suspended before a\n * deployment gained them must keep replaying against the sequence its history holds.\n */\nconst CANCELLATION_PATCH = 'agent:cancellation';\n\n/**\n * Identifies the selected-history load to {@link AgentLoopHooks.patched}. `load:thread` keeps its\n * name and its position; what changed is what it CHECKPOINTS — the messages the turn will send\n * rather than the whole `ThreadDetail` — and a checkpoint's payload is a wire contract with every\n * run already in flight just as its name is.\n *\n * A marker rather than a tolerance for the old payload, because the two shapes cannot be told apart\n * where it matters: both carry `messages` and a `title`, and an empty thread serializes to something\n * either release could have written. The marker is a fact the JOURNAL holds, at a position the\n * runtime hands back to a run that recorded a real step there, so the branch is decided by the run's\n * own history rather than by a guess at its bytes. What rides on getting it right is\n * `history:summarize`: its presence depends on a split the old payload carries no record of, so a\n * resume that read that payload as the new shape would skip a position the history has spent.\n */\nconst SELECTED_HISTORY_PATCH = 'agent:selected-history';\n\n/**\n * Identifies the JOURNALED prompt-stage set to {@link AgentLoopHooks.patched} — the marker that lets\n * {@link PromptStages} be read back from a run's own history instead of re-derived from whatever\n * module config the process replaying it happens to hold.\n *\n * WHERE IT SITS, and why the choice is narrow. Probed after the history load and immediately before\n * `run:started-at`. The position has to be one that every journal written before this marker existed\n * fills with a REAL step whatever it was configured with — because `patched` refuses, raising\n * `NonDeterminismError` rather than rewinding, when it finds a DIFFERENT `patch:` marker where it\n * looks. That rules out the position after `persist:user`, which holds `agent:selected-history`, and\n * the position after `persist:run:start`, which holds `agent:cancellation` on a deployment that\n * enables none of the three stages. `load:thread`, `run:started-at` and `persist:run:start` are the\n * unconditional steps in between, and this marker takes the gap before the second of them.\n *\n * WHY NOT A MARKER PER STAGE, guarding each stage's own position. Because a stage's position is\n * already occupied on every deployment that has the stage switched on: a journal written with memory\n * enabled holds `memory:digest` exactly where that marker would sit, `patched` rewinds and answers\n * false there, and the guard would then SKIP a checkpoint the history holds — diverging a few\n * positions later, on every in-flight run of every host already using the feature. That is the\n * opposite of the protection it was reached for. `agent:dispatched-steps` can be guarded that way\n * only because no journal anywhere holds the shape it guards without also holding the marker.\n * Journals DO hold `memory:digest`, `retrieve` and `skills:catalog` with no marker in front of them.\n *\n * So the marker records a property of the BODY — \"this run journals which prompt stages it had\" —\n * and the per-stage answers ride in the checkpoint below, where three independent switches are\n * stated separately instead of one boolean standing in for all of them.\n */\nconst PROMPT_STAGES_PATCH = 'agent:prompt-stages';\n\n/**\n * Which of the three optional prompt stages this RUN had. Each spends a checkpoint position that\n * exists only where a host wired the matching dep, so together they decide the turn's checkpoint\n * SEQUENCE:\n *\n * - `memory` → `memory:digest`\n * - `retriever` → `retrieve`\n * - `skills` → `skills:catalog`\n *\n * Read from module config ONCE, at {@link PROMPT_STAGES_PATCH}'s position, and journaled there.\n * Every later replay reads those three answers back — so enabling memory on a deployment cannot\n * insert a position into a run that is parked on a human's approval, and disabling it cannot take\n * one away.\n *\n * WHAT IT DOES NOT COVER, because the next reader should not have to assume. `quota` is the one\n * stage of this kind that CANNOT be guarded this way: `quota:check` is the loop's first position, so\n * the only marker position that precedes it is the workflow's own first, which\n * `agent:dispatched-steps` already owns — and a second marker there would make that guard raise\n * instead of rewind. Enabling a quota store under a parked run therefore still shifts its sequence.\n * `pricingStore` (`pricing:list`), `intake` (`intake:ask`/`intake:answers`), `inputProcessors`\n * (`process:input:<step>`), `outputProcessors` (`process:output:<step>` and the follow-ups gate),\n * `followUpsCount` (`followups:<step>` and its usage row) and `outputSchema` (`structured:*`) all\n * sit after this marker and so COULD join this payload; they do not yet. A field added here for one\n * of them reads back `undefined` on a run journaled before it, which has to mean \"fall back to\n * config\" — that run's exposure unchanged rather than inverted.\n *\n * WHAT STAYS MODULE CONFIG, deliberately: the turn's TOOL LIST. Whether the model is offered `skill`\n * or `remember` is uniform across a deployment and is re-derived on whichever worker serves a\n * dispatched model call, and the `skill`/`remember` handlers already answer a call they have no\n * catalog or digest for as a tool failure. Only positions are journaled here.\n */\ninterface PromptStages {\n memory: boolean;\n retriever: boolean;\n skills: boolean;\n}\n\n/**\n * The prompt stages this run is held to: the journal's record of them, or — for a run whose journal\n * predates {@link PROMPT_STAGES_PATCH} — the live configuration, which is what that run's own body\n * used.\n */\nasync function resolvePromptStages(\n deps: AgentLoopDeps,\n hooks: AgentLoopHooks,\n): Promise<PromptStages> {\n const configured: PromptStages = {\n memory: deps.memory !== undefined,\n retriever: deps.retriever !== undefined,\n skills: deps.skills !== undefined,\n };\n return (await (hooks.patched?.(PROMPT_STAGES_PATCH) ?? Promise.resolve(true)))\n ? hooks.step('run:prompt-stages', () => Promise.resolve(configured))\n : configured;\n}\n\n// What a stage answers where the RUN recorded it but this process has nothing wired to serve it —\n// the mid-rollout case of a dep taken away under a run that is still in flight.\n//\n// Reachable only on the attempt that first ARRIVES at the position: a replay is served the journaled\n// payload without running the body at all. So what it costs is one run's worth of the stage\n// degrading to nothing, in exchange for the position staying where the history put it — the same\n// posture the `skill` and `remember` handlers take when their config has gone.\nconst UNSERVED_MEMORY: MemoryDigest = { scopes: [], entries: [], omitted: 0, pinnedOmitted: 0 };\nconst UNSERVED_SKILLS: SkillOffer = { scopes: [], entries: [], omitted: 0 };\n\n/**\n * Read the cancel flag at one of the loop's safe points, and unwind the turn if it is set.\n *\n * The read is a checkpoint, which is the whole design: the answer becomes a fact the journal holds\n * rather than one each replaying process asks afresh — see {@link AgentLoopHooks.cancelled}. Unwinds\n * by THROWING, the same way a suspend leaves the turn, so every `catch` between here and the runner\n * already knows to let it past without writing checkpoints of its own.\n *\n * A tool that is already executing is NOT interrupted. There is no un-executing a side effect, and\n * abandoning a dispatched step mid-flight would leave the journal holding a dispatch whose result\n * never lands — so an in-flight call finishes, is recorded exactly as it would have been, and the\n * cancel is observed at the next point instead.\n */\nasync function haltIfCancelled(\n hooks: AgentLoopHooks,\n cancellable: boolean,\n name: string,\n): Promise<void> {\n const observe = hooks.cancelled;\n if (!cancellable || observe === undefined) {\n return;\n }\n if (await hooks.step(name, () => observe())) {\n throw new RunCancelledError();\n }\n}\n\n/** What every per-call helper below needs from the turn that requested the call. */\ninterface ToolTurnContext {\n deps: AgentLoopDeps;\n input: AgentRunInput;\n hooks: AgentLoopHooks;\n /** The assistant message the calls hang off. */\n messageId: string;\n /** The run's live stream — an `ask` posts its question set here while the turn parks. */\n writer: SinkWriter;\n /**\n * What each call pushed through `ctx.emitUi`, by call id, read off the tool steps' results. The\n * step persists them onto the message in call order once every tool has settled.\n */\n toolUi: Map<string, AgentUiComponent[]>;\n toolText: Map<string, string>;\n /** Set when a `terminal` tool succeeded: the turn ends after this step. */\n halt: { terminal: boolean; independentProposal?: boolean };\n actionApprovalMode?: ActionApprovalMode;\n /**\n * What `skills:catalog` recorded this turn, or undefined where skills are not configured. A\n * `skill` call is served against THIS, never against a fresh provider read — see {@link loadSkill}.\n */\n skills?: SkillOffer;\n /**\n * What `memory:digest` recorded this turn, or undefined where memory is not configured. A\n * `remember` call is authorized against THIS digest's scopes, never a fresh resolution — see\n * {@link writeMemory}.\n */\n memory?: MemoryDigest;\n /** What `persona:resolve` recorded, or undefined where the turn runs under no persona. */\n persona?: TurnPersona;\n}\n\n/** A tool call whose kind has been settled by its `persist:toolcall` checkpoint. */\ninterface ClaimedToolCall {\n /** The call as the model asked for it. */\n call: ToolCallRequest;\n /** The same call with `kind` agreeing with the branch actually taken. */\n resolvedCall: ToolCallRequest;\n toolType: ToolKind;\n targetAgent?: string;\n /** For an `agent` call — whether the journal says this delegation runs detached. */\n detached?: boolean;\n /** The journal says a successful call ends the turn (`ToolSpec.terminal`). */\n terminal?: boolean;\n /** Opt in to the completed-preflight presentation checkpoint from the journaled claim. */\n presentCompletedPreflight?: true;\n /**\n * For an `action` call — how the journal says it is approved. Undefined for a call claimed before\n * approval policies existed, which waits on the requester with no expiry, as it always did.\n */\n approval?: ClaimedApproval;\n preflight?: ToolPreflightResult | { status: 'failed'; error: string };\n proposalId?: string;\n ctx: AiToolCtx;\n}\n\n/**\n * The approval branch an `action` call takes, settled inside its `persist:toolcall` checkpoint:\n * - `ask` → park on a person (`approver`), for at most `ttlMs` when set;\n * - `auto` → the policy did not require one: run straight away;\n * - `remembered` → an earlier decision in this thread approved this tool for good: run straight away.\n */\ntype ClaimedApproval =\n | { mode: 'ask'; approver: string; ttlMs?: number; expiresAt?: string }\n | { mode: 'auto' }\n | { mode: 'remembered'; approver: string };\n\n/** What a decided action call records next to its outcome, and streams as `approval-settled`. */\ninterface ApprovalMeta {\n approver?: string;\n decidedBy: string;\n decidedVia?: string;\n remember?: boolean;\n /**\n * Stream `approval-settled` with the outcome. False for a call claimed before approval policies\n * existed: its decision is still recorded, but that run keeps writing the frames it always wrote.\n */\n streamed: boolean;\n}\n\n/** One invocation's result, already reduced to what the persist checkpoint writes. */\ntype ToolOutcome =\n | { status: 'executed'; output: unknown; executionMs: number }\n | { status: 'failed'; error: string; executionMs: number }\n | { status: 'denied'; reason: string; executionMs: number };\n\n/**\n * Record the call and settle its KIND, which decides this call's control flow: an `action` suspends\n * the run on an approval signal (`signal:tool:<runId>:<callId>`), anything else records a step.\n * Reading it from `deps.registry` in the loop body would tie that branch to the registry of\n * WHICHEVER PROCESS runs the body — and a process whose registry lacks this tool reads `undefined`,\n * falls back to 'read', and expects a `tool:` checkpoint where the history holds `signal:tool:`.\n * That is a NonDeterminismError on resume, and worse, when execution is dispatched\n * (`hooks.dispatchTool`) it reaches a worker that DOES have the tool: an action executed with\n * nobody's approval.\n *\n * Two things keep that from happening, and they answer different halves of it:\n *\n * - The kind is RETURNED from the `persist:toolcall` step, so every replay reads back the same\n * verdict instead of asking its own registry. That makes the decision CONSISTENT.\n * - The kind it writes is the one {@link stampToolKinds} put on the call inside the llm\n * checkpoint, where the tool was offered. That makes the decision CORRECT — the step is not\n * necessarily first reached by a process that knows the tool. A dispatched turn resumes on\n * whichever instance consumes the model step's result, and settling an approval resumes it on\n * whichever instance took the decision; neither is chosen by role. A pod that registers no\n * tool classes reached this step and journaled `read` for an action tool, intermittently,\n * depending on which pod won that race.\n *\n * The local lookup remains as the fallback for a call that arrives unstamped: a journal written\n * before kinds travelled, or a host driving the loop with no llm checkpoint of its own. Same step\n * name at the same position throughout, so runs already in flight keep replaying.\n */\nasync function claimToolCall(\n turn: ToolTurnContext,\n call: ToolCallRequest,\n): Promise<ClaimedToolCall> {\n const { deps, input, hooks, messageId } = turn;\n const persisted = (await hooks.step(`persist:toolcall:${call.id}`, async () => {\n const spec = deps.registry.spec(call.name);\n const kind: ToolKind = call.kind ?? declaredKind(deps, call.name);\n // Both kinds that park the turn on a person. The store knows read/action only; a delegation is\n // neither approved nor rejected by a human, so it persists as a read.\n const awaitsHuman = kind === 'action' || kind === 'ask';\n // Decided HERE, inside the checkpoint, and returned from it: the policy and the remembered set\n // can both change while a run is parked, and the branch below (park or run) has to be the one\n // the journal recorded. A run claimed before this existed reads `approval` back as undefined and\n // waits on the requester, exactly as it did.\n const independentApproval =\n turn.actionApprovalMode === 'independent' && kind === 'action'\n ? hooks.dispatchLlm !== undefined && call.actionApproval !== undefined\n ? call.actionApproval\n : await resolveActionProposalApproval({\n actor: input.actor,\n store: deps.store,\n tool: { name: call.name, kind: 'action', ...(spec !== undefined ? { spec } : {}) },\n thread: {\n threadId: input.threadId,\n runId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n },\n ...(deps.approvalPolicy !== undefined ? { policy: deps.approvalPolicy } : {}),\n })\n : undefined;\n let preflight: ClaimedToolCall['preflight'];\n let prepared: Awaited<ReturnType<typeof prepareActionProposal>> | undefined;\n if (\n turn.actionApprovalMode === 'independent' &&\n call.prepared !== undefined &&\n hooks.dispatchLlm !== undefined\n )\n prepared = call.prepared;\n if (kind === 'action' && hooks.dispatchLlm !== undefined && call.preflight !== undefined) {\n preflight = call.preflight;\n } else if (kind === 'action' && hooks.dispatchLlm !== undefined && spec === undefined) {\n // A legacy remote journal has no prepared stamp. Keep its original approval branch;\n // every new worker stamps preparation before returning the turn.\n preflight = { status: 'ready' };\n } else if (kind === 'action') {\n try {\n const allowedTools =\n turn.persona?.allowedTools === undefined\n ? deps.toolAllowList\n : intersectAllowLists(deps.toolAllowList, turn.persona.allowedTools);\n if (independentApproval?.mode === 'ask') {\n prepared = await prepareActionProposal(\n deps.registry,\n call.name,\n call.input,\n toolCallContext(toolContext(deps, input, hooks), call.id),\n deps.rolesPolicy,\n allowedTools === undefined ? {} : { allowedTools },\n );\n preflight = prepared.preflight;\n } else {\n preflight = await deps.registry.prepare(\n call.name,\n call.input,\n toolCallContext(toolContext(deps, input, hooks), call.id),\n deps.rolesPolicy,\n allowedTools === undefined ? {} : { allowedTools },\n );\n }\n } catch (error) {\n if (\n hooks.isControlFlowError?.(error) === true ||\n isControlFlowSignal(error) ||\n isReplayIntegrityError(error)\n )\n throw error;\n preflight = {\n status: 'failed',\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n let confirmation = preflight?.status === 'ready' ? preflight.confirmation : undefined;\n const approval =\n kind === 'action' && preflight?.status === 'ready'\n ? (independentApproval ?? (await claimApproval(turn, call, spec)))\n : undefined;\n let proposalId: string | undefined;\n if (turn.actionApprovalMode === 'independent' && approval?.mode === 'ask') {\n if (!prepared) throw new Error('Independent action lacks trusted prepared input');\n const proposalStore = deps.store as AgentStore & ActionProposalStore;\n if (typeof proposalStore.createActionProposal !== 'function')\n throw new Error('Independent action proposal store unavailable');\n proposalId = `proposal-${createHash('sha256')\n .update(JSON.stringify([hooks.runId, call.id]))\n .digest('hex')}`;\n const display = confirmation ??\n spec?.presentation?.confirm ?? { title: `Allow ${call.name}?`, verb: 'Approve' };\n const fill = (value: string) =>\n value.replace(/\\{([^}]+)\\}/g, (_match, path: string) => {\n let current: unknown = prepared?.input;\n for (const part of path.split('.'))\n current =\n current !== null && typeof current === 'object'\n ? (current as Record<string, unknown>)[part]\n : undefined;\n return current === undefined ? '' : String(current);\n });\n const create =\n prepared.replacementKey === undefined\n ? proposalStore.createActionProposal.bind(proposalStore)\n : (() => {\n const store = proposalStore as AgentStore &\n ActionProposalStore &\n ActionProposalSupersessionStore;\n if (typeof store.createReplacingActionProposal !== 'function')\n throw new Error('Independent replacement requires atomic supersession store');\n return store.createReplacingActionProposal.bind(store);\n })();\n const created = await create({\n ...(prepared.replacementKey !== undefined\n ? { replacementKey: prepared.replacementKey }\n : {}),\n id: proposalId,\n tenantRef: input.actor.tenantRef ?? null,\n actorRef: input.actor.id,\n threadId: input.threadId,\n originRunId: hooks.runId,\n originMessageId: messageId,\n originToolCallId: call.id,\n toolName: call.name,\n input: prepared.input,\n preparationInput: prepared.preparationInput,\n executionContext: {\n requestId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(input.uiCapabilities !== undefined ? { uiCapabilities: input.uiCapabilities } : {}),\n },\n confirmation: confirmation ?? {\n title: fill(display.title),\n verb: fill(display.verb),\n ...(display.detail !== undefined ? { detail: fill(display.detail) } : {}),\n },\n approver: approval.approver,\n expiresAt: approval.expiresAt === undefined ? null : Date.parse(approval.expiresAt),\n idempotencyKey: toolCallContext(toolContext(deps, input, hooks), call.id).idempotencyKey,\n });\n if (created.status === 'conflict') throw new Error('Action proposal replay payload conflict');\n confirmation = created.proposal?.confirmation ?? confirmation;\n }\n const parks = kind === 'ask' || (approval?.mode === 'ask' && proposalId === undefined);\n await deps.store.recordToolCall({\n toolCallId: call.id,\n messageId,\n toolName: call.name,\n toolType: awaitsHuman ? 'action' : 'read',\n input: call.input,\n status: proposalId !== undefined ? 'proposed' : parks ? 'pending_approval' : 'auto_executed',\n ...(proposalId !== undefined ? { proposalId } : {}),\n runId: hooks.runId,\n ...(confirmation !== undefined ? { confirmation } : {}),\n ...(approval !== undefined && approval.mode !== 'auto'\n ? { approver: approval.approver }\n : {}),\n ...(approval?.mode === 'ask' && approval.expiresAt !== undefined\n ? { expiresAt: approval.expiresAt }\n : {}),\n });\n if (approval?.mode === 'ask') {\n // Streamed from inside the same checkpoint so a replay never repeats it. The call itself was\n // announced by the model step that asked for it, so the frame can name it by id.\n await turn.writer.write(\n encodeStreamEvent({\n kind: 'approval-requested',\n id: call.id,\n ...(proposalId !== undefined\n ? { target: { kind: 'proposal' as const, proposalId } }\n : {}),\n approver: approval.approver,\n ...(confirmation !== undefined ? { confirmation } : {}),\n ...(approval.expiresAt !== undefined ? { expiresAt: approval.expiresAt } : {}),\n }),\n );\n }\n return {\n kind,\n ...(spec?.targetAgent !== undefined ? { targetAgent: spec.targetAgent } : {}),\n // Only an `agent` spec ever carries this, and only when the author declared it — so a\n // deployment with no detached edge writes the same bytes here it always has.\n ...(spec?.detached === true ? { detached: true } : {}),\n // Same for `terminal`: absent unless declared, so a deployment with no terminal tool writes\n // the bytes it always has, and a replay reads the branch back instead of re-deciding it.\n ...(spec?.terminal === true ? { terminal: true } : {}),\n // Journal this extra checkpoint's opt-in; historical claims without it keep their sequence.\n ...(preflight?.status === 'completed' && deps.registry.hasPresentation(call.name)\n ? { presentCompletedPreflight: true }\n : {}),\n ...(approval !== undefined ? { approval } : {}),\n ...(preflight !== undefined ? { preflight } : {}),\n ...(proposalId !== undefined ? { proposalId } : {}),\n };\n })) as\n | {\n kind?: ToolKind;\n targetAgent?: string;\n detached?: boolean;\n terminal?: boolean;\n presentCompletedPreflight?: true;\n approval?: ClaimedApproval;\n preflight?: ClaimedToolCall['preflight'];\n proposalId?: string;\n }\n | undefined;\n const toolType: ToolKind = persisted?.kind ?? call.kind ?? 'read';\n return {\n call,\n // What the rest of the turn — the dispatched tool envelope, the stream frames — sees as this\n // call's kind, so it agrees with the branch actually taken instead of with a second lookup.\n resolvedCall: call.kind === toolType ? call : { ...call, kind: toolType },\n toolType,\n ...(persisted?.targetAgent !== undefined ? { targetAgent: persisted.targetAgent } : {}),\n ...(persisted?.detached === true ? { detached: true } : {}),\n ...(persisted?.terminal === true ? { terminal: true } : {}),\n ...(persisted?.presentCompletedPreflight === true ? { presentCompletedPreflight: true } : {}),\n ...(toolType === 'action' && persisted?.approval !== undefined\n ? { approval: persisted.approval }\n : {}),\n ...(persisted?.preflight !== undefined ? { preflight: persisted.preflight } : {}),\n ...(persisted?.proposalId !== undefined ? { proposalId: persisted.proposalId } : {}),\n ctx: toolContext(deps, input, hooks),\n };\n}\n\n/**\n * How an `action` call gets approved: ask the turn's policy, then — when it wants a person — check\n * whether someone in this thread already approved this tool for good. Runs INSIDE the call's\n * `persist:toolcall` checkpoint; see {@link claimToolCall}.\n */\nasync function claimApproval(\n turn: ToolTurnContext,\n call: ToolCallRequest,\n spec: ToolSpec | undefined,\n): Promise<ClaimedApproval> {\n const { deps, input, hooks } = turn;\n const policy = deps.approvalPolicy ?? new DefaultApprovalPolicy();\n const requirement: ApprovalRequirement = await policy.requirementFor(\n { name: call.name, kind: 'action', ...(spec !== undefined ? { spec } : {}) },\n input.actor,\n {\n threadId: input.threadId,\n runId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n },\n );\n if (!requirement.required) {\n return { mode: 'auto' };\n }\n const remembered = (await deps.store.rememberedApprovals?.(input.threadId)) ?? [];\n if (remembered.includes(call.name)) {\n return { mode: 'remembered', approver: requirement.approver };\n }\n const ttlMs =\n requirement.ttlMs !== undefined && Number.isFinite(requirement.ttlMs) && requirement.ttlMs > 0\n ? Math.floor(requirement.ttlMs)\n : undefined;\n return {\n mode: 'ask',\n approver: requirement.approver,\n ...(ttlMs !== undefined\n ? { ttlMs, expiresAt: new Date(Date.now() + ttlMs).toISOString() }\n : {}),\n };\n}\n\n/** What a served `skill` call hands back to the model — the procedure, and where it came from. */\ninterface LoadedSkillOutput {\n name: string;\n scope: string;\n body: string;\n /** Scopes of same-named skills this one overrode. Present only when it overrode something. */\n shadows?: string[];\n}\n\n/**\n * Serve one `skill` call: read the body and hand it to the model as an ordinary tool result.\n *\n * WHY THE BODY IS RETURNED FROM THE CHECKPOINT. Which instructions entered a turn's prompt is a\n * decision about the turn, and a decision about a turn has to be readable from its journal — the\n * same property `persist:toolcall` gives the read/action branch. A replay that re-read the provider\n * would compose a DIFFERENT prompt from a skill edited in between, on a transcript position the\n * history already holds: the model would then be answering something nobody can reconstruct from the\n * record, and a turn whose step count depends on what it was told would ask for a position its\n * history has no room for. Inside `tool:<callId>` the first attempt's text is the only text there\n * ever was.\n *\n * The positions are a read tool's, exactly (`persist:toolcall` above, `tool:<id>` here,\n * `persist:toolexec:<id>`/`persist:toolfail:<id>` after), so nothing about the shape of a turn\n * depends on whether a call was a skill — only on the kind the journal recorded.\n */\nasync function loadSkillIntoTurn(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n startedAt: number,\n): Promise<ToolOutcome> {\n const { deps, input, hooks } = turn;\n const { call } = claimed;\n const config = deps.skills;\n const offer = turn.skills;\n const outcome = await hooks.step(\n `tool:${call.id}`,\n async (): Promise<{ ok: true; output: LoadedSkillOutput } | { ok: false; error: string }> => {\n if (config === undefined || offer === undefined) {\n // Reachable only where a call's journaled kind is `skill` but this process has no skills\n // configured — a deployment mid-rollout. A tool failure, because it is the one vocabulary\n // the model can act on, and because failing the run would strand a turn over a lookup.\n return { ok: false, error: 'Skills are not available in this deployment.' };\n }\n const parsed = await skillInputSchema['~standard'].validate(call.input);\n if (parsed.issues !== undefined) {\n return {\n ok: false,\n error: `invalid skill input: ${parsed.issues.map((each) => `${(each.path ?? []).join('.') || '(root)'}: ${each.message}`).join('; ')}`,\n };\n }\n const loaded = await loadSkill(config, offer, parsed.value.name, skillContext(input));\n if (!loaded.ok) {\n return { ok: false, error: loaded.error };\n }\n return {\n ok: true,\n output: {\n name: loaded.skill.name,\n scope: loaded.skill.scope,\n body: loaded.skill.body,\n ...(loaded.shadows !== undefined ? { shadows: loaded.shadows } : {}),\n },\n };\n },\n );\n return outcome.ok\n ? { status: 'executed', output: outcome.output, executionMs: Date.now() - startedAt }\n : { status: 'failed', error: outcome.error, executionMs: Date.now() - startedAt };\n}\n\n/**\n * Serve one `remember` call: write the fact and hand the stored record back as an ordinary tool\n * result.\n *\n * WHY THE WRITE HAPPENS INSIDE THE CHECKPOINT. Two reasons, and the second is the one that is easy\n * to miss. It makes the write idempotent under replay — a resumed run reads the record back from\n * `tool:<callId>` instead of storing a second copy of a fact the model only decided once. And it\n * makes what the model was TOLD about the write part of the journal, so the transcript a later step\n * reads is the one the first attempt built, rather than whatever a second write would have returned.\n *\n * The positions are a read tool's, exactly, so nothing about the shape of a turn depends on whether\n * a call wrote a memory — only on the kind the journal recorded.\n */\nasync function rememberIntoTurn(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n startedAt: number,\n): Promise<ToolOutcome> {\n const { deps, input, hooks } = turn;\n const { call } = claimed;\n const config = deps.memory;\n const digest = turn.memory;\n const outcome = await hooks.step(\n `tool:${call.id}`,\n async (): Promise<{ ok: true; record: MemoryRecord } | { ok: false; error: string }> => {\n if (config === undefined || digest === undefined) {\n // Reachable only where a call's journaled kind is `memory` but this process has none\n // configured — a deployment mid-rollout. A tool failure, because it is the one vocabulary\n // the model can act on, and because failing the run would strand a turn over a lookup.\n return { ok: false, error: 'Memory is not available in this deployment.' };\n }\n const parsed = await rememberInputSchema['~standard'].validate(call.input);\n if (parsed.issues !== undefined) {\n return {\n ok: false,\n error: `invalid remember input: ${parsed.issues.map((each) => `${(each.path ?? []).join('.') || '(root)'}: ${each.message}`).join('; ')}`,\n };\n }\n return await writeMemory({\n config,\n digest,\n call: parsed.value,\n ctx: skillContext(input),\n runId: hooks.runId,\n });\n },\n );\n if (!outcome.ok) {\n return { status: 'failed', error: outcome.error, executionMs: Date.now() - startedAt };\n }\n publishAgentMemoryWritten({\n runId: hooks.runId,\n scope: outcome.record.scope,\n chars: outcome.record.text.length,\n });\n return { status: 'executed', output: outcome.record, executionMs: Date.now() - startedAt };\n}\n\n/** The turn's identity as the skills seam sees it — the same inputs the prompt is resolved from. */\nfunction skillContext(input: AgentRunInput): SkillContext {\n return {\n actor: input.actor,\n threadId: input.threadId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(input.uiCapabilities !== undefined ? { uiCapabilities: input.uiCapabilities } : {}),\n };\n}\n\n/**\n * Execute one claimed call. Requests its checkpoint SYNCHRONOUSLY (nothing is awaited before\n * `hooks.dispatchTool`/`hooks.step`), which is what lets a batch of these be launched together and\n * still occupy positions in call order — see {@link AgentLoopHooks.parallel}.\n *\n * A tool's own failure is an outcome, not a throw: the model gets it as a result and adapts. Only\n * the runner's control flow (a durable suspend / continue-as-new) and a replay-integrity refusal\n * escape — a `catch` that answered either of those by writing a `persist:toolfail` checkpoint would\n * diverge from the replay's real result, or ask for a position a diverged history has no room for\n * so the operator reads the second refusal instead of the disagreement that caused it.\n */\nasync function invokeClaimedTool(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n): Promise<ToolOutcome> {\n const { deps, input, hooks } = turn;\n const { call, resolvedCall, ctx } = claimed;\n // An `agent` call branches to delegation before reaching here, so anything that isn't an `action`\n // is a read — the same posture the kind fallback itself takes.\n const toolType = claimed.toolType === 'action' ? 'action' : 'read';\n const startedAt = Date.now();\n try {\n // Inside the same `try` as a registered tool's invocation, so a provider that throws is recorded\n // as this call's failure — and a suspend or a replay refusal still leaves untouched below.\n if (claimed.toolType === 'skill') {\n return await loadSkillIntoTurn(turn, claimed, startedAt);\n }\n if (claimed.toolType === 'memory') {\n return await rememberIntoTurn(turn, claimed, startedAt);\n }\n // Under a persona with an allow-list, the same narrowing the offer had — agent ∩ persona — is\n // what `invoke` holds the call to. Without one, nothing new is checked.\n const invokeAllowList =\n turn.persona?.allowedTools === undefined\n ? deps.toolAllowList\n : intersectAllowLists(deps.toolAllowList, turn.persona.allowedTools);\n let raw: unknown;\n if (hooks.dispatchTool) {\n const stepCtx: ToolStepCtx = {\n actor: input.actor,\n threadId: input.threadId,\n runId: hooks.runId,\n requestId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(input.uiCapabilities !== undefined ? { uiCapabilities: input.uiCapabilities } : {}),\n };\n const envelope: ToolStepEnvelope = {\n toolName: call.name,\n input: call.input,\n ctx: stepCtx,\n ...(invokeAllowList !== undefined ? { allowedTools: invokeAllowList } : {}),\n ...(deps.toolTimeoutMs !== undefined ? { timeoutMs: deps.toolTimeoutMs } : {}),\n // Numeric-only: the handler applies withToolTimeout AND its own local `classify` — see\n // ToolStepEnvelope.transientRetry.\n transientRetry: resolveToolTransientRetryNumbers(deps.toolTransientRetry),\n // The handler hands back what the tool pushed through `ctx.emitUi` with its output.\n collectUi: true,\n };\n // The handler applies withToolTimeout (and the retry loop) itself — no loop-side wrap for\n // a dispatched call.\n raw = await hooks.dispatchTool(resolvedCall, envelope);\n } else {\n const invocation = hooks.step(`tool:${call.id}`, async () => {\n // Pushed components stream as they happen and ride this step's RESULT into the journal\n // (see `wrapToolStepOutput`), so a replay neither re-streams nor re-persists them.\n const ui = createNegotiatedUiCollector(call.id, ctx, deps.resolveUiCatalog, (event) =>\n turn.writer.write(encodeStreamEvent(event)),\n );\n let output: unknown;\n try {\n output = await traceToolExecution(\n hooks.runId,\n { toolCallId: call.id, toolName: call.name, toolType },\n () =>\n invokeWithTransientRetry(\n () => {\n ui.restart();\n return deps.registry.invoke(\n call.name,\n call.input,\n { ...toolCallContext(ctx, call.id), emitUi: ui.emit },\n deps.rolesPolicy,\n invokeAllowList !== undefined ? { allowedTools: invokeAllowList } : {},\n );\n },\n deps.toolTransientRetry ?? {},\n {\n ...(hooks.isControlFlowError !== undefined\n ? { isControlFlowError: hooks.isControlFlowError }\n : {}),\n onRetry: (attempt, retryError) => {\n publishAgentToolRetry({\n toolName: call.name,\n toolCallId: call.id,\n attempt,\n message:\n retryError instanceof Error ? retryError.message : String(retryError),\n });\n },\n },\n ),\n );\n } catch (error) {\n if (error instanceof Error && error.name === 'ToolPreflightDeniedError')\n return wrapToolPreflightDenied(error.message);\n throw error;\n }\n return wrapToolStepOutput(output, ui.components(), ui.text());\n });\n raw =\n deps.toolTimeoutMs !== undefined\n ? await withToolTimeout(invocation, deps.toolTimeoutMs, call.name)\n : await invocation;\n }\n const { output, ui, preflightDenied, text } = unwrapToolStepOutput(raw);\n if (text) turn.toolText.set(call.id, text);\n if (preflightDenied !== undefined)\n return { status: 'denied', reason: preflightDenied, executionMs: Date.now() - startedAt };\n if (ui.length > 0) {\n turn.toolUi.set(call.id, ui);\n }\n if (claimed.terminal === true) {\n turn.halt.terminal = true;\n }\n return { status: 'executed', output, executionMs: Date.now() - startedAt };\n } catch (error) {\n if (\n hooks.isControlFlowError?.(error) === true ||\n isControlFlowSignal(error) ||\n isReplayIntegrityError(error)\n ) {\n throw error;\n }\n if (error instanceof Error && error.name === 'ToolPreflightDeniedError') {\n return { status: 'denied', reason: error.message, executionMs: Date.now() - startedAt };\n }\n return {\n status: 'failed',\n error: error instanceof Error ? error.message : String(error),\n executionMs: Date.now() - startedAt,\n };\n }\n}\n\n/** Persist one settled invocation and shape the result the model is fed. */\nasync function recordToolOutcome(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n outcome: ToolOutcome,\n deciderRef: string,\n meta?: ApprovalMeta,\n): Promise<ToolResult> {\n const { deps, hooks } = turn;\n const { call } = claimed;\n const toolType = claimed.toolType === 'action' ? 'action' : 'read';\n // What a decided call adds to its row: how it was decided. Written with the outcome rather than\n // at a checkpoint of its own, so an approval adds no position to the turn.\n const decided =\n meta === undefined\n ? {}\n : {\n executedByRef: meta.decidedBy,\n ...(meta.decidedVia !== undefined ? { decidedVia: meta.decidedVia } : {}),\n ...(meta.remember === true ? { remember: true } : {}),\n };\n const settle = async () => {\n if (meta === undefined || !meta.streamed) {\n return;\n }\n await turn.writer.write(\n encodeStreamEvent({\n kind: 'approval-settled',\n id: call.id,\n status: 'approved',\n ...(meta.approver !== undefined ? { approver: meta.approver } : {}),\n decidedBy: meta.decidedBy,\n ...(meta.decidedVia !== undefined ? { decidedVia: meta.decidedVia } : {}),\n ...(meta.remember === true ? { remember: true } : {}),\n }),\n );\n };\n if (outcome.status === 'denied') {\n await hooks.step(`persist:toolreject:${call.id}`, async () => {\n await deps.store.updateToolCall({\n toolCallId: call.id,\n status: meta === undefined ? 'rejected' : 'failed',\n error: outcome.reason,\n ...decided,\n });\n await settle();\n });\n return {\n id: call.id,\n name: call.name,\n output: { rejected: true, reason: outcome.reason },\n denied: true,\n error: `This action was denied by its preflight check: ${outcome.reason}. The requested mutation did not run.`,\n };\n }\n if (outcome.status === 'failed') {\n await hooks.step(`persist:toolfail:${call.id}`, async () => {\n await deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'failed',\n error: outcome.error,\n executionMs: outcome.executionMs,\n ...decided,\n });\n await settle();\n });\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType,\n status: 'failed',\n durationMs: outcome.executionMs,\n });\n return { id: call.id, name: call.name, output: null, error: outcome.error };\n }\n await hooks.step(`persist:toolexec:${call.id}`, async () => {\n await deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'executed',\n output: outcome.output,\n executionMs: outcome.executionMs,\n ...(toolType === 'action' ? { executedByRef: deciderRef } : {}),\n ...decided,\n });\n await settle();\n });\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType,\n status: 'executed',\n durationMs: outcome.executionMs,\n });\n return { id: call.id, name: call.name, output: outcome.output };\n}\n\n/**\n * Delegate to another agent (an `agent`-kind call) and record what came back as this call's output:\n * the delegate's ANSWER when the turn waited for it, a {@link DetachedDelegationReceipt} when it did\n * not.\n *\n * The two branches write the same checkpoint, under the same name, at the same position — every\n * difference between them lives in the RUNNER's own positions (`ctx.child` suspends and joins;\n * `ctx.startChild` records a `spawn:` and moves on). That is deliberate: which branch a call takes\n * is decided by `persist:toolcall`, whose answer comes out of the journal, so the loop's sequence\n * cannot depend on a registry the replaying process happens to hold.\n */\nasync function delegateToolCall(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n): Promise<ToolResult> {\n const { deps, input, hooks } = turn;\n const { call, targetAgent = call.name } = claimed;\n const task = extractTask(call.input);\n // A detached hop counts like any other: a cycle is cheaper to start that way, not less unbounded.\n const refusal =\n personaRefusal(turn.persona, call.name) ?? delegationRefusal({ deps, input, targetAgent });\n const start = claimed.detached === true && refusal === null ? hooks.startAgent : undefined;\n publishAgentDelegated({\n runId: hooks.runId,\n toAgent: targetAgent,\n ...(input.agentName !== undefined ? { fromAgent: input.agentName } : {}),\n ...(start !== undefined ? { detached: true } : {}),\n });\n let sub: { text: string } | DetachedDelegationReceipt;\n if (refusal !== null) {\n sub = { text: refusal };\n } else if (start !== undefined) {\n const started = await start({ agentName: targetAgent, task, toolCallId: call.id });\n sub = detachedStarted({ agent: targetAgent, runId: started.runId });\n } else if (hooks.runAgent) {\n sub = await hooks.runAgent(targetAgent, task);\n } else {\n sub = { text: `(no multi-agent support wired; cannot reach \"${targetAgent}\")` };\n }\n await hooks.step(`persist:toolexec:${call.id}`, () =>\n deps.store.updateToolCall({ toolCallId: call.id, status: 'executed', output: sub }),\n );\n return { id: call.id, name: call.name, output: sub };\n}\n\n/**\n * Settle an `ask` call against a human. The model authored the questions, so unlike the configured\n * intake there is nothing to persist first — `persist:toolcall` already wrote the row, under the\n * same name and at the same position any other kind would have used.\n *\n * Costs nothing beyond the step that produced it: the question set arrived as the ARGUMENTS of a\n * tool call the model was already making, in a step already billed as `chat`. There is no second\n * model call and therefore no usage row of its own — the opposite of the structured-output pass,\n * which really does buy an extra call.\n *\n * The two new positions here (`stream:elicitation:<id>`, and the wait) are reachable only when this\n * call's journaled kind is `ask`, which no run recorded before the kind existed. Every replay reads\n * that kind back rather than re-deciding it, so no run can disagree about whether they are there.\n */\nasync function elicitToolCall(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n): Promise<ToolResult> {\n const { deps, hooks } = turn;\n const { call, ctx } = claimed;\n // Validated HERE rather than by the registry, which never sees this tool. Deterministic on the\n // same footing as `validateStructured`: a module-constant schema over an input the `llm:<i>`\n // checkpoint already holds, so every replay reaches the same verdict — and the same branch.\n const parsed = await askInputSchema['~standard'].validate(call.input);\n if (parsed.issues !== undefined) {\n const error = `invalid ask input: ${parsed.issues.map((each) => `${(each.path ?? []).join('.') || '(root)'}: ${each.message}`).join('; ')}`;\n await hooks.step(`persist:toolfail:${call.id}`, () =>\n deps.store.updateToolCall({ toolCallId: call.id, status: 'failed', error }),\n );\n // A malformed question set is the model's mistake to fix, so it comes back as a tool failure —\n // the vocabulary the model already knows how to answer — rather than failing the run.\n return { id: call.id, name: call.name, output: null, error };\n }\n const request: ElicitationRequest = {\n id: call.id,\n source: 'ask',\n questions: parsed.value.questions,\n ...(parsed.value.preamble !== undefined ? { preamble: parsed.value.preamble } : {}),\n };\n await hooks.step(`stream:elicitation:${call.id}`, async () => {\n await turn.writer.write(encodeStreamEvent({ kind: 'elicitation', id: call.id, request }));\n });\n const reply = await awaitElicitation(hooks, request, ctx);\n const result = settleElicitation(request, reply);\n await hooks.step(\n result.skipped ? `persist:toolreject:${call.id}` : `persist:toolexec:${call.id}`,\n () =>\n deps.store.updateToolCall({\n toolCallId: call.id,\n status: result.skipped ? 'rejected' : 'executed',\n output: result,\n ...(result.skipped ? { error: 'skipped by the user' } : {}),\n ...(reply.answeredByRef !== undefined ? { executedByRef: reply.answeredByRef } : {}),\n }),\n );\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType: 'action',\n status: result.skipped ? 'rejected' : 'executed',\n });\n return { id: call.id, name: call.name, output: result };\n}\n\n/** Everything a claimed call still needs, on its own: delegation or approval, then execute. */\nasync function runClaimedToolCall(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n): Promise<ToolResult> {\n const { deps, input, hooks } = turn;\n const { call, toolType, ctx } = claimed;\n if (claimed.proposalId !== undefined) {\n turn.halt.independentProposal = true;\n return { id: call.id, name: call.name, output: actionProposalReceipt(claimed.proposalId) };\n }\n // Delegation is handled at the LOOP level (not in a step) because the durable runner maps it to\n // `ctx.child`, a ctx-level suspend point.\n if (toolType === 'agent') {\n return delegateToolCall(turn, claimed);\n }\n // An `ask` never reaches a handler: it is settled by a person, not executed.\n if (toolType === 'ask') {\n return elicitToolCall(turn, claimed);\n }\n if (claimed.preflight !== undefined && claimed.preflight.status !== 'ready') {\n const result = claimed.preflight;\n if (result.status === 'completed' && claimed.presentCompletedPreflight === true) {\n // Journal presentation separately: a completed preflight never enters the execution step.\n const raw = await hooks.step(`present:${call.id}`, async () => {\n const ui = createNegotiatedUiCollector(call.id, ctx, deps.resolveUiCatalog, (event) =>\n turn.writer.write(encodeStreamEvent(event)),\n );\n await deps.registry.presentOutput(call.name, result.output, {\n ...toolCallContext(ctx, call.id),\n emitUi: ui.emit,\n });\n return wrapToolStepOutput(result.output, ui.components(), ui.text());\n });\n const presented = unwrapToolStepOutput(raw);\n if (presented.ui.length > 0) turn.toolUi.set(call.id, presented.ui);\n if (presented.text) turn.toolText.set(call.id, presented.text);\n }\n if (result.status === 'completed' && claimed.terminal === true) turn.halt.terminal = true;\n const outcome: ToolOutcome =\n result.status === 'completed'\n ? { status: 'executed', output: result.output, executionMs: 0 }\n : result.status === 'denied'\n ? { status: 'denied', reason: result.reason, executionMs: 0 }\n : { status: 'failed', error: result.error, executionMs: 0 };\n return recordToolOutcome(turn, claimed, outcome, input.actor.id);\n }\n // WHO settled an action tool: the Decision's ref (a console admin) when it carries one, else\n // the run's own actor (the chat flow). Stamped on both the executed and rejected persists.\n let deciderRef = input.actor.id;\n let meta: ApprovalMeta | undefined;\n if (toolType === 'action' && claimed.approval?.mode === 'remembered') {\n meta = {\n approver: claimed.approval.approver,\n decidedBy: input.actor.id,\n decidedVia: 'remembered',\n remember: true,\n streamed: true,\n };\n } else if (toolType === 'action' && claimed.approval?.mode !== 'auto') {\n const ttlMs = claimed.approval?.mode === 'ask' ? claimed.approval.ttlMs : undefined;\n const decision =\n ttlMs !== undefined\n ? await hooks.awaitApproval(call, ctx, { timeoutMs: ttlMs })\n : await hooks.awaitApproval(call, ctx);\n deciderRef = decision.executedByRef ?? input.actor.id;\n // Only a call claimed under a policy streams how it settled — a run from before that keeps\n // writing exactly the frames it always wrote.\n const streamsSettlement = claimed.approval !== undefined;\n if (decision.expired === true) {\n return expireToolCall(turn, claimed);\n }\n if (!decision.approved) {\n await hooks.step(`persist:toolreject:${call.id}`, async () => {\n await deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'rejected',\n executedByRef: deciderRef,\n ...(decision.reason !== undefined ? { error: decision.reason } : {}),\n ...(decision.decidedVia !== undefined ? { decidedVia: decision.decidedVia } : {}),\n });\n if (streamsSettlement) {\n await turn.writer.write(\n encodeStreamEvent({\n kind: 'approval-settled',\n id: call.id,\n status: 'rejected',\n decidedBy: deciderRef,\n ...(decision.decidedVia !== undefined ? { decidedVia: decision.decidedVia } : {}),\n ...(decision.reason !== undefined ? { reason: decision.reason } : {}),\n }),\n );\n }\n });\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType,\n status: 'rejected',\n });\n return {\n id: call.id,\n name: call.name,\n output: { rejected: true, reason: decision.reason ?? DEFAULT_REFUSAL_REASON },\n denied: true,\n // What the MODEL is told. It used to be the bare word `rejected`, which names no actor and\n // reads exactly like a tool that blew up — so the answer that followed would speculate about\n // causes (\"the key may not exist\", \"there may be permission restrictions\") and offer to try\n // again. A person's decision is not a fault to diagnose, so this says who decided, that\n // nothing ran, and what not to do next.\n error: refusalNarrative(decision.reason),\n };\n }\n meta = {\n decidedBy: deciderRef,\n ...(decision.decidedVia !== undefined ? { decidedVia: decision.decidedVia } : {}),\n ...(decision.remember === true ? { remember: true } : {}),\n streamed: streamsSettlement,\n };\n }\n return recordToolOutcome(turn, claimed, await invokeClaimedTool(turn, claimed), deciderRef, meta);\n}\n\n/**\n * The approval request lapsed with nobody deciding. Settled on the rejection's own checkpoint name\n * — an expiry is a refusal as far as the sequence is concerned, and one fewer name to keep stable —\n * but persisted as `expired`, streamed as `approval-settled { status: 'expired' }`, and put to the\n * model as \"nobody approved this in time\" rather than as someone's \"no\".\n */\nasync function expireToolCall(\n turn: ToolTurnContext,\n claimed: ClaimedToolCall,\n): Promise<ToolResult> {\n const { deps, hooks } = turn;\n const { call } = claimed;\n await hooks.step(`persist:toolreject:${call.id}`, async () => {\n await deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'expired',\n error: APPROVAL_EXPIRED_REASON,\n });\n await turn.writer.write(\n encodeStreamEvent({ kind: 'approval-settled', id: call.id, status: 'expired' }),\n );\n });\n publishAgentToolCall({\n runId: hooks.runId,\n toolName: call.name,\n toolType: 'action',\n status: 'rejected',\n });\n return {\n id: call.id,\n name: call.name,\n output: { rejected: true, expired: true, reason: APPROVAL_EXPIRED_REASON },\n denied: true,\n expired: true,\n error: expiryNarrative(),\n };\n}\n\n/** The reason an expired call is denied with — on the row, the stream frame and the result. */\nexport const APPROVAL_EXPIRED_REASON = 'approval expired';\n\n/**\n * How an expiry is put to the model. Nobody said no, so it must not read like a refusal — but it\n * must stop the model from simply trying again, which would park the turn on the same unanswered\n * request.\n */\nfunction expiryNarrative(): string {\n return (\n 'This action needed approval, and the approval request expired before anyone decided. ' +\n 'Nothing ran and nothing changed. Do not run it again on your own; tell the person it was not ' +\n 'approved in time and ask whether they still want it.'\n );\n}\n\n/**\n * The frame a settled call is streamed on. A refusal is its own kind, ahead of the error branch:\n * `denied` and `error` are both set on a declined call — the first for every consumer, the second\n * because `error` is the channel a model reads an outcome on — and a client that saw the error\n * frame would draw a person's \"no\" as a malfunction.\n */\nfunction outputFrame(result: ToolResult): AgentStreamEvent {\n if (result.denied === true) {\n const reason = refusalReason(result);\n return {\n kind: 'tool-output-denied',\n id: result.id,\n ...(reason !== undefined ? { reason } : {}),\n };\n }\n return result.error !== undefined\n ? { kind: 'tool-output-error', id: result.id, error: result.error }\n : { kind: 'tool-output', id: result.id, output: result.output };\n}\n\n/** The reason a person gave when declining, if they gave one — read back off the result. */\nfunction refusalReason(result: ToolResult): string | undefined {\n const { output } = result;\n if (output !== null && typeof output === 'object' && 'reason' in output) {\n const reason = (output as { reason: unknown }).reason;\n return typeof reason === 'string' && reason !== DEFAULT_REFUSAL_REASON ? reason : undefined;\n }\n return undefined;\n}\n\n/**\n * Stored as the reason when someone declines without giving one. It is a placeholder, not something\n * a person said, so every reader has to filter it out — which is why it is exported rather than\n * spelled again wherever a refusal is read back.\n */\nexport const DEFAULT_REFUSAL_REASON = 'rejected by user';\n\n/**\n * How a refusal is put to the model. Written as instructions rather than as a status because the\n * model's next move is the whole problem: told only that something was \"rejected\", it treats the\n * refusal as a fault, lists possible causes it cannot check, and offers to retry the same action —\n * which asks the person to say no twice.\n */\nfunction refusalNarrative(reason: string | undefined): string {\n const base =\n 'The person was asked to approve this action and declined it. Nothing ran and nothing changed. ' +\n 'This is their decision, not an error, a missing record or a permissions problem — do not ' +\n 'explain it as one, do not guess at causes, and do not run this action again or reach for ' +\n 'another way to do the same thing. Acknowledge the decision and ask what they would like instead.';\n return reason === undefined ? base : `${base} They said: ${reason}`;\n}\n\n/**\n * Overlap the INVOCATIONS of a batch of claimed calls, and only those. The persist checkpoints on\n * either side stay strictly sequential, in call order — they are asked for after their neighbours'\n * positions are already spent, so nothing about them depends on which tool finished first.\n *\n * A rejection here is the runner unwinding the turn, never a tool's own failure\n * ({@link invokeClaimedTool} reports those). Rethrow the first one in call order and persist\n * NOTHING: the resume replays this whole block, and a `persist:toolexec` written now would sit at\n * the position the replay computes for the FIRST call's — which, when the invocations are dispatched\n * steps, all share one checkpoint name, so the mismatch raises no refusal at all and simply hands\n * one call's output to another.\n */\nasync function invokeClaimedToolsTogether(\n turn: ToolTurnContext,\n parallel: NonNullable<AgentLoopHooks['parallel']>,\n claimed: ClaimedToolCall[],\n): Promise<ToolResult[]> {\n const settled = await parallel(claimed.map((entry) => () => invokeClaimedTool(turn, entry)));\n for (const outcome of settled) {\n if (!outcome.ok) {\n throw outcome.error;\n }\n }\n const results: ToolResult[] = [];\n for (const [index, entry] of claimed.entries()) {\n const outcome = settled[index];\n if (outcome?.ok === true) {\n results.push(await recordToolOutcome(turn, entry, outcome.value, turn.input.actor.id));\n }\n }\n return results;\n}\n\n/**\n * Something the LOOP produced that the model did not ask for — retrieved passages, a validated\n * structured answer — carried to a client as an ordinary auto-executed tool call. It rides the\n * assistant message it informed (calls and results both, so a reader can pair them), a row in the\n * tool-call table (so a governance surface counts it), and a live pair of stream frames.\n */\ninterface SyntheticToolCall {\n /** The checkpoint that records the row, minus its `:<messageId>` suffix. */\n step: string;\n call: ToolCallRequest;\n result: ToolResult;\n}\n\n/** What a turn answered with: the assistant text, plus the validated `outputSchema` value if any. */\nexport interface AgentLoopResult<TOutput = unknown> {\n text: string;\n /** Present only when `AgentLoopDeps.outputSchema` was set — the validated structured answer. */\n object?: TOutput;\n}\n\n/**\n * The provider-agnostic agent turn, reused by both the inline and durable runners.\n * It drives the model→tools→model iteration; the runner supplies the `step`/`awaitApproval`\n * hooks that make the same loop body either in-process or a replay-safe durable workflow.\n */\nexport async function runAgentLoop<TOutput = unknown>(\n boundDeps: AgentLoopDeps<TOutput>,\n requested: AgentRunInput,\n hooks: AgentLoopHooks,\n): Promise<AgentLoopResult<TOutput>> {\n // The persona, FIRST and only when the run names one: its definition is read from config once and\n // frozen in this checkpoint, so a run resumed after the persona was edited or removed keeps the\n // prompt and allow-list it started with. A run that names none spends no position here — which is\n // every run started before personas existed, so those replay on the sequence they recorded.\n const persona =\n requested.persona === undefined\n ? undefined\n : ((await hooks.step('persona:resolve', () => resolveTurnPersona(boundDeps, requested))) ??\n undefined);\n // From here on the input names the persona the turn actually runs under — none, when the one it\n // asked for is no longer declared — so provenance and tool context never claim one that did not apply.\n const input: AgentRunInput =\n persona === undefined || persona.id !== requested.persona\n ? withoutPersona(requested)\n : requested;\n // A turn with a selected model runs EVERY call it makes on it — the answer, a structured-output\n // pass, the follow-ups — and labels its usage with it when the provider reports no model id.\n const deps: AgentLoopDeps<TOutput> =\n input.model === undefined\n ? boundDeps\n : {\n ...boundDeps,\n model: withSelectedModel(boundDeps.model, input.model),\n modelId: input.model,\n };\n const maxSteps = deps.maxSteps ?? 8;\n let system = await resolveSystemPrompt(deps, input, persona);\n const inputProcessors = deps.inputProcessors ?? [];\n const outputProcessors = deps.outputProcessors ?? [];\n // An output gate and the run's own sink are mutually exclusive, so the presence of a processor —\n // not a per-turn condition — decides whether the model call writes to the sink or through a gate.\n // What the chain DECLARES then decides what that costs the reader: an incremental chain releases a\n // lookback-bounded prefix as it arrives, an undeclared one holds the answer whole.\n const gateMode = resolveOutputGateMode(outputProcessors);\n const gated = gateMode !== 'off';\n const gateLookback = resolveGateLookback(outputProcessors);\n let structured: TOutput | undefined;\n\n if (deps.quota !== undefined) {\n const quota = deps.quota;\n const state = await hooks.step('quota:check', () => quota.check(input.actor.id, deps.day));\n if (!state.withinLimit) {\n publishAgentQuotaExceeded({\n actorId: input.actor.id,\n usedTokens: state.usedTokens,\n limitTokens: state.limitTokens,\n });\n throw new QuotaExceededError();\n }\n }\n\n if (input.regenerate === true) {\n // Re-run the last exchange: drop every message after the thread's last user message (keeping\n // it), then answer it again. No new user message is appended.\n await hooks.step('regenerate:truncate', async () => {\n const existing = await deps.store.getThread(input.threadId);\n const messages = existing?.messages ?? [];\n let lastUserIndex = -1;\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n if (messages[index]?.role === 'user') {\n lastUserIndex = index;\n break;\n }\n }\n const firstDropped = messages[lastUserIndex + 1];\n if (firstDropped !== undefined) {\n await deps.store.truncateFrom(input.threadId, firstDropped.id);\n }\n });\n } else {\n await hooks.step('persist:user', () =>\n deps.store.appendMessage({\n threadId: input.threadId,\n role: 'user',\n content: input.userText,\n runId: hooks.runId,\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(input.attachments !== undefined ? { attachments: input.attachments } : {}),\n }),\n );\n }\n\n const history = (await (hooks.patched?.(SELECTED_HISTORY_PATCH) ?? Promise.resolve(true)))\n ? await loadSelectedHistory(deps, input, hooks)\n : await loadWholeThread(deps, input, hooks);\n let modelMessages: ModelMessage[] = history.messages;\n const summarize = deps.historyPolicy?.summarize?.bind(deps.historyPolicy);\n if (summarize !== undefined && history.dropped.length > 0) {\n modelMessages = await foldDroppedHistory(summarize, deps, input, hooks, history);\n }\n\n const writer = await hooks.openSink();\n let lastText = '';\n let steps = 0;\n let totalInput = 0;\n let totalOutput = 0;\n\n publishAgentRunStarted({\n runId: hooks.runId,\n threadId: input.threadId,\n actorId: input.actor.id,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n });\n\n // Which of the three optional prompt stages below this run takes a position for, decided ONCE and\n // journaled — see {@link PromptStages}. Every `stages.*` read after this is therefore a fact about\n // the run rather than about the deployment replaying it, which is what lets a turn parked on a\n // human survive an operator switching one of them on.\n const stages = await resolvePromptStages(deps, hooks);\n\n // Its own step so durable replay reuses the ORIGINAL wall-clock start — durationMs stays honest\n // across suspend/resume.\n const startedAt = await hooks.step('run:started-at', () => Promise.resolve(Date.now()));\n // Optional-chained: a store without run recording makes this (and persist:run:end) a no-op.\n await hooks.step('persist:run:start', async () => {\n // Hashed BEFORE the retrieved-context block is folded in below, so the hash identifies the\n // prompt VERSION (agent base + contributors), not a given turn's retrieval.\n const promptHash = createHash('sha256').update(system).digest('hex');\n await deps.store.recordRunStart?.({\n runId: hooks.runId,\n threadId: input.threadId,\n actorRef: input.actor.id,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.parentRunId !== undefined ? { parentRunId: input.parentRunId } : {}),\n promptHash,\n });\n });\n\n // What the assistant already believes about this person, folded in ABOVE the retrieved passages\n // and the skills catalog — see `AgentLoopDeps.memory` for why the order runs most-durable-first.\n // Below `persist:run:start` on purpose: that step hashes the prompt VERSION, and a hash that moved\n // with whose memory was loaded would identify a person rather than a prompt.\n //\n // One checkpoint, holding the WHOLE digest: the scopes the resolver returned and the entries that\n // survived selection, precedence and the ceiling. That payload is what the block is rendered from\n // AND what a later `remember` call is authorized against — so which memories entered this prompt,\n // and which scopes this turn could write, are facts the journal holds rather than answers a\n // replaying process's provider would give afresh. Where the host runs an index, the SEARCH happens\n // in here too: a ranking is the most re-derivable decision in this library, so a replay has to\n // read its result back rather than ask an index that has since moved.\n //\n // THE QUERY IS THE USER'S OWN MESSAGE, and nothing else. It is the only thing available before the\n // first model call — which is where memory has to be, since a memory is worthless unless it is in\n // front of the model on the turn nobody thought to look — and it is already a journaled input to\n // this run, so it needs no determinism machinery of its own. What it fails at is a turn with no\n // topic (\"and the other thing?\"): `pinned` is the answer to those, not a cleverer query.\n let memoryDigest: MemoryDigest | undefined;\n if (stages.memory) {\n const config = deps.memory;\n memoryDigest = await hooks.step('memory:digest', () =>\n config === undefined\n ? Promise.resolve(UNSERVED_MEMORY)\n : offerMemories({ config, ctx: skillContext(input), query: input.userText }),\n );\n // No entries, no block: an actor the assistant has concluded nothing about pays nothing, rather\n // than reading a heading over an empty list and inferring something from its presence.\n const digest = memoryDigest;\n const block =\n digest.entries.length > 0\n ? buildMemoryBlock({\n entries: digest.entries,\n writable: memoryIsWritable(deps),\n partial: digest.omitted > 0 || digest.recalled === true,\n })\n : '';\n if (block.length > 0) {\n system = `${system}\\n\\n${block}`;\n }\n // What memory cost this prompt, next to what the ceiling left out — the only way an operator can\n // name which of the prompt's contributors grew when a turn's input tokens jump.\n publishAgentMemoryResolved({\n runId: hooks.runId,\n scopes: digest.scopes.length,\n offered: digest.entries.length,\n omitted: digest.omitted,\n pinnedOmitted: digest.pinnedOmitted,\n recalled: digest.recalled === true,\n promptChars: block.length,\n });\n }\n\n // Inject-mode RAG: retrieve once for the user message and fold the passages into the system prompt\n // (a `ctx.step` so it's replay-cached under durable). Recorded below as a synthetic tool call on\n // the first assistant message, so citations surface through the same machinery as agentic search.\n let injectedPassages: Passage[] | undefined;\n if (stages.retriever) {\n const retriever = deps.retriever;\n const topK = deps.retrievalTopK ?? 5;\n const passages = await hooks.step('retrieve', () =>\n spanned(\n 'retrieval',\n hooks.runId,\n { runId: hooks.runId, queryLength: input.userText.length, topK },\n () => retriever?.retrieve(input.userText, { topK }) ?? Promise.resolve([]),\n (retrieved) => ({ count: retrieved.length }),\n ),\n );\n if (passages.length > 0) {\n injectedPassages = passages;\n system = `${system}\\n\\n${buildContextBlock(passages)}`;\n }\n publishAgentRetrieved({ runId: hooks.runId, query: input.userText, count: passages.length });\n }\n\n // The skills catalog, LAST of the four things that write the system block (base prompt,\n // contributors, retrieved context, this) — so a reader of the assembled prompt meets the agent's\n // own instructions before the menu of ones it could go and fetch.\n //\n // One checkpoint, holding the WHOLE offer: the scopes the resolver returned and the entries that\n // survived precedence. That payload is what the block is rendered from and what a later `skill`\n // call is served against, so the two things a turn's prompt depends on — which scopes applied, and\n // which skills they yielded — are facts the journal holds rather than answers a replaying\n // process's provider would give afresh.\n let skillOffer: SkillOffer | undefined;\n if (stages.skills) {\n const config = deps.skills;\n skillOffer = await hooks.step('skills:catalog', () =>\n config === undefined\n ? Promise.resolve(UNSERVED_SKILLS)\n : offerSkills(config, skillContext(input)),\n );\n // No entries, no block: an actor whose scopes yield nothing pays nothing, rather than reading a\n // heading over an empty list and wondering what it was for.\n const block = skillOffer.entries.length > 0 ? buildSkillsBlock(skillOffer.entries) : '';\n if (block.length > 0) {\n system = `${system}\\n\\n${block}`;\n }\n // What skills cost this prompt, reported next to what they left out — the only way an operator\n // can name which of the prompt's contributors grew when a turn's input tokens jump.\n publishAgentSkillsResolved({\n runId: hooks.runId,\n scopes: skillOffer.scopes.length,\n offered: skillOffer.entries.length,\n omitted: skillOffer.omitted,\n promptChars: block.length,\n });\n }\n\n // Fetched ONCE per run (not per step/message) and reused for every step's cost estimate below.\n // Returned as a plain array (not the Map built from it) so durable replay can JSON-cache the step.\n let prices: CurrentModelPrice[] = [];\n if (deps.pricingStore !== undefined) {\n const pricingStore = deps.pricingStore;\n prices = await hooks.step('pricing:list', () => pricingStore.listCurrentPrices());\n }\n const priceByModel = new Map(prices.map((price) => [price.modelId, price]));\n\n // The configured intake, LAST before the first model call: everything the run records about\n // itself (start time, run row, retrieval, prices) is settled before the turn parks on a person,\n // who may take a day. Its whole block is reachable only through `deps.intake`.\n if (deps.intake !== undefined) {\n const asked = await runIntake(\n deps.intake,\n deps,\n input,\n hooks,\n writer,\n history.hasAssistantMessage,\n );\n if (asked !== null) {\n modelMessages.push(asked);\n }\n }\n\n // Whether this run can observe a cancel at all, resolved ONCE at a fixed position rather than per\n // step: `patched` consumes a position of its own for a fresh run and gives it back to an in-flight\n // one, so asking once is both cheaper and the only form whose cost does not depend on how many\n // steps a turn happens to take. Gated on the hook's presence, which is a property of the runner\n // (uniform across a deployment's pods), never of the run.\n const cancellable =\n hooks.cancelled !== undefined &&\n (await (hooks.patched?.(CANCELLATION_PATCH) ?? Promise.resolve(true)));\n\n // NOTE: no try/finally around this loop. A durable runner suspends by THROWING through the stack\n // at `awaitApproval` (ctx.waitForSignal); a finally would then call writer.end() on every suspend\n // and prematurely close the live stream. We only end on normal completion — the throw propagates\n // to the engine, and the resumed replay reaches the writer.end() below.\n for (let i = 0; i < maxSteps; i += 1) {\n // Between steps, and therefore before the next model call: the cheapest point in the turn to\n // stop at, since nothing has been spent on this step yet.\n await haltIfCancelled(hooks, cancellable, `cancel:check:${i}`);\n\n // Open a UI step spanning this model call AND its tool execution — matching the AI SDK's own\n // step semantics, so tool-output lands inside the step that made the call. Wrapped in a durable\n // step so replay doesn't re-emit it (a no-op for the inline runner).\n await hooks.step(`stream:step-start:${i}`, async () => {\n await writer.write(encodeStreamEvent({ kind: 'step-start' }));\n });\n\n // Every step, not once per run: the transcript grows between steps, so a processor that only\n // saw the opening prompt would wave through whatever a tool result carried back. The result is\n // a per-step DERIVED prompt — `modelMessages` stays the loop's canonical transcript, so a\n // redaction never becomes the thread's own memory of what was said.\n let prompt: ProcessedPrompt = { system, messages: modelMessages };\n if (inputProcessors.length > 0) {\n prompt = await hooks.step(`process:input:${i}`, () =>\n runInputProcessors(inputProcessors, prompt, processorContext(input, i)),\n );\n }\n\n let turn: BufferedModelTurnResult;\n if (hooks.dispatchLlm) {\n // No definitionsFor here: the envelope carries only wire-safe data (a ToolDefinition holds a\n // live schema instance) — the serving handler re-derives tool definitions from the actor.\n // `bufferOutput` for EITHER gate mode, incremental included: the handler streams into a\n // worker-side sink this loop cannot interpose on, so there is no prefix to release here and\n // the declaration buys the reader nothing. The turn is held whole — the result comes back with\n // `bufferedFrames` and no `releasedText`, which is what puts the gate step on its whole-answer\n // release path.\n turn = await hooks.dispatchLlm(i, {\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n system: prompt.system,\n messages: prompt.messages,\n actor: input.actor,\n threadId: input.threadId,\n actionApprovalMode: history.actionApprovalMode ?? 'blocking',\n preflightContext: {\n actor: input.actor,\n threadId: input.threadId,\n runId: hooks.runId,\n requestId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(input.uiCapabilities !== undefined ? { uiCapabilities: input.uiCapabilities } : {}),\n },\n ...(gated ? { bufferOutput: true } : {}),\n ...(input.model !== undefined ? { model: input.model } : {}),\n ...(persona?.allowedTools !== undefined\n ? { personaAllowedTools: persona.allowedTools }\n : {}),\n });\n } else {\n const tools = withMemoryTool({\n tools: withSkillTool({\n tools: withAskTool({\n tools: await deps.registry.definitionsFor(\n input.actor,\n deps.rolesPolicy,\n intersectAllowLists(deps.toolAllowList, persona?.allowedTools),\n {\n threadId: input.threadId,\n ...(input.uiCapabilities !== undefined\n ? { uiCapabilities: input.uiCapabilities }\n : {}),\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n },\n ),\n ask: deps.ask,\n }),\n enabled: deps.skills !== undefined,\n }),\n enabled: memoryIsWritable(deps),\n });\n turn = await hooks.step(`llm:${i}`, async () => {\n // Both of these ride the CHECKPOINT rather than a local variable: a run that suspends\n // between the model call and the gate resumes with `llm:<i>` served from the journal, and\n // state held in this process would be gone by then — the turn's whole stream, silently\n // dropped, or a prefix flushed into the reader's stream a second time.\n const incremental =\n gateMode === 'incremental'\n ? createIncrementalGate({\n processors: outputProcessors,\n ctx: processorContext(input, i),\n lookbackChars: gateLookback,\n writer,\n })\n : undefined;\n const buffer = gateMode === 'whole' ? createFrameBuffer() : undefined;\n // Reasoning and pushed UI are read off the frames INSIDE the checkpoint, so they are\n // journaled with the turn and a replay persists the same thinking instead of none.\n const frames = observeTurnFrames(incremental?.writer ?? buffer?.writer ?? writer);\n // Stamped from THIS process's registry, which is the one that built `tools` above — and\n // stamped inside the checkpoint, so the kinds are journaled with the calls they describe\n // rather than re-derived by whatever process replays this turn.\n const result = stampToolKinds(\n withTurnFrames(\n await traceLlmTurn(hooks.runId, i, () =>\n deps.model.runTurn({\n system: prompt.system,\n messages: prompt.messages,\n tools,\n sink: frames.writer,\n }),\n ),\n frames.summary(),\n ),\n deps,\n );\n if (incremental !== undefined) {\n await incremental.settled();\n const refusal = incremental.rejection();\n return {\n ...result,\n releasedText: incremental.released(),\n ...(refusal !== undefined ? { gateRejection: refusal } : {}),\n };\n }\n return buffer === undefined ? result : { ...result, bufferedFrames: buffer.frames() };\n });\n }\n // The gate runs before ANYTHING downstream: before the held frames reach the subscriber, before\n // the assistant message is persisted, before this text becomes the next step's context.\n let rejection: { processor: string; reason: string } | undefined;\n if (gated) {\n const gate = await hooks.step(`process:output:${i}`, async () => {\n // Which release this turn still owes is read from the JOURNALED model result, never from\n // the chain configured on whichever process is running now: `releasedText` is the record\n // that a prefix already reached the reader, so a run that resumes under a re-declared chain\n // cannot flush the same answer a second time.\n const released = turn.releasedText;\n // A refusal an incremental gate already reached, carried out of `llm:<i>` instead of thrown\n // from it. Re-running the chain would bill the same verdict twice.\n if (turn.gateRejection !== undefined) {\n return { text: turn.text, rejection: turn.gateRejection };\n }\n const settled = await runOutputProcessors(\n outputProcessors,\n { text: turn.text, toolCalls: turn.toolCalls },\n processorContext(input, i),\n );\n // Releasing inside the same checkpoint as the verdict is what makes \"refused\" and \"nothing\n // was streamed\" one fact rather than two that a suspend could separate. For an incremental\n // turn the second half of that is weaker by construction — a prefix is already out — and\n // the whole-answer pass stays authoritative for both the stream and the store.\n if (settled.rejection === undefined) {\n if (released === undefined) {\n for (const chunk of releaseGatedFrames(turn.bufferedFrames ?? [], settled.text)) {\n await writer.write(chunk);\n }\n } else {\n const tail = gateTail(outputProcessors, released, settled.text);\n if (tail.length > 0) {\n await writer.write(encodeStreamEvent({ kind: 'text', text: tail }));\n }\n }\n }\n return settled;\n });\n rejection = gate.rejection;\n turn = { ...turn, text: gate.text };\n }\n // provider-reported model wins over the configured fallback, so cost can't misattribute\n const resolvedModelId = turn.modelId ?? deps.modelId ?? 'unknown';\n // The same model, for the stream: absent rather than a made-up `'unknown'`.\n const stepModel = turn.modelId ?? deps.modelId;\n // Provider-reported spend wins; else an estimate from the (once-per-run cached) price list; else\n // `null` — surfaced on the stream's step-finish frame and the persisted assistant message below.\n const costUsd = resolveCostUsd(turn.usage, turn.costUsd, priceByModel.get(resolvedModelId));\n // Each call's declared kind, so thread-read consumers (and the stream frames the model adapter\n // writes) know it without hardcoding a tool-name allowlist. The kind the llm checkpoint already\n // stamped WINS: it came from the process that offered the tool, whereas this one is only the\n // process replaying the turn, and the two disagree exactly when that matters — see\n // {@link stampToolKinds}. The fallback is for a journal written before kinds travelled.\n const toolCallsWithKind: ToolCallRequest[] = turn.toolCalls.map((call) => ({\n ...call,\n kind: call.kind ?? declaredKind(deps, call.name),\n }));\n\n await hooks.step(`persist:usage:${i}`, () =>\n deps.store.recordUsage({\n threadId: input.threadId,\n actorRef: input.actor.id,\n modelId: resolvedModelId,\n purpose: 'chat',\n usage: turn.usage,\n // persist the provider's actual cost when reported; the read-model prefers it over pricing\n ...(turn.costUsd !== undefined ? { costUsd: turn.costUsd } : {}),\n }),\n );\n if (deps.quota !== undefined) {\n const quota = deps.quota;\n await hooks.step(`quota:bump:${i}`, () =>\n quota.bump(input.actor.id, deps.day, turn.usage.inputTokens + turn.usage.outputTokens),\n );\n }\n\n // Thrown only AFTER the two accounting checkpoints: those tokens were genuinely spent, and a\n // refusal that also hid its own cost would let a mis-tuned gate burn a budget invisibly.\n if (rejection !== undefined) {\n throw new OutputRejectedError(rejection.processor, rejection.reason);\n }\n\n steps += 1;\n totalInput += turn.usage.inputTokens;\n totalOutput += turn.usage.outputTokens;\n lastText = turn.text;\n publishAgentMessage({\n runId: hooks.runId,\n threadId: input.threadId,\n role: 'assistant',\n textLength: turn.text.length,\n });\n\n // A turn with no tool calls is the last one. Generate follow-up suggestions here (before the\n // append) so they land on the final assistant message, and stop after.\n const isFinalTurn = turn.toolCalls.length === 0;\n // Restating the GATED text, never the model's raw reply: the formatting pass is a translation of\n // the answer that survived the gate, not a second route out of the model.\n if (isFinalTurn && deps.outputSchema !== undefined) {\n structured = await structureAnswer(\n deps.outputSchema,\n deps,\n input,\n hooks,\n restatementPrompt(prompt.messages, turn.text, deps.outputFromTranscript === true),\n i,\n );\n }\n let followUps: string[] | undefined;\n if (isFinalTurn && deps.followUpsCount !== undefined && deps.followUpsCount > 0) {\n const count = deps.followUpsCount;\n // Stays on hooks.step (not dispatchLlm) — a short, non-streamed call, deliberately not\n // dispatched as a routed remote step.\n const generated = await hooks.step(`followups:${i}`, () =>\n spanned(\n 'follow-ups',\n hooks.runId,\n { runId: hooks.runId, step: i, count },\n () =>\n generateFollowUps(\n deps.model,\n [...modelMessages, { role: 'assistant', content: turn.text }],\n count,\n ),\n (result) => ({\n followUps: result.followUps.length,\n inputTokens: result.usage.inputTokens,\n outputTokens: result.usage.outputTokens,\n ...(result.modelId !== undefined ? { modelId: result.modelId } : {}),\n }),\n ),\n );\n // Model-generated, persisted and rendered — so the chain rules on each one, on the whole\n // suggestion (they are never streamed, so an `incremental` declaration buys nothing here). A\n // refusal DROPS that suggestion rather than ending a run whose answer already passed — see\n // {@link gateFollowUps}.\n let suggestions = generated.followUps;\n if (outputProcessors.length > 0) {\n suggestions = await hooks.step(`process:output:followups:${i}`, () =>\n gateFollowUps(outputProcessors, suggestions, processorContext(input, i)),\n );\n }\n if (suggestions.length > 0) {\n followUps = suggestions;\n }\n await hooks.step(`persist:usage:followups:${i}`, () =>\n deps.store.recordUsage({\n threadId: input.threadId,\n actorRef: input.actor.id,\n modelId: generated.modelId ?? deps.modelId ?? 'unknown',\n purpose: 'follow_ups',\n usage: generated.usage,\n }),\n );\n }\n\n // Inject-mode retrieval and the structured answer both reach a client as ordinary tool calls.\n // Their ids are derived from the RUN, not from the message they hang off, because the message\n // does not exist yet and both have to be on the append below: a reader pairs a call with its\n // result off the message, so a call added afterwards would render as a tool still running.\n // Every value here is already settled by a checkpoint this turn ran (`retrieve`,\n // `structured:<step>:<n>`), so a replay rebuilds the same pair without minting anything.\n const synthetic: SyntheticToolCall[] = [];\n if (i === 0 && injectedPassages !== undefined) {\n const call: ToolCallRequest = {\n id: `retrieve-${hooks.runId}`,\n name: 'retrieve',\n input: { query: input.userText },\n kind: 'read',\n };\n const output = { passages: injectedPassages };\n synthetic.push({\n step: 'persist:retrieval',\n call,\n result: { id: call.id, name: call.name, output },\n });\n }\n if (structured !== undefined) {\n const call: ToolCallRequest = {\n id: `structured-${hooks.runId}`,\n name: 'structured_output',\n input: {},\n kind: 'read',\n };\n synthetic.push({\n step: 'persist:structured',\n call,\n result: { id: call.id, name: call.name, output: structured },\n });\n }\n const messageCalls = [...toolCallsWithKind, ...synthetic.map((entry) => entry.call)];\n const syntheticResults = synthetic.map((entry) => entry.result);\n\n const assistant = await hooks.step(`persist:assistant:${i}`, () =>\n deps.store.appendMessage({\n threadId: input.threadId,\n role: 'assistant',\n content: turn.text,\n // Stamps which turn wrote this message, so a reader does not have to infer it from\n // timestamps — an inference a regenerate breaks, since it re-answers a surviving prompt.\n runId: hooks.runId,\n usage: { ...turn.usage, costUsd },\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(turn.reasoning !== undefined ? { reasoning: turn.reasoning } : {}),\n ...(turn.reasoningMs !== undefined ? { reasoningMs: turn.reasoningMs } : {}),\n ...(turn.ui !== undefined && turn.ui.length > 0 ? { ui: turn.ui } : {}),\n ...(messageCalls.length > 0 ? { toolCalls: messageCalls } : {}),\n ...(syntheticResults.length > 0 ? { toolResults: syntheticResults } : {}),\n ...(followUps !== undefined ? { followUps } : {}),\n }),\n );\n // Tool results ride on the same assistant message that made the calls — the compact shape the\n // store persists and `mapMessages` (in every model adapter) expands into an assistant + tool\n // message pair. We keep the reference and attach the model's own `toolResults` below once the\n // tools have run.\n const assistantMessage: ModelMessage = {\n role: 'assistant',\n content: turn.text,\n ...(messageCalls.length > 0 ? { toolCalls: messageCalls } : {}),\n ...(syntheticResults.length > 0 ? { toolResults: syntheticResults } : {}),\n };\n modelMessages.push(assistantMessage);\n\n for (const entry of synthetic) {\n const { call, result } = entry;\n await hooks.step(`${entry.step}:${assistant.id}`, async () => {\n await deps.store.recordToolCall({\n toolCallId: call.id,\n messageId: assistant.id,\n toolName: call.name,\n toolType: 'read',\n input: call.input,\n status: 'auto_executed',\n runId: hooks.runId,\n });\n await deps.store.updateToolCall({\n toolCallId: call.id,\n status: 'executed',\n output: result.output,\n });\n // The same pair of frames an executed read tool writes, so a live subscriber renders this\n // through the tool-call machinery it already has rather than learning a frame kind.\n await writer.write(\n encodeStreamEvent({\n kind: 'tool-input-available',\n id: call.id,\n name: call.name,\n input: call.input,\n toolKind: 'read',\n }),\n );\n await writer.write(\n encodeStreamEvent({ kind: 'tool-output', id: call.id, output: result.output }),\n );\n });\n }\n\n if (isFinalTurn) {\n await hooks.step(`stream:step-finish:${i}`, async () => {\n await writer.write(\n encodeStreamEvent({\n kind: 'step-finish',\n usage: turn.usage,\n costUsd,\n ...(turn.reasoningMs !== undefined ? { reasoningMs: turn.reasoningMs } : {}),\n ...(stepModel !== undefined ? { model: stepModel } : {}),\n }),\n );\n });\n break;\n }\n\n // Before the turn's tools are DISPATCHED — the last point at which stopping costs nothing,\n // because the moment the first handler runs there is a side effect no cancel can take back. One\n // observation for the whole batch rather than one per call: the calls are a single ask from the\n // model, and stopping half way through leaves the next step reading a message whose tool results\n // it cannot pair with the calls above them.\n await haltIfCancelled(hooks, cancellable, `cancel:tools:${i}`);\n\n const results: ToolResult[] = [];\n const turnCalls: ToolTurnContext = {\n deps,\n input,\n hooks,\n messageId: assistant.id,\n writer,\n toolUi: new Map(),\n toolText: new Map(),\n halt: { terminal: false },\n actionApprovalMode: history.actionApprovalMode ?? 'blocking',\n ...(skillOffer !== undefined ? { skills: skillOffer } : {}),\n ...(memoryDigest !== undefined ? { memory: memoryDigest } : {}),\n ...(persona !== undefined ? { persona } : {}),\n };\n // A model routinely asks for several tools at once, and running them back to back makes the turn\n // cost their sum. Overlapping them is safe here because a checkpoint position is handed out on\n // the CALL, not when the work settles: launching every invocation in one tick — what\n // `hooks.parallel` promises — pins the `tool:` block in call order however the tools then finish,\n // the same anchor `ctx.all` gets by reserving its block before dispatching. The claim and persist\n // checkpoints stay sequential around it.\n //\n // Only a turn whose every call is a plain `read` qualifies:\n // - an `action` suspends on an approval signal, which is human time rather than I/O, so\n // overlapping what follows it buys nothing — and reserving an invocation position for a call\n // that may yet be REJECTED spends a position the rejected branch never fills.\n // - an `agent` delegation is `ctx.child`, whose parallel form is the runtime's own `ctx.all`:\n // one workflow ref over a reserved block, carrying the `parallelGroup` bookkeeping that makes\n // a fan render as a fan. That is not N independent task closures, so it cannot ride this hook.\n // The kinds come from the `persist:toolcall` checkpoints, never from a local registry lookup, so\n // every process replaying this turn reaches the same verdict.\n const parallel = hooks.parallel;\n if (\n parallel !== undefined &&\n toolCallsWithKind.length > 1 &&\n (await (hooks.patched?.(PARALLEL_TOOLS_PATCH) ?? Promise.resolve(true)))\n ) {\n // Claiming the whole turn first is what makes the kinds knowable before the first execution —\n // and it is also what moves the checkpoints, hence the `patched` gate above.\n const claimed: ClaimedToolCall[] = [];\n for (const call of toolCallsWithKind) {\n claimed.push(await claimToolCall(turnCalls, call));\n }\n // A `skill` load and a `remember` write qualify alongside a `read`: each takes its position on\n // the call exactly as a read does, and each spends a read's `tool:`/`persist:` names. What\n // disqualifies the other two kinds is not that they have effects — it is that an `action`\n // suspends on human time and an `agent` delegation is the runtime's own `ctx.all`.\n if (\n claimed.every(\n (entry) =>\n entry.toolType === 'read' || entry.toolType === 'skill' || entry.toolType === 'memory',\n )\n ) {\n results.push(...(await invokeClaimedToolsTogether(turnCalls, parallel, claimed)));\n } else {\n for (const entry of claimed) {\n results.push(await runClaimedToolCall(turnCalls, entry));\n }\n }\n } else {\n for (const call of toolCallsWithKind) {\n results.push(await runClaimedToolCall(turnCalls, await claimToolCall(turnCalls, call)));\n }\n }\n const settledResults = [...results, ...syntheticResults];\n const toolText = escapeUnsafeToolUiText(\n toolCallsWithKind\n .map((call) => turnCalls.toolText.get(call.id))\n .filter((text): text is string => text !== undefined)\n .join('\\n'),\n );\n assistantMessage.toolResults = settledResults;\n\n // Stream each tool's result so the client flips its live tool card from \"running\" to the\n // rendered output (renderResult → DataTable/Chart, executeSql → rows). One durable step keeps\n // replay from re-emitting. Which frame each result goes out on is `outputFrame`'s call: a\n // refusal has its own, and `error` carries only what the model is told.\n await hooks.step(`stream:tool-outputs:${i}`, async () => {\n // The results land on the message from INSIDE this checkpoint rather than at one of their\n // own: this turn's checkpoint sequence is a wire contract with every run already in flight,\n // and a position inserted between two recorded ones is refused on resume. Every value in\n // `settledResults` comes from a checkpoint above, so a replay writes the same list anyway.\n await deps.store.setMessageToolResults(assistant.id, settledResults);\n if (toolText)\n await deps.store.appendMessage({\n threadId: input.threadId,\n role: 'assistant',\n content: toolText,\n runId: hooks.runId,\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n });\n // What the tools pushed joins what the model turn streamed, on the same message, in call\n // order. Every list here was read off a checkpoint above, so a replay writes the same value.\n const toolUi = toolCallsWithKind.flatMap((call) => turnCalls.toolUi.get(call.id) ?? []);\n if (toolUi.length > 0) {\n await deps.store.setMessageUi?.(assistant.id, mergeUi(turn.ui, toolUi));\n }\n for (const result of results) {\n await writer.write(encodeStreamEvent(outputFrame(result)));\n }\n });\n\n if (toolText) {\n modelMessages.push({ role: 'assistant', content: toolText });\n lastText += `\\n${toolText}`;\n }\n await hooks.step(`stream:step-finish:${i}`, async () => {\n await writer.write(\n encodeStreamEvent({\n kind: 'step-finish',\n usage: turn.usage,\n costUsd,\n ...(turn.reasoningMs !== undefined ? { reasoningMs: turn.reasoningMs } : {}),\n ...(stepModel !== undefined ? { model: stepModel } : {}),\n }),\n );\n });\n\n // A `terminal` tool succeeded: its effect is the answer, so no model call narrates it. Read off\n // the calls' `persist:toolcall` checkpoints and their outcomes, so a replay ends here too.\n if (turnCalls.halt.terminal || turnCalls.halt.independentProposal) {\n break;\n }\n }\n\n if (history.title === '' || history.title === 'New chat') {\n await hooks.step('persist:title', () =>\n deps.store.setTitle(input.threadId, deriveTitle(input.userText)),\n );\n }\n\n const delivery = input.deliverTo;\n if (delivery !== undefined) {\n // A detached run's answer has nowhere to go but a message of its own: the turn that delegated it\n // ended without it, so there is no tool result left to fill and no live stream to write into.\n // Stamped with THIS run and agent, which is how a reader tells \"the research agent finished\"\n // from the assistant's next reply.\n //\n // The position exists only for a run carrying a delivery address, and only a detached\n // delegation's own child run carries one — so the sequence of every other turn is untouched.\n await hooks.step('deliver:detached', async () => {\n if ((await deps.store.getThread(delivery.threadId)) === null) {\n // The conversation was deleted while this ran. The work cannot be un-run, but delivering\n // into a thread nobody kept would resurrect it, and the tool-call row it would settle went\n // with it.\n return;\n }\n const agent = input.agentName ?? 'default';\n await deps.store.appendMessage({\n threadId: delivery.threadId,\n role: 'assistant',\n content: lastText,\n agentName: agent,\n runId: hooks.runId,\n });\n await deps.store.updateToolCall({\n toolCallId: delivery.toolCallId,\n status: 'executed',\n output: detachedDelivered({ agent, runId: hooks.runId, text: lastText }),\n });\n });\n }\n\n // Normal completion only. The loop never records 'failed' — it doesn't catch its own crash;\n // failure recording is the RUNNER's job. A checkpointed step, so a resumed replay settles once.\n await hooks.step('persist:run:end', async () => {\n await deps.store.recordRunEnd?.({\n runId: hooks.runId,\n status: 'completed',\n durationMs: Date.now() - startedAt,\n });\n });\n\n await writer.end();\n publishAgentRunFinished({\n runId: hooks.runId,\n threadId: input.threadId,\n steps,\n inputTokens: totalInput,\n outputTokens: totalOutput,\n });\n return { text: lastText, ...(structured !== undefined ? { object: structured } : {}) };\n}\n","import { DefaultApprovalPolicy } from './spi/approval-policy.js';\nimport type { ApprovalPolicy, ApprovalThreadRef, ApprovalToolRef } from './spi/approval-policy.js';\nimport type { Actor } from './types.js';\nexport type ClaimedActionApproval =\n | { mode: 'auto' }\n | { mode: 'remembered'; approver: string }\n | { mode: 'ask'; approver: string; ttlMs?: number; expiresAt?: string };\nexport interface ResolveActionProposalApprovalInput {\n actor: Actor;\n thread: ApprovalThreadRef;\n tool: ApprovalToolRef;\n store: { rememberedApprovals?(threadId: string): Promise<string[]> };\n policy?: ApprovalPolicy;\n clock?: () => number;\n}\n/** Journal this result on the trusted producer before choosing strict proposal preparation. */\nexport async function resolveActionProposalApproval(\n input: ResolveActionProposalApprovalInput,\n): Promise<ClaimedActionApproval> {\n const policy = input.policy ?? new DefaultApprovalPolicy();\n const requirement = await policy.requirementFor(input.tool, input.actor, input.thread);\n if (!requirement.required) return { mode: 'auto' };\n const remembered = (await input.store.rememberedApprovals?.(input.thread.threadId)) ?? [];\n if (remembered.includes(input.tool.name))\n return { mode: 'remembered', approver: requirement.approver };\n const roundedTtl =\n requirement.ttlMs !== undefined && Number.isFinite(requirement.ttlMs)\n ? Math.floor(requirement.ttlMs)\n : 0;\n if (roundedTtl <= 0) return { mode: 'ask', approver: requirement.approver };\n const now = (input.clock ?? Date.now)();\n if (\n !Number.isSafeInteger(now) ||\n !Number.isSafeInteger(roundedTtl) ||\n !Number.isSafeInteger(now + roundedTtl)\n )\n throw new RangeError('Invalid action approval deadline');\n return {\n mode: 'ask',\n approver: requirement.approver,\n ttlMs: roundedTtl,\n expiresAt: new Date(now + roundedTtl).toISOString(),\n };\n}\n","import { snapshotActionProposal } from './action-proposal-transitions.js';\nimport type { RolesPolicy } from './spi/roles-policy.js';\nimport type { AiToolCtx } from './spi/tool.js';\nimport type { InvokeOptions, ToolRegistry } from './tool-registry.js';\n\n/** Trusted producer path: retain the original JSON and the exact data shown for approval. */\nexport async function prepareActionProposal(\n registry: ToolRegistry,\n name: string,\n input: unknown,\n ctx: AiToolCtx,\n policy: RolesPolicy,\n options: InvokeOptions = {},\n) {\n const preparationInput = snapshotActionProposal(input);\n const prepared = await registry.prepareValidated(\n name,\n snapshotActionProposal(preparationInput),\n ctx,\n policy,\n { ...options, snapshotInput: true },\n );\n let replacementKey: string | undefined;\n const replacement = registry.spec(name)?.replacementKey;\n if (prepared.preflight.status === 'ready' && replacement !== undefined) {\n replacementKey =\n typeof replacement === 'string'\n ? replacement\n : await replacement(snapshotActionProposal(prepared.input), ctx);\n if (\n replacementKey !== undefined &&\n (typeof replacementKey !== 'string' || !replacementKey || replacementKey.length > 255)\n )\n throw new TypeError(\n 'replacementKey must be a nonempty string of at most 255 UTF-16 code units',\n );\n }\n return {\n ...(replacementKey !== undefined ? { replacementKey } : {}),\n preparationInput,\n input: prepared.input,\n // Completed results keep their normal handler contract; they never create a proposal.\n preflight:\n prepared.preflight.status === 'ready'\n ? snapshotActionProposal(prepared.preflight)\n : prepared.preflight,\n };\n}\n","export type ActionApprovalMode = 'blocking' | 'independent';\nexport type ActionProposalTarget = { kind: 'proposal'; proposalId: string };\nexport interface ActionProposalReceipt {\n proposalId: string;\n status: 'pending';\n executed: false;\n}\nexport function actionProposalReceipt(proposalId: string): ActionProposalReceipt {\n return { proposalId, status: 'pending', executed: false };\n}\n","import { emit } from '@dudousxd/nestjs-diagnostics';\nimport type { ChannelRegistry } from '@dudousxd/nestjs-diagnostics';\nimport type { QuotaPeriod } from './spi/quota-provider.js';\n\n/** Payloads carried on each `aviary:agent:*` channel. */\nexport interface AgentRunStarted {\n runId: string;\n threadId: string;\n actorId: string;\n /** Which agent is handling the run. */\n agentName?: string;\n /** The persona of that agent the run is under, when it is under one. */\n persona?: string;\n}\nexport interface AgentMessageEvent {\n runId: string;\n threadId: string;\n role: 'user' | 'assistant';\n textLength: number;\n}\nexport interface AgentToolCallEvent {\n runId: string;\n toolName: string;\n toolType: 'read' | 'action';\n status: string;\n durationMs?: number;\n}\n/**\n * A turn refused for budget. Published by the send gate (`429`) and the message queue when a\n * `QuotaProvider` reports `blocked`, and by the loop's own per-day `QuotaStore` gate. The figures\n * are the exhausted window's: a window that does not count tokens (a USD-only spend cap) carries no\n * token figures, never a made-up `0`.\n */\nexport interface AgentQuotaExceeded {\n actorId: string;\n /** The window that ran out. Absent from the loop's per-day `QuotaStore` gate. */\n period?: QuotaPeriod;\n /** The provider's words for the block, when it gave some. */\n reason?: string;\n usedTokens?: number;\n limitTokens?: number;\n usedUsd?: number;\n limitUsd?: number;\n}\nexport interface AgentRunFinished {\n runId: string;\n threadId: string;\n steps: number;\n inputTokens: number;\n outputTokens: number;\n}\nexport interface AgentRunFailed {\n runId: string;\n /** Stable failure slug, e.g. `quota_exceeded` or `run_failed`. */\n code: string;\n message: string;\n}\nexport interface AgentDelegated {\n runId: string;\n fromAgent?: string;\n toAgent: string;\n /** The delegate was STARTED, not awaited — this run's turn ended without its answer. */\n detached?: boolean;\n}\nexport interface AgentRetrieved {\n runId: string;\n query: string;\n /** How many passages the retriever returned. */\n count: number;\n}\n/**\n * The skills a turn was offered, published once per run at the `skills:catalog` checkpoint. Metadata\n * only — counts and the block's size, never a skill's name or its body.\n */\nexport interface AgentSkillsResolved {\n runId: string;\n /** How many scope tokens the resolver returned for this turn. */\n scopes: number;\n /** Skills in the catalog block the model was shown. */\n offered: number;\n /** Applicable skills the `maxSkills` ceiling left out — non-zero means the catalog is partial. */\n omitted: number;\n /**\n * Characters the catalog block added to the system prompt. The WHOLE of what skills cost it: a\n * skill's body never enters the system block, it arrives as a tool result on the transcript.\n */\n promptChars: number;\n}\n/**\n * The memories a turn was shown, published once per run at the `memory:digest` checkpoint. Metadata\n * only — counts and the block's size, never a memory's key or its text. A key is as revealing as a\n * fact (`diagnosis`, `clearance`), so it does not travel on a diagnostics channel either.\n */\nexport interface AgentMemoryResolved {\n runId: string;\n /** How many scope tokens the resolver returned for this turn. */\n scopes: number;\n /** Memories in the block the model was shown. */\n offered: number;\n /** Applicable memories the `maxMemories` ceiling left out — non-zero means the block is partial. */\n omitted: number;\n /**\n * Of `omitted`, how many were ALWAYS-ON. The one to alert on: ordinary omission is the budget\n * working, while a dropped always-on memory is a deployment's own standing policies having stopped\n * reaching any prompt — more was pinned than the block holds.\n */\n pinnedOmitted: number;\n /**\n * Whether the block was selected by relevance to this turn rather than read whole. Distinguishes\n * \"this deployment holds few memories\" from \"this turn drew twenty out of two thousand\", which\n * `offered` alone reports identically.\n */\n recalled: boolean;\n /** Characters the memory block added to the system prompt. The WHOLE of what memory cost it. */\n promptChars: number;\n}\n/**\n * A turn writing one memory — the event an operator watches to see the agent's own write volume,\n * which is the risk surface memory has and retrieval does not. The scope token travels (it is what\n * says whose prompt just changed, and `run.started` already carries an actor id); the key and the\n * text do not.\n */\nexport interface AgentMemoryWritten {\n runId: string;\n scope: string;\n /** Length of the stored fact in characters — never the fact itself. */\n chars: number;\n}\n/**\n * A transient-classified tool error being retried in place (no new checkpoint) — see\n * `invokeWithTransientRetry`. Emitted once per retry (not for the final, non-retried outcome).\n */\nexport interface AgentToolRetry {\n toolName: string;\n toolCallId: string;\n /** 1-based ordinal of the attempt that just failed and is about to be retried. */\n attempt: number;\n /** The failed attempt's error message. */\n message: string;\n}\n\n// --- Span (trace) payloads — the START-phase payload of each traced operation. Metadata only:\n// token counts / lengths / names, never prompt or output text (the point events' redaction\n// posture). The traced result rides the `end`/`asyncEnd` envelope; see agent-loop's span helpers.\n\n/** START payload of an `aviary:agent:llm.turn:*` span — one model call within a run. */\nexport interface AgentLlmTurnSpan {\n runId: string;\n /** Zero-based model-call index within the run (the loop's step counter). */\n step: number;\n}\n/** START payload of an `aviary:agent:tool.execution:*` span — one tool invocation. */\nexport interface AgentToolExecutionSpan {\n runId: string;\n toolCallId: string;\n toolName: string;\n toolType: 'read' | 'action';\n}\n/** START payload of an `aviary:agent:retrieval:*` span — inject-mode RAG retrieval. */\nexport interface AgentRetrievalSpan {\n runId: string;\n /** Length of the retrieval query in characters — never the query text itself. */\n queryLength: number;\n topK: number;\n}\n/** START payload of an `aviary:agent:follow-ups:*` span — the extra follow-up-suggestions call. */\nexport interface AgentFollowUpsSpan {\n runId: string;\n /** Zero-based model-call index of the final turn the follow-ups ride on. */\n step: number;\n /** How many follow-up questions were requested. */\n count: number;\n}\n\n/**\n * START payload of an `aviary:agent:structured-output:*` span — the formatting pass that restates a\n * finished answer as `AgentLoopDeps.outputSchema`. `attempt` is 0 for the pass itself and counts up\n * for each bounded repair, so a run that needed three tries is visible as three spans.\n */\nexport interface AgentStructuredOutputSpan {\n runId: string;\n /** Zero-based model-call index of the final turn whose answer is being restated. */\n step: number;\n attempt: number;\n}\n\n/** Declaration-merge so `emit('agent', ...)`, `trace('agent', ...)` and telescope infer the agent payloads. */\ndeclare module '@dudousxd/nestjs-diagnostics' {\n interface ChannelRegistry {\n agent: {\n 'run.started': AgentRunStarted;\n message: AgentMessageEvent;\n 'tool-call': AgentToolCallEvent;\n 'quota.exceeded': AgentQuotaExceeded;\n 'run.finished': AgentRunFinished;\n 'run.failed': AgentRunFailed;\n delegated: AgentDelegated;\n retrieved: AgentRetrieved;\n 'skills.resolved': AgentSkillsResolved;\n 'memory.resolved': AgentMemoryResolved;\n 'memory.written': AgentMemoryWritten;\n 'tool.retry': AgentToolRetry;\n // Span-only events (published via trace() on :start/:end/:asyncStart/:asyncEnd/:error\n // sub-channels, never as point events) — see AgentSpanEvent below.\n 'llm.turn': AgentLlmTurnSpan;\n 'tool.execution': AgentToolExecutionSpan;\n retrieval: AgentRetrievalSpan;\n 'follow-ups': AgentFollowUpsSpan;\n 'structured-output': AgentStructuredOutputSpan;\n };\n }\n}\n\nexport function publishAgentRunStarted(payload: AgentRunStarted): void {\n emit('agent', 'run.started', payload);\n}\nexport function publishAgentMessage(payload: AgentMessageEvent): void {\n emit('agent', 'message', payload);\n}\nexport function publishAgentToolCall(payload: AgentToolCallEvent): void {\n emit('agent', 'tool-call', payload);\n}\nexport function publishAgentQuotaExceeded(payload: AgentQuotaExceeded): void {\n emit('agent', 'quota.exceeded', payload);\n}\nexport function publishAgentRunFinished(payload: AgentRunFinished): void {\n emit('agent', 'run.finished', payload);\n}\nexport function publishAgentRunFailed(payload: AgentRunFailed): void {\n emit('agent', 'run.failed', payload);\n}\nexport function publishAgentDelegated(payload: AgentDelegated): void {\n emit('agent', 'delegated', payload);\n}\nexport function publishAgentRetrieved(payload: AgentRetrieved): void {\n emit('agent', 'retrieved', payload);\n}\nexport function publishAgentToolRetry(payload: AgentToolRetry): void {\n emit('agent', 'tool.retry', payload);\n}\nexport function publishAgentSkillsResolved(payload: AgentSkillsResolved): void {\n emit('agent', 'skills.resolved', payload);\n}\nexport function publishAgentMemoryResolved(payload: AgentMemoryResolved): void {\n emit('agent', 'memory.resolved', payload);\n}\nexport function publishAgentMemoryWritten(payload: AgentMemoryWritten): void {\n emit('agent', 'memory.written', payload);\n}\n\n/**\n * Events published ONLY as spans — via `trace('agent', ...)` on the five `:start`/`:end`/\n * `:asyncStart`/`:asyncEnd`/`:error` sub-channels — never as point events on the base channel.\n * They are deliberately NOT in {@link AGENT_DIAGNOSTIC_EVENTS}: the point-event watcher has\n * nothing to subscribe to on their base channels, and claiming their keys would be meaningless\n * (the generic bridge only records point traffic).\n */\nexport type AgentSpanEvent =\n | 'llm.turn'\n | 'tool.execution'\n | 'retrieval'\n | 'follow-ups'\n | 'structured-output';\n\n/** All span-only events, in a stable order — for a future span recorder to derive sub-channels from. */\nexport const AGENT_SPAN_EVENTS: readonly AgentSpanEvent[] = [\n 'llm.turn',\n 'tool.execution',\n 'retrieval',\n 'follow-ups',\n 'structured-output',\n];\n\n/** Compile-time-only check: every {@link AgentSpanEvent} must appear in `AGENT_SPAN_EVENTS`. */\ntype AgentSpanEventsCoverAllKeys = [AgentSpanEvent] extends [(typeof AGENT_SPAN_EVENTS)[number]]\n ? true\n : ['AGENT_SPAN_EVENTS is missing an AgentSpanEvent'];\nconst agentSpanEventsCoverAllKeys: AgentSpanEventsCoverAllKeys = true;\nvoid agentSpanEventsCoverAllKeys;\n\n/** Compile-time-only check: every span event must be declared on `ChannelRegistry['agent']`. */\ntype AgentSpanEventsAreRegistered = [AgentSpanEvent] extends [keyof ChannelRegistry['agent']]\n ? true\n : [\"AGENT_SPAN_EVENTS names an event not declared on ChannelRegistry['agent']\"];\nconst agentSpanEventsAreRegistered: AgentSpanEventsAreRegistered = true;\nvoid agentSpanEventsAreRegistered;\n\n/** Every POINT event key declared on `ChannelRegistry['agent']` above — derived, not hand-copied. */\nexport type AgentDiagnosticEvent = Exclude<keyof ChannelRegistry['agent'], AgentSpanEvent>;\n\n/**\n * All 12 point events on `ChannelRegistry['agent']`, in a stable order — handy for wiring\n * subscribers (mirrors nestjs-media's `MEDIA_DIAGNOSTIC_EVENTS`). Span-only events (see\n * {@link AgentSpanEvent}) are excluded. A drift between this list and the registry is a compile\n * error in both directions: an extra/misspelled entry fails this array's own\n * `readonly AgentDiagnosticEvent[]` annotation immediately; a missing entry fails the\n * {@link AgentDiagnosticEventsCoverAllKeys} check below.\n */\nexport const AGENT_DIAGNOSTIC_EVENTS: readonly AgentDiagnosticEvent[] = [\n 'run.started',\n 'message',\n 'tool-call',\n 'quota.exceeded',\n 'run.finished',\n 'run.failed',\n 'delegated',\n 'retrieved',\n 'skills.resolved',\n 'memory.resolved',\n 'memory.written',\n 'tool.retry',\n];\n\n/** Compile-time-only check: every point event of `ChannelRegistry['agent']` must appear above. */\ntype AgentDiagnosticEventsCoverAllKeys = [AgentDiagnosticEvent] extends [\n (typeof AGENT_DIAGNOSTIC_EVENTS)[number],\n]\n ? true\n : [\"AGENT_DIAGNOSTIC_EVENTS is missing a key declared on ChannelRegistry['agent']\"];\n\n// If this line stops typechecking, an event was added to (or renamed on) ChannelRegistry['agent']\n// without a matching update to AGENT_DIAGNOSTIC_EVENTS (point events) or AgentSpanEvent (spans).\nconst agentDiagnosticEventsCoverAllKeys: AgentDiagnosticEventsCoverAllKeys = true;\nvoid agentDiagnosticEventsCoverAllKeys;\n\n/**\n * The telescope key for an agent diagnostics channel — `agent:<event>`. This is the key the\n * `@dudousxd/nestjs-diagnostics-telescope` generic bridge matches its `exclude` option against,\n * and the label its \"Busiest events\" panel shows. Distinct from the `aviary:agent:<event>` channel\n * name used on the wire. Mirrors `mediaDiagnosticKey`.\n */\nexport type AgentDiagnosticKey = `agent:${AgentDiagnosticEvent}`;\n\n/**\n * Compose the telescope key for an agent event, typed against {@link AgentDiagnosticEvent} so a\n * misspelled event is a compile error. Feed the result to `nestjsDiagnosticsTelescope({ exclude:\n * [...] })` to mute a noisy channel, e.g. `agentDiagnosticKey('message')`.\n */\nexport function agentDiagnosticKey(event: AgentDiagnosticEvent): AgentDiagnosticKey {\n return `agent:${event}`;\n}\n","import { snapshotActionProposal } from './action-proposal-transitions.js';\nimport { prepareUiEmission } from './genui/capabilities.js';\nimport type { Catalog } from './genui/catalog.js';\nimport type { ToolDescribeScope } from './spi/tool.js';\nimport type { AgentStreamEvent } from './stream-events.js';\nimport { type UiCollector, createUiCollector } from './tool-ui.js';\nexport type ResolveToolUiCatalog = (scope: ToolDescribeScope) => Catalog | Promise<Catalog>;\nexport interface NegotiatedUiCollector extends UiCollector {\n text(): string;\n}\nexport function createNegotiatedUiCollector(\n toolCallId: string,\n scope: ToolDescribeScope,\n resolveCatalog?: ResolveToolUiCatalog,\n write?: (event: AgentStreamEvent) => void | Promise<void>,\n): NegotiatedUiCollector {\n const collector = createUiCollector(toolCallId, write);\n const texts = new Map<string, string>();\n let next = 0;\n return {\n components: collector.components,\n text: () => [...texts.values()].join('\\n'),\n restart: () => {\n next = 0;\n texts.clear();\n collector.restart();\n },\n emit: async (component, props, options = {}) => {\n if (!resolveCatalog) {\n // No server catalog to negotiate against: the client's declaration can only narrow what is\n // drawn. A component it does not declare (at this version) degrades to its fallback text,\n // else is left out — never a throw, which would fail the tool body itself.\n const declared =\n scope.uiCapabilities === undefined ||\n scope.uiCapabilities.components.some(\n (entry) => entry.name === component && entry.version === (options.version ?? 1),\n );\n if (declared) return collector.emit(component, props, options);\n const id = options.id ?? `${toolCallId}:ui:${next++}`;\n if (options.fallbackText !== undefined && options.fallbackText.length > 0) {\n texts.set(id, options.fallbackText);\n await write?.({ kind: 'text', text: options.fallbackText });\n }\n return { id };\n }\n const capturedProps = snapshotActionProposal(props);\n const capturedOptions = { ...options };\n const catalog = await resolveCatalog(scope);\n const prepared = await prepareUiEmission(\n catalog,\n scope.uiCapabilities,\n component,\n capturedProps,\n capturedOptions.version,\n );\n const id = capturedOptions.id ?? `${toolCallId}:ui:${next++}`;\n if (prepared.kind === 'text') {\n texts.set(id, prepared.text);\n await write?.({ kind: 'text', text: prepared.text });\n return { id };\n }\n return collector.emit(prepared.component, prepared.props, {\n id,\n version: prepared.version,\n fallbackText: prepared.fallbackText,\n ...(prepared.componentVersions !== undefined\n ? { componentVersions: prepared.componentVersions }\n : {}),\n });\n },\n };\n}\n","/**\n * Transient tool-error classification + the retry loop that wraps a tool's own invocation. A\n * classified-transient error (a DB deadlock, a lock-wait timeout, a serialization failure) means\n * the server rolled the tool's work back — retrying THAT class is safe, unlike a tool's general\n * business failure, which stays a one-shot outcome (no durable step retries: a tool may not be\n * idempotent). See `runAgentLoop`'s `tool:<call.id>` step body and `AgentRunSteps.tool` — both wrap\n * `registry.invoke(...)` with {@link invokeWithTransientRetry} so a retry never becomes a new\n * checkpoint; history still shows exactly one step per tool call.\n */\n\nimport { isControlFlowSignal } from './control-flow.js';\nimport { ToolPreflightDeniedError } from './tool-registry.js';\n\n/** Narrow, structural check for a MySQL/Postgres/SQLite transient error shape — no casts. */\nfunction hasTransientShape(error: unknown): boolean {\n if (typeof error !== 'object' || error === null) {\n return false;\n }\n const code = 'code' in error ? (error as { code: unknown }).code : undefined;\n const errno = 'errno' in error ? (error as { errno: unknown }).errno : undefined;\n const sqlState = 'sqlState' in error ? (error as { sqlState: unknown }).sqlState : undefined;\n if (code === 1213 || code === 1205 || errno === 1213 || errno === 1205) {\n return true; // MySQL ER_LOCK_DEADLOCK / ER_LOCK_WAIT_TIMEOUT numeric codes\n }\n if (code === 'ER_LOCK_DEADLOCK' || code === 'ER_LOCK_WAIT_TIMEOUT') {\n return true; // MySQL driver string codes\n }\n if (code === '40001' || code === '40P01' || sqlState === '40001' || sqlState === '40P01') {\n return true; // Postgres serialization_failure / deadlock_detected SQLSTATEs\n }\n if (code === 'SQLITE_BUSY') {\n return true;\n }\n const message = 'message' in error ? (error as { message: unknown }).message : undefined;\n return (\n typeof message === 'string' && /deadlock|lock wait timeout|serialization failure/i.test(message)\n );\n}\n\n/**\n * Default transient-tool-error classifier: true for a recognized MySQL/Postgres/SQLite\n * lock-contention shape (by driver `code`/`errno`/`sqlState`, or a matching message), checked on\n * the error itself and one level of `cause` (drivers commonly wrap the original error). A plain\n * `Error` with none of these markers — any other business failure — is `false`.\n */\nexport function isTransientToolError(error: unknown): boolean {\n if (error instanceof ToolPreflightDeniedError) return false;\n if (hasTransientShape(error)) {\n return true;\n }\n if (typeof error === 'object' && error !== null && 'cause' in error) {\n const cause = (error as { cause: unknown }).cause;\n if (cause !== undefined && cause !== error && hasTransientShape(cause)) {\n return true;\n }\n }\n return false;\n}\n\n/** Total attempts (initial try + retries) when `toolTransientRetry` doesn't set `attempts`. */\nexport const DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS = 2;\n/** Backoff base in ms — the wait between attempt N and N+1 is `backoffMs * N`. */\nexport const DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS = 150;\n\n/** The host-configurable half of the policy — everything except the (non-wire-safe) `classify` fn. */\nexport interface ToolTransientRetryOptions {\n /** Total attempts (initial try + retries). Defaults to {@link DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS}. */\n attempts?: number;\n /** Backoff base in ms. Defaults to {@link DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS}. */\n backoffMs?: number;\n /** Overrides the default classifier — widen or narrow which errors are treated as transient. */\n classify?: (error: unknown) => boolean;\n}\n\n/** `false` disables transient retry entirely — a tool's own thrown error surfaces immediately. */\nexport type ToolTransientRetrySetting = ToolTransientRetryOptions | false;\n\n/** Just the wire-safe (numeric) half of a resolved policy — what a dispatched envelope carries. */\nexport interface ToolTransientRetryNumbers {\n attempts: number;\n backoffMs: number;\n}\n\n/**\n * Resolves the numeric half of `toolTransientRetry` for the dispatched wire envelope: `false` when\n * explicitly disabled, else concrete `{ attempts, backoffMs }` (defaults filled in) — never\n * `undefined`, so the dispatched handler always gets a definite answer instead of re-deriving its\n * own default. The `classify` function never rides this — it isn't wire-safe; the dispatched\n * handler resolves its own `classify` from its local module options (see `AgentRunSteps.tool`).\n */\nexport function resolveToolTransientRetryNumbers(\n setting: ToolTransientRetrySetting | undefined,\n): ToolTransientRetryNumbers | false {\n if (setting === false) {\n return false;\n }\n return {\n attempts: setting?.attempts ?? DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS,\n backoffMs: setting?.backoffMs ?? DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS,\n };\n}\n\nexport interface InvokeWithTransientRetryOptions {\n /**\n * Widens what counts as a control-flow signal (durable suspend / continue-as-new) so a retry never\n * swallows one — same rule the loop's tool catch applies. An ADDITION to the built-in marker check\n * ({@link isControlFlowSignal}), which already covers every signal the durable runtimes raise;\n * supply this only for a runner whose signals carry no marker.\n */\n isControlFlowError?: (error: unknown) => boolean;\n /**\n * Called before each wait-and-retry, with the 1-based ordinal of the attempt that just failed and\n * the error it threw. The call site uses this to emit the `tool.retry` diagnostics point event —\n * `invokeWithTransientRetry` itself carries no tool identity (name/callId), only the thunk.\n */\n onRetry?: (attempt: number, error: unknown) => void;\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\n/**\n * Retries `fn` in place — never a new durable step/checkpoint, just repeated attempts inside\n * whichever step body already wraps this call. `setting: false` runs `fn` once, unwrapped (no\n * classify/backoff bookkeeping at all). Otherwise: try; on a thrown error, rethrow immediately if\n * it's a recognized control-flow signal, else if the (possibly custom) classifier calls it\n * transient AND attempts remain, wait `backoffMs * attemptNumber` and retry; otherwise rethrow the\n * error as-is.\n */\nexport async function invokeWithTransientRetry<T>(\n fn: () => Promise<T>,\n setting: ToolTransientRetrySetting,\n options?: InvokeWithTransientRetryOptions,\n): Promise<T> {\n if (setting === false) {\n return fn();\n }\n const attempts = setting.attempts ?? DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS;\n const backoffMs = setting.backoffMs ?? DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS;\n const classify = setting.classify ?? isTransientToolError;\n\n let attempt = 1;\n for (;;) {\n try {\n return await fn();\n } catch (error) {\n if (\n error instanceof ToolPreflightDeniedError ||\n isControlFlowSignal(error) ||\n options?.isControlFlowError?.(error) === true\n ) {\n throw error;\n }\n const attemptsRemain = attempt < attempts;\n if (!attemptsRemain || !classify(error)) {\n throw error;\n }\n options?.onRetry?.(attempt, error);\n await delay(backoffMs * attempt);\n attempt += 1;\n }\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport {\n validateActionProposalExpiryBatch,\n validateActionProposalWorkerClaim,\n} from './action-proposal-discovery.js';\nimport { claimActionProposalOutcome } from './action-proposal-outcome.js';\nimport {\n actionProposalCreationMatches,\n actionProposalScopeMatches,\n initialActionProposal,\n snapshotActionProposal,\n transitionActionProposalClaim,\n transitionActionProposalDecision,\n transitionActionProposalLease,\n transitionActionProposalSettlement,\n transitionActionProposalSupersession,\n validateActionProposalCreation,\n validateActionProposalListQuery,\n} from './action-proposal-transitions.js';\nimport type {\n ActionProposalOutcome,\n ActionProposalOutcomeLease,\n} from './spi/action-proposal-outcome-store.js';\nimport type {\n ActionProposal,\n ActionProposalDecisionCommand,\n ActionProposalMutationResult,\n ActionProposalScope,\n ActionProposalStore,\n ActionProposalStoreOptions,\n ClaimActionProposal,\n CreateActionProposal,\n CreateActionProposalResult,\n ExtendActionProposalLease,\n ListActionProposals,\n SettleActionProposal,\n} from './spi/action-proposal-store.js';\nimport type { ActionProposalWorkerStore } from './spi/action-proposal-worker-store.js';\n\n/** Reference single-process implementation; durable adapters use the same transitions under CAS. */\nexport class InMemoryActionProposalStore implements ActionProposalStore, ActionProposalWorkerStore {\n protected readonly rows = new Map<string, ActionProposal>();\n protected readonly clock: () => number;\n constructor(options: ActionProposalStoreOptions = {}) {\n this.clock = options.clock ?? Date.now;\n }\n async createActionProposal(input: CreateActionProposal): Promise<CreateActionProposalResult> {\n validateActionProposalCreation(input);\n const row = this.rows.get(input.id);\n if (row) {\n if (!actionProposalScopeMatches(row, input)) return { status: 'conflict' };\n return {\n status: actionProposalCreationMatches(row, input) ? 'unchanged' : 'conflict',\n proposal: snapshotActionProposal(row),\n };\n }\n const proposal = initialActionProposal(input, this.clock());\n this.rows.set(input.id, proposal);\n return { status: 'created', proposal: snapshotActionProposal(proposal) };\n }\n async getActionProposal(scope: ActionProposalScope, id: string): Promise<ActionProposal | null> {\n const row = this.rows.get(id);\n return row && actionProposalScopeMatches(row, scope) ? snapshotActionProposal(row) : null;\n }\n async listActionProposals(\n scope: ActionProposalScope,\n query: ListActionProposals = {},\n ): Promise<ActionProposal[]> {\n const limit = validateActionProposalListQuery(query);\n return [...this.rows.values()]\n .filter(\n (row) =>\n actionProposalScopeMatches(row, scope) &&\n (query.decision === undefined || row.decision === query.decision) &&\n (query.after === undefined ||\n row.createdAt > query.after.createdAt ||\n (row.createdAt === query.after.createdAt && row.id > query.after.id)),\n )\n .sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))\n .slice(0, limit)\n .map(snapshotActionProposal);\n }\n private mutate(\n scope: ActionProposalScope,\n id: string,\n transition: (row: ActionProposal, now: number) => ActionProposalMutationResult,\n ): ActionProposalMutationResult {\n const row = this.rows.get(id);\n if (!row || !actionProposalScopeMatches(row, scope)) return { status: 'not_found' };\n const result = transition(row, this.clock());\n if (result.proposal) this.rows.set(id, snapshotActionProposal(result.proposal));\n return result;\n }\n async decideActionProposal(\n scope: ActionProposalScope,\n id: string,\n command: ActionProposalDecisionCommand,\n ): Promise<ActionProposalMutationResult> {\n return this.mutate(scope, id, (row, now) =>\n transitionActionProposalDecision(row, command, now),\n );\n }\n async claimActionProposal(\n scope: ActionProposalScope,\n id: string,\n command: ClaimActionProposal,\n ): Promise<ActionProposalMutationResult> {\n return this.mutate(scope, id, (row, now) =>\n transitionActionProposalClaim(row, command, now, randomUUID()),\n );\n }\n async extendActionProposalLease(\n scope: ActionProposalScope,\n id: string,\n command: ExtendActionProposalLease,\n ): Promise<ActionProposalMutationResult> {\n return this.mutate(scope, id, (row, now) => transitionActionProposalLease(row, command, now));\n }\n async settleActionProposal(\n scope: ActionProposalScope,\n id: string,\n command: SettleActionProposal,\n ): Promise<ActionProposalMutationResult> {\n return this.mutate(scope, id, (row, now) =>\n transitionActionProposalSettlement(row, command, now),\n );\n }\n\n async claimNextActionProposal(command: ClaimActionProposal): Promise<ActionProposal | null> {\n const now = this.clock();\n validateActionProposalWorkerClaim(command, now);\n const candidates = [...this.rows.values()]\n .filter(\n (row) =>\n row.decision === 'approved' &&\n (row.execution?.status === 'queued' ||\n (row.execution?.status === 'executing' &&\n row.execution.lease !== null &&\n now >= row.execution.lease.expiresAt)),\n )\n .sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))\n .slice(0, 32);\n for (const candidate of candidates) {\n const claimed = await this.claimActionProposal(candidate, candidate.id, command);\n if (claimed.status === 'applied' && claimed.proposal) return claimed.proposal;\n }\n return null;\n }\n\n async expireActionProposals(command: { limit: number }): Promise<number> {\n const now = this.clock();\n validateActionProposalExpiryBatch(command, now);\n const candidates = [...this.rows.values()]\n .filter((row) => row.decision === 'pending' && row.expiresAt !== null && now >= row.expiresAt)\n .sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))\n .slice(0, command.limit);\n let expired = 0;\n for (const candidate of candidates) {\n const result = await this.decideActionProposal(candidate, candidate.id, {\n decision: 'expired',\n actorRef: 'system',\n via: 'expiry',\n });\n if (result.status === 'applied') expired++;\n }\n return expired;\n }\n async claimNextActionProposalOutcome(\n command: ClaimActionProposal,\n ): Promise<{ outcome: ActionProposalOutcome; lease: ActionProposalOutcomeLease } | null> {\n const now = this.clock();\n validateActionProposalWorkerClaim(command, now);\n const candidates = [...this.rows.values()]\n .filter(\n (row) =>\n row.outcomeDelivery?.status === 'pending' &&\n (!row.outcomeDelivery.lease || now >= row.outcomeDelivery.lease.expiresAt),\n )\n .sort((a, b) => a.createdAt - b.createdAt || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))\n .slice(0, 32);\n for (const candidate of candidates) {\n const row = this.rows.get(candidate.id);\n if (!row) continue;\n const next = claimActionProposalOutcome(row, command, this.clock(), randomUUID());\n if (!next?.outcome || !next.outcomeDelivery?.lease) continue;\n this.rows.set(next.id, next);\n return {\n outcome: snapshotActionProposal(next.outcome),\n lease: {\n outcomeId: next.outcome.id,\n token: next.outcomeDelivery.lease.token,\n generation: next.outcomeDelivery.generation,\n },\n };\n }\n return null;\n }\n\n async createReplacingActionProposal(\n input: CreateActionProposal,\n ): Promise<CreateActionProposalResult> {\n validateActionProposalCreation(input);\n const existing = this.rows.get(input.id);\n if (existing) return this.createActionProposal(input);\n const proposal = initialActionProposal(input, this.clock());\n // Build every replacement snapshot before changing any row; no await exposes partial state.\n const replacements: ActionProposal[] = [];\n if (input.replacementKey)\n for (const row of this.rows.values()) {\n if (\n row.decision !== 'pending' ||\n !actionProposalScopeMatches(row, input) ||\n row.toolName !== input.toolName ||\n row.replacementKey !== input.replacementKey\n )\n continue;\n const result = transitionActionProposalSupersession(\n row,\n proposal,\n { replacementProposalId: proposal.id, actorRef: input.actorRef, via: 'supersession' },\n this.clock(),\n );\n if (result.proposal) replacements.push(result.proposal);\n }\n this.rows.set(proposal.id, proposal);\n for (const row of replacements) this.rows.set(row.id, row);\n return { status: 'created', proposal: snapshotActionProposal(proposal) };\n }\n async supersedeActionProposal(\n scope: ActionProposalScope,\n id: string,\n command: { replacementProposalId: string; actorRef: string; via: string },\n ): Promise<ActionProposalMutationResult> {\n const replacement = this.rows.get(command.replacementProposalId);\n if (!replacement || !actionProposalScopeMatches(replacement, scope))\n return { status: 'not_found' };\n return this.mutate(scope, id, (row, now) =>\n transitionActionProposalSupersession(row, replacement, command, now),\n );\n }\n}\n","import {\n actionProposalOutcomeFenceValid,\n actionProposalOutcomeText,\n} from './action-proposal-outcome.js';\nimport { snapshotActionProposal } from './action-proposal-transitions.js';\nimport type { ToolCallOutcome } from './dangling-tool-calls.js';\nimport { InMemoryActionProposalStore } from './in-memory-action-proposal-store.js';\nimport type {\n ActionProposalOutcomeLease,\n ActionProposalOutcomeStore,\n} from './spi/action-proposal-outcome-store.js';\nimport type { ActionProposalScope } from './spi/action-proposal-store.js';\nimport {\n type AgentStore,\n type AppendMessageInput,\n type CreateThreadInput,\n type RecordRunStartInput,\n type RecordToolCallInput,\n type RecordUsageInput,\n type ToolCallApprovalState,\n type UpdateThreadInput,\n type UpdateToolCallInput,\n} from './spi/agent-store.js';\nimport { toolCallApprovalFromRow } from './spi/approval-policy.js';\nimport type {\n ChatQueueStore,\n EnqueueMessageInput,\n QueuePause,\n QueuedMessage,\n QueuedMessagePatch,\n} from './spi/chat-queue.js';\nimport { type AgentUiComponent } from './stream-events.js';\nimport type { ToolConfirmation } from './tool-presentation.js';\nimport {\n type MessageFeedback,\n type StoredMessage,\n type ThreadDetail,\n type ThreadSummary,\n type ToolCallApproval,\n type ToolCallStatus,\n type ToolResult,\n} from './types.js';\n\ninterface ThreadRow extends ThreadSummary {\n actorRef: string;\n tenantRef: string | null;\n activeStreamId?: string;\n messages: StoredMessage[];\n}\n\ninterface ToolCallRow {\n proposalId?: string;\n toolCallId: string;\n messageId: string;\n threadId: string;\n toolName: string;\n toolType: 'read' | 'action';\n input: unknown;\n output?: unknown;\n status: ToolCallStatus;\n error?: string;\n executionMs?: number;\n createdAt: string;\n /** The run this call belongs to; `undefined` when the caller didn't supply one. */\n runId?: string;\n executedByRef?: string;\n approver?: string;\n confirmation?: ToolConfirmation;\n expiresAt?: string;\n remember?: boolean;\n decidedVia?: string;\n}\n\ninterface UsageRow {\n actorRef: string;\n threadId: string;\n modelId: string;\n inputTokens: number;\n outputTokens: number;\n cacheWriteTokens?: number;\n cacheReadTokens?: number;\n costUsd?: number;\n day: string;\n createdAt: string;\n}\n\n/** A recorded usage row exposed to the governance read-model (input/output split + thread/day). */\nexport interface GovernanceUsageRow {\n actorRef: string;\n threadId: string;\n modelId: string;\n inputTokens: number;\n outputTokens: number;\n /** Subset of `inputTokens` written to the prompt cache this turn; undefined when not reported. */\n cacheWriteTokens?: number;\n /** Subset of `inputTokens` served from the prompt cache this turn; undefined when not reported. */\n cacheReadTokens?: number;\n /** Provider-reported actual cost for the turn, when known; undefined → estimate from pricing. */\n costUsd?: number;\n day: string;\n createdAt: string;\n}\n\n/** A recorded tool call exposed to the governance read-model (thread resolved, with timestamp). */\nexport interface GovernanceToolCallRow {\n toolCallId: string;\n toolName: string;\n toolType: 'read' | 'action';\n status: ToolCallStatus;\n threadId: string;\n /** The message that requested the call — the thread drill-down groups by it. */\n messageId: string;\n /** Wall-clock milliseconds the tool took to run; undefined when it never recorded one. */\n executionMs?: number;\n /** The failure text for a `failed` call; undefined otherwise. */\n error?: string;\n createdAt: string;\n /** The run this call belongs to; undefined when the caller didn't supply one. */\n runId?: string;\n}\n\n/** A stored message exposed to the governance read-model (the thread drill-down's transcript). */\nexport interface GovernanceMessageRow {\n messageId: string;\n threadId: string;\n role: string;\n content: string;\n agentName?: string;\n createdAt: string;\n}\n\n/** A tool call awaiting a HITL decision, joined to its thread + message for the approvals inbox. */\nexport interface GovernancePendingApprovalRow {\n toolCallId: string;\n toolName: string;\n input: unknown;\n threadId: string;\n threadTitle: string;\n actorRef: string;\n agentName?: string;\n requestedAt: string;\n /** The run this call belongs to; undefined when the caller didn't supply one. */\n runId?: string;\n}\n\n/** Thread metadata exposed to the governance read-model (title/actor/count/last activity). */\nexport interface GovernanceThreadRow {\n threadId: string;\n title: string;\n actorRef: string;\n messageCount: number;\n updatedAt: string;\n}\n\ninterface RunRow {\n runId: string;\n threadId: string;\n actorRef: string;\n agentName?: string;\n status: 'running' | 'completed' | 'failed' | 'cancelled';\n durationMs?: number;\n errorCode?: string;\n errorMessage?: string;\n retries: number;\n startedAt: string;\n settledAt?: string;\n /** sha256 hex of the run's resolved (pre-RAG) system prompt; undefined for a pre-existing run. */\n promptHash?: string;\n /** The run that delegated this one; undefined for a turn nobody delegated. */\n parentRunId?: string;\n}\n\n/** A recorded run outcome exposed to the governance read-model (reliability surfaces). */\nexport interface GovernanceRunRow {\n runId: string;\n threadId: string;\n actorRef: string;\n agentName?: string;\n status: 'running' | 'completed' | 'failed' | 'cancelled';\n durationMs?: number;\n errorCode?: string;\n errorMessage?: string;\n retries: number;\n startedAt: string;\n settledAt?: string;\n promptHash?: string;\n /**\n * The run that delegated this one; undefined for a turn nobody delegated. The edge exists in the\n * durable journal too, but a reader of run rows has only this — and a DETACHED child outlives its\n * parent's turn, so nothing in the transcript pairs them either.\n */\n parentRunId?: string;\n}\n\n/** A fully in-memory `AgentStore` for tests and the offline demo. */\nexport class InMemoryAgentStore\n extends InMemoryActionProposalStore\n implements AgentStore, ChatQueueStore, ActionProposalOutcomeStore\n{\n private readonly threads = new Map<string, ThreadRow>();\n /** Each thread's waiting messages, in run order. */\n private readonly queues = new Map<string, QueuedMessage[]>();\n private readonly pauses = new Map<string, QueuePause>();\n private readonly toolCalls = new Map<string, ToolCallRow>();\n private readonly usage: UsageRow[] = [];\n private readonly runs = new Map<string, RunRow>();\n\n private now(): string {\n return new Date().toISOString();\n }\n\n async createThread(input: CreateThreadInput): Promise<ThreadSummary> {\n const id = input.id ?? crypto.randomUUID();\n if (this.threads.has(id)) {\n throw new Error(`thread ${id} already exists`);\n }\n const ts = this.now();\n const row: ThreadRow = {\n id,\n actorRef: input.actor.id,\n tenantRef: input.actor.tenantRef ?? null,\n title: input.title ?? 'New chat',\n transient: input.transient ?? false,\n createdAt: ts,\n updatedAt: ts,\n messages: [],\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n };\n this.threads.set(id, row);\n return this.toSummary(row);\n }\n\n async getThread(threadId: string): Promise<ThreadDetail | null> {\n const row = this.threads.get(threadId);\n if (row === undefined) {\n return null;\n }\n return {\n ...this.toSummary(row),\n messages: row.messages.map((message) => this.withApprovals(message)),\n // The run streaming right now — the one field the read-model reports it under.\n ...(row.activeStreamId !== undefined ? { activeRunId: row.activeStreamId } : {}),\n };\n }\n\n /** A message with the approval record of every call on it that was put to a person. */\n private withApprovals(message: StoredMessage): StoredMessage {\n const approvals: ToolCallApproval[] = [];\n for (const call of this.toolCalls.values()) {\n if (call.messageId !== message.id) {\n continue;\n }\n const approval = toolCallApprovalFromRow({\n toolCallId: call.toolCallId,\n ...(call.proposalId !== undefined ? { proposalId: call.proposalId } : {}),\n status: call.status,\n approver: call.approver,\n confirmation: call.confirmation,\n expiresAt: call.expiresAt,\n remember: call.remember,\n executedByRef: call.executedByRef,\n decidedVia: call.decidedVia,\n error: call.error,\n });\n if (approval !== null) {\n approvals.push(approval);\n }\n }\n return approvals.length > 0 ? { ...message, approvals } : message;\n }\n\n async rememberedApprovals(threadId: string): Promise<string[]> {\n const names = new Set<string>();\n for (const call of this.toolCalls.values()) {\n if (call.threadId === threadId && call.remember === true) {\n names.add(call.toolName);\n }\n }\n const thread = this.threads.get(threadId);\n if (thread)\n for (const proposal of this.rows.values())\n if (\n proposal.threadId === threadId &&\n proposal.actorRef === thread.actorRef &&\n proposal.tenantRef === thread.tenantRef &&\n proposal.decisionAudit?.remember === true &&\n (proposal.execution?.status === 'succeeded' || proposal.execution?.status === 'failed')\n )\n names.add(proposal.toolName);\n return [...names];\n }\n\n async toolCallInput(toolCallId: string): Promise<unknown> {\n return this.toolCalls.get(toolCallId)?.input ?? null;\n }\n\n async toolCallApproval(toolCallId: string): Promise<ToolCallApprovalState | null> {\n const call = this.toolCalls.get(toolCallId);\n if (call === undefined) {\n return null;\n }\n return {\n status: call.status,\n approver: call.approver ?? null,\n expiresAt: call.expiresAt ?? null,\n };\n }\n\n async listThreads(actorRef: string, limit = 50): Promise<ThreadSummary[]> {\n return [...this.threads.values()]\n .filter((row) => row.actorRef === actorRef && !row.transient)\n .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt))\n .slice(0, limit)\n .map((row) => this.toSummary(row));\n }\n\n async softDeleteThread(threadId: string): Promise<void> {\n this.threads.delete(threadId);\n }\n\n async forkThread(threadId: string, fromMessageId: string): Promise<ThreadSummary> {\n const source = this.threads.get(threadId);\n if (source === undefined) {\n throw new Error(`thread ${threadId} not found`);\n }\n const cutoff = source.messages.findIndex((message) => message.id === fromMessageId);\n const kept = cutoff >= 0 ? source.messages.slice(0, cutoff + 1) : [...source.messages];\n const id = crypto.randomUUID();\n const ts = this.now();\n const row: ThreadRow = {\n id,\n actorRef: source.actorRef,\n tenantRef: source.tenantRef,\n title: source.title,\n transient: false,\n createdAt: ts,\n updatedAt: ts,\n // Feedback rates a message in ITS thread; a fork starts unrated.\n messages: kept.map(({ feedback: _feedback, ...message }) => ({ ...message })),\n ...(source.defaultAgent != null ? { defaultAgent: source.defaultAgent } : {}),\n ...(source.model != null ? { model: source.model } : {}),\n ...(source.persona != null ? { persona: source.persona } : {}),\n };\n this.threads.set(id, row);\n return this.toSummary(row);\n }\n\n async ownerOfThread(threadId: string): Promise<string | null> {\n return this.threads.get(threadId)?.actorRef ?? null;\n }\n\n async ownerOfToolCall(toolCallId: string): Promise<string | null> {\n const call = this.toolCalls.get(toolCallId);\n if (call === undefined) {\n return null;\n }\n return this.threads.get(call.threadId)?.actorRef ?? null;\n }\n\n async runForToolCall(toolCallId: string): Promise<string | null> {\n const call = this.toolCalls.get(toolCallId);\n if (call === undefined) {\n return null;\n }\n return call.runId ?? this.threads.get(call.threadId)?.activeStreamId ?? null;\n }\n\n async ownerOfActiveStream(runId: string): Promise<string | null> {\n for (const row of this.threads.values()) {\n if (row.activeStreamId === runId) {\n return row.actorRef;\n }\n }\n return null;\n }\n\n async setTitle(threadId: string, title: string): Promise<void> {\n const row = this.threads.get(threadId);\n if (row !== undefined) {\n row.title = title;\n row.updatedAt = this.now();\n }\n }\n\n async updateThread(threadId: string, patch: UpdateThreadInput): Promise<void> {\n const row = this.threads.get(threadId);\n if (row === undefined) {\n return;\n }\n if (patch.title !== undefined) {\n row.title = patch.title;\n }\n if (patch.defaultAgent !== undefined) {\n row.defaultAgent = patch.defaultAgent;\n }\n if (patch.model !== undefined) {\n row.model = patch.model;\n }\n if (patch.persona !== undefined) {\n row.persona = patch.persona;\n }\n row.updatedAt = this.now();\n }\n\n async activeRunForThread(threadId: string): Promise<string | null> {\n return this.threads.get(threadId)?.activeStreamId ?? null;\n }\n\n /**\n * The thread's default agent, projected. A map lookup here, but the SQL adapters answer this with\n * a one-column read instead of materializing the whole transcript — so the caller that only needs\n * this scalar has a method to ask for it.\n */\n async defaultAgentForThread(threadId: string): Promise<string | null> {\n return this.threads.get(threadId)?.defaultAgent ?? null;\n }\n\n /** The thread's persona, projected like {@link defaultAgentForThread}. */\n async personaForThread(threadId: string): Promise<string | null> {\n return this.threads.get(threadId)?.persona ?? null;\n }\n\n /** The thread's pinned model, projected like {@link defaultAgentForThread}. */\n async modelForThread(threadId: string): Promise<string | null> {\n return this.threads.get(threadId)?.model ?? null;\n }\n\n /**\n * Persist the start of a run (turn). Replay-safe: called under a durable localStep.\n *\n * Takes the SPI's own {@link RecordRunStartInput} rather than a hand-copied shape: a field added\n * to the input is otherwise accepted and dropped, silently, by every adapter that re-declares it.\n */\n async recordRunStart(run: RecordRunStartInput): Promise<void> {\n this.runs.set(run.runId, {\n runId: run.runId,\n threadId: run.threadId,\n actorRef: run.actorRef,\n status: 'running',\n retries: 0,\n startedAt: this.now(),\n ...(run.agentName !== undefined ? { agentName: run.agentName } : {}),\n ...(run.parentRunId !== undefined ? { parentRunId: run.parentRunId } : {}),\n ...(run.promptHash !== undefined ? { promptHash: run.promptHash } : {}),\n });\n }\n\n /** Settle a run's outcome. A no-op when the run is unknown (mirrors `setTitle`/`updateThread`). */\n async recordRunEnd(end: {\n runId: string;\n status: 'completed' | 'failed' | 'cancelled';\n durationMs?: number;\n errorCode?: string;\n errorMessage?: string;\n }): Promise<void> {\n const row = this.runs.get(end.runId);\n if (row === undefined) {\n return;\n }\n row.status = end.status;\n row.settledAt = this.now();\n if (end.durationMs !== undefined) {\n row.durationMs = end.durationMs;\n }\n if (end.errorCode !== undefined) {\n row.errorCode = end.errorCode;\n }\n if (end.errorMessage !== undefined) {\n row.errorMessage = end.errorMessage;\n }\n }\n\n /** Bump the run's llm-step retry counter. */\n async bumpRunRetries(runId: string): Promise<void> {\n const row = this.runs.get(runId);\n if (row !== undefined) {\n row.retries += 1;\n }\n }\n\n async promoteThread(threadId: string): Promise<void> {\n const row = this.threads.get(threadId);\n if (row?.transient) {\n row.transient = false;\n row.updatedAt = this.now();\n }\n }\n\n async setActiveStream(threadId: string, runId: string | null): Promise<void> {\n const row = this.threads.get(threadId);\n if (row !== undefined) {\n if (runId === null) {\n // biome-ignore lint/performance/noDelete: exactOptionalPropertyTypes forbids assigning undefined to an optional prop\n delete row.activeStreamId;\n } else {\n row.activeStreamId = runId;\n }\n }\n }\n\n async claimActiveStream(\n threadId: string,\n runId: string,\n options: { replacing?: string } = {},\n ): Promise<boolean> {\n const row = this.threads.get(threadId);\n if (row === undefined) {\n return false;\n }\n const holder = row.activeStreamId;\n if (holder !== undefined && holder !== runId && holder !== options.replacing) {\n return false;\n }\n row.activeStreamId = runId;\n return true;\n }\n\n async releaseActiveStream(threadId: string, runId: string): Promise<boolean> {\n const row = this.threads.get(threadId);\n if (row?.activeStreamId !== runId) {\n return false;\n }\n // biome-ignore lint/performance/noDelete: exactOptionalPropertyTypes forbids assigning undefined to an optional prop\n delete row.activeStreamId;\n return true;\n }\n\n async enqueueMessage(input: EnqueueMessageInput): Promise<QueuedMessage> {\n const ts = this.now();\n const message: QueuedMessage = {\n id: crypto.randomUUID(),\n threadId: input.threadId,\n actor: input.actor,\n content: input.content,\n ...(input.attachments !== undefined && input.attachments.length > 0\n ? { attachments: input.attachments }\n : {}),\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(input.model !== undefined ? { model: input.model } : {}),\n ...(input.pageContext !== undefined ? { pageContext: input.pageContext } : {}),\n ...(input.uiCapabilities !== undefined ? { uiCapabilities: input.uiCapabilities } : {}),\n ...(input.hostContext !== undefined ? { hostContext: input.hostContext } : {}),\n ...(input.interrupt === true ? { interrupt: true } : {}),\n createdAt: ts,\n updatedAt: ts,\n };\n const queue = this.queues.get(input.threadId) ?? [];\n if (input.at === 'head') {\n queue.unshift(message);\n } else {\n queue.push(message);\n }\n this.queues.set(input.threadId, queue);\n return { ...message };\n }\n\n async listQueue(threadId: string): Promise<QueuedMessage[]> {\n return (this.queues.get(threadId) ?? []).map((message) => ({ ...message }));\n }\n\n async getQueuedMessage(id: string): Promise<QueuedMessage | null> {\n const found = this.findQueued(id);\n return found === undefined ? null : { ...found.message };\n }\n\n async updateQueuedMessage(id: string, patch: QueuedMessagePatch): Promise<QueuedMessage | null> {\n const found = this.findQueued(id);\n if (found === undefined) {\n return null;\n }\n const { message } = found;\n if (patch.content !== undefined) {\n message.content = patch.content;\n }\n if (patch.attachments !== undefined) {\n if (patch.attachments === null || patch.attachments.length === 0) {\n // biome-ignore lint/performance/noDelete: exactOptionalPropertyTypes forbids assigning undefined to an optional prop\n delete message.attachments;\n } else {\n message.attachments = patch.attachments;\n }\n }\n if (patch.interrupt !== undefined) {\n if (patch.interrupt) {\n message.interrupt = true;\n } else {\n // biome-ignore lint/performance/noDelete: exactOptionalPropertyTypes forbids assigning undefined to an optional prop\n delete message.interrupt;\n }\n }\n message.updatedAt = this.now();\n return { ...message };\n }\n\n async moveQueuedMessage(id: string, index: number): Promise<boolean> {\n const found = this.findQueued(id);\n if (found === undefined) {\n return false;\n }\n const { queue, position, message } = found;\n queue.splice(position, 1);\n const target = Math.max(0, Math.min(queue.length, Math.trunc(index)));\n queue.splice(target, 0, message);\n return true;\n }\n\n async removeQueuedMessage(id: string): Promise<boolean> {\n const found = this.findQueued(id);\n if (found === undefined) {\n return false;\n }\n found.queue.splice(found.position, 1);\n return true;\n }\n\n async clearQueue(threadId: string): Promise<number> {\n const count = this.queues.get(threadId)?.length ?? 0;\n this.queues.delete(threadId);\n return count;\n }\n\n async queuePause(threadId: string): Promise<QueuePause | null> {\n return this.pauses.get(threadId) ?? null;\n }\n\n async setQueuePause(threadId: string, pause: QueuePause | null): Promise<void> {\n if (pause === null) {\n this.pauses.delete(threadId);\n } else {\n this.pauses.set(threadId, pause);\n }\n }\n\n private findQueued(\n id: string,\n ): { queue: QueuedMessage[]; position: number; message: QueuedMessage } | undefined {\n for (const queue of this.queues.values()) {\n const position = queue.findIndex((message) => message.id === id);\n const message = queue[position];\n if (message !== undefined) {\n return { queue, position, message };\n }\n }\n return undefined;\n }\n\n async getThreadActionProposalScope(threadId: string): Promise<ActionProposalScope | null> {\n const row = this.threads.get(threadId);\n return row ? { threadId, actorRef: row.actorRef, tenantRef: row.tenantRef } : null;\n }\n async admitActionProposalOutcome(\n command: ActionProposalOutcomeLease,\n ): ReturnType<ActionProposalOutcomeStore['admitActionProposalOutcome']> {\n const row = [...this.rows.values()].find((row) => row.outcome?.id === command.outcomeId);\n if (!row?.outcome || !row.outcomeDelivery) return { status: 'not_found' };\n if (row.outcomeDelivery.status === 'admitted')\n return {\n status: 'unchanged',\n ...(row.outcomeDelivery.messageId !== undefined\n ? { messageId: row.outcomeDelivery.messageId }\n : {}),\n };\n if (row.outcomeDelivery.status === 'discarded') return { status: 'discarded' };\n if (!actionProposalOutcomeFenceValid(row, command, this.clock())) return { status: 'conflict' };\n const thread = this.threads.get(row.threadId);\n if (!thread) {\n this.rows.set(\n row.id,\n snapshotActionProposal({\n ...row,\n outcomeDelivery: { ...row.outcomeDelivery, status: 'discarded', lease: null },\n }),\n );\n return { status: 'discarded' };\n }\n if (thread.actorRef !== row.actorRef || thread.tenantRef !== row.tenantRef)\n return { status: 'conflict' };\n if (thread.activeStreamId) return { status: 'busy' };\n // No await between checking the thread holder and committing both in-memory mutations.\n const message: StoredMessage = {\n id: crypto.randomUUID(),\n role: 'assistant',\n content: actionProposalOutcomeText(row.outcome),\n createdAt: this.now(),\n actionProposalOutcome: snapshotActionProposal(row.outcome),\n ui: snapshotActionProposal(row.outcome.ui),\n };\n const next = snapshotActionProposal({\n ...row,\n outcomeDelivery: {\n ...row.outcomeDelivery,\n status: 'admitted' as const,\n lease: null,\n messageId: message.id,\n },\n });\n thread.messages.push(message);\n thread.updatedAt = message.createdAt;\n this.rows.set(row.id, next);\n return { status: 'applied', messageId: message.id };\n }\n async appendMessage(input: AppendMessageInput): Promise<StoredMessage> {\n const row = this.threads.get(input.threadId);\n if (row === undefined) {\n throw new Error(`thread ${input.threadId} not found`);\n }\n const message: StoredMessage = {\n id: crypto.randomUUID(),\n role: input.role,\n content: input.content,\n createdAt: this.now(),\n ...(input.toolCalls !== undefined ? { toolCalls: input.toolCalls } : {}),\n ...(input.toolResults !== undefined ? { toolResults: input.toolResults } : {}),\n ...(input.attachments !== undefined ? { attachments: input.attachments } : {}),\n ...(input.followUps !== undefined ? { followUps: input.followUps } : {}),\n ...(input.usage !== undefined ? { usage: input.usage } : {}),\n ...(input.agentName !== undefined ? { agentName: input.agentName } : {}),\n ...(input.persona !== undefined ? { persona: input.persona } : {}),\n ...(input.runId !== undefined ? { runId: input.runId } : {}),\n ...(input.reasoning !== undefined ? { reasoning: input.reasoning } : {}),\n ...(input.reasoningMs !== undefined ? { reasoningMs: input.reasoningMs } : {}),\n ...(input.ui !== undefined ? { ui: input.ui } : {}),\n ...(input.actionProposalOutcome !== undefined\n ? { actionProposalOutcome: input.actionProposalOutcome }\n : {}),\n };\n row.messages.push(message);\n row.updatedAt = message.createdAt;\n return message;\n }\n\n async setMessageToolResults(messageId: string, results: ToolResult[]): Promise<void> {\n for (const row of this.threads.values()) {\n const message = row.messages.find((candidate) => candidate.id === messageId);\n if (message !== undefined) {\n message.toolResults = results;\n return;\n }\n }\n }\n\n async setMessageUi(messageId: string, ui: AgentUiComponent[]): Promise<void> {\n for (const row of this.threads.values()) {\n const index = row.messages.findIndex((candidate) => candidate.id === messageId);\n const message = row.messages[index];\n if (message !== undefined) {\n const { ui: _previous, ...rest } = message;\n row.messages[index] = ui.length > 0 ? { ...rest, ui } : rest;\n return;\n }\n }\n }\n\n async threadOfMessage(messageId: string): Promise<string | null> {\n return this.threadIdForMessage(messageId) ?? null;\n }\n\n async setMessageFeedback(messageId: string, feedback: MessageFeedback | null): Promise<void> {\n for (const row of this.threads.values()) {\n const index = row.messages.findIndex((candidate) => candidate.id === messageId);\n const message = row.messages[index];\n if (message !== undefined) {\n const { feedback: _previous, ...rest } = message;\n row.messages[index] = feedback !== null ? { ...rest, feedback } : rest;\n return;\n }\n }\n }\n\n async truncateFrom(threadId: string, messageId: string): Promise<void> {\n const row = this.threads.get(threadId);\n if (row === undefined) {\n return;\n }\n const cutoff = row.messages.findIndex((message) => message.id === messageId);\n if (cutoff >= 0) {\n row.messages = row.messages.slice(0, cutoff);\n }\n }\n\n /**\n * Of `mediaIds`, the ones a surviving message — or a message waiting in the queue — in one of\n * this actor's threads still carries.\n * Re-derived from the messages each call, so a media whose message was truncated away reads as\n * unreferenced again.\n */\n async referencedMediaIds(actorRef: string, mediaIds: readonly string[]): Promise<string[]> {\n if (mediaIds.length === 0) {\n return [];\n }\n const wanted = new Set(mediaIds);\n const found = new Set<string>();\n for (const thread of this.threads.values()) {\n if (thread.actorRef !== actorRef) {\n continue;\n }\n // A message waiting in the thread's queue carries its attachments too: it has been sent, it\n // just has not run yet — collecting its media would fail the turn it is waiting to start.\n const queued = this.queues.get(thread.id) ?? [];\n for (const message of [...thread.messages, ...queued]) {\n for (const attachment of message.attachments ?? []) {\n if (wanted.has(attachment.mediaId)) {\n found.add(attachment.mediaId);\n }\n }\n }\n }\n return [...wanted].filter((mediaId) => found.has(mediaId));\n }\n\n async recordToolCall(input: RecordToolCallInput): Promise<void> {\n this.toolCalls.set(input.toolCallId, {\n toolCallId: input.toolCallId,\n ...(input.proposalId !== undefined ? { proposalId: input.proposalId } : {}),\n messageId: input.messageId,\n threadId: this.threadIdForMessage(input.messageId) ?? '',\n toolName: input.toolName,\n toolType: input.toolType,\n input: input.input,\n status: input.status,\n createdAt: this.now(),\n ...(input.runId !== undefined ? { runId: input.runId } : {}),\n ...(input.approver !== undefined ? { approver: input.approver } : {}),\n ...(input.confirmation !== undefined\n ? { confirmation: structuredClone(input.confirmation) }\n : {}),\n ...(input.expiresAt !== undefined ? { expiresAt: input.expiresAt } : {}),\n });\n }\n\n async toolCallOutcomes(toolCallIds: readonly string[]): Promise<ToolCallOutcome[]> {\n const outcomes: ToolCallOutcome[] = [];\n for (const id of toolCallIds) {\n const row = this.toolCalls.get(id);\n if (row !== undefined) {\n outcomes.push({\n id,\n status: row.status,\n ...(row.output !== undefined ? { output: row.output } : {}),\n ...(row.error !== undefined ? { error: row.error } : {}),\n });\n }\n }\n return outcomes;\n }\n\n async failUnsettledToolCalls(runId: string, error: string): Promise<number> {\n let settled = 0;\n for (const row of this.toolCalls.values()) {\n if (row.runId === runId && row.status === 'pending_approval') {\n row.status = 'failed';\n row.error = error;\n settled += 1;\n }\n }\n return settled;\n }\n\n async updateToolCall(input: UpdateToolCallInput): Promise<void> {\n const row = this.toolCalls.get(input.toolCallId);\n if (row === undefined) {\n return;\n }\n row.status = input.status;\n if (input.output !== undefined) {\n row.output = input.output;\n }\n if (input.error !== undefined) {\n row.error = input.error;\n }\n if (input.executionMs !== undefined) {\n row.executionMs = input.executionMs;\n }\n if (input.executedByRef !== undefined) {\n row.executedByRef = input.executedByRef;\n }\n if (input.remember !== undefined) {\n row.remember = input.remember;\n }\n if (input.decidedVia !== undefined) {\n row.decidedVia = input.decidedVia;\n }\n }\n\n async recordUsage(input: RecordUsageInput): Promise<void> {\n const createdAt = this.now();\n this.usage.push({\n actorRef: input.actorRef,\n threadId: input.threadId,\n modelId: input.modelId,\n inputTokens: input.usage.inputTokens,\n outputTokens: input.usage.outputTokens,\n day: createdAt.slice(0, 10),\n createdAt,\n ...(input.usage.cacheWriteTokens !== undefined\n ? { cacheWriteTokens: input.usage.cacheWriteTokens }\n : {}),\n ...(input.usage.cacheReadTokens !== undefined\n ? { cacheReadTokens: input.usage.cacheReadTokens }\n : {}),\n ...(input.costUsd !== undefined ? { costUsd: input.costUsd } : {}),\n });\n }\n\n async quotaToday(\n actorRef: string,\n day: string,\n ): Promise<{ usedTokens: number; costUsd: number }> {\n return this.usageBetween(actorRef, day, day);\n }\n\n async usageBetween(\n actorRef: string,\n fromDay: string,\n toDay: string,\n ): Promise<{ usedTokens: number; costUsd: number }> {\n const rows = this.usage.filter(\n (row) => row.actorRef === actorRef && row.day >= fromDay && row.day <= toDay,\n );\n const usedTokens = rows.reduce((sum, row) => sum + row.inputTokens + row.outputTokens, 0);\n const costUsd = rows.reduce((sum, row) => sum + (row.costUsd ?? 0), 0);\n return { usedTokens, costUsd };\n }\n\n /** Test helper: read the recorded usage rows (modelId + token totals). */\n usageRows(): { actorRef: string; tokens: number; modelId: string }[] {\n return this.usage.map((row) => ({\n actorRef: row.actorRef,\n tokens: row.inputTokens + row.outputTokens,\n modelId: row.modelId,\n }));\n }\n\n /** Governance read-model feed: recorded usage rows with the input/output split + thread/day. */\n governanceUsage(): GovernanceUsageRow[] {\n return this.usage.map((row) => ({\n actorRef: row.actorRef,\n threadId: row.threadId,\n modelId: row.modelId,\n inputTokens: row.inputTokens,\n outputTokens: row.outputTokens,\n day: row.day,\n createdAt: row.createdAt,\n ...(row.cacheWriteTokens !== undefined ? { cacheWriteTokens: row.cacheWriteTokens } : {}),\n ...(row.cacheReadTokens !== undefined ? { cacheReadTokens: row.cacheReadTokens } : {}),\n ...(row.costUsd !== undefined ? { costUsd: row.costUsd } : {}),\n }));\n }\n\n /** Governance read-model feed: recorded tool calls with the resolved thread + timestamp. */\n governanceToolCalls(): GovernanceToolCallRow[] {\n return [...this.toolCalls.values()].map((row) => ({\n toolCallId: row.toolCallId,\n toolName: row.toolName,\n toolType: row.toolType,\n status: row.status,\n threadId: row.threadId,\n messageId: row.messageId,\n createdAt: row.createdAt,\n ...(row.executionMs !== undefined ? { executionMs: row.executionMs } : {}),\n ...(row.error !== undefined ? { error: row.error } : {}),\n ...(row.runId !== undefined ? { runId: row.runId } : {}),\n }));\n }\n\n /** Governance read-model feed: every stored message, thread-resolved, for the thread drill-down. */\n governanceMessages(): GovernanceMessageRow[] {\n const rows: GovernanceMessageRow[] = [];\n for (const thread of this.threads.values()) {\n for (const message of thread.messages) {\n rows.push({\n messageId: message.id,\n threadId: thread.id,\n role: message.role,\n content: message.content,\n createdAt: message.createdAt,\n ...(message.agentName !== undefined ? { agentName: message.agentName } : {}),\n });\n }\n }\n return rows;\n }\n\n /**\n * Governance read-model feed: tool calls sitting `pending_approval`, joined to their thread\n * (title/actorRef) and the message that requested them (`agentName`, when the message has one).\n */\n governancePendingApprovals(): GovernancePendingApprovalRow[] {\n const rows: GovernancePendingApprovalRow[] = [];\n for (const call of this.toolCalls.values()) {\n if (call.status !== 'pending_approval') {\n continue;\n }\n const thread = this.threads.get(call.threadId);\n if (thread === undefined) {\n continue;\n }\n const message = thread.messages.find((candidate) => candidate.id === call.messageId);\n rows.push({\n toolCallId: call.toolCallId,\n toolName: call.toolName,\n input: call.input,\n threadId: call.threadId,\n threadTitle: thread.title,\n actorRef: thread.actorRef,\n requestedAt: call.createdAt,\n ...(message?.agentName !== undefined ? { agentName: message.agentName } : {}),\n ...(call.runId !== undefined ? { runId: call.runId } : {}),\n });\n }\n return rows;\n }\n\n /** Governance read-model feed: thread metadata (title/actor/message count/last activity). */\n governanceThreads(): GovernanceThreadRow[] {\n return [...this.threads.values()].map((row) => ({\n threadId: row.id,\n title: row.title,\n actorRef: row.actorRef,\n messageCount: row.messages.length,\n updatedAt: row.updatedAt,\n }));\n }\n\n /** Governance read-model feed: recorded run outcomes (the reliability surfaces). */\n governanceRuns(): GovernanceRunRow[] {\n return [...this.runs.values()].map((row) => ({\n runId: row.runId,\n threadId: row.threadId,\n actorRef: row.actorRef,\n status: row.status,\n retries: row.retries,\n startedAt: row.startedAt,\n ...(row.agentName !== undefined ? { agentName: row.agentName } : {}),\n ...(row.parentRunId !== undefined ? { parentRunId: row.parentRunId } : {}),\n ...(row.durationMs !== undefined ? { durationMs: row.durationMs } : {}),\n ...(row.errorCode !== undefined ? { errorCode: row.errorCode } : {}),\n ...(row.errorMessage !== undefined ? { errorMessage: row.errorMessage } : {}),\n ...(row.settledAt !== undefined ? { settledAt: row.settledAt } : {}),\n ...(row.promptHash !== undefined ? { promptHash: row.promptHash } : {}),\n }));\n }\n\n private threadIdForMessage(messageId: string): string | undefined {\n for (const [threadId, row] of this.threads) {\n if (row.messages.some((message) => message.id === messageId)) {\n return threadId;\n }\n }\n return undefined;\n }\n\n /** Test helper: read the recorded tool-call rows. */\n toolCallRows(): {\n toolCallId: string;\n toolName: string;\n toolType: 'read' | 'action';\n status: ToolCallStatus;\n input?: unknown;\n output?: unknown;\n error?: string;\n runId?: string;\n executedByRef?: string;\n approver?: string;\n expiresAt?: string;\n remember?: boolean;\n decidedVia?: string;\n }[] {\n return [...this.toolCalls.values()].map((row) => ({\n toolCallId: row.toolCallId,\n toolName: row.toolName,\n toolType: row.toolType,\n status: row.status,\n input: row.input,\n ...(row.output !== undefined ? { output: row.output } : {}),\n ...(row.error !== undefined ? { error: row.error } : {}),\n ...(row.runId !== undefined ? { runId: row.runId } : {}),\n ...(row.executedByRef !== undefined ? { executedByRef: row.executedByRef } : {}),\n ...(row.approver !== undefined ? { approver: row.approver } : {}),\n ...(row.expiresAt !== undefined ? { expiresAt: row.expiresAt } : {}),\n ...(row.remember !== undefined ? { remember: row.remember } : {}),\n ...(row.decidedVia !== undefined ? { decidedVia: row.decidedVia } : {}),\n }));\n }\n\n private toSummary(row: ThreadRow): ThreadSummary {\n const last = row.messages[row.messages.length - 1];\n return {\n id: row.id,\n title: row.title,\n transient: row.transient,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n ...(last !== undefined ? { lastMessagePreview: last.content.slice(0, 120) } : {}),\n defaultAgent: row.defaultAgent ?? null,\n ...(row.model != null ? { model: row.model } : {}),\n persona: row.persona ?? null,\n };\n }\n}\n","import { createHash, createHmac, timingSafeEqual } from 'node:crypto';\nimport type { ConfirmTokenClaim, ConfirmTokenStore } from './spi/confirm-token-store.js';\n\n/** How long a preview stays confirmable unless the tool says otherwise. */\nexport const DEFAULT_CONFIRM_TTL_MS = 15 * 60 * 1000;\n\n/** What a confirm token is bound to. Change any of it and the token stops matching. */\nexport interface ConfirmTokenSubject {\n /** The tool's name. */\n tool: string;\n /** `ctx.actor.id`. */\n actorId: string;\n /** `ctx.actor.tenantRef`; absent and `''` sign the same. */\n tenantRef?: string;\n /** The call's arguments, WITHOUT `confirm` / `confirmToken`. */\n args: unknown;\n}\n\n/**\n * JSON with object keys sorted at every depth, so two argument objects that differ only in key\n * order produce the same text. `undefined` properties are dropped (as `JSON.stringify` does); a\n * bare `undefined` and an `undefined` array element are `null`.\n */\nexport function canonicalJson(value: unknown): string {\n if (value === undefined) return 'null';\n if (value === null || typeof value !== 'object') return JSON.stringify(value) ?? 'null';\n if (Array.isArray(value)) return `[${value.map(canonicalJson).join(',')}]`;\n if (typeof (value as { toJSON?: unknown }).toJSON === 'function') {\n return canonicalJson((value as { toJSON(): unknown }).toJSON());\n }\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([, entry]) => entry !== undefined)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n return `{${entries.map(([key, entry]) => `${JSON.stringify(key)}:${canonicalJson(entry)}`).join(',')}}`;\n}\n\n/** The signed text is itself canonical JSON, so no field can bleed into its neighbour. */\nfunction signature(subject: ConfirmTokenSubject, expiresAt: number, secret: string): string {\n if (secret === '') {\n throw new Error('confirm token: the secret is empty');\n }\n return createHmac('sha256', secret)\n .update(\n canonicalJson([\n 'agent-confirm',\n subject.tool,\n subject.actorId,\n subject.tenantRef ?? '',\n expiresAt,\n subject.args,\n ]),\n )\n .digest('base64url');\n}\n\n/**\n * Issue a confirm token: `<expiresAt>.<signature>`, an HMAC-SHA256 (keyed by `secret`) over the tool,\n * the actor, the tenant, the expiry and the canonical arguments. Stateless — nothing is stored — and\n * useless for another actor, tenant, tool or argument, or after `expiresAt` (epoch-ms).\n */\nexport function signConfirmToken(\n subject: ConfirmTokenSubject,\n options: { secret: string; expiresAt: number },\n): string {\n return `${options.expiresAt}.${signature(subject, options.expiresAt, options.secret)}`;\n}\n\n/** The expiry (epoch-ms) a token carries, or `undefined` for a malformed one. Not a verification. */\nexport function confirmTokenExpiry(token: string): number | undefined {\n const separator = token.indexOf('.');\n if (separator <= 0) return undefined;\n const expiresAt = Number(token.slice(0, separator));\n return Number.isSafeInteger(expiresAt) && expiresAt > 0 ? expiresAt : undefined;\n}\n\n/** Was this token issued for exactly this subject, with this secret, and is it still valid at `now`? */\nexport function verifyConfirmToken(\n token: string | null | undefined,\n subject: ConfirmTokenSubject,\n options: { secret: string; now?: number },\n): boolean {\n if (typeof token !== 'string') return false;\n const expiresAt = confirmTokenExpiry(token);\n if (expiresAt === undefined || expiresAt < (options.now ?? Date.now())) return false;\n const expected = Buffer.from(signature(subject, expiresAt, options.secret));\n const given = Buffer.from(token.slice(token.indexOf('.') + 1));\n return expected.length === given.length && timingSafeEqual(expected, given);\n}\n\n/** SHA-256 (hex) of a token — what a {@link ConfirmTokenStore} keys on, so the token is never stored. */\nexport function hashConfirmToken(token: string): string {\n return createHash('sha256').update(token).digest('hex');\n}\n\n/**\n * A single-process {@link ConfirmTokenStore}: tests, scripts, and a deployment that runs ONE replica.\n * With more than one, a token spent on replica A is still fresh on replica B — use the Drizzle or\n * MikroORM store (`AGENT_CONFIRM_TOKEN_STORE`, bound by their modules).\n * Expired marks are dropped lazily, on the next claim.\n */\nexport class InMemoryConfirmTokenStore implements ConfirmTokenStore {\n private readonly claims = new Map<string, ConfirmTokenClaim>();\n\n async claim(input: ConfirmTokenClaim): Promise<boolean> {\n await this.purgeExpired();\n if (this.claims.has(input.hash)) return false;\n this.claims.set(input.hash, { ...input });\n return true;\n }\n\n async release(hash: string): Promise<void> {\n this.claims.delete(hash);\n }\n\n async purgeExpired(now: number = Date.now()): Promise<number> {\n let purged = 0;\n for (const [hash, claim] of this.claims) {\n if (claim.expiresAt < now) {\n this.claims.delete(hash);\n purged += 1;\n }\n }\n return purged;\n }\n\n /** How many tokens are currently marked as spent. */\n get size(): number {\n return this.claims.size;\n }\n}\n","import type { ChannelStore } from './spi/channel-store.js';\n\n/**\n * Process-local {@link ChannelStore}: a single replica, tests, development. Keeps at most\n * `maxEntries` live keys; past that the oldest writes are forgotten first.\n */\nexport class InMemoryChannelStore implements ChannelStore {\n readonly #entries = new Map<string, { value: string | null; expiresAt: number }>();\n\n constructor(private readonly maxEntries = 50_000) {}\n\n #live(key: string) {\n const entry = this.#entries.get(key);\n if (entry === undefined) return undefined;\n if (entry.expiresAt > Date.now()) return entry;\n this.#entries.delete(key);\n return undefined;\n }\n\n #put(key: string, value: string | null, ttlMs: number) {\n const now = Date.now();\n this.#entries.delete(key);\n this.#entries.set(key, { value, expiresAt: now + ttlMs });\n if (this.#entries.size <= this.maxEntries) return;\n // Insertion order is write order: the first keys are the oldest.\n for (const [stored, entry] of this.#entries) {\n if (this.#entries.size <= this.maxEntries && entry.expiresAt > now) break;\n this.#entries.delete(stored);\n }\n }\n\n async claim(key: string, ttlMs: number): Promise<boolean> {\n if (this.#live(key) !== undefined) return false;\n this.#put(key, null, ttlMs);\n return true;\n }\n\n async get(key: string): Promise<string | null> {\n return this.#live(key)?.value ?? null;\n }\n\n async set(key: string, value: string, ttlMs: number): Promise<void> {\n this.#put(key, value, ttlMs);\n }\n\n async delete(key: string): Promise<void> {\n this.#entries.delete(key);\n }\n\n async purgeExpired(now: number = Date.now()): Promise<number> {\n let purged = 0;\n for (const [key, entry] of this.#entries) {\n if (entry.expiresAt <= now) {\n this.#entries.delete(key);\n purged += 1;\n }\n }\n return purged;\n }\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport {\n DEFAULT_CONFIRM_TTL_MS,\n confirmTokenExpiry,\n hashConfirmToken,\n signConfirmToken,\n verifyConfirmToken,\n} from './confirm-token.js';\nimport type { ConfirmTokenStore } from './spi/confirm-token-store.js';\nimport type { AiToolCtx, ToolHandler } from './spi/tool.js';\nimport type { ToolSpec } from './types.js';\n\n/** The two fields {@link defineConfirmedTool} adds to a tool's input. */\nexport interface ConfirmFields {\n /** `true` to commit; absent (or `false`) to preview. */\n confirm?: boolean;\n /** The `confirmToken` the preview returned. */\n confirmToken?: string;\n}\n\n/** The words a confirmed tool says to the model. Each has an English default. */\nexport interface ConfirmedToolMessages {\n /** Sent with every preview: how to confirm. `{minutes}` is replaced with the token's lifetime. */\n confirm?: string;\n /** Thrown for a missing, tampered, mismatched or expired token. */\n invalid?: string;\n /** Thrown for a token that already committed. */\n used?: string;\n}\n\nconst DEFAULT_MESSAGES: Required<ConfirmedToolMessages> = {\n confirm:\n 'Nothing was written. Show this preview to the user and ask them to confirm. To commit, call this tool again with the SAME arguments plus \"confirm\": true and this \"confirmToken\" (valid for {minutes} minutes).',\n invalid:\n 'Invalid or expired confirmation: nothing was written. Call the tool without \"confirm\" to get a fresh preview, then confirm with the \"confirmToken\" it returns, without changing the arguments.',\n used: 'This preview was already confirmed: nothing was written again. To repeat the operation, ask for a new preview.',\n};\n\n/** Thrown by a confirmed tool that refused a confirmation. Nothing was written. */\nexport class ConfirmTokenError extends Error {\n constructor(\n /** `invalid`: missing, tampered, mismatched or expired. `used`: it already committed once. */\n readonly reason: 'invalid' | 'used',\n message: string,\n ) {\n super(message);\n this.name = 'ConfirmTokenError';\n }\n}\n\n/** What {@link defineConfirmedTool} takes: the usual spec fields (no `kind`), plus the gate's own. */\nexport interface ConfirmedToolOptions\n extends Omit<ToolSpec, 'kind' | 'inputSchema' | 'targetAgent' | 'detached' | 'terminal'> {\n /** The app's own input schema. `confirm` / `confirmToken` are added by {@link withConfirmFields}. */\n input: StandardSchemaV1;\n /**\n * The HMAC key the tokens are signed with — the app's secret (`ConfigService.getOrThrow(...)`), or\n * one of its own. A function is read on every call. Required: there is no default, and an empty\n * one throws.\n */\n secret: string | (() => string);\n /** How long a preview stays confirmable. Default 15 minutes. */\n ttlMs?: number;\n /**\n * Makes a token single use. WITHOUT a store a token commits as many times as it is sent until it\n * expires — a retry or a repeated call writes twice. The store modules bind one to\n * `AGENT_CONFIRM_TOKEN_STORE`; `InMemoryConfirmTokenStore` is for one replica.\n */\n store?: ConfirmTokenStore;\n messages?: ConfirmedToolMessages;\n}\n\n/** What a step reports: a sentence for the model to relay, and the structured detail behind it. */\nexport interface ConfirmedToolOutcome {\n summary: string;\n data?: unknown;\n}\n\n/** The three steps of a confirmed write. */\nexport interface ConfirmedToolSteps<Args, Prepared> {\n /**\n * Resolve and validate everything the write needs, applying the SAME rules the commit relies on.\n * Throw to refuse. Writes nothing. Runs for the preview AND again for the confirmation — state may\n * have changed in between — and a refusal here does not spend the token.\n */\n prepare(args: Args, ctx: AiToolCtx): Promise<Prepared> | Prepared;\n /** What is about to happen. Writes nothing. */\n preview(prepared: Prepared, ctx: AiToolCtx): Promise<ConfirmedToolOutcome> | ConfirmedToolOutcome;\n /** Write, and say what was written. A throw gives the token back. */\n commit(prepared: Prepared, ctx: AiToolCtx): Promise<ConfirmedToolOutcome> | ConfirmedToolOutcome;\n}\n\n/** A confirmed tool's answer to a call without `confirm`. */\nexport interface ConfirmedToolPreview {\n status: 'preview';\n summary: string;\n data?: unknown;\n confirmToken: string;\n /** ISO-8601 instant the token stops working. */\n expiresAt: string;\n /** Instructions for the model: show the preview, then call again with the token. */\n confirm: string;\n}\n\n/** A confirmed tool's answer to a confirmation that committed. */\nexport interface ConfirmedToolDone {\n status: 'done';\n summary: string;\n data?: unknown;\n}\n\nexport type ConfirmedToolResult = ConfirmedToolPreview | ConfirmedToolDone;\n\n/** The JSON Schema of {@link ConfirmFields}, merged into the schema the model is shown. */\nexport const CONFIRM_JSON_SCHEMA_PROPERTIES = {\n confirm: {\n type: 'boolean',\n description:\n 'Omit to get a preview (nothing is written). Send true, with confirmToken, to commit.',\n },\n confirmToken: {\n type: 'string',\n description: 'The confirmToken the preview returned. Required when confirm is true.',\n },\n} as const;\n\n/**\n * Marks a schema that is ANOTHER schema plus a few JSON Schema properties. A converter that knows the\n * inner schema better than the wrapper can (a Zod 3 schema has no Standard JSON Schema extension, so\n * only the AI SDK's or the MCP SDK's own converter can describe it) converts `base` and adds\n * `properties`. `@dudousxd/nestjs-agent-ai-sdk` and `-mcp-server` both read it.\n */\nexport const SCHEMA_EXTENSION = Symbol.for('@dudousxd/nestjs-agent:schema-extension');\n\nexport interface SchemaExtension {\n base: StandardSchemaV1;\n properties: Record<string, unknown>;\n}\n\n/** The {@link SchemaExtension} a schema carries, if any. */\nexport function schemaExtensionOf(schema: StandardSchemaV1): SchemaExtension | undefined {\n const extension = (schema as { [SCHEMA_EXTENSION]?: unknown })[SCHEMA_EXTENSION];\n return typeof extension === 'object' && extension !== null\n ? (extension as SchemaExtension)\n : undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Split a call's input into the app's arguments and the two confirmation fields. */\nfunction splitConfirm(input: unknown): { args: unknown; fields: ConfirmFields } {\n if (!isRecord(input)) return { args: input, fields: {} };\n const { confirm, confirmToken, ...args } = input;\n return {\n args,\n fields: {\n ...(typeof confirm === 'boolean' ? { confirm } : {}),\n ...(typeof confirmToken === 'string' ? { confirmToken } : {}),\n },\n };\n}\n\ntype JsonSchemaConverter = (options?: unknown) => Record<string, unknown>;\n\n/** The schema's Standard JSON Schema `input` converter, when it has one. */\nfunction jsonSchemaInputOf(schema: StandardSchemaV1): JsonSchemaConverter | undefined {\n const standard = schema['~standard'] as { jsonSchema?: { input?: unknown } };\n const input = standard.jsonSchema?.input;\n return typeof input === 'function'\n ? (options) => (input as JsonSchemaConverter).call(standard.jsonSchema, options)\n : undefined;\n}\n\n/**\n * Wrap a tool's input schema so it also accepts {@link ConfirmFields}, without the app declaring\n * them. `validate` takes the two fields off, checks them itself, hands the REST to the app's schema\n * (so a strict schema never sees a key it did not declare) and puts them back on the validated value.\n *\n * The wrapper always carries the Standard JSON Schema extension: the app schema's own JSON Schema\n * plus the two properties. A schema without the extension (Zod 3, a bare Standard Schema) degrades\n * there to a permissive object that still declares the two fields — but the wrapper also carries a\n * {@link SchemaExtension}, so the AI SDK adapter and the MCP server convert a Zod 3 schema with their\n * own converters and show the model its real shape. `validate` stays the authority either way.\n */\nexport function withConfirmFields<Schema extends StandardSchemaV1>(\n schema: Schema,\n): StandardSchemaV1<\n StandardSchemaV1.InferInput<Schema> & ConfirmFields,\n StandardSchemaV1.InferOutput<Schema> & ConfirmFields\n> {\n const inner = schema['~standard'];\n const innerJsonSchema = jsonSchemaInputOf(schema);\n const describe = (options?: unknown): Record<string, unknown> => {\n const base = innerJsonSchema?.(options) ?? { additionalProperties: true };\n return {\n ...base,\n type: 'object',\n properties: {\n ...(isRecord(base.properties) ? base.properties : {}),\n ...CONFIRM_JSON_SCHEMA_PROPERTIES,\n },\n };\n };\n const wrapped = {\n [SCHEMA_EXTENSION]: { base: schema, properties: CONFIRM_JSON_SCHEMA_PROPERTIES },\n '~standard': {\n version: 1,\n vendor: '@dudousxd/nestjs-agent',\n validate: async (value: unknown) => {\n if (!isRecord(value)) {\n return { issues: [{ message: 'expected an object' }] };\n }\n const issues: StandardSchemaV1.Issue[] = [];\n // `null` is how some models say \"absent\"; it is read as absent rather than refused.\n if (value.confirm != null && typeof value.confirm !== 'boolean') {\n issues.push({ message: 'expected a boolean', path: ['confirm'] });\n }\n if (value.confirmToken != null && typeof value.confirmToken !== 'string') {\n issues.push({ message: 'expected a string', path: ['confirmToken'] });\n }\n const { args, fields } = splitConfirm(value);\n const result = await inner.validate(args);\n if (result.issues !== undefined) {\n return { issues: [...issues, ...result.issues] };\n }\n if (issues.length > 0) {\n return { issues };\n }\n return { value: isRecord(result.value) ? { ...result.value, ...fields } : result.value };\n },\n jsonSchema: { input: describe, output: describe },\n },\n };\n return wrapped as unknown as StandardSchemaV1<\n StandardSchemaV1.InferInput<Schema> & ConfirmFields,\n StandardSchemaV1.InferOutput<Schema> & ConfirmFields\n >;\n}\n\n/**\n * A write with a human gate that lives INSIDE the tool: preview first, commit on confirmation.\n *\n * - Called without `confirm`: runs `prepare`, writes nothing, and returns the `preview` with a signed\n * `confirmToken`.\n * - Called again with the SAME arguments, `confirm: true` and that token: runs `prepare` again, then\n * `commit`.\n *\n * The token is an HMAC over the tool, `ctx.actor.id`, `ctx.actor.tenantRef`, the expiry and the\n * canonical arguments, so it cannot be replayed by another actor, in another tenant, on another\n * tool or with a changed argument. With a `store` it is also single use: it is claimed right before\n * `commit` (a refusal in `prepare` does not spend it) and released if `commit` throws.\n *\n * Registered as `kind: 'read'` on purpose. An `action` parks on the loop's HITL approval, which an\n * MCP caller cannot answer — `AgentMcpServerModule` keeps `action` tools off the surface, and MCP clients\n * without elicitation have no other channel. The gate being in the handler is what lets the same\n * tool serve the chat loop and MCP; the user sees the preview because the model has to relay it to\n * get a token it can confirm with.\n *\n * ```ts\n * provideAgentTool(\n * (store: ConfirmTokenStore, config: ConfigService, orders: OrdersService) =>\n * defineConfirmedTool(\n * { name: 'refund_order', description: '...', input: z.object({ orderId: z.string() }),\n * secret: () => config.getOrThrow('CONFIRM_SECRET'), store },\n * {\n * prepare: ({ orderId }, ctx) => orders.loadRefundable(orderId, ctx.actor),\n * preview: (order) => ({ summary: `Refund ${order.total} to ${order.customer}?`, data: order }),\n * commit: async (order) => ({ summary: 'Refunded.', data: await orders.refund(order) }),\n * },\n * ),\n * [AGENT_CONFIRM_TOKEN_STORE, ConfigService, OrdersService],\n * );\n * ```\n *\n * `input` is the app's own schema: `confirm` and `confirmToken` are added by\n * {@link withConfirmFields}, and `prepare` receives the arguments without them.\n */\nexport function defineConfirmedTool<Args = unknown, Prepared = unknown>(\n options: ConfirmedToolOptions,\n steps: ConfirmedToolSteps<Args, Prepared>,\n): ConfirmedTool {\n const { secret, ttlMs = DEFAULT_CONFIRM_TTL_MS, store, messages, input, ...specFields } = options;\n const text = { ...DEFAULT_MESSAGES, ...messages };\n const howToConfirm = text.confirm.replaceAll('{minutes}', String(Math.round(ttlMs / 60_000)));\n const secretNow = () => (typeof secret === 'function' ? secret() : secret);\n\n const handler: ToolHandler = {\n async execute(value: unknown, ctx: AiToolCtx): Promise<ConfirmedToolResult> {\n const { args, fields } = splitConfirm(value);\n const subject = {\n tool: options.name,\n actorId: ctx.actor.id,\n ...(ctx.actor.tenantRef !== undefined ? { tenantRef: ctx.actor.tenantRef } : {}),\n args,\n };\n const confirming = fields.confirm === true;\n const token = fields.confirmToken;\n if (confirming && !verifyConfirmToken(token, subject, { secret: secretNow() })) {\n throw new ConfirmTokenError('invalid', text.invalid);\n }\n\n const prepared = await steps.prepare(args as Args, ctx);\n\n if (!confirming || token === undefined) {\n const preview = await steps.preview(prepared, ctx);\n const expiresAt = Date.now() + ttlMs;\n return {\n status: 'preview',\n summary: preview.summary,\n ...(preview.data !== undefined ? { data: preview.data } : {}),\n confirmToken: signConfirmToken(subject, { secret: secretNow(), expiresAt }),\n expiresAt: new Date(expiresAt).toISOString(),\n confirm: howToConfirm,\n };\n }\n\n // Claimed only now: everything `prepare` refuses leaves the token usable, and a commit that\n // throws gives it back so the same preview can be confirmed again.\n const hash = hashConfirmToken(token);\n if (store !== undefined) {\n const claimed = await store.claim({\n hash,\n actorRef: ctx.actor.id,\n tool: options.name,\n expiresAt: confirmTokenExpiry(token) ?? Date.now() + ttlMs,\n });\n if (!claimed) {\n throw new ConfirmTokenError('used', text.used);\n }\n }\n try {\n const done = await steps.commit(prepared, ctx);\n return {\n status: 'done',\n summary: done.summary,\n ...(done.data !== undefined ? { data: done.data } : {}),\n };\n } catch (error) {\n // The commit's own error is the one worth reporting, whatever the release does.\n await store?.release(hash).catch(() => undefined);\n throw error;\n }\n },\n };\n return {\n spec: { ...specFields, kind: 'read', inputSchema: withConfirmFields(input) },\n handler,\n };\n}\n\n/**\n * What {@link defineConfirmedTool} returns: a functional tool (`{ spec, handler }`) — pass it to\n * `AgentModule.forRoot({ tools })`, or build it in `provideAgentTool(factory, inject)` when it\n * needs injected services (the confirm-token store, the secret from `ConfigService`).\n */\nexport interface ConfirmedTool {\n spec: ToolSpec;\n handler: ToolHandler;\n}\n","import {\n AgentStreamError,\n type SinkWriter,\n type StreamError,\n type TokenStreamSink,\n} from './spi/token-stream-sink.js';\nimport { encodeStreamEvent } from './stream-events.js';\n\n/** One stored row of a run's stream. `frame` is `null` on the terminal row. */\nexport interface StreamFrameRow {\n seq: number;\n /** One NDJSON line (`{...}\\n`) as the writer wrote it; `null` marks the end of the run. */\n frame: string | null;\n /** On the terminal row of a FAILED run: the `StreamError` as JSON. `null` otherwise. */\n error: string | null;\n}\n\n/**\n * The table a {@link SqlTokenStreamSink} keeps its rows in — the only part of it that speaks SQL, so\n * a store package implements this and inherits the rest (coalescing, ordering, polling, TTL).\n * `@dudousxd/nestjs-agent-store-drizzle` and `-store-mikro-orm` ship one each, over\n * `agent_stream_frame` (`run_id`, `seq`, `frame`, `error`, `created_at`; primary key\n * `(run_id, seq)`).\n */\nexport interface StreamFrameTable {\n /**\n * Insert the run's NEXT row: `seq = MAX(seq) + 1` for the run, taken in the SAME statement as the\n * insert, so the `(run_id, seq)` primary key settles two writers that ask at once. Throws on that\n * collision ({@link isUniqueViolation} says which errors are one) — the sink retries.\n */\n append(\n runId: string,\n row: { frame: string | null; error: string | null; createdAt: number },\n ): Promise<void>;\n /** The run's rows with `seq > after`, ascending, at most `limit`. */\n read(runId: string, after: number, limit: number): Promise<StreamFrameRow[]>;\n /** Does the table hold any row for the run? */\n has(runId: string): Promise<boolean>;\n /** Delete every row of these runs. */\n remove(runIds: readonly string[]): Promise<void>;\n /** Runs whose LAST row was written before `cutoff` (epoch-ms). */\n lapsedRuns(cutoff: number): Promise<string[]>;\n /**\n * Is this error a lost race for a `(run_id, seq)` — a duplicate key, or the database rolling this\n * writer back as a deadlock victim (InnoDB's way of settling two concurrent `INSERT … SELECT`) —\n * and nothing else (a missing table, a dead connection)?\n */\n isUniqueViolation(error: unknown): boolean;\n}\n\nexport interface SqlTokenStreamSinkOptions {\n /**\n * Gap (ms) between two reads of a run a subscriber is following — the most a frame waits in the\n * table before a browser sees it. Default 250.\n */\n pollIntervalMs?: number;\n /**\n * Gap (ms) between two reads once the run has written nothing for five seconds (parked on a\n * person, a slow tool), so an open SSE connection on a quiet run costs one query a second. The\n * first frame to arrive puts the subscriber back on `pollIntervalMs`. Default 1000; never below\n * `pollIntervalMs`.\n */\n idlePollIntervalMs?: number;\n /**\n * Window (ms) consecutive `text` frames are gathered over and written as ONE row — a model\n * streams token by token, and a row per token is more writes than a database should take for a\n * chat answer. Any other frame, `end()`, `fail()` and `flush()` write what is gathered first, so\n * order is kept. Default 50. `0` writes every frame as its own row.\n */\n flushMs?: number;\n /**\n * TTL (seconds) of a run's rows, counted from its LAST write — a long run stays, a run that\n * crashed without ending still lapses. {@link SqlTokenStreamSink.purgeExpired} deletes them.\n * Default 3600 (1h). `0` keeps rows until `close()`.\n */\n ttlSeconds?: number;\n /**\n * Purge lapsed runs as a side effect of ending a run, at most once a minute, so the table stays\n * bounded in an app that never schedules {@link SqlTokenStreamSink.purgeExpired}. Default `true`.\n */\n autoPurge?: boolean;\n}\n\nconst DEFAULT_TTL_SECONDS = 3600;\nconst DEFAULT_POLL_INTERVAL_MS = 250;\nconst DEFAULT_IDLE_POLL_INTERVAL_MS = 1000;\nconst IDLE_AFTER_MS = 5000;\nconst DEFAULT_FLUSH_MS = 50;\nconst READ_PAGE = 500;\nconst PURGE_CHUNK = 200;\nconst AUTO_PURGE_EVERY_MS = 60_000;\nconst APPEND_ATTEMPTS = 8;\n\n/** One run's write side in this process: the text being gathered, and the writes already queued. */\ninterface RunWrites {\n text: string | null;\n timer: ReturnType<typeof setTimeout> | undefined;\n /** Settles when every write queued so far has been attempted. Never rejects. */\n tail: Promise<void>;\n pending: number;\n /** A gathered write that failed on its timer, with nobody awaiting it — raised by the next call. */\n failure: { error: unknown } | undefined;\n}\n\nconst decoder = new TextDecoder();\nconst encoder = new TextEncoder();\nconst sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\n\n/** The text of a chunk that is exactly one `{\"kind\":\"text\",\"text\":…}` line, else `null`. */\nfunction textOf(line: string): string | null {\n if (!line.startsWith('{\"kind\":\"text\"')) return null;\n try {\n const parsed: unknown = JSON.parse(line);\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n Object.keys(parsed).length === 2 &&\n (parsed as { kind?: unknown }).kind === 'text' &&\n typeof (parsed as { text?: unknown }).text === 'string'\n ) {\n return (parsed as { text: string }).text;\n }\n } catch {\n /* not one event: stored as written */\n }\n return null;\n}\n\n/**\n * A multi-replica {@link TokenStreamSink} over the app's SQL database — for a deployment with\n * several replicas and NO Redis. The replica running the turn appends each frame as a row; any\n * replica serves the run's SSE by reading the rows past its cursor, in order, until the terminal\n * row. A late subscriber replays from the first row, as with the in-process and Redis sinks, and a\n * run that `fail()`ed throws its {@link AgentStreamError} after the replay.\n *\n * Two things differ from the Redis sink, both the price of having no broker:\n *\n * - **Delivery is polled** — a frame waits up to `pollIntervalMs` before a browser sees it.\n * - **Text is coalesced on the way in.** Consecutive `text` frames written within `flushMs` are\n * stored as ONE `text` frame. The stored rows ARE the run's stream: every subscriber, on every\n * replica, reads the same rows in the same order, so the SSE ids `chat/:runId/stream` numbers\n * them with — and an `?after=` cursor — stay exact across replicas.\n *\n * Sequence numbers are per run, start at 1 and have no gaps (see {@link StreamFrameTable.append}).\n * Text a writer is still gathering lives in the process for at most `flushMs`; a process that dies\n * in that window loses it from the LIVE stream (the persisted message is unaffected).\n *\n * Framework- and dialect-free: the SQL is the {@link StreamFrameTable}'s. Use\n * `DrizzleTokenStreamSink` / `MikroOrmTokenStreamSink` from the store packages.\n */\nexport class SqlTokenStreamSink implements TokenStreamSink {\n private readonly pollIntervalMs: number;\n private readonly idlePollIntervalMs: number;\n private readonly flushMs: number;\n private readonly ttlSeconds: number;\n private readonly autoPurge: boolean;\n private readonly writes = new Map<string, RunWrites>();\n private lastAutoPurge = 0;\n\n constructor(\n private readonly table: StreamFrameTable,\n options: SqlTokenStreamSinkOptions = {},\n ) {\n this.pollIntervalMs = Math.max(1, options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);\n this.idlePollIntervalMs = Math.max(\n this.pollIntervalMs,\n options.idlePollIntervalMs ?? DEFAULT_IDLE_POLL_INTERVAL_MS,\n );\n this.flushMs = Math.max(0, options.flushMs ?? DEFAULT_FLUSH_MS);\n this.ttlSeconds = options.ttlSeconds ?? DEFAULT_TTL_SECONDS;\n this.autoPurge = options.autoPurge ?? true;\n }\n\n private runWrites(runId: string): RunWrites {\n let state = this.writes.get(runId);\n if (state === undefined) {\n state = {\n text: null,\n timer: undefined,\n tail: Promise.resolve(),\n pending: 0,\n failure: undefined,\n };\n this.writes.set(runId, state);\n }\n return state;\n }\n\n /** Forget a run's write state once nothing is gathered, queued or left to report. */\n private release(runId: string, state: RunWrites): void {\n if (\n state.pending === 0 &&\n state.text === null &&\n state.failure === undefined &&\n this.writes.get(runId) === state\n ) {\n this.writes.delete(runId);\n }\n }\n\n /** Queue `work` behind every write already queued for the run, so rows land in call order. */\n private enqueue(runId: string, state: RunWrites, work: () => Promise<void>): Promise<void> {\n state.pending += 1;\n const next = state.tail.then(work);\n state.tail = next\n .then(\n () => undefined,\n () => undefined,\n )\n .then(() => {\n state.pending -= 1;\n this.release(runId, state);\n });\n return next;\n }\n\n /** Queue the gathered text (if any) as one `text` row. */\n private flushText(runId: string, state: RunWrites): Promise<void> {\n if (state.timer !== undefined) {\n clearTimeout(state.timer);\n state.timer = undefined;\n }\n if (state.text === null) return Promise.resolve();\n const line = decoder.decode(encodeStreamEvent({ kind: 'text', text: state.text }));\n state.text = null;\n return this.enqueue(runId, state, () => this.append(runId, line, null));\n }\n\n /** Raise, once, a gathered write that failed with nobody awaiting it. */\n private raiseFailure(state: RunWrites): void {\n const failure = state.failure;\n if (failure !== undefined) {\n state.failure = undefined;\n throw failure.error;\n }\n }\n\n /** Append one row — a frame, or the terminal row (`frame: null`, with `error` on a failure). */\n private async append(runId: string, frame: string | null, error: string | null): Promise<void> {\n for (let attempt = 1; ; attempt += 1) {\n try {\n await this.table.append(runId, { frame, error, createdAt: Date.now() });\n return;\n } catch (caught) {\n if (attempt >= APPEND_ATTEMPTS || !this.table.isUniqueViolation(caught)) throw caught;\n }\n }\n }\n\n /** Write out what is gathered, then a terminal row; raise a failure nobody saw. */\n private async terminate(runId: string, error: string | null): Promise<void> {\n const state = this.runWrites(runId);\n const flushed = this.flushText(runId, state);\n const ended = this.enqueue(runId, state, () => this.append(runId, null, error));\n await Promise.all([flushed, ended]);\n this.raiseFailure(state);\n this.release(runId, state);\n this.purgeInBackground();\n }\n\n /**\n * The run's writer. Writers opened for the same run in one process share what they are gathering,\n * so a delegated run's text (forwarded through a child writer) and its parent's next frame keep\n * the order they were written in.\n */\n open(runId: string): SinkWriter {\n return {\n write: async (chunk: Uint8Array) => {\n const state = this.runWrites(runId);\n this.raiseFailure(state);\n const line = decoder.decode(chunk);\n const text = this.flushMs > 0 ? textOf(line.trimEnd()) : null;\n if (text !== null) {\n state.text = (state.text ?? '') + text;\n // Counted from the FIRST gathered token, not the last: a steady stream still reaches the\n // table every `flushMs`, instead of being held for as long as the model keeps talking.\n if (state.timer === undefined) {\n state.timer = setTimeout(() => {\n state.timer = undefined;\n this.flushText(runId, state).catch((error: unknown) => {\n state.failure = { error };\n });\n }, this.flushMs);\n }\n return;\n }\n const flushed = this.flushText(runId, state);\n const appended = this.enqueue(runId, state, () => this.append(runId, line, null));\n await Promise.all([flushed, appended]);\n },\n flush: async () => {\n const state = this.runWrites(runId);\n const flushed = this.flushText(runId, state);\n await Promise.all([flushed, state.tail]);\n this.raiseFailure(state);\n this.release(runId, state);\n },\n end: () => this.terminate(runId, null),\n fail: (error: StreamError) =>\n this.terminate(runId, JSON.stringify({ code: error.code, message: error.message })),\n };\n }\n\n async *subscribe(runId: string): AsyncIterable<Uint8Array> {\n let cursor = 0;\n let quietSince = Date.now();\n while (true) {\n const rows = await this.table.read(runId, cursor, READ_PAGE);\n for (const row of rows) {\n cursor = row.seq;\n if (row.frame === null) {\n if (row.error !== null) {\n throw new AgentStreamError(JSON.parse(row.error) as StreamError);\n }\n return;\n }\n yield encoder.encode(row.frame);\n }\n if (rows.length > 0) {\n quietSince = Date.now();\n // A full page means there may be more already written: read on without waiting.\n if (rows.length >= READ_PAGE) continue;\n }\n await sleep(\n Date.now() - quietSince >= IDLE_AFTER_MS ? this.idlePollIntervalMs : this.pollIntervalMs,\n );\n }\n }\n\n /** Does the table hold anything for the run — a frame, or its end? */\n has(runId: string): Promise<boolean> {\n return this.table.has(runId);\n }\n\n async close(runId: string): Promise<void> {\n const state = this.writes.get(runId);\n if (state !== undefined) {\n if (state.timer !== undefined) clearTimeout(state.timer);\n state.timer = undefined;\n state.text = null;\n state.failure = undefined;\n await state.tail;\n this.writes.delete(runId);\n }\n await this.table.remove([runId]);\n }\n\n /**\n * Delete every run whose last write is older than `ttlSeconds` at `now` (epoch-ms) — ended runs\n * past their replay window and runs that crashed without ending alike. Returns how many runs went.\n * Safe from any replica, and from several at once. A no-op under `ttlSeconds: 0`.\n */\n async purgeExpired(now: number = Date.now()): Promise<number> {\n if (this.ttlSeconds <= 0) return 0;\n const lapsed = await this.table.lapsedRuns(now - this.ttlSeconds * 1000);\n for (let index = 0; index < lapsed.length; index += PURGE_CHUNK) {\n await this.table.remove(lapsed.slice(index, index + PURGE_CHUNK));\n }\n return lapsed.length;\n }\n\n /** {@link purgeExpired}, unawaited and at most once a minute. Its failure is not the run's. */\n private purgeInBackground(): void {\n if (!this.autoPurge || this.ttlSeconds <= 0) return;\n const now = Date.now();\n if (now - this.lastAutoPurge < AUTO_PURGE_EVERY_MS) return;\n this.lastAutoPurge = now;\n this.purgeExpired(now).catch(() => {\n // Retried after the next run ends; a purge that cannot run must not fail a finished turn.\n });\n }\n}\n","import type {\n ActionProposalDecision,\n ActionProposalMutationResult,\n} from './spi/action-proposal-store.js';\n\nexport interface TextActionProposalCandidate {\n id: string;\n decision: ActionProposalDecision;\n}\nexport type TextActionProposalResolution =\n | { status: 'unmatched' }\n | { status: 'ambiguous'; proposalIds: string[] }\n | {\n status: 'decision';\n proposalId: string;\n decision: 'approved' | 'rejected';\n remember: boolean;\n };\n\n/**\n * Recognizes complete, explicit decision messages. This grants no authority: callers must\n * resolve the authenticated actor and use the normal scoped decision service with via=text.\n * Never feed model output here or consume an unmatched message as an approval.\n */\nexport function resolveTextActionProposalDecision(\n text: string,\n proposals: readonly TextActionProposalCandidate[],\n vocabulary?: TextActionProposalVocabulary,\n): TextActionProposalResolution {\n const command = parseTextActionProposalCommand(text, vocabulary);\n if (command.status === 'unmatched') return command;\n const { decision, remember } = command;\n const pending = proposals.filter((proposal) => proposal.decision === 'pending');\n const explicitId = command.proposalId;\n if (explicitId !== undefined) {\n if (!pending.some((proposal) => proposal.id === explicitId)) return { status: 'unmatched' };\n return { status: 'decision', proposalId: explicitId, decision, remember };\n }\n if (pending.length === 0) return { status: 'unmatched' };\n if (pending.length > 1) return { status: 'ambiguous', proposalIds: pending.map(({ id }) => id) };\n const candidate = pending[0];\n if (!candidate) return { status: 'unmatched' };\n return { status: 'decision', proposalId: candidate.id, decision, remember };\n}\n\nexport type TextActionProposalCommand =\n | { status: 'unmatched' }\n | {\n status: 'command';\n decision: 'approved' | 'rejected';\n remember: boolean;\n proposalId?: string;\n };\n\n/**\n * The words a whole chat message must consist of to decide a proposal by text. Matched\n * case-insensitively, as the complete message (an optional trailing `.`/`!`, an optional `#ID`).\n */\nexport interface TextActionProposalVocabulary {\n /** Approve, e.g. `sim`, `yes`. */\n approve: readonly string[];\n /** Reject, e.g. `não`, `no`. */\n reject: readonly string[];\n /** The phrase after an approve word that also approves later calls of the tool in this thread. */\n remember: readonly string[];\n /**\n * The language these words are in (a BCP 47 tag, e.g. `pt-BR`). Surfaces that speak on their own\n * (text channels) pick their default texts by it, so the words and the texts agree.\n */\n language?: string;\n}\n\n/**\n * English. Portuguese ships as {@link ptBrActionProposalText}; any other language through\n * `AgentModule.forRoot({ actionProposalText })`.\n */\nexport const DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY: TextActionProposalVocabulary = {\n approve: ['yes', 'confirm', 'approve', 'approved', 'ok'],\n reject: ['no', 'cancel', 'reject', 'deny'],\n remember: ['always in this conversation'],\n};\n\n/** What the agent answers to a text decision. Every field has an English default. */\nexport interface TextActionProposalReplies {\n approved: string;\n rejected: string;\n expired: string;\n /** The proposal could not change (already decided by someone else, superseded, …). */\n unchanged: string;\n /** More than one pending proposal could be meant: ask for the `#ID`. */\n ambiguous(proposalIds: readonly string[]): string;\n /** Too many pending proposals to pick one without an explicit `#ID`. */\n tooMany: string;\n}\n\nexport const DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES: TextActionProposalReplies = {\n approved: 'Proposal approved and queued to run.',\n rejected: 'Proposal rejected; nothing was run.',\n expired: 'The proposal expired; nothing was run.',\n unchanged: 'This proposal could not be changed; refresh the list to see where it stands.',\n ambiguous: (ids) => `Which proposal? Reply confirm #ID or cancel #ID: ${ids.join(', ')}`,\n tooMany: 'There are several proposals. Confirm or reject one with an explicit #ID.',\n};\n\n/** `AgentModule.forRoot({ actionProposalText })`: either part replaces the default it names. */\nexport interface TextActionProposalConfig {\n vocabulary?: Partial<TextActionProposalVocabulary>;\n replies?: Partial<TextActionProposalReplies>;\n}\n\n/** The reply to a decision the store answered with `result`. */\nexport function textActionProposalReply(\n result: Pick<ActionProposalMutationResult, 'status'> & {\n proposal?: { decision: ActionProposalDecision };\n },\n decision: 'approved' | 'rejected',\n replies: TextActionProposalReplies = DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES,\n): string {\n return result.status === 'expired' || result.proposal?.decision === 'expired'\n ? replies.expired\n : result.status === 'applied' || result.status === 'unchanged'\n ? decision === 'approved'\n ? replies.approved\n : replies.rejected\n : replies.unchanged;\n}\n\nconst escapeRegExp = (word: string) => word.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\nconst alternatives = (words: readonly string[]) =>\n words\n .map((word) => word.trim())\n .filter((word) => word.length > 0)\n .map((word) => escapeRegExp(word).replace(/\\s+/g, '\\\\s+'))\n .join('|');\nconst fold = (word: string) => word.trim().toLowerCase();\n\n/** Parse exact consent syntax only. Authentication and target lookup remain the caller's responsibility. */\nexport function parseTextActionProposalCommand(\n text: string,\n vocabulary: TextActionProposalVocabulary = DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY,\n): TextActionProposalCommand {\n if (/[\\r\\n]/u.test(text)) return { status: 'unmatched' };\n const verbs = alternatives([...vocabulary.approve, ...vocabulary.reject]);\n if (verbs.length === 0) return { status: 'unmatched' };\n const remember = alternatives(vocabulary.remember);\n const match = new RegExp(\n `^(${verbs})${remember.length > 0 ? `(?: (${remember}))?` : '()'}(?: #([^\\\\s]+?))?[.!]?$`,\n 'iu',\n ).exec(text.trim());\n if (!match) return { status: 'unmatched' };\n const verb = match[1] === undefined ? undefined : fold(match[1]);\n if (verb === undefined) return { status: 'unmatched' };\n // A word on both lists is read as a refusal: never infer consent from an ambiguous word.\n const decision = vocabulary.reject.some((word) => fold(word) === verb) ? 'rejected' : 'approved';\n const remembers = match[2] !== undefined && match[2] !== '';\n if (remembers && decision !== 'approved') return { status: 'unmatched' };\n return {\n status: 'command',\n decision,\n remember: remembers,\n ...(match[3] !== undefined ? { proposalId: match[3] } : {}),\n };\n}\n\n/**\n * Brazilian Portuguese text decisions — `AgentModule.forRoot({ actionProposalText: ptBrActionProposalText })`.\n * Commands in Portuguese (English ones still work), replies in Portuguese.\n */\nexport const ptBrActionProposalText: Required<TextActionProposalConfig> = {\n vocabulary: {\n language: 'pt-BR',\n approve: [\n 'sim',\n 'confirmo',\n 'confirmar',\n 'aprovar',\n 'aprovo',\n 'pode',\n ...DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY.approve,\n ],\n reject: [\n 'não',\n 'nao',\n 'cancelar',\n 'cancela',\n 'rejeitar',\n 'rejeito',\n ...DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY.reject,\n ],\n remember: ['sempre nesta conversa', ...DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY.remember],\n },\n replies: {\n approved: 'Proposta aprovada e enfileirada para execução.',\n rejected: 'Proposta rejeitada; nenhuma ação foi executada.',\n expired: 'A proposta expirou; nenhuma ação foi executada.',\n unchanged:\n 'Não foi possível alterar esta proposta; atualize a lista para consultar seu estado.',\n ambiguous: (ids) => `Qual proposta? Responda confirmar #ID ou cancelar #ID: ${ids.join(', ')}`,\n tooMany: 'Há várias propostas. Confirme ou rejeite usando #ID explícito.',\n },\n};\n","import type { ActionProposalOutcomeDelivery } from './spi/action-proposal-outcome-store.js';\nimport type {\n ActionProposal,\n ActionProposalExecution,\n ActionProposalMutationResult,\n} from './spi/action-proposal-store.js';\n\n/**\n * What leaves the server about a proposal — the routes, a text decision's answer, AG-UI, the approval\n * port. The stored row minus what only the worker and the store may hold: the execution and\n * delivery leases (whose token lets a holder settle the work), the idempotency key the tool's side\n * effect is keyed on, and the execution address (the original preparation input and the request's\n * context).\n */\nexport interface ActionProposalView\n extends Omit<\n ActionProposal,\n 'execution' | 'outcomeDelivery' | 'idempotencyKey' | 'preparationInput' | 'executionContext'\n > {\n execution: Omit<ActionProposalExecution, 'lease'> | null;\n outcomeDelivery?: Omit<ActionProposalOutcomeDelivery, 'lease'>;\n}\n\n/** {@link ActionProposalMutationResult} with its proposal as an {@link ActionProposalView}. */\nexport interface ActionProposalMutationView extends Omit<ActionProposalMutationResult, 'proposal'> {\n proposal?: ActionProposalView;\n}\n\n/** The public view of a stored proposal. See {@link ActionProposalView}. */\nexport function toActionProposalView(proposal: ActionProposal): ActionProposalView {\n const {\n execution,\n outcomeDelivery,\n idempotencyKey: _idempotencyKey,\n preparationInput: _preparationInput,\n executionContext: _executionContext,\n ...rest\n } = proposal;\n return {\n ...rest,\n execution: execution === null ? null : withoutLease(execution),\n ...(outcomeDelivery !== undefined ? { outcomeDelivery: withoutLease(outcomeDelivery) } : {}),\n };\n}\n\n/** The public view of a mutation's answer. See {@link ActionProposalView}. */\nexport function toActionProposalMutationView(\n result: ActionProposalMutationResult,\n): ActionProposalMutationView {\n const { proposal, ...rest } = result;\n return {\n ...rest,\n ...(proposal !== undefined ? { proposal: toActionProposalView(proposal) } : {}),\n };\n}\n\nfunction withoutLease<T extends { lease: unknown }>(value: T): Omit<T, 'lease'> {\n const { lease: _lease, ...rest } = value;\n return rest;\n}\n","import { snapshotActionProposal } from './action-proposal-transitions.js';\nimport { type ResolveToolUiCatalog, createNegotiatedUiCollector } from './negotiated-tool-ui.js';\nimport type { ActionProposal } from './spi/action-proposal-store.js';\nimport type { BackgroundActorResolver } from './spi/background-actor-resolver.js';\nimport type { RolesPolicy } from './spi/roles-policy.js';\nimport type { AgentUiComponent } from './stream-events.js';\nimport type { ToolRegistry } from './tool-registry.js';\nimport type { Actor } from './types.js';\n\nexport interface ActionProposalExecutionDeps {\n registry: ToolRegistry;\n rolesPolicy: RolesPolicy;\n allowedTools?: string[];\n host?: unknown;\n resolveUiCatalog?: ResolveToolUiCatalog;\n}\nexport interface ActionProposalExecutorOptions {\n resolver: BackgroundActorResolver;\n /** Resolve exact recorded agent/persona against current configuration; throw if it disappeared. */\n resolveExecution(proposal: ActionProposal, actor: Actor): Promise<ActionProposalExecutionDeps>;\n}\nexport type ActionProposalExecutionResult =\n | { status: 'succeeded'; result?: unknown; ui: AgentUiComponent[]; text?: string }\n | { status: 'failed'; error: string; ui: AgentUiComponent[]; text?: string };\nexport class ActionProposalExecutor {\n constructor(private readonly options: ActionProposalExecutorOptions) {}\n async execute(proposal: ActionProposal): Promise<ActionProposalExecutionResult> {\n let ui = createNegotiatedUiCollector(proposal.originToolCallId, {\n actor: { id: proposal.actorRef },\n threadId: proposal.threadId,\n });\n try {\n const actor = await this.options.resolver.resolve({\n actorRef: proposal.actorRef,\n tenantRef: proposal.tenantRef,\n });\n if (\n !actor ||\n actor.id !== proposal.actorRef ||\n (actor.tenantRef ?? null) !== proposal.tenantRef\n )\n throw new Error('Action proposal requester no longer exists or scope changed');\n const deps = await this.options.resolveExecution(proposal, actor);\n if (deps.registry.spec(proposal.toolName)?.kind !== 'action')\n throw new Error('Action proposal tool no longer exists as an action');\n const context = proposal.executionContext;\n ui = createNegotiatedUiCollector(\n proposal.originToolCallId,\n {\n actor,\n threadId: proposal.threadId,\n ...(context?.agentName !== undefined ? { agentName: context.agentName } : {}),\n ...(context?.uiCapabilities !== undefined\n ? { uiCapabilities: context.uiCapabilities }\n : {}),\n },\n deps.resolveUiCatalog,\n );\n const output = await deps.registry.invoke(\n proposal.toolName,\n snapshotActionProposal(\n Object.hasOwn(proposal, 'preparationInput') ? proposal.preparationInput : proposal.input,\n ),\n {\n actor,\n threadId: proposal.threadId,\n runId: proposal.originRunId,\n requestId: context?.requestId ?? proposal.originRunId,\n toolCallId: proposal.originToolCallId,\n idempotencyKey: proposal.idempotencyKey,\n ...(context?.agentName !== undefined ? { agentName: context.agentName } : {}),\n ...(context?.persona !== undefined ? { persona: context.persona } : {}),\n ...(context?.pageContext !== undefined ? { pageContext: context.pageContext } : {}),\n ...(context?.uiCapabilities !== undefined\n ? { uiCapabilities: context.uiCapabilities }\n : {}),\n ...(deps.host !== undefined ? { host: deps.host } : {}),\n emitUi: ui.emit,\n },\n deps.rolesPolicy,\n {\n approvedInput: proposal.input,\n ...(deps.allowedTools !== undefined ? { allowedTools: deps.allowedTools } : {}),\n },\n );\n return snapshotActionProposal({\n status: 'succeeded',\n ...(output !== undefined ? { result: output } : {}),\n ui: ui.components(),\n ...(ui.text() ? { text: ui.text() } : {}),\n });\n } catch (error) {\n return {\n status: 'failed',\n error: error instanceof Error ? error.message : String(error),\n ui: ui.components(),\n ...(ui.text() ? { text: ui.text() } : {}),\n };\n }\n }\n}\n","import type { ActionProposalExecutor } from './action-proposal-executor.js';\nimport type { ActionProposalOutcomeStore } from './spi/action-proposal-outcome-store.js';\nimport type { ActionProposal, ActionProposalStore } from './spi/action-proposal-store.js';\nimport type { ActionProposalWorkerStore } from './spi/action-proposal-worker-store.js';\nexport interface ActionProposalWorkerOptions {\n store: ActionProposalStore & ActionProposalWorkerStore & ActionProposalOutcomeStore;\n executor: ActionProposalExecutor;\n workerId: string;\n pollIntervalMs?: number;\n leaseMs?: number;\n maxConcurrency?: number;\n onError?(error: unknown): void;\n onSettled?(proposal: ActionProposal): Promise<void>;\n}\nexport class ActionProposalWorker {\n private readonly leaseMs: number;\n private readonly pollIntervalMs: number;\n private readonly maxConcurrency: number;\n private timer?: ReturnType<typeof setTimeout>;\n private stopped = false;\n private readonly renewals = new Set<ReturnType<typeof setInterval>>();\n private active: Promise<void> | undefined;\n constructor(private readonly options: ActionProposalWorkerOptions) {\n this.leaseMs = options.leaseMs ?? 30000;\n this.pollIntervalMs = options.pollIntervalMs ?? 1000;\n this.maxConcurrency = options.maxConcurrency ?? 1;\n for (const value of [this.leaseMs, this.pollIntervalMs, this.maxConcurrency])\n if (!Number.isSafeInteger(value) || value <= 0)\n throw new RangeError('Worker configuration must be positive safe integers');\n if (this.pollIntervalMs >= this.leaseMs / 3)\n throw new RangeError('Worker poll interval must be below one third of lease');\n if (!options.workerId) throw new TypeError('workerId is required');\n }\n start(): void {\n if (this.timer !== undefined || this.stopped) return;\n const tick = async () => {\n if (this.stopped) return;\n try {\n await this.runOnce();\n } catch (error) {\n this.options.onError?.(error);\n }\n if (!this.stopped) this.timer = setTimeout(tick, this.pollIntervalMs);\n };\n this.timer = setTimeout(tick, 0);\n }\n async stop(): Promise<void> {\n this.stopped = true;\n for (const timer of this.renewals) clearInterval(timer);\n this.renewals.clear();\n if (this.timer !== undefined) clearTimeout(this.timer);\n await this.active;\n }\n runOnce(): Promise<void> {\n if (this.active) return this.active;\n if (this.stopped) return Promise.resolve();\n const task = this.tick();\n this.active = task;\n return task.finally(() => {\n if (this.active === task) this.active = undefined;\n });\n }\n private async tick(): Promise<void> {\n await this.options.store.expireActionProposals({ limit: 100 });\n const work: Promise<void>[] = [];\n for (let index = 0; index < this.maxConcurrency && !this.stopped; index++) {\n const proposal = await this.options.store.claimNextActionProposal({\n workerId: this.options.workerId,\n leaseMs: this.leaseMs,\n });\n if (!proposal) break;\n work.push(this.execute(proposal));\n }\n await Promise.all(work);\n for (let index = 0; index < 32 && !this.stopped; index++) {\n const delivery = await this.options.store.claimNextActionProposalOutcome({\n workerId: this.options.workerId,\n leaseMs: this.leaseMs,\n });\n if (!delivery) break;\n await this.options.store.admitActionProposalOutcome(delivery.lease);\n }\n }\n private async execute(proposal: ActionProposal): Promise<void> {\n const lease = proposal.execution?.lease;\n if (!lease) throw new Error('Claimed action lacks execution lease');\n let fenced = true;\n let renewing: Promise<void> | undefined;\n const renew = () => {\n if (renewing || !fenced) return;\n renewing = this.options.store\n .extendActionProposalLease(proposal, proposal.id, {\n token: lease.token,\n generation: lease.generation,\n leaseMs: this.leaseMs,\n })\n .then(\n (result) => {\n if (result.status !== 'applied') fenced = false;\n },\n (error) => {\n fenced = false;\n this.options.onError?.(error);\n },\n )\n .finally(() => {\n renewing = undefined;\n });\n };\n const timer = setInterval(renew, this.leaseMs / 3);\n this.renewals.add(timer);\n try {\n const result = await this.options.executor.execute(proposal);\n clearInterval(timer);\n await renewing;\n if (!fenced) return;\n const settled = await this.options.store.settleActionProposal(proposal, proposal.id, {\n ...result,\n token: lease.token,\n generation: lease.generation,\n });\n if (settled.status === 'applied' && settled.proposal)\n await this.options.onSettled?.(settled.proposal);\n } finally {\n clearInterval(timer);\n this.renewals.delete(timer);\n await renewing;\n }\n }\n}\n","import type { ActionProposalOutcomeStore } from './spi/action-proposal-outcome-store.js';\nimport type {\n ActionProposalStore,\n ActionProposalSupersessionStore,\n} from './spi/action-proposal-store.js';\nimport type { ActionProposalWorkerStore } from './spi/action-proposal-worker-store.js';\nimport type { AgentStore } from './spi/agent-store.js';\nimport type { BackgroundActorResolver } from './spi/background-actor-resolver.js';\nimport { isChatQueueStore } from './spi/chat-queue.js';\nexport type ActionProposalRuntimeStore = AgentStore &\n ActionProposalStore &\n ActionProposalWorkerStore &\n ActionProposalOutcomeStore &\n ActionProposalSupersessionStore;\nexport function assertIndependentActionCapabilities(\n store: AgentStore,\n resolver: BackgroundActorResolver | undefined,\n): asserts store is ActionProposalRuntimeStore {\n const candidate = store as unknown as Record<string, unknown>;\n if (!resolver || typeof resolver.resolve !== 'function')\n throw new Error('Independent action mode requires a BackgroundActorResolver');\n if (!isChatQueueStore(store) || candidate.actionProposalAdmissionSupported === false)\n throw new Error('Independent action mode requires transactional thread admission');\n const required = [\n 'createActionProposal',\n 'getActionProposal',\n 'listActionProposals',\n 'decideActionProposal',\n 'claimActionProposal',\n 'extendActionProposalLease',\n 'settleActionProposal',\n 'claimNextActionProposal',\n 'expireActionProposals',\n 'getThreadActionProposalScope',\n 'claimNextActionProposalOutcome',\n 'admitActionProposalOutcome',\n 'createReplacingActionProposal',\n 'supersedeActionProposal',\n ];\n if (required.some((method) => typeof candidate[method] !== 'function'))\n throw new Error(\n 'Independent action mode requires proposal, worker, outcome and admission capabilities on the conversation store',\n );\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport type { ToolHandler } from './spi/tool.js';\nimport type { ToolSpec } from './types.js';\n\nexport interface FunctionalTool<I = unknown, O = unknown> {\n spec: ToolSpec;\n handler: ToolHandler<I, O>;\n}\n\nexport type FunctionalToolDefinition<I, O> = Omit<ToolSpec, 'inputSchema' | 'kind'> & {\n input: StandardSchemaV1<unknown, I>;\n kind?: ToolSpec['kind'];\n} & ToolHandler<I, O>;\n\n/** Framework-independent authoring; every method keeps the author's object as its receiver. */\nexport function createFunctionalTool<I, O>(\n definition: FunctionalToolDefinition<I, O>,\n): FunctionalTool<I, O> {\n const { input, execute, present, preflight, isEnabled, canUse, describe, kind, ...metadata } =\n definition;\n return {\n spec: { ...metadata, kind: kind ?? 'read', inputSchema: input },\n handler: {\n execute: execute.bind(definition),\n ...(present === undefined ? {} : { present: present.bind(definition) }),\n ...(preflight === undefined ? {} : { preflight: preflight.bind(definition) }),\n ...(isEnabled === undefined ? {} : { isEnabled: isEnabled.bind(definition) }),\n ...(canUse === undefined ? {} : { canUse: canUse.bind(definition) }),\n ...(describe === undefined ? {} : { describe: describe.bind(definition) }),\n },\n };\n}\n"],"mappings":";;;;AAWO,IAAMA,gBAAgBC,uBAAOC,IAAI,gCAAA;AACjC,IAAMC,cAAcF,uBAAOC,IAAI,8BAAA;AAC/B,IAAME,eAAeH,uBAAOC,IAAI,+BAAA;AAMhC,IAAMG,uBAAuBJ,uBAAOC,IAAI,uCAAA;AACxC,IAAMI,aAAaL,uBAAOC,IAAI,6BAAA;AAC9B,IAAMK,cAAcN,uBAAOC,IAAI,8BAAA;AAC/B,IAAMM,qBAAqBP,uBAAOC,IAAI,qCAAA;AAMtC,IAAMO,oBAAoBR,uBAAOC,IAAI,oCAAA;AACrC,IAAMQ,sBAAsBT,uBAAOC,IAAI,sCAAA;AACvC,IAAMS,iBAAiBV,uBAAOC,IAAI,uCAAA;AAClC,IAAMU,uBAAuBX,uBAAOC,IAAI,uCAAA;AAExC,IAAMW,2BAA2BZ,uBAAOC,IAAI,2CAAA;AAE5C,IAAMY,uBAAuBb,uBAAOC,IAAI,uCAAA;AAExC,IAAMa,sBAAsBd,uBAAOC,IAAI,sCAAA;AAEvC,IAAMc,sBAAsBf,uBAAOC,IAAI,sCAAA;AAEvC,IAAMe,kBAAkBhB,uBAAOC,IAAI,kCAAA;AAEnC,IAAMgB,2BAA2BjB,uBAAOC,IAAI,2CAAA;AAG5C,IAAMiB,qBAAqBlB,uBAAOC,IAAI,qCAAA;AAEtC,IAAMkB,4BAA4BnB,uBAAOC,IAAI,4CAAA;AAK7C,IAAMmB,wBAAwBpB,uBAAOC,IAAI,wCAAA;AAMzC,IAAMoB,2BAA2BrB,uBAAOC,IAAI,2CAAA;AAK5C,IAAMqB,sBAAsBtB,uBAAOC,IAAI,sCAAA;AAMvC,IAAMsB,eAAevB,uBAAOC,IAAI,+BAAA;AAMhC,IAAMuB,eAAexB,uBAAOC,IAAI,+BAAA;AAKhC,IAAMwB,sBAAsBzB,uBAAOC,IAAI,sCAAA;AAMvC,IAAMyB,4BAA4B1B,uBAAOC,IAAI,4CAAA;AAO7C,IAAM0B,sBAAsB3B,uBAAOC,IAAI,sCAAA;;;AC5BvC,SAAS2B,mBAAmBC,MAAsB;AACvD,SAAO;IAAEC,MAAM,6BAAMD,MAAN;EAAW;AAC5B;AAFgBD;AAKT,SAASG,iBACdF,MACAG,IAAU;AAEV,aAAWC,SAASJ,KAAKK,WAAW;AAClC,UAAMC,QAAQF,MAAMG,OAAOC,KAAK,CAACC,UAAUA,MAAMN,OAAOA,EAAAA;AACxD,QAAIG,UAAUI,OAAW,QAAOJ;EAClC;AACA,SAAOI;AACT;AATgBR;AAiBT,SAASS,kBAAkBC,UAAyBH,OAAa;AACtE,SAAO;IACLI,SAAS,wBAACC,SAAwBF,SAASC,QAAQ;MAAE,GAAGC;MAAML;IAAM,CAAA,GAA3D;EACX;AACF;AAJgBE;;;ACnDT,IAAMI,mBAAN,cAA+BC,MAAAA;EArCtC,OAqCsCA;;;EAC3BC;EACT,YAAYC,OAAoB;AAC9B,UAAMA,MAAMC,OAAO;AACnB,SAAKC,OAAO;AACZ,SAAKH,OAAOC,MAAMD;EACpB;AACF;;;AC2KA,IAAMI,UAAU,IAAIC,YAAAA;AAGb,SAASC,kBAAkBC,OAAuB;AACvD,SAAOH,QAAQI,OAAO,GAAGC,KAAKC,UAAUH,KAAAA,CAAAA;CAAU;AACpD;AAFgBD;AAYT,SAASK,kBAAkBC,MAAY;AAC5C,MAAI;AACF,UAAMC,SAAkBJ,KAAKK,MAAMF,IAAAA;AACnC,QACE,OAAOC,WAAW,YAClBA,WAAW,QACX,OAAQA,OAA4BE,SAAS,UAC7C;AACA,aAAOF;IACT;EACF,QAAQ;EAER;AACA,SAAO;AACT;AAdgBF;;;ACxMT,SAASK,kBACdC,QACAC,MAAoBC,KAAKD,KAAG;AAE5B,QAAME,WAAU,IAAIC,YAAAA;AACpB,MAAIC,UAAU;AACd,MAAIC,YAAY;AAChB,MAAIC,cAAc;AAClB,MAAIC;AACJ,QAAMC,KAAK,oBAAIC,IAAAA;AAEf,WAASC,aAAAA;AACP,QAAIH,mBAAmBI,QAAW;AAChCL,qBAAeM,KAAKC,IAAI,GAAGb,IAAAA,IAAQO,cAAAA;AACnCA,uBAAiBI;IACnB;EACF;AALSD;AAOT,WAASI,YAAYC,MAAY;AAC/B,QAAIA,KAAKC,KAAI,EAAGC,WAAW,GAAG;AAC5B;IACF;AACA,UAAMC,QAAQC,kBAAkBJ,IAAAA;AAChC,QAAIG,UAAU,MAAM;AAClB;IACF;AACA,QAAIA,MAAME,SAAS,aAAa;AAC9Bb,yBAAmBP,IAAAA;AACnBK,mBAAaa,MAAMG;AACnB;IACF;AACAX,eAAAA;AACA,QAAIQ,MAAME,SAAS,MAAM;AAGvBZ,SAAGc,IAAIJ,MAAMK,IAAI;QACfA,IAAIL,MAAMK;QACVC,WAAWN,MAAMM;QACjBC,OAAOP,MAAMO;QACb,GAAIP,MAAMQ,YAAYf,SAAY;UAAEe,SAASR,MAAMQ;QAAQ,IAAI,CAAC;MAClE,CAAA;IACF;EACF;AAxBSZ;AA0BT,WAASa,QAAQC,OAAiB;AAChCxB,eAAWF,SAAQ2B,OAAOD,OAAO;MAAEE,QAAQ;IAAK,CAAA;AAChD,QAAIC,UAAU3B,QAAQ4B,QAAQ,IAAA;AAC9B,WAAOD,YAAY,IAAI;AACrBjB,kBAAYV,QAAQ6B,MAAM,GAAGF,OAAAA,CAAAA;AAC7B3B,gBAAUA,QAAQ6B,MAAMF,UAAU,CAAA;AAClCA,gBAAU3B,QAAQ4B,QAAQ,IAAA;IAC5B;EACF;AARSL;AAUT,SAAO;IACL5B,QAAQ;MACNmC,MAAMN,OAAK;AAGTD,gBAAQC,KAAAA;AACR,eAAO7B,OAAOmC,MAAMN,KAAAA;MACtB;MACAO,KAAK,6BAAMpC,OAAOoC,IAAG,GAAhB;MACLC,MAAM,wBAACC,UAAUtC,OAAOqC,KAAKC,KAAAA,GAAvB;IACR;IACAC,UAAAA;AACE,UAAIlC,QAAQa,SAAS,GAAG;AACtBH,oBAAYV,OAAAA;AACZA,kBAAU;MACZ;AACAM,iBAAAA;AACA,aAAO;QACL,GAAIL,UAAUY,SAAS,IAAI;UAAEZ;UAAWC,aAAaM,KAAK2B,MAAMjC,WAAAA;QAAa,IAAI,CAAC;QAClF,GAAIE,GAAGgC,OAAO,IAAI;UAAEhC,IAAI;eAAIA,GAAGiC,OAAM;;QAAI,IAAI,CAAC;MAChD;IACF;EACF;AACF;AA7EgB3C;AAgFT,SAAS4C,eAA0CC,SAAWC,QAAwB;AAC3F,SAAO;IACL,GAAGD;IACH,GAAIA,QAAOtC,cAAcM,UAAaiC,OAAOvC,cAAcM,SACvD;MAAEN,WAAWuC,OAAOvC;IAAU,IAC9B,CAAC;IACL,GAAIsC,QAAOrC,gBAAgBK,UAAaiC,OAAOtC,gBAAgBK,SAC3D;MAAEL,aAAasC,OAAOtC;IAAY,IAClC,CAAC;IACL,GAAIqC,QAAOnC,OAAOG,UAAaiC,OAAOpC,OAAOG,SAAY;MAAEH,IAAIoC,OAAOpC;IAAG,IAAI,CAAC;EAChF;AACF;AAXgBkC;;;AChGhB,IAAMG,eAAe;AAWd,SAASC,mBACdC,QACAC,IACAC,MAAa;AAGb,QAAMC,WAAW,OAAOH,WAAW,YAAYA,WAAW,QAAQF,gBAAgBE;AAClF,MAAIC,GAAGG,WAAW,KAAK,CAACD,YAAY,CAACD,MAAM;AACzC,WAAOF;EACT;AACA,QAAMK,UAAgC;IACpC,CAACP,YAAAA,GAAe;IAChBE;IACAC,IAAI;SAAIA;;IACR,GAAIC,OAAO;MAAEA;IAAK,IAAI,CAAC;EACzB;AACA,SAAOG;AACT;AAjBgBN;AAoBT,SAASO,wBAAwBC,QAAc;AACpD,QAAMF,UAAgC;IACpC,CAACP,YAAAA,GAAe;IAChBE,QAAQ;IACRC,IAAI,CAAA;IACJO,iBAAiBD;EACnB;AACA,SAAOF;AACT;AARgBC;AAWT,SAASG,qBAAqBC,KAAY;AAM/C,MACE,OAAOA,QAAQ,YACfA,QAAQ,QACPA,IAAsCZ,YAAAA,MAAkB,GACzD;AACA,UAAMO,UAAUK;AAChB,WAAO;MACLV,QAAQK,QAAQL;MAChBC,IAAIU,MAAMC,QAAQP,QAAQJ,EAAE,IAAII,QAAQJ,KAAK,CAAA;MAC7C,GAAI,OAAOI,QAAQH,SAAS,WAAW;QAAEA,MAAMG,QAAQH;MAAK,IAAI,CAAC;MACjE,GAAI,OAAOG,QAAQG,oBAAoB,WACnC;QAAEA,iBAAiBH,QAAQG;MAAgB,IAC3C,CAAC;IACP;EACF;AACA,SAAO;IAAER,QAAQU;IAAKT,IAAI,CAAA;EAAG;AAC/B;AAtBgBQ;AA+BT,SAASI,iBAAiBC,QAAQ,QAAM;AAC7C,MAAIC,OAAO;AACX,SAAO,OAAOC,YAAYC,QAAQC,UAAU,CAAC,MAAC;AAC5C,QAAIA,QAAQC,OAAOC,QAAW;AAC5B,aAAO;QAAED,IAAID,QAAQC;MAAG;IAC1B;AACA,UAAMA,KAAK,GAAGL,KAAAA,OAAYC,IAAAA;AAC1BA,YAAQ;AACR,WAAO;MAAEI;IAAG;EACd;AACF;AAVgBN;AA4BT,SAASQ,kBACdC,YACAC,OAAyD;AAEzD,QAAMC,SAAS,oBAAIC,IAAAA;AACnB,MAAIV,OAAO;AACX,QAAMW,QAAe,8BAAOC,WAAWC,OAAOV,UAAU,CAAC,MAAC;AACxD,QAAI,OAAOS,cAAc,YAAYA,UAAUvB,WAAW,GAAG;AAC3D,YAAM,IAAIyB,MAAM,8CAAA;IAClB;AACA,QAAI,OAAOD,UAAU,YAAYA,UAAU,QAAQjB,MAAMC,QAAQgB,KAAAA,GAAQ;AACvE,YAAM,IAAIC,MAAM,qCAAA;IAClB;AACA,QAAIV,KAAKD,QAAQC;AACjB,QAAIA,OAAOC,QAAW;AACpBD,WAAK,GAAGG,UAAAA,OAAiBP,IAAAA;AACzBA,cAAQ;IACV;AACA,UAAMe,QAA0B;MAC9BX;MACAQ;;;MAGAC,OAAOG,KAAKC,MAAMD,KAAKE,UAAUL,KAAAA,CAAAA;MACjC,GAAIV,QAAQgB,YAAYd,SAAY;QAAEc,SAAShB,QAAQgB;MAAQ,IAAI,CAAC;MACpE,GAAIhB,QAAQiB,iBAAiBf,SAAY;QAAEe,cAAcjB,QAAQiB;MAAa,IAAI,CAAC;MACnF,GAAIjB,QAAQkB,sBAAsBhB,SAC9B;QAAEgB,mBAAmB;UAAE,GAAGlB,QAAQkB;QAAkB;MAAE,IACtD,CAAC;MACLd;IACF;AAEAE,WAAOa,IAAIlB,IAAIW,KAAAA;AACf,UAAMP,QAAQ;MAAEe,MAAM;MAAM,GAAGR;IAAM,CAAA;AACrC,WAAO;MAAEX;IAAG;EACd,GA7BqB;AA8BrB,SAAO;IACLO,MAAAA;IACAa,YAAY,6BAAM;SAAIf,OAAOgB,OAAM;OAAvB;IACZC,SAAS,6BAAA;AACP1B,aAAO;IACT,GAFS;EAGX;AACF;AA3CgBM;AA8CT,SAASqB,WACXC,OAA2D;AAE9D,QAAMC,SAAS,oBAAInB,IAAAA;AACnB,aAAWoB,QAAQF,OAAO;AACxB,eAAWhB,aAAakB,QAAQ,CAAA,GAAI;AAClCD,aAAOP,IAAIV,UAAUR,IAAIQ,SAAAA;IAC3B;EACF;AACA,SAAO;OAAIiB,OAAOJ,OAAM;;AAC1B;AAVgBE;AAaT,SAASI,uBAAuB5C,MAAY;AACjD,SAAOA,KACJ6C,WAAW,MAAU,SAAA,EACrBC,QACC,qBACA,CAACC,SAAS,MAAMA,KAAKC,WAAW,CAAA,EAAGC,SAAS,EAAA,EAAIC,SAAS,GAAG,GAAA,CAAA,EAAM;AAExE;AAPgBN;;;ACvGT,IAAMO,aAAa;;;ACgF1B,IAAMC,qBAAqB;EACzB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIK,SAASC,iBAAiBC,OAAiB;AAChD,QAAMC,YAAYD;AAClB,SAAOF,mBAAmBI,MAAM,CAACC,WAAW,OAAOF,UAAUE,MAAAA,MAAY,UAAA;AAC3E;AAHgBJ;AAUhB,eAAsBK,iBACpBJ,OACAK,UACAC,OAAa;AAEb,MAAIP,iBAAiBC,KAAAA,GAAQ;AAC3B,UAAMA,MAAMO,oBAAoBF,UAAUC,KAAAA;AAC1C;EACF;AACA,QAAMN,MAAMQ,gBAAgBH,UAAU,IAAA;AACxC;AAVsBD;AAaf,SAASK,kBAAkBC,SAAsB;AACtD,SAAO;IACLC,IAAID,QAAQC;IACZC,SAASF,QAAQE;IACjB,GAAIF,QAAQG,gBAAgBC,UAAaJ,QAAQG,YAAYE,SAAS,IAClE;MAAEF,aAAaH,QAAQG;IAAY,IACnC,CAAC;IACL,GAAIH,QAAQM,cAAcF,SAAY;MAAEE,WAAWN,QAAQM;IAAU,IAAI,CAAC;IAC1E,GAAIN,QAAQO,YAAYH,SAAY;MAAEG,SAASP,QAAQO;IAAQ,IAAI,CAAC;IACpE,GAAIP,QAAQQ,UAAUJ,SAAY;MAAEI,OAAOR,QAAQQ;IAAM,IAAI,CAAC;IAC9D,GAAIR,QAAQS,cAAc,OAAO;MAAEA,WAAW;IAAK,IAAI,CAAC;IACxDC,WAAWV,QAAQU;IACnBC,WAAWX,QAAQW;EACrB;AACF;AAdgBZ;;;ACpHT,SAASa,gBAAgBC,SAA+B;AAC7D,aAAWC,UAAUD,SAAS;AAC5B,UAAME,YACJD,OAAOE,gBAAgBC,WAAcH,OAAOI,cAAc,MAAMJ,OAAOE;AACzE,UAAMG,WAAWL,OAAOM,aAAaH,UAAaH,OAAOO,WAAWP,OAAOM;AAC3E,QAAIL,aAAaI,UAAU;AACzB,aAAO;QACLG,QAAQR,OAAOQ;QACfC,QAAQ,GAAGT,OAAOQ,WAAW,QAAQ,UAAU,SAAA,IAAaH,WAAW,UAAU,OAAA;MACnF;IACF;EACF;AACA,SAAOF;AACT;AAbgBL;AAgBT,SAASY,eAAeV,QAAmB;AAChD,QAAMW,SAAmB,CAAA;AACzB,MAAIX,OAAOM,aAAaH,UAAaH,OAAOM,WAAW,GAAG;AACxDK,WAAOC,KAAKZ,OAAOO,UAAUP,OAAOM,QAAQ;EAC9C;AACA,MACEN,OAAOE,gBAAgBC,UACvBH,OAAOE,cAAc,KACrBF,OAAOI,eAAeD,QACtB;AACAQ,WAAOC,KAAKZ,OAAOI,aAAaJ,OAAOE,WAAW;EACpD;AACA,SAAOS,OAAOE,WAAW,IAAI,OAAOC,KAAKC,IAAG,GAAIJ,MAAAA;AAClD;AAbgBD;AAmBT,SAASM,aAAajB,SAA+B;AAC1D,MAAID,gBAAgBC,OAAAA,MAAaI,OAAW,QAAOA;AACnD,MAAIc;AACJ,aAAWjB,UAAUD,SAAS;AAC5B,QAAIC,OAAOkB,WAAWf,OAAW;AACjC,UAAMgB,QAAQT,eAAeV,MAAAA;AAC7B,QAAImB,UAAU,QAAQA,QAAQnB,OAAOkB,OAAQ;AAC7C,QAAID,YAAYd,UAAagB,QAAQF,QAAQE,OAAO;AAClDF,gBAAU;QAAET,QAAQR,OAAOQ;QAAQW;MAAM;IAC3C;EACF;AACA,SAAOF;AACT;AAZgBD;AAeT,SAASI,iBACdZ,QACAa,KAAS;AAET,QAAMC,OAAOD,IAAIE,eAAc;AAC/B,QAAMC,QAAQH,IAAII,YAAW;AAC7B,QAAMC,MAAML,IAAIM,YAAW,EAAGC,MAAM,GAAG,EAAA;AACvC,MAAIpB,WAAW,OAAO;AACpB,UAAMqB,OAAO,IAAIC,KAAKA,KAAKC,IAAIT,MAAME,OAAOH,IAAIW,WAAU,IAAK,CAAA,CAAA;AAC/D,WAAO;MAAEC,SAASP;MAAKQ,OAAOR;MAAKS,UAAUN,KAAKF,YAAW;IAAG;EAClE;AACA,QAAMS,QAAQ,IAAIN,KAAKA,KAAKC,IAAIT,MAAME,OAAO,CAAA,CAAA;AAC7C,QAAMa,OAAO,IAAIP,KAAKA,KAAKC,IAAIT,MAAME,QAAQ,GAAG,CAAA,CAAA;AAChD,SAAO;IACLS,SAASG,MAAMT,YAAW,EAAGC,MAAM,GAAG,EAAA;IACtCM,OAAOG,KAAKV,YAAW,EAAGC,MAAM,GAAG,EAAA;IACnCO,UAAU,IAAIL,KAAKA,KAAKC,IAAIT,MAAME,QAAQ,GAAG,CAAA,CAAA,EAAIG,YAAW;EAC9D;AACF;AAlBgBP;;;ACzFhB,eAAsBkB,gBACpBC,OACAC,QAAyB;AAEzB,aAAWC,SAASD,QAAQ;AAC1B,UAAMD,MAAMG,iBAAiBD,KAAAA;EAC/B;AACF;AAPsBH;;;ACiDf,IAAMK,qCAAqC;AA+D3C,IAAMC,sBAAN,cAAkCC,MAAAA;EAnJzC,OAmJyCA;;;;EAE9BC;;EAEAC;EAET,YAAYD,WAAmBC,QAAgB;AAC7C,UAAM,uBAAuBD,SAAAA,MAAeC,MAAAA,EAAQ;AACpD,SAAKC,OAAO;AACZ,SAAKF,YAAYA;AACjB,SAAKC,SAASA;EAChB;AACF;AAOO,IAAME,uBAAN,cAAmCJ,MAAAA;EAtK1C,OAsK0CA;;;;EAE/BK;;EAEAJ;EAET,YAAYI,OAA2BJ,WAAmBK,OAAgB;AACxE,UACE,GAAGD,KAAAA,eAAoBJ,SAAAA,aAAsBK,iBAAiBN,QAAQM,MAAMC,UAAUC,OAAOF,KAAAA,CAAAA,EAAQ;AAEvG,SAAKH,OAAO;AACZ,SAAKE,QAAQA;AACb,SAAKJ,YAAYA;AACjB,SAAKK,QAAQA;EACf;AACF;;;ACmKO,IAAMG,8BAA8B;AAOpC,SAASC,sBAAsBC,SAAe;AAInD,MAAIA,QAAQC,UAAUH,6BAA6B;AACjD,WAAO;MAAEE;MAASE,WAAW;IAAM;EACrC;AACA,SAAO;IAAEF,SAASA,QAAQG,MAAM,GAAGL,2BAAAA;IAA8BI,WAAW;EAAK;AACnF;AARgBH;;;ACpVT,IAAMK,qBAAqB;AAmE3B,IAAMC,wBAAN,MAAMA;EApEb,OAoEaA;;;EACXC,eAAeC,MAA4C;AACzD,WAAO;MAAEC,UAAUD,KAAKE,SAAS;MAAUC,UAAUN;IAAmB;EAC1E;AACF;AAGO,SAASO,iBAAiBC,OAAcC,UAA6B;AAC1E,MAAIA,SAASH,aAAaN,oBAAoB;AAC5C,WAAOQ,MAAME,OAAOD,SAASE;EAC/B;AACA,SAAOH,MAAMI,OAAOC,SAASJ,SAASH,QAAQ,MAAM;AACtD;AALgBC;AAQhB,eAAsBO,kBACpBC,QACAP,OACAC,UAA6B;AAE7B,MAAIM,QAAQC,cAAcC,QAAW;AACnC,WAAOF,OAAOC,UAAUR,OAAOC,QAAAA;EACjC;AACA,SAAOF,iBAAiBC,OAAOC,QAAAA;AACjC;AATsBK;AA8Bf,SAASI,wBAAwBC,MAA4B;AAClE,MAAIA,KAAIb,aAAa,QAAQa,KAAIb,aAAaW,QAAW;AACvD,WAAO;EACT;AACA,QAAMG,SACJD,KAAIC,WAAW,sBAAsBD,KAAIC,WAAW,aAChD,YACAD,KAAIC,WAAW,aACb,aACAD,KAAIC,WAAW,YACb,YACA;AACV,QAAMC,YACJF,KAAIE,qBAAqBC,OACrBH,KAAIE,UAAUE,YAAW,IACzB,OAAOJ,KAAIE,cAAc,WACvBF,KAAIE,YACJJ;AACR,QAAMO,UAAUJ,WAAW,cAAcA,WAAW;AACpD,SAAO;IACLK,YAAYN,KAAIM;IAChB,GAAIN,KAAIO,cAAc,OAAO;MAAEA,YAAYP,KAAIO;IAAW,IAAI,CAAC;IAC/DpB,UAAUa,KAAIb;IACd,GAAIa,KAAIQ,gBAAgB,OAAO;MAAEA,cAAcR,KAAIQ;IAAa,IAAI,CAAC;IACrEP;IACA,GAAIC,cAAcJ,SAAY;MAAEI;IAAU,IAAI,CAAC;IAC/C,GAAIF,KAAIS,aAAa,OAAO;MAAEA,UAAU;IAAK,IAAI,CAAC;IAClD,GAAIJ,WAAW,OAAOL,KAAIU,kBAAkB,WAAW;MAAEC,WAAWX,KAAIU;IAAc,IAAI,CAAC;IAC3F,GAAIL,WAAW,OAAOL,KAAIY,eAAe,WAAW;MAAEA,YAAYZ,KAAIY;IAAW,IAAI,CAAC;IACtF,GAAIX,WAAW,cAAc,OAAOD,KAAIa,UAAU,WAAW;MAAEC,QAAQd,KAAIa;IAAM,IAAI,CAAC;EACxF;AACF;AA/BgBd;;;AChET,SAASgB,aAAaC,OAAkBC,OAA6B;AAC1E,MAAIA,UAAUC,QAAW;AACvB,WAAO;EACT;AACA,QAAMC,mBAAmBH,MAAMG,oBAAoB;AACnD,QAAMC,kBAAkBJ,MAAMI,mBAAmB;AACjD,QAAMC,sBAAsBL,MAAMM,cAAcH,mBAAmBC;AACnE,SACGC,sBAAsB,MAAaJ,MAAMM,kBACzCJ,mBAAmB,OAAcF,MAAMO,wBAAwBP,MAAMM,mBACrEH,kBAAkB,OAAcH,MAAMQ,uBAAuBR,MAAMM,mBACnEP,MAAMU,eAAe,MAAaT,MAAMU;AAE7C;AAbgBZ;AAgBhB,SAASa,QAAQC,MAA2BC,QAAuC;AACjF,SAAOD,KAAIE,WAAWhB,aAAac,MAAKC,OAAOE,IAAIH,KAAII,OAAO,CAAA;AAChE;AAFSL;AAKF,SAASM,cACdC,MACAL,QAAuC;AAEvC,QAAMM,UAAU,oBAAIC,IAAAA;AAIpB,aAAWR,QAAOM,MAAM;AACtB,UAAMG,SAASF,QAAQJ,IAAIH,KAAII,OAAO,KAAK;MACzCM,UAAU;MACVjB,aAAa;MACbI,cAAc;MACdK,SAAS;IACX;AACAO,WAAOC,YAAY;AACnBD,WAAOhB,eAAeO,KAAIP;AAC1BgB,WAAOZ,gBAAgBG,KAAIH;AAC3BY,WAAOP,WAAWH,QAAQC,MAAKC,MAAAA;AAC/BM,YAAQI,IAAIX,KAAII,SAASK,MAAAA;EAC3B;AACA,QAAMG,UAA0B,CAAA;AAChC,aAAW,CAACR,SAASK,MAAAA,KAAWF,SAAS;AACvCK,IAAAA,QAAOC,KAAK;MACVT;MACAM,UAAUD,OAAOC;MACjBjB,aAAagB,OAAOhB;MACpBI,cAAcY,OAAOZ;MACrBK,SAASO,OAAOP;IAClB,CAAA;EACF;AACAU,EAAAA,QAAOE,KACL,CAACC,MAAMC,UAAUA,MAAMd,UAAUa,KAAKb,WAAWa,KAAKX,QAAQa,cAAcD,MAAMZ,OAAO,CAAA;AAE3F,SAAOQ;AACT;AAnCgBP;AAsCT,SAASa,cACdZ,MACAL,QAAuC;AAEvC,QAAMkB,UAAU,oBAAIX,IAAAA;AAIpB,aAAWR,QAAOM,MAAM;AACtB,UAAMG,SAASU,QAAQhB,IAAIH,KAAIoB,QAAQ,KAAK;MAC1CV,UAAU;MACVW,aAAa;MACbnB,SAAS;MACToB,WAAW,oBAAIC,IAAAA;IACjB;AACAd,WAAOC,YAAY;AACnBD,WAAOY,eAAerB,KAAIP,cAAcO,KAAIH;AAC5CY,WAAOP,WAAWH,QAAQC,MAAKC,MAAAA;AAC/BQ,WAAOa,UAAUE,IAAIxB,KAAIyB,QAAQ;AACjCN,YAAQR,IAAIX,KAAIoB,UAAUX,MAAAA;EAC5B;AACA,QAAMG,UAA0B,CAAA;AAChC,aAAW,CAACQ,UAAUX,MAAAA,KAAWU,SAAS;AACxCP,IAAAA,QAAOC,KAAK;MACVO;MACAV,UAAUD,OAAOC;MACjBW,aAAaZ,OAAOY;MACpBnB,SAASO,OAAOP;MAChBwB,aAAajB,OAAOa,UAAUK;IAChC,CAAA;EACF;AACAf,EAAAA,QAAOE,KACL,CAACC,MAAMC,UAAUA,MAAMd,UAAUa,KAAKb,WAAWa,KAAKK,SAASH,cAAcD,MAAMI,QAAQ,CAAA;AAE7F,SAAOR;AACT;AAnCgBM;AA2CT,SAASU,eACdtB,MACAL,QACA4B,SACAC,SAA0D;AAE1D,QAAMC,WAAW,oBAAIvB,IAAAA;AACrB,aAAWR,QAAOM,MAAM;AACtB,UAAMG,SAASsB,SAAS5B,IAAIH,KAAIyB,QAAQ,KAAK;MAAEf,UAAU;MAAGW,aAAa;MAAGnB,SAAS;IAAE;AACvFO,WAAOC,YAAY;AACnBD,WAAOY,eAAerB,KAAIP,cAAcO,KAAIH;AAC5CY,WAAOP,WAAWH,QAAQC,MAAKC,MAAAA;AAC/B8B,aAASpB,IAAIX,KAAIyB,UAAUhB,MAAAA;EAC7B;AACA,QAAMG,UAA2B,CAAA;AACjC,aAAW,CAACa,UAAUhB,MAAAA,KAAWsB,UAAU;AACzC,UAAMC,SAASH,QAAQ1B,IAAIsB,QAAAA;AAC3B,QAAIO,WAAW3C,UAAa,CAACyC,QAAQG,uBAAuB;AAC1D;IACF;AACArB,IAAAA,QAAOC,KAAK;MACVY;MACAS,OAAOF,QAAQE,SAAS;MACxBd,UAAUY,QAAQZ,YAAY;MAC9BV,UAAUD,OAAOC;MACjBW,aAAaZ,OAAOY;MACpBnB,SAASO,OAAOP;IAClB,CAAA;EACF;AACAU,EAAAA,QAAOE,KACL,CAACC,MAAMC,UAAUA,MAAMd,UAAUa,KAAKb,WAAWa,KAAKU,SAASR,cAAcD,MAAMS,QAAQ,CAAA;AAE7F,SAAOb,QAAOuB,MAAM,GAAGL,QAAQM,KAAK;AACtC;AAjCgBR;AAwCT,SAASS,kBACd/B,MACAL,QAAuC;AAEvC,QAAMqC,SAA4B;IAChC5B,UAAU;IACVjB,aAAa;IACbI,cAAc;IACdwB,aAAa;IACbnB,SAAS;EACX;AACA,aAAWF,QAAOM,MAAM;AACtBgC,WAAO5B,YAAY;AACnB4B,WAAO7C,eAAeO,KAAIP;AAC1B6C,WAAOzC,gBAAgBG,KAAIH;AAC3ByC,WAAOjB,eAAerB,KAAIP,cAAcO,KAAIH;AAC5CyC,WAAOpC,WAAWH,QAAQC,MAAKC,MAAAA;EACjC;AACA,SAAOqC;AACT;AAnBgBD;AAsBT,SAASE,iBACdjC,MACAL,QAAuC;AAEvC,QAAMuC,QAAQ,oBAAIhC,IAAAA;AAClB,aAAWR,QAAOM,MAAM;AACtB,UAAMG,SAAS+B,MAAMrC,IAAIH,KAAIyC,GAAG,KAAK;MAAEpB,aAAa;MAAGnB,SAAS;IAAE;AAClEO,WAAOY,eAAerB,KAAIP,cAAcO,KAAIH;AAC5CY,WAAOP,WAAWH,QAAQC,MAAKC,MAAAA;AAC/BuC,UAAM7B,IAAIX,KAAIyC,KAAKhC,MAAAA;EACrB;AACA,QAAMG,UAA4B,CAAA;AAClC,aAAW,CAAC6B,KAAKhC,MAAAA,KAAW+B,OAAO;AACjC5B,IAAAA,QAAOC,KAAK;MAAE4B;MAAKpB,aAAaZ,OAAOY;MAAanB,SAASO,OAAOP;IAAQ,CAAA;EAC9E;AACAU,EAAAA,QAAOE,KAAK,CAACC,MAAMC,UAAUD,KAAK0B,IAAIxB,cAAcD,MAAMyB,GAAG,CAAA;AAC7D,SAAO7B;AACT;AAjBgB2B;AAoBT,SAASG,aAAaC,OAAsB;AACjD,SAAO;IACLC,OAAO,oBAAIC,KAAK,GAAGF,MAAMG,OAAO,gBAAgB;IAChDC,KAAK,oBAAIF,KAAK,GAAGF,MAAMK,KAAK,gBAAgB;EAC9C;AACF;AALgBN;;;ACxOhB,eAAsBO,cAAcC,MAAgBC,SAAqB;AACvE,QAAMC,WACJ,OAAOF,KAAKG,YAAY,aAAa,MAAMH,KAAKG,QAAO,IAAMH,KAAKG,WAAW;AAC/E,MAAI,CAACD,UAAU;AACb,WAAO;EACT;AACA,SAAOD,SAASG,cAAcC,SAAY,OAAO,MAAMJ,QAAQG,UAAS;AAC1E;AAPsBL;AActB,eAAsBO,qBACpBC,SAAY;AAEZ,QAAMC,UAAU,MAAMC,QAAQC,IAC5BH,QAAQI,IAAI,OAAOC,WAAW;IAC5BA;IACAT,SAAS,MAAMJ,cAAca,MAAMZ,MAAMY,MAAMX,OAAO;EACxD,EAAA,CAAA;AAEF,SAAOO,QAAQK,OAAO,CAACC,SAAQA,KAAIX,OAAO,EAAEQ,IAAI,CAACG,SAAQA,KAAIF,KAAK;AACpE;AAVsBN;AAgBtB,eAAsBS,gBAAgBC,OAAcf,SAAqB;AACvE,SAAOA,SAASgB,WAAWZ,SAAY,OAAO,MAAMJ,QAAQgB,OAAOD,KAAAA;AACrE;AAFsBD;AAQtB,eAAsBG,oBACpBX,SACAS,OAAY;AAEZ,QAAMR,UAAU,MAAMC,QAAQC,IAC5BH,QAAQI,IAAI,OAAOC,WAAW;IAC5BA;IACAO,SAAS,MAAMJ,gBAAgBC,OAAOJ,MAAMX,OAAO;EACrD,EAAA,CAAA;AAEF,SAAOO,QAAQK,OAAO,CAACC,SAAQA,KAAIK,OAAO,EAAER,IAAI,CAACG,SAAQA,KAAIF,KAAK;AACpE;AAXsBM;AActB,eAAsBE,kBACpBC,OACAL,OACAM,QAAmB;AAEnB,QAAMd,UAAU,MAAMC,QAAQC,IAC5BW,MAAMV,IAAI,OAAOY,UAAU;IAAEA;IAAMJ,SAAS,MAAMG,OAAOE,IAAIR,OAAOO,IAAAA;EAAM,EAAA,CAAA;AAE5E,SAAOf,QAAQK,OAAO,CAACD,UAAUA,MAAMO,OAAO,EAAER,IAAI,CAACC,UAAUA,MAAMW,IAAI;AAC3E;AATsBH;AAgBf,SAASK,uBACdJ,OACAK,cAAkC;AAElC,MAAIA,iBAAiBrB,QAAW;AAC9B,WAAOgB;EACT;AACA,QAAMF,UAAU,IAAIQ,IAAID,YAAAA;AACxB,SAAOL,MAAMR,OAAO,CAACU,SAASJ,QAAQS,IAAIL,KAAKM,IAAI,CAAA;AACrD;AATgBJ;;;ACzET,SAASK,oBACdC,OACAC,QAAqC;AAErC,MAAID,UAAUE,QAAW;AACvB,WAAOD,WAAWC,SAAYA,SAAY;SAAID;;EAChD;AACA,MAAIA,WAAWC,QAAW;AACxB,WAAO;SAAIF;;EACb;AACA,QAAMG,UAAU,IAAIC,IAAIH,MAAAA;AACxB,SAAOD,MAAMK,OAAO,CAACC,SAASH,QAAQI,IAAID,IAAAA,CAAAA;AAC5C;AAZgBP;AAeT,SAASS,YACdC,YACAC,IAAsB;AAEtB,MAAIA,OAAOR,QAAW;AACpB,WAAOA;EACT;AACA,SAAOO,YAAYE,UAAUC,KAAK,CAACC,YAAYA,QAAQH,OAAOA,EAAAA;AAChE;AARgBF;AAWT,SAASM,oBAAoBD,SAAgB;AAClD,SAAO;IACLH,IAAIG,QAAQH;IACZK,OAAOF,QAAQE;IACf,GAAIF,QAAQG,gBAAgBd,SAAY;MAAEc,aAAaH,QAAQG;IAAY,IAAI,CAAC;EAClF;AACF;AANgBF;AAmBT,SAASG,oBACdC,aACAZ,MAAY;AAEZ,aAAWG,cAAcS,aAAa;AACpC,eAAWL,WAAWJ,WAAWE,YAAY,CAAA,GAAI;AAC/C,UAAIE,QAAQM,SAASC,SAASd,IAAAA,MAAU,MAAM;AAC5C,eAAO;UAAEe,OAAOZ,WAAWH;UAAMO,SAASA,QAAQH;QAAG;MACvD;IACF;EACF;AACA,SAAOR;AACT;AAZgBe;;;AC/BT,SAASK,sBAAsBC,SAAqB;AACzD,QAAMC,UACHD,QAAQE,cAAcC,SAAYC,KAAKC,UAAUL,QAAQE,SAAS,EAAEI,SAAS,MAC7EN,QAAQO,gBAAgBJ,SAAYC,KAAKC,UAAUL,QAAQO,WAAW,EAAED,SAAS;AACpF,SAAOE,KAAKC,MAAMT,QAAQU,QAAQJ,SAASL,UAAU,CAAA,IAAK;AAC5D;AALgBF;AA2BT,SAASY,cAAcC,SAA6B;AACzD,QAAMC,WAAWD,QAAQC,YAAYd;AACrC,QAAMe,SAAwB;;;;IAI5B,GAAIF,QAAQG,gBAAgBZ,SAAY;MAAEY,aAAaH,QAAQG;IAAY,IAAI,CAAC;IAChFC,OAAOC,UAAwB;AAC7B,UAAIC,MAAM;AACV,UAAIN,QAAQG,gBAAgBZ,QAAW;AACrCe,cAAMV,KAAKW,IAAID,KAAKD,SAASX,SAASM,QAAQG,WAAW;MAC3D;AACA,UAAIH,QAAQQ,cAAcjB,QAAW;AACnCe,cAAMV,KAAKW,IAAID,KAAKG,SAASJ,UAAUL,QAAQQ,WAAWP,QAAAA,CAAAA;MAC5D;AAGAK,YAAMV,KAAKc,IAAIJ,KAAKV,KAAKW,IAAI,GAAGF,SAASX,SAAS,CAAA,CAAA;AAClD,aAAO;QAAEiB,MAAMN,SAASO,MAAMN,GAAAA;QAAMO,MAAMR,SAASO,MAAM,GAAGN,GAAAA;MAAK;IACnE;EACF;AACA,SAAON,QAAQc,cAAcvB,SAAY;IAAE,GAAGW;IAAQY,WAAWd,QAAQc;EAAU,IAAIZ;AACzF;AAtBgBH;AAyBhB,SAASU,SACPJ,UACAG,WACAP,UAA2C;AAE3C,MAAIc,QAAQV,SAASX;AACrB,MAAIsB,QAAQ;AACZ,SAAOD,QAAQ,GAAG;AAChB,UAAM3B,UAAUiB,SAASU,QAAQ,CAAA;AACjC,QAAI3B,YAAYG,QAAW;AACzB;IACF;AACA,UAAM0B,OAAOhB,SAASb,OAAAA;AACtB,QAAI2B,QAAQV,SAASX,UAAUsB,QAAQC,OAAOT,WAAW;AACvD;IACF;AACAQ,aAASC;AACTF,aAAS;EACX;AACA,SAAOA;AACT;AApBSN;AA2BF,IAAMS,sCACX;AAQK,SAASC,mBACdC,OACAC,cAAsBH,qCAAmC;AAEzD,SAAO,OAAOI,YAAAA;AACZ,UAAMC,UAAsB;MAAEC,OAAO,6BAAA;MAAO,GAAP;MAAUC,KAAK,6BAAA;MAAO,GAAP;MAAUC,MAAM,6BAAA;MAAO,GAAP;IAAS;AAC7E,UAAMC,OAAO,MAAMP,MAAMQ,QAAQ;MAC/BC,QAAQR;MACRhB,UAAUiB;MACVQ,OAAO,CAAA;MACPC,MAAMR;IACR,CAAA;AACA,WAAO;MACLS,MAAML,KAAKK;MACXC,OAAON,KAAKM;MACZ,GAAIN,KAAKO,YAAY3C,SAAY;QAAE2C,SAASP,KAAKO;MAAQ,IAAI,CAAC;IAChE;EACF;AACF;AAlBgBf;;;AC1EhB,IAAMgB,UAAU,IAAIC,YAAAA;AAEb,SAASC,oBAAAA;AACd,QAAMC,SAAmB,CAAA;AACzB,SAAO;IACLC,QAAQ;MACNC,OAAO,wBAACC,UAAAA;AACN,mBAAWC,QAAQP,QAAQQ,OAAOF,KAAAA,EAAOG,MAAM,IAAA,GAAO;AACpD,cAAIF,KAAKG,SAAS,GAAG;AACnBP,mBAAOQ,KAAKJ,IAAAA;UACd;QACF;MACF,GANO;MAOPK,KAAK,6BAAA;MAAO,GAAP;MACLC,MAAM,6BAAA;MAAO,GAAP;IACR;IACAV,QAAQ,6BAAMA,QAAN;EACV;AACF;AAhBgBD;AA6BT,SAASY,mBAAmBX,QAA2BY,MAAY;AACxE,QAAMC,WAAyB,CAAA;AAC/B,MAAIC,UAAU;AACd,aAAWC,SAASf,QAAQ;AAC1B,UAAMgB,QAAQC,kBAAkBF,KAAAA;AAChC,QAAIC,UAAU,QAAQA,MAAME,SAAS,QAAQ;AAG3C,UAAI,CAACJ,WAAWF,KAAKL,SAAS,GAAG;AAC/BM,iBAASL,KAAKW,kBAAkB;UAAED,MAAM;UAAQN;QAAK,CAAA,CAAA;AACrDE,kBAAU;MACZ;AACA;IACF;AACAD,aAASL,KAAKW,kBAAkBH,KAAAA,CAAAA;EAClC;AACA,MAAI,CAACF,WAAWF,KAAKL,SAAS,GAAG;AAC/BM,aAASL,KAAKW,kBAAkB;MAAED,MAAM;MAAQN;IAAK,CAAA,CAAA;EACvD;AACA,SAAOC;AACT;AApBgBF;AA0BhB,eAAsBS,mBACpBC,YACAC,QACAC,KAAqB;AAErB,MAAIC,UAAUF;AACd,aAAWG,aAAaJ,YAAY;AAClC,QAAI;AACFG,gBAAU,MAAMC,UAAUC,QAAQF,SAASD,GAAAA;IAC7C,SAASI,OAAO;AACd,YAAM,IAAIC,qBAAqB,SAASH,UAAUI,MAAMF,KAAAA;IAC1D;EACF;AACA,SAAOH;AACT;AAdsBJ;AA6BtB,eAAsBU,oBACpBT,YACAU,QACAR,KAAqB;AAErB,MAAIX,OAAOmB,OAAOnB;AAClB,aAAWa,aAAaJ,YAAY;AAClC,QAAIW;AACJ,QAAI;AACFA,gBAAU,MAAMP,UAAUC,QAAQ;QAAEd;QAAMqB,WAAWF,OAAOE;MAAU,GAAGV,GAAAA;IAC3E,SAASI,OAAO;AACd,YAAM,IAAIC,qBAAqB,UAAUH,UAAUI,MAAMF,KAAAA;IAC3D;AACA,QAAIK,QAAQE,WAAW,UAAU;AAC/B,aAAO;QAAEtB;QAAMuB,WAAW;UAAEV,WAAWA,UAAUI;UAAMO,QAAQJ,QAAQI;QAAO;MAAE;IAClF;AACA,QAAIJ,QAAQE,WAAW,WAAW;AAChCtB,aAAOoB,QAAQpB;IACjB;EACF;AACA,SAAO;IAAEA;EAAK;AAChB;AArBsBkB;AAqCtB,eAAsBO,cACpBhB,YACAiB,WACAf,KAAqB;AAErB,QAAMgB,OAAiB,CAAA;AACvB,aAAWC,YAAYF,WAAW;AAChC,UAAMG,UAAU,MAAMX,oBAAoBT,YAAY;MAAET,MAAM4B;MAAUP,WAAW,CAAA;IAAG,GAAGV,GAAAA;AACzF,QAAIkB,QAAQN,cAAcO,UAAaD,QAAQ7B,KAAKL,SAAS,GAAG;AAC9DgC,WAAK/B,KAAKiC,QAAQ7B,IAAI;IACxB;EACF;AACA,SAAO2B;AACT;AAbsBF;AA+Bf,SAASM,sBAAsBtB,YAAsC;AAC1E,MAAIA,WAAWd,WAAW,GAAG;AAC3B,WAAO;EACT;AACA,SAAOc,WAAWuB,MAAM,CAACnB,cAAcA,UAAUoB,gBAAgBH,MAAAA,IAC7D,gBACA;AACN;AAPgBC;AAiBT,SAASG,oBAAoBzB,YAAsC;AACxE,MAAI0B,WAAW;AACf,aAAWtB,aAAaJ,YAAY;AAClC,QAAII,UAAUoB,gBAAgBH,QAAW;AACvCK,iBAAWC,KAAKC,IACdF,UACAtB,UAAUoB,YAAYK,iBAAiBC,kCAAAA;IAE3C;EACF;AACA,SAAOJ;AACT;AAXgBD;AA0CT,SAASM,sBAAsBC,SAKrC;AACC,QAAM,EAAEhC,YAAYE,KAAK2B,eAAejD,OAAM,IAAKoD;AACnD,MAAIC,MAAM;AACV,MAAIzC,WAAW;AACf,MAAIsB;AAEJ,MAAIoB,UAAU;AACd,QAAMtB,YAA+B,CAAA;AAGrC,MAAIuB,QAAuBC,QAAQC,QAAO;AAE1C,iBAAeC,UAAAA;AACb,QAAIL,IAAI/C,WAAW,GAAG;AACpB;IACF;AACA,QAAIkC;AACJ,QAAI;AACFA,gBAAU,MAAMX,oBAAoBT,YAAY;QAAET,MAAM0C;QAAKrB;MAAU,GAAGV,GAAAA;IAC5E,QAAQ;AAGNgC,gBAAU;AACV;IACF;AACA,QAAId,QAAQN,cAAcO,QAAW;AACnCP,kBAAYM,QAAQN;AACpB;IACF;AAIA,UAAMyB,YAAYnB,QAAQ7B,KAAKiD,MAAM,GAAGb,KAAKC,IAAI,GAAGR,QAAQ7B,KAAKL,SAAS2C,aAAAA,CAAAA;AAC1E,QAAIU,UAAUrD,UAAUM,SAASN,UAAU,CAACqD,UAAUE,WAAWjD,QAAAA,GAAW;AAC1E;IACF;AACA,UAAMkD,QAAQH,UAAUC,MAAMhD,SAASN,MAAM;AAC7CM,eAAW+C;AACX,UAAM3D,OAAOC,MAAMiB,kBAAkB;MAAED,MAAM;MAAQN,MAAMmD;IAAM,CAAA,CAAA;EACnE;AA3BeJ;AA6Bf,iBAAeK,OAAO7D,OAAiB;AACrC,eAAWC,QAAQP,QAAQQ,OAAOF,KAAAA,EAAOG,MAAM,IAAA,GAAO;AACpD,UAAIF,KAAKG,WAAW,GAAG;AACrB;MACF;AACA,YAAMS,QAAQC,kBAAkBb,IAAAA;AAChC,UAAIY,UAAU,QAAQmB,cAAcO,QAAW;AAC7C;MACF;AACA,UAAI1B,MAAME,SAAS,QAAQ;AACzBoC,eAAOtC,MAAMJ;AACb,YAAI,CAAC2C,SAAS;AACZ,gBAAMI,QAAAA;QACR;AACA;MACF;AACA,UAAI3C,MAAME,SAAS,wBAAwB;AACzCe,kBAAUzB,KAAK;UAAEyD,IAAIjD,MAAMiD;UAAIpC,MAAMb,MAAMa;UAAMqC,OAAOlD,MAAMkD;QAAM,CAAA;MACtE;AACA,YAAMjE,OAAOC,MAAMiB,kBAAkBH,KAAAA,CAAAA;IACvC;EACF;AArBegD;AAuBf,SAAO;IACL/D,QAAQ;MACNC,OAAO,wBAACC,UAAAA;AACNqD,gBAAQA,MAAMW,KAAK,MAAMH,OAAO7D,KAAAA,CAAAA;AAChC,eAAOqD;MACT,GAHO;MAIP/C,KAAK,6BAAA;MAAO,GAAP;MACLC,MAAM,6BAAA;MAAO,GAAP;IACR;IACA+B,SAAS,6BAAMe,OAAN;IACT3C,UAAU,6BAAMA,UAAN;IACVsB,WAAW,6BAAMA,WAAN;EACb;AACF;AAlFgBiB;AA6FT,SAASgB,SACd/C,YACAR,UACAD,MAAY;AAEZ,MAAI,CAACA,KAAKkD,WAAWjD,QAAAA,GAAW;AAC9B,UAAM,IAAIe,qBACR,UACAP,WAAWgD,IAAI,CAAC5C,cAAcA,UAAUI,IAAI,EAAEyC,KAAK,UAAA,GACnD,IAAIC,MACF,+CAA+C1D,SAASN,MAAM,yMAAoM,CAAA;EAGxQ;AACA,SAAOK,KAAKiD,MAAMhD,SAASN,MAAM;AACnC;AAfgB6D;;;ACtUT,IAAMI,wBAAN,cAAoCC,MAAAA;EAd3C,OAc2CA;;;;EAEhCC;;EAEAC;;EAEAC;EAET,YAAYF,QAA2CC,MAAcC,UAAkB;AACrF,UAAMC,SACJH,OAAOI,SAAS,IACZJ,OAAOK,IAAI,CAACC,WAAUA,OAAMC,OAAO,EAAEC,KAAK,IAAA,IAC1C;AACN,UAAM,mCAAmCN,QAAAA,gBAAwBC,MAAAA,EAAQ;AACzE,SAAKM,OAAO;AACZ,SAAKT,SAASA;AACd,SAAKC,OAAOA;AACZ,SAAKC,WAAWA;EAClB;AACF;AAYO,SAASQ,YAAYT,MAAY;AACtC,QAAMU,aAAa;IAACV;IAAMA,KAAKW,MAAM,aAAA,IAAiB,CAAA;IAAIX,KAAKW,MAAM,aAAA,IAAiB,CAAA;;AACtF,aAAWC,aAAaF,YAAY;AAClC,QAAIE,cAAcC,QAAW;AAC3B;IACF;AACA,QAAI;AACF,aAAOC,KAAKC,MAAMH,SAAAA;IACpB,QAAQ;IAER;EACF;AACA,SAAOC;AACT;AAbgBJ;AAqBhB,eAAsBO,mBACpBC,QACAjB,MACAkB,UAAiB;AAEjB,QAAMN,YAAYM,aAAaL,SAAYK,WAAWT,YAAYT,IAAAA;AAClE,MAAIY,cAAcC,QAAW;AAC3B,WAAO;MAAEM,IAAI;MAAOpB,QAAQ,CAAA;IAAG;EACjC;AACA,QAAMqB,UAAS,MAAMH,OAAO,WAAA,EAAaI,SAAST,SAAAA;AAClD,SAAOQ,QAAOrB,WAAWc,SACrB;IAAEM,IAAI;IAAOpB,QAAQqB,QAAOrB;EAAO,IACnC;IAAEoB,IAAI;IAAMG,OAAOF,QAAOE;EAAM;AACtC;AAbsBN;AAoBf,IAAMO,wCACX;AAGK,SAASC,kBACdC,aACA1B,QAAyC;AAEzC,QAAMG,SACJH,OAAOI,SAAS,IACZJ,OACGK,IAAI,CAACC,WAAU,IAAIA,OAAMqB,QAAQ,CAAA,GAAInB,KAAK,GAAA,KAAQ,QAAA,KAAaF,OAAMC,OAAO,EAAE,EAC9EC,KAAK,IAAA,IACR;AACN,SAAO,GAAGkB,WAAAA;;;EAAqDvB,MAAAA;AACjE;AAXgBsB;;;AClET,IAAMG,0BAA0B;EACrC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAwBK,SAASC,gBAAgBC,UAA6B;AAC3D,SAAOA,SAASC,WAAW,CAAA;AAC7B;AAFgBF;AAKT,SAASG,gBAAgBF,UAA6B;AAC3D,SAAOA,SAASG,UAAUC,UAAaJ,SAASG,MAAME,SAAS;AACjE;AAFgBH;AAIhB,IAAMI,eAAe;AACrB,IAAMC,gBAAgB;AACtB,IAAMC,iBAAiB;AAEvB,SAASC,OAAOC,OAAa;AAC3B,QAAMC,QAAQL,aAAaM,KAAKF,KAAAA;AAChC,MAAIC,UAAU,MAAM;AAClB,WAAO;EACT;AACA,QAAM,CAAA,EAAGE,MAAMC,OAAOC,GAAAA,IAAOJ;AAC7B,QAAMK,OAAO,IAAIC,KAAKA,KAAKC,IAAIC,OAAON,IAAAA,GAAOM,OAAOL,KAAAA,IAAS,GAAGK,OAAOJ,GAAAA,CAAAA,CAAAA;AACvE,SACEC,KAAKI,eAAc,MAAOD,OAAON,IAAAA,KACjCG,KAAKK,YAAW,MAAOF,OAAOL,KAAAA,IAAS,KACvCE,KAAKM,WAAU,MAAOH,OAAOJ,GAAAA;AAEjC;AAZSN;AAcT,SAASc,UAAUb,OAAa;AAC9B,MAAI;AACF,UAAMc,MAAM,IAAIC,IAAIf,KAAAA;AACpB,WAAOc,IAAIE,aAAa,WAAWF,IAAIE,aAAa;EACtD,QAAQ;AACN,WAAO;EACT;AACF;AAPSH;AAST,SAASI,UAAUC,SAAiBlB,OAAa;AAC/C,MAAI;AACF,WAAO,IAAImB,OAAO,OAAOD,OAAAA,MAAa,GAAA,EAAKE,KAAKpB,KAAAA;EAClD,QAAQ;AAEN,WAAON;EACT;AACF;AAPSuB;AAST,SAASI,SAASC,OAAkC;AAClD,MAAI,OAAOA,UAAU,YAAYb,OAAOc,SAASD,KAAAA,GAAQ;AACvD,WAAOA;EACT;AACA,MAAI,OAAOA,UAAU,YAAYxB,eAAesB,KAAKE,MAAME,KAAI,CAAA,GAAK;AAClE,WAAOf,OAAOa,KAAAA;EAChB;AACA,SAAO5B;AACT;AARS2B;AAcF,SAASI,yBACdnC,UACAU,OAAa;AAEb,QAAMP,QAAQH,SAASG;AACvB,MAAIA,UAAUC,UAAaD,MAAME,SAAS,UAAU;AAClD,QAAIL,SAASoC,kBAAkB,MAAM;AACnC,aAAO;IACT;AACA,WAAOrC,gBAAgBC,QAAAA,EAAUqC,KAAK,CAACC,WAAWA,OAAO5B,UAAUA,KAAAA,IAC/D,OACA;EACN;AACA,UAAQP,MAAME,MAAI;IAChB,KAAK,UAAU;AACb,UAAI,CAACG,eAAesB,KAAKpB,MAAMwB,KAAI,CAAA,KAAO,CAACf,OAAOc,SAASd,OAAOT,KAAAA,CAAAA,GAAS;AACzE,eAAO;MACT;AACA,YAAM6B,SAASpB,OAAOT,KAAAA;AACtB,YAAM8B,MAAMT,SAAS5B,MAAMqC,GAAG;AAC9B,YAAMC,MAAMV,SAAS5B,MAAMsC,GAAG;AAC9B,UAAID,QAAQpC,UAAamC,SAASC,KAAK;AACrC,eAAO,oBAAoBA,GAAAA;MAC7B;AACA,UAAIC,QAAQrC,UAAamC,SAASE,KAAK;AACrC,eAAO,mBAAmBA,GAAAA;MAC5B;AACA,aAAO;IACT;IACA,KAAK;AACH,aAAO/B,UAAU,UAAUA,UAAU,UAAU,OAAO;IACxD,KAAK,QAAQ;AACX,UAAI,CAACD,OAAOC,KAAAA,GAAQ;AAClB,eAAO;MACT;AACA,UAAI,OAAOP,MAAMqC,QAAQ,YAAY/B,OAAON,MAAMqC,GAAG,KAAK9B,QAAQP,MAAMqC,KAAK;AAC3E,eAAO,uBAAuBrC,MAAMqC,GAAG;MACzC;AACA,UAAI,OAAOrC,MAAMsC,QAAQ,YAAYhC,OAAON,MAAMsC,GAAG,KAAK/B,QAAQP,MAAMsC,KAAK;AAC3E,eAAO,wBAAwBtC,MAAMsC,GAAG;MAC1C;AACA,aAAO;IACT;IACA,KAAK;AACH,UAAI,CAAClC,cAAcuB,KAAKpB,KAAAA,GAAQ;AAC9B,eAAO;MACT;AACA;IACF,KAAK;AACH,UAAI,CAACa,UAAUb,KAAAA,GAAQ;AACrB,eAAO;MACT;AACA;IACF,KAAK;IACL,KAAK,YAAY;AACf,YAAM8B,MAAMT,SAAS5B,MAAMqC,GAAG;AAC9B,YAAMC,MAAMV,SAAS5B,MAAMsC,GAAG;AAC9B,UAAID,QAAQpC,UAAaM,MAAMgC,SAASF,KAAK;AAC3C,eAAO,oBAAoBA,GAAAA;MAC7B;AACA,UAAIC,QAAQrC,UAAaM,MAAMgC,SAASD,KAAK;AAC3C,eAAO,mBAAmBA,GAAAA;MAC5B;AACA;IACF;EACF;AACA,MAAItC,MAAMyB,YAAYxB,UAAauB,UAAUxB,MAAMyB,SAASlB,KAAAA,MAAW,OAAO;AAC5E,WAAO;EACT;AACA,SAAO;AACT;AAtEgByB;AA6ET,SAASQ,0BACd3C,UACA4C,QAAyB;AAEzB,QAAMC,UAAUD,OAAOE,OAAO,CAACpC,UAAUA,UAAU,EAAA;AACnD,MAAImC,QAAQH,WAAW,GAAG;AACxB,WAAO1C,SAASG,OAAO4C,aAAa,OAAO,uBAAuB;EACpE;AACA,MAAI/C,SAASgD,aAAa,QAAQH,QAAQH,SAAS,GAAG;AACpD,WAAO;EACT;AACA,aAAWhC,SAASmC,SAAS;AAC3B,UAAMI,UAAUd,yBAAyBnC,UAAUU,KAAAA;AACnD,QAAIuC,YAAY,MAAM;AACpB,aAAOA;IACT;EACF;AACA,SAAO;AACT;AAlBgBN;AAwBT,SAASO,qBAAqBC,KAAY;AAC/C,MAAI,OAAOA,QAAQ,YAAYA,QAAQ,MAAM;AAC3C,WAAO/C;EACT;AACA,QAAMgD,YAAYD;AAClB,QAAM9C,OAAO+C,UAAU/C;AACvB,MAAI,OAAOA,SAAS,YAAY,CAAEP,wBAA8CuD,SAAShD,IAAAA,GAAO;AAC9F,WAAOD;EACT;AACA,QAAM4B,QAAQ,wBAACtB,UACZ,OAAOA,UAAU,YAAYS,OAAOc,SAASvB,KAAAA,KAAW,OAAOA,UAAU,WACrEA,QACDN,QAHQ;AAId,QAAMoC,MAAMR,MAAMoB,UAAUZ,GAAG;AAC/B,QAAMC,MAAMT,MAAMoB,UAAUX,GAAG;AAC/B,SAAO;IACLpC;IACA,GAAI,OAAO+C,UAAUE,gBAAgB,WAAW;MAAEA,aAAaF,UAAUE;IAAY,IAAI,CAAC;IAC1F,GAAIF,UAAUL,aAAa,OAAO;MAAEA,UAAU;IAAK,IAAI,CAAC;IACxD,GAAIP,QAAQpC,SAAY;MAAEoC;IAAI,IAAI,CAAC;IACnC,GAAIC,QAAQrC,SAAY;MAAEqC;IAAI,IAAI,CAAC;IACnC,GAAI,OAAOW,UAAUxB,YAAY,WAAW;MAAEA,SAASwB,UAAUxB;IAAQ,IAAI,CAAC;EAChF;AACF;AAvBgBsB;AA8BT,SAASK,yBAAyBpD,OAAc;AACrD,MAAI,OAAOA,UAAU,YAAYA,UAAU,MAAM;AAC/C,WAAO,CAAA;EACT;AACA,QAAMgD,MAAOhD,MAAkCqD;AAC/C,MAAI,CAACC,MAAMC,QAAQP,GAAAA,GAAM;AACvB,WAAO,CAAA;EACT;AACA,QAAMK,YAAmC,CAAA;AACzC,aAAWG,QAAQR,KAAK;AACtB,QAAI,OAAOQ,SAAS,YAAYA,SAAS,MAAM;AAC7C;IACF;AACA,UAAMP,YAAYO;AAClB,QAAI,OAAOP,UAAUQ,OAAO,YAAY,OAAOR,UAAUS,WAAW,UAAU;AAC5E;IACF;AACA,UAAM5D,UAA+BwD,MAAMC,QAAQN,UAAUnD,OAAO,IAChEmD,UAAUnD,QAAQ6D,QAAQ,CAACxB,WAAAA;AACzB,UAAI,OAAOA,WAAW,YAAYA,WAAW,MAAM;AACjD,eAAO,CAAA;MACT;AACA,YAAM,EAAE5B,OAAOqD,MAAK,IAAKzB;AACzB,aAAO,OAAO5B,UAAU,YAAY,OAAOqD,UAAU,WAAW;QAAC;UAAErD;UAAOqD;QAAM;UAAK,CAAA;IACvF,CAAA,IACA,CAAA;AACJ,UAAMC,QAAQd,qBAAqBE,UAAUjD,KAAK;AAClD,UAAM8D,WAAWR,MAAMC,QAAQN,UAAUa,QAAQ,IAC7Cb,UAAUa,SAASnB,OAAO,CAACpC,UAA2B,OAAOA,UAAU,QAAA,IACvE,CAAA;AACJ8C,cAAUU,KAAK;MACbN,IAAIR,UAAUQ;MACdC,QAAQT,UAAUS;MAClB5D;MACA,GAAI+D,UAAU5D,SAAY;QAAED,OAAO6D;MAAM,IAAI,CAAC;MAC9C,GAAIC,SAASvB,SAAS,IAAI;QAAEuB;MAAS,IAAI,CAAC;MAC1C,GAAIb,UAAUJ,aAAa,OAAO;QAAEA,UAAU;MAAK,IAAI,CAAC;MACxD,GAAII,UAAUhB,kBAAkB,OAAO;QAAEA,eAAe;MAAK,IAAI,CAAC;IACpE,CAAA;EACF;AACA,SAAOoB;AACT;AAzCgBD;;;AC9GT,SAASY,0BAA0BC,OAAkC;AAC1E,MAAI,OAAOA,UAAU,YAAYA,UAAU,MAAM;AAC/C,WAAO;MAAEC,SAAS,CAAC;IAAE;EACvB;AACA,QAAMC,YAAYF;AAClB,MAAI,OAAOE,UAAUD,YAAY,YAAYC,UAAUD,YAAY,MAAM;AACvE,WAAOD;EACT;AACA,QAAMG,gBAAgBD,UAAUC,iBAAiBD,UAAUE;AAC3D,QAAMC,cAAcH,UAAUG,eAAeH,UAAUI;AACvD,SAAO;IACLL,SAAS,CAAC;IACV,GAAIC,UAAUK,aAAa,SAASL,UAAUM,YAAY,OAAO;MAAEA,SAAS;IAAK,IAAI,CAAC;IACtF,GAAIL,kBAAkBM,SAAY;MAAEN;IAAc,IAAI,CAAC;IACvD,GAAIE,gBAAgBI,SAAY;MAAEJ;IAAY,IAAI,CAAC;EACrD;AACF;AAhBgBN;AA6BT,SAASW,mBACdC,SACAC,KAAgC;AAEhC,QAAMZ,QAAQD,0BAA0Ba,GAAAA;AACxC,QAAMX,UAAoC,CAAC;AAC3C,QAAMY,YAAsB,CAAA;AAC5B,aAAWC,YAAYH,QAAQI,WAAW;AACxC,UAAMC,YAAYhB,MAAMQ,YAAY,OAAOC,SAAYT,MAAMC,QAAQa,SAASG,EAAE;AAChF,QAAID,cAAcP,QAAW;AAC3BR,cAAQa,SAASG,EAAE,IAAI;WAAKH,SAASI,YAAY,CAAA;;AACjDL,gBAAUM,KAAKL,SAASG,EAAE;AAC1B;IACF;AAIA,UAAMG,QAAQJ,UAAUK,OACtB,CAACC,UAAUA,UAAU,MAAMC,yBAAyBT,UAAUQ,KAAAA,MAAW,IAAA;AAE3ErB,YAAQa,SAASG,EAAE,IAAIH,SAASU,aAAa,OAAOJ,QAAQA,MAAMK,MAAM,GAAG,CAAA;EAC7E;AACA,SAAO;IACLxB;IACAO,SAASR,MAAMQ,YAAY;IAC3BK;IACA,GAAIb,MAAMG,kBAAkBM,SAAY;MAAEiB,YAAY1B,MAAMG;IAAc,IAAI,CAAC;IAC/E,GAAIH,MAAMK,gBAAgBI,SAAY;MAAEJ,aAAaL,MAAMK;IAAY,IAAI,CAAC;EAC9E;AACF;AA7BgBK;AA0CT,SAASiB,kBACdhB,SACAX,OAAkC;AAElC,QAAM4B,UAAUlB,mBAAmBC,SAASX,KAAAA;AAC5C,SAAO;IAAE,GAAG4B;IAASC,SAASC,yBAAyBnB,SAASiB,OAAAA;EAAS;AAC3E;AANgBD;AAYT,SAASG,yBACdnB,SACAiB,SAA2B;AAE3B,QAAMG,QAAQpB,QAAQI,UAAUiB,IAAI,CAAClB,aAAAA;AACnC,UAAMmB,SAASL,QAAQ3B,QAAQa,SAASG,EAAE,KAAK,CAAA;AAC/C,UAAMiB,SAASD,OAAOD,IACpB,CAACV,UAAUa,gBAAgBrB,QAAAA,EAAUsB,KAAK,CAACC,WAAWA,OAAOf,UAAUA,KAAAA,GAAQgB,SAAShB,KAAAA;AAE1F,WAAO,GAAGR,SAASyB,MAAM,WAAML,OAAOM,SAAS,IAAIN,OAAOO,KAAK,IAAA,IAAQ,aAAA;EACzE,CAAA;AACA,QAAMC,UAAUd,QAAQpB,UACpB,+EACA;AACJ,SAAO,GAAGkC,OAAAA;EAAYX,MAAMU,KAAK,IAAA,CAAA;AACnC;AAfgBX;AAkBT,IAAMa,gBAAgB;AAStB,IAAMC,oBAAoB;AAEjC,SAASC,MAAMC,MAA2BC,SAAe;AACvD,SAAO;IAAEA;IAASD;EAAK;AACzB;AAFSD;AAIT,SAASG,YACPpC,KACAkC,MACAG,QAAgC;AAEhC,MAAI,OAAOrC,QAAQ,YAAYA,QAAQ,MAAM;AAC3CqC,WAAO9B,KAAK0B,MAAMC,MAAM,mBAAA,CAAA;AACxB,WAAOrC;EACT;AACA,QAAMP,YAAYU;AAClB,MAAI,OAAOV,UAAUoB,UAAU,YAAYpB,UAAUoB,MAAMkB,WAAW,GAAG;AACvES,WAAO9B,KAAK0B,MAAM;SAAIC;MAAM;OAAU,4BAAA,CAAA;AACtC,WAAOrC;EACT;AACA,MAAI,OAAOP,UAAUoC,UAAU,YAAYpC,UAAUoC,MAAME,WAAW,GAAG;AACvES,WAAO9B,KAAK0B,MAAM;SAAIC;MAAM;OAAU,4BAAA,CAAA;AACtC,WAAOrC;EACT;AACA,SAAO;IACLa,OAAOpB,UAAUoB;IACjBgB,OAAOpC,UAAUoC;IACjB,GAAI,OAAOpC,UAAUgD,WAAW,WAAW;MAAEA,QAAQhD,UAAUgD;IAAO,IAAI,CAAC;EAC7E;AACF;AAvBSF;AAyBT,SAASG,cACPvC,KACAkC,MACAG,QAAgC;AAEhC,MAAI,OAAOrC,QAAQ,YAAYA,QAAQ,MAAM;AAC3CqC,WAAO9B,KAAK0B,MAAMC,MAAM,mBAAA,CAAA;AACxB,WAAOrC;EACT;AACA,QAAMP,YAAYU;AAClB,MAAI,OAAOV,UAAUe,OAAO,YAAYf,UAAUe,GAAGuB,WAAW,GAAG;AACjES,WAAO9B,KAAK0B,MAAM;SAAIC;MAAM;OAAO,4BAAA,CAAA;AACnC,WAAOrC;EACT;AACA,MAAI,OAAOP,UAAUqC,WAAW,YAAYrC,UAAUqC,OAAOC,WAAW,GAAG;AACzES,WAAO9B,KAAK0B,MAAM;SAAIC;MAAM;OAAW,4BAAA,CAAA;AACvC,WAAOrC;EACT;AACA,MAAI2C;AACJ,MAAIlD,UAAUkD,UAAU3C,QAAW;AACjC2C,YAAQC,qBAAqBnD,UAAUkD,KAAK;AAC5C,QAAIA,UAAU3C,QAAW;AACvBwC,aAAO9B,KACL0B,MAAM;WAAIC;QAAM;QAAS;SAAS,kBAAkBQ,wBAAwBb,KAAK,IAAA,CAAA,EAAO,CAAA;AAE1F,aAAOhC;IACT;EACF;AACA,QAAM8C,YACJ,OAAOrD,UAAUsD,gBAAgB,YAAYtD,UAAUsD,YAAYhB,SAAS,IACxE;IAAEgB,aAAatD,UAAUsD;EAAY,IACrC,CAAC;AACP,QAAMC,QAAQL,UAAU3C,UAAa2C,MAAMM,SAAS;AACpD,MAAI,CAACD,UAAU,CAACE,MAAMC,QAAQ1D,UAAU2D,OAAO,KAAK3D,UAAU2D,QAAQrB,WAAW,IAAI;AACnFS,WAAO9B,KAAK0B,MAAM;SAAIC;MAAM;OAAY,2BAAA,CAAA;AACxC,WAAOrC;EACT;AACA,QAAMoD,UAA+B,CAAA;AACrC,aAAW,CAACC,OAAOC,SAAAA,MAAeJ,MAAMC,QAAQ1D,UAAU2D,OAAO,IAC7D3D,UAAU2D,UACV,CAAA,GACFG,QAAO,GAAI;AACX,UAAM3B,SAASW,YAAYe,WAAW;SAAIjB;MAAM;MAAWgB;OAAQb,MAAAA;AACnE,QAAIZ,WAAW5B,QAAW;AACxBoD,cAAQ1C,KAAKkB,MAAAA;IACf;EACF;AACA,MAAIoB,OAAO;AAIT,UAAM3C,WAAgC;MACpCG,IAAIf,UAAUe;MACdsB,QAAQrC,UAAUqC;MAClB,GAAGgB;MACH,GAAIM,QAAQrB,SAAS,IAAI;QAAEqB;MAAQ,IAAI,CAAC;MACxCT;MACA,GAAIlD,UAAUsB,aAAa,OAAO;QAAEA,UAAU;MAAK,IAAI,CAAC;IAC1D;AACA,UAAMyC,WAAUN,MAAMC,QAAQ1D,UAAUgB,QAAQ,IAC5ChB,UAAUgB,SAASG,OAAO,CAACC,UAA2B,OAAOA,UAAU,QAAA,IACvE,CAAA;AACJ,UAAMJ,YAAW+C,SAAQ5C,OAAO,CAACC,UAAUC,yBAAyBT,UAAUQ,KAAAA,MAAW,IAAA;AACzF,QAAI2C,SAAQzB,SAAS,KAAKtB,UAASsB,WAAW,GAAG;AAC/CS,aAAO9B,KACL0B,MAAM;WAAIC;QAAM;SAAa,iBAAkBM,MAA2BM,IAAI,SAAS,CAAA;AAEzF,aAAOjD;IACT;AACA,WAAOS,UAASsB,SAAS,IAAI;MAAE,GAAG1B;MAAUI,UAAAA;IAAS,IAAIJ;EAC3D;AAGA,MAAI,CAAC6C,MAAMC,QAAQ1D,UAAUgB,QAAQ,KAAKhB,UAAUgB,SAASsB,WAAW,GAAG;AACzES,WAAO9B,KACL0B,MACE;SAAIC;MAAM;OACV,iGAAA,CAAA;AAGJ,WAAOrC;EACT;AACA,QAAMwD,UAAU,IAAIC,IAAIL,QAAQ7B,IAAI,CAACK,WAAWA,OAAOf,KAAK,CAAA;AAC5D,QAAMJ,WAAWhB,UAAUgB,SAASG,OAClC,CAACC,UAA2B,OAAOA,UAAU,YAAY2C,QAAQE,IAAI7C,KAAAA,CAAAA;AAEvE,MAAIJ,SAASsB,WAAW,GAAG;AACzBS,WAAO9B,KACL0B,MAAM;SAAIC;MAAM;OAAa,yDAAA,CAAA;AAE/B,WAAOrC;EACT;AACA,SAAO;IACLQ,IAAIf,UAAUe;IACdsB,QAAQrC,UAAUqC;IAClB,GAAGgB;IACHM;IACA,GAAIT,UAAU3C,SAAY;MAAE2C;IAAM,IAAI,CAAC;IACvClC;IACA,GAAIhB,UAAUsB,aAAa,OAAO;MAAEA,UAAU;IAAK,IAAI,CAAC;IACxD,GAAItB,UAAUkE,kBAAkB,OAAO;MAAEA,eAAe;IAAK,IAAI,CAAC;EACpE;AACF;AAtGSjB;AAwGT,IAAMkB,kBAAkB;EACtBX,MAAM;EACNY,sBAAsB;EACtBC,YAAY;IACVC,UAAU;MACRd,MAAM;MACNF,aACE;IACJ;IACAzC,WAAW;MACT2C,MAAM;MACNe,UAAU;MACVC,UAAU9B;MACV+B,OAAO;QACLjB,MAAM;QACNY,sBAAsB;QACtBM,UAAU;UAAC;UAAM;;QACjBL,YAAY;UACVtD,IAAI;YACFyC,MAAM;YACNF,aAAa;UACf;UACAjB,QAAQ;YAAEmB,MAAM;UAAS;UACzBF,aAAa;YAAEE,MAAM;YAAUF,aAAa;UAAmC;UAC/EJ,OAAO;YACLM,MAAM;YACNY,sBAAsB;YACtBM,UAAU;cAAC;;YACXpB,aACE;YACFe,YAAY;cACVb,MAAM;gBAAEA,MAAM;gBAAUmB,MAAM;qBAAIvB;;cAAyB;cAC3DwB,aAAa;gBAAEpB,MAAM;cAAS;cAC9BkB,UAAU;gBAAElB,MAAM;cAAU;cAC5BqB,KAAK;gBACHrB,MAAM;kBAAC;kBAAU;;gBACjBF,aAAa;cACf;cACAwB,KAAK;gBACHtB,MAAM;kBAAC;kBAAU;;gBACjBF,aAAa;cACf;cACAyB,SAAS;gBAAEvB,MAAM;gBAAUF,aAAa;cAAsC;YAChF;UACF;UACAhC,UAAU;YAAEkC,MAAM;YAAWF,aAAa;UAA2C;UACrFY,eAAe;YACbV,MAAM;YACNF,aAAa;UACf;UACAtC,UAAU;YACRwC,MAAM;YACNe,UAAU;YACVE,OAAO;cAAEjB,MAAM;YAAS;YACxBF,aACE;UACJ;UACAK,SAAS;YACPH,MAAM;YACNe,UAAU;YACVE,OAAO;cACLjB,MAAM;cACNY,sBAAsB;cACtBM,UAAU;gBAAC;gBAAS;;cACpBL,YAAY;gBACVjD,OAAO;kBAAEoC,MAAM;gBAAS;gBACxBpB,OAAO;kBAAEoB,MAAM;gBAAS;gBACxBR,QAAQ;kBAAEQ,MAAM;kBAAUwB,WAAW;gBAAE;cACzC;YACF;UACF;QACF;MACF;IACF;EACF;EACAN,UAAU;IAAC;;AACb;AASO,IAAMO,iBAA0D;EACrE,aAAa;IACXC,SAAS;IACTC,QAAQ;IACRC,UAAU,wBAAChE,UAAAA;AACT,YAAM2B,SAAmC,CAAA;AACzC,UAAI,OAAO3B,UAAU,YAAYA,UAAU,MAAM;AAC/C,eAAO;UAAE2B,QAAQ;YAACJ,MAAM,CAAA,GAAI,mBAAA;;QAAsB;MACpD;AACA,YAAM3C,YAAYoB;AAClB,UAAI,CAACqC,MAAMC,QAAQ1D,UAAUa,SAAS,KAAKb,UAAUa,UAAUyB,WAAW,GAAG;AAC3E,eAAO;UAAES,QAAQ;YAACJ,MAAM;cAAC;eAAc,2BAAA;;QAA8B;MACvE;AACA,UAAI3C,UAAUa,UAAUyB,SAASI,mBAAmB;AAClD,eAAO;UACLK,QAAQ;YAACJ,MAAM;cAAC;eAAc,qBAAqBD,iBAAAA,YAA6B;;QAClF;MACF;AACA,YAAM7B,YAAmC,CAAA;AACzC,iBAAW,CAAC+C,OAAOlD,GAAAA,KAAQV,UAAUa,UAAUiD,QAAO,GAAI;AACxD,cAAMlD,WAAWqC,cAAcvC,KAAK;UAAC;UAAakD;WAAQb,MAAAA;AAC1D,YAAInC,aAAaL,QAAW;AAC1BM,oBAAUI,KAAKL,QAAAA;QACjB;MACF;AACA,UAAImC,OAAOT,SAAS,GAAG;AACrB,eAAO;UAAES;QAAO;MAClB;AACA,aAAO;QACL3B,OAAO;UACLP;UACA,GAAI,OAAOb,UAAUsE,aAAa,WAAW;YAAEA,UAAUtE,UAAUsE;UAAS,IAAI,CAAC;QACnF;MACF;IACF,GA9BU;IA+BVe,YAAY;MAAEnC,OAAO,6BAAMiB,iBAAN;IAAsB;EAC7C;AACF;AAOO,IAAMmB,uBACX;AAQK,SAASC,oBAAAA;AACd,SAAO;IACLC,MAAM/C;IACNgD,MAAM;IACNnC,aAAagC;IACbI,aAAaT;EACf;AACF;AAPgBM;AAuBT,IAAMI,0BACX;;;AC1eK,IAAMC,eAAe;AAGrB,SAASC,WAAWC,OAAY;AACrC,SAAO,SAASA,MAAMC,EAAE;AAC1B;AAFgBF;AAKT,SAASG,YAAYC,WAAiB;AAC3C,SAAO,UAAUA,SAAAA;AACnB;AAFgBD;AAgCT,IAAME,uBAAsC;EACjDC,SAAS,wBAAC,EAAEL,MAAK,MAA+B;IAC9CD,WAAWC,KAAAA;OACPA,MAAMG,cAAcG,SAAY;MAACJ,YAAYF,MAAMG,SAAS;QAAK,CAAA;IACrEL;KAHO;AAKX;AA+CO,SAASS,oBAAoBC,QAAwB;AAC1D,SAAO;IACLC,MAAM,wBAAC,EAAEC,OAAM,MAAOF,OAAOG,OAAO,CAACC,UAAUF,OAAOG,SAASD,MAAME,KAAK,CAAA,GAApE;IACNC,MAAM,wBAAC,EAAEC,MAAMF,MAAK,MAClBN,OAAOS,KAAK,CAACL,UAAUA,MAAMI,SAASA,QAAQJ,MAAME,UAAUA,KAAAA,GAAQI,QAAQ,MAD1E;EAER;AACF;AANgBX;AAcT,SAASY,uBAAuBC,WAAmC;AACxE,SAAO;IACLX,MAAM,8BAAO,EAAEC,QAAQW,IAAG,MAAE;AAC1B,YAAMC,OAAO,oBAAIC,IAAAA;AACjB,YAAMC,SAAyB,CAAA;AAC/B,iBAAWC,YAAYL,WAAW;AAChC,mBAAWM,WAAW,MAAMD,SAAShB,KAAK;UAAEC;UAAQW;QAAI,CAAA,GAAI;AAC1D,gBAAMM,MAAM,GAAGD,QAAQZ,KAAK,KAASY,QAAQV,IAAI;AACjD,cAAI,CAACM,KAAKM,IAAID,GAAAA,GAAM;AAClBL,iBAAKO,IAAIF,GAAAA;AACTH,mBAAOM,KAAKJ,OAAAA;UACd;QACF;MACF;AACA,aAAOF;IACT,GAbM;IAcNT,MAAM,8BAAO,EAAEC,MAAMF,OAAOO,IAAG,MAAE;AAC/B,iBAAWI,YAAYL,WAAW;AAChC,cAAMF,OAAO,MAAMO,SAASV,KAAK;UAAEC;UAAMF;UAAOO;QAAI,CAAA;AACpD,YAAIH,SAAS,MAAM;AACjB,iBAAOA;QACT;MACF;AACA,aAAO;IACT,GARM;EASR;AACF;AA1BgBC;AAgET,IAAMY,qBAAqB;AAmB3B,SAASC,oBACdC,WACAvB,QACAwB,YAAoBH,oBAAkB;AAEtC,QAAMI,OAAO,IAAIC,IAAI1B,OAAO2B,IAAI,CAACvB,OAAOwB,UAAU;IAACxB;IAAOwB;GAAM,CAAA;AAChE,QAAMC,SAAS,oBAAIH,IAAAA;AACnB,aAAWV,WAAWO,WAAW;AAG/B,QAAI,CAACE,KAAKP,IAAIF,QAAQZ,KAAK,GAAG;AAC5B;IACF;AACA,UAAM0B,WAAWD,OAAOE,IAAIf,QAAQV,IAAI;AACxC,QAAIwB,aAAalC,QAAW;AAC1BiC,aAAOG,IAAIhB,QAAQV,MAAM;QAACU;OAAQ;IACpC,OAAO;AACLc,eAASV,KAAKJ,OAAAA;IAChB;EACF;AACA,QAAMiB,WAAgC,CAAA;AACtC,aAAWC,cAAcL,OAAOM,OAAM,GAAI;AACxC,UAAMC,UAAU;SAAIF;MAAYG,KAC9B,CAACC,GAAGC,OAAOd,KAAKM,IAAIO,EAAElC,KAAK,KAAK,MAAMqB,KAAKM,IAAIQ,EAAEnC,KAAK,KAAK,EAAA;AAE7D,UAAMoC,SAASJ,QAAQ,CAAA;AACvB,QAAII,WAAW5C,QAAW;AACxB;IACF;AACA,UAAM6C,UAAUL,QAAQM,MAAM,CAAA,EAAGf,IAAI,CAACgB,cAAcA,UAAUvC,KAAK;AACnE6B,aAASb,KAAK;MACZd,MAAMkC,OAAOlC;MACbsC,aAAaJ,OAAOI;MACpBxC,OAAOoC,OAAOpC;MACd,GAAIqC,QAAQI,SAAS,IAAI;QAAEJ;MAAQ,IAAI,CAAC;IAC1C,CAAA;EACF;AAIAR,WAASI,KAAK,CAACC,GAAGC,MAAAA;AAChB,UAAMO,WAAWrB,KAAKM,IAAIO,EAAElC,KAAK,KAAK,MAAMqB,KAAKM,IAAIQ,EAAEnC,KAAK,KAAK;AACjE,WAAO0C,YAAY,IAAIA,UAAUC,QAAQT,EAAEhC,MAAMiC,EAAEjC,IAAI;EACzD,CAAA;AACA,SAAO;IACL0C,SAASf,SAASS,MAAM,GAAGlB,SAAAA;IAC3ByB,SAASC,KAAKC,IAAI,GAAGlB,SAASY,SAASrB,SAAAA;EACzC;AACF;AAhDgBF;AAkDhB,SAASyB,QAAQT,GAAWC,GAAS;AACnC,SAAOD,IAAIC,IAAI,KAAKD,IAAIC,IAAI,IAAI;AAClC;AAFSQ;AAKT,eAAsBK,YAAYC,QAAsB1C,KAAiB;AACvE,QAAMX,SAAS,OAAOqD,OAAOrD,UAAUN,sBAAsBC,QAAQgB,GAAAA;AACrE,QAAMY,YAAY,MAAM8B,OAAOtC,SAAShB,KAAK;IAAEC;IAAQW;EAAI,CAAA;AAC3D,SAAO;IAAEX;IAAQ,GAAGsB,oBAAoBC,WAAWvB,QAAQqD,OAAO7B,SAAS;EAAE;AAC/E;AAJsB4B;AAWf,SAASE,iBAAiBN,SAAqC;AACpE,QAAMO,QAAQP,QAAQrB,IAAI,CAAC6B,UAAAA;AACzB,UAAMf,UACJe,MAAMf,YAAY7C,SAAY,KAAK,4BAA4B4D,MAAMf,QAAQgB,KAAK,IAAA,CAAA;AACpF,WAAO,KAAKD,MAAMlD,IAAI,KAAKkD,MAAMpD,KAAK,YAAOoD,MAAMZ,WAAW,GAAGH,OAAAA;EACnE,CAAA;AACA,SAAO;;aAEIiB,eAAAA;;EAEXH,MAAME,KAAK,IAAA,CAAA;;AAEb;AAZgBH;AAeT,IAAMI,kBAAkB;AAO/B,IAAMC,oBAAoB;EACxBC,MAAM;EACNC,sBAAsB;EACtBC,UAAU;IAAC;;EACXC,YAAY;IACVzD,MAAM;MACJsD,MAAM;MACNhB,aAAa;IACf;EACF;AACF;AAEA,SAASoB,OAAMC,MAA2BC,SAAe;AACvD,SAAO;IAAEA;IAASD;EAAK;AACzB;AAFSD,OAAAA,QAAAA;AAeF,IAAMG,mBAAmB;EAC9B,aAAa;IACXC,SAAS;IACTC,QAAQ;IACRC,UAAU,wBAACC,UAAAA;AACT,UAAI,OAAOA,UAAU,YAAYA,UAAU,MAAM;AAC/C,eAAO;UAAEC,QAAQ;YAACR,OAAM,CAAA,GAAI,mBAAA;;QAAsB;MACpD;AACA,YAAMrB,YAAY4B;AAClB,UAAI,OAAO5B,UAAUrC,SAAS,YAAYqC,UAAUrC,KAAKuC,WAAW,GAAG;AACrE,eAAO;UAAE2B,QAAQ;YAACR,OAAM;cAAC;eAAS,4BAAA;;QAA+B;MACnE;AACA,aAAO;QAAEO,OAAO;UAAEjE,MAAMqC,UAAUrC;QAAK;MAAE;IAC3C,GATU;IAUVmE,YAAY;MAAEC,OAAO,6BAAMf,mBAAN;IAAwB;EAC/C;AACF;AAEO,IAAMgB,yBACX;AAOK,SAASC,sBAAAA;AACd,SAAO;IACLtE,MAAMoD;IACNmB,MAAM;IACNjC,aAAa+B;IACbG,aAAaX;EACf;AACF;AAPgBS;AAaT,SAASG,cAAc,EAC5BC,OACAC,QAAO,GACuC;AAC9C,SAAOA,UAAU;OAAID;IAAOJ,oBAAAA;MAAyBI;AACvD;AALgBD;AAqBhB,eAAsBG,UACpB7B,QACA8B,OACA7E,MACAK,KAAiB;AAEjB,QAAM6C,QAAQ2B,MAAMnC,QAAQzC,KAAK,CAACoC,cAAcA,UAAUrC,SAASA,IAAAA;AACnE,MAAIkD,UAAU5D,QAAW;AACvB,UAAMwF,YAAYD,MAAMnC,QAAQrB,IAAI,CAACgB,cAAcA,UAAUrC,IAAI,EAAEmD,KAAK,IAAA;AACxE,WAAO;MACL4B,IAAI;MACJC,OACEF,UAAUvC,WAAW,IACjB,mBAAmBvC,IAAAA,qDACnB,mBAAmBA,IAAAA,qCAAyC8E,SAAAA;IACpE;EACF;AACA,QAAM5E,OAAO,MAAM6C,OAAOtC,SAASV,KAAK;IAAEC,MAAMkD,MAAMlD;IAAMF,OAAOoD,MAAMpD;IAAOO;EAAI,CAAA;AACpF,MAAIH,SAAS,MAAM;AACjB,WAAO;MAAE6E,IAAI;MAAOC,OAAO,UAAUhF,IAAAA;IAAkD;EACzF;AACA,SAAO;IACL+E,IAAI;IACJnF,OAAO;MAAEI,MAAMkD,MAAMlD;MAAMsC,aAAaY,MAAMZ;MAAaxC,OAAOoD,MAAMpD;MAAOI;IAAK;IACpF,GAAIgD,MAAMf,YAAY7C,SAAY;MAAE6C,SAASe,MAAMf;IAAQ,IAAI,CAAC;EAClE;AACF;AA1BsByC;AA4Ef,SAASK,kBAAkBC,SAA0B;AAC1D,QAAM,EAAEpF,OAAOJ,QAAQyF,QAAQnG,MAAK,IAAKkG;AACzC,MAAI,CAACxF,OAAOG,SAASC,KAAAA,GAAQ;AAC3B,WAAO;MAAEsF,SAAS;MAAOC,QAAQ,IAAIvF,KAAAA;IAA8C;EACrF;AACA,QAAMwF,MAAMvG,WAAWC,KAAAA;AACvB,MAAIc,UAAUwF,KAAK;AACjB,WAAO;MAAEF,SAAS;IAAK;EACzB;AACA,MAAID,OAAOZ,SAAS,SAAS;AAC3B,WAAO;MACLa,SAAS;MACTC,QAAQ,uCAAuCvF,KAAAA,kCAAuCwF,GAAAA;IACxF;EACF;AACA,SAAOJ,QAAQK,aAAa,OACxB;IAAEH,SAAS;EAAK,IAChB;IAAEA,SAAS;IAAOC,QAAQ,iBAAiBvF,KAAAA;EAA2C;AAC5F;AAlBgBmF;;;AC1OT,IAAMO,uBAAuB;AAQ7B,IAAMC,yBAAyB;AAoC/B,SAASC,oBAAoB,EAClCC,SACAC,QACAC,cAAcL,sBACdM,SAAS,MAAK,GACW;AACzB,QAAMC,OAAO,IAAIC,IAAIJ,OAAOK,IAAI,CAACC,OAAOC,UAAU;IAACD;IAAOC;GAAM,CAAA;AAChE,QAAMC,QAAQ,oBAAIJ,IAAAA;AAClB,aAAWK,SAASV,SAAS;AAG3B,QAAI,CAACI,KAAKO,IAAID,MAAMH,KAAK,GAAG;AAC1B;IACF;AACA,UAAMK,WAAWH,MAAMI,IAAIH,MAAMI,GAAG;AACpC,QAAIF,aAAaG,QAAW;AAC1BN,YAAMO,IAAIN,MAAMI,KAAK;QAACJ;OAAM;IAC9B,OAAO;AACLE,eAASK,KAAKP,KAAAA;IAChB;EACF;AACA,QAAMQ,WAAgC,CAAA;AACtC,aAAWC,cAAcV,MAAMW,OAAM,GAAI;AACvC,UAAMC,UAAU;SAAIF;MAAYG,KAC9B,CAACC,GAAGC,OAAOpB,KAAKS,IAAIU,EAAEhB,KAAK,KAAK,MAAMH,KAAKS,IAAIW,EAAEjB,KAAK,KAAK,EAAA;AAE7D,UAAMkB,SAASJ,QAAQ,CAAA;AACvB,QAAII,WAAWV,QAAW;AACxB;IACF;AACA,UAAMW,YAAYL,QAAQM,MAAM,CAAA,EAAGrB,IAAI,CAACsB,YAAY;MAClDrB,OAAOqB,OAAOrB;MACdsB,MAAMD,OAAOC;MACbC,QAAQF,OAAOG,OAAOD;IACxB,EAAA;AAIA,UAAME,SAASX,QAAQY,KAAK,CAACC,cAAcA,UAAUF,WAAW,IAAA;AAChEd,aAASD,KAAK;MACZ,GAAGQ;MACH,GAAIO,SAAS;QAAEA,QAAQ;MAAK,IAAI,CAAC;MACjC,GAAIN,UAAUS,SAAS,IAAI;QAAET;MAAU,IAAI,CAAC;IAC9C,CAAA;EACF;AAiBA,QAAMU,eAAe,wBAACb,GAAsBC,OACzCpB,KAAKS,IAAIU,EAAEhB,KAAK,KAAK,MAAMH,KAAKS,IAAIW,EAAEjB,KAAK,KAAK,MACjD8B,SAAQb,EAAEc,WAAWf,EAAEe,SAAS,KAChCD,SAAQd,EAAET,KAAKU,EAAEV,GAAG,GAHD;AAIrB,QAAMyB,WAAWrB,SACdZ,IAAI,CAACI,OAAOF,WAAW;IAAEE;IAAOF;EAAM,EAAA,EACtCc,KACC,CAACC,GAAGC,MACFgB,QAAQjB,EAAEb,KAAK,IAAI8B,QAAQhB,EAAEd,KAAK,MACjCP,UAAUoB,EAAEb,MAAMsB,WAAW,OAAOT,EAAEf,QAAQgB,EAAEhB,QAAQ4B,aAAab,EAAEb,OAAOc,EAAEd,KAAK,EAAA,EAEzFiB,MAAM,GAAGzB,WAAAA,EACTI,IAAI,CAAC4B,cAAcA,UAAUxB,KAAK;AACrC,QAAM+B,gBACJvB,SAASwB,OAAO,CAAChC,UAAUA,MAAMsB,WAAW,IAAA,EAAMG,SAClDI,SAASG,OAAO,CAAChC,UAAUA,MAAMsB,WAAW,IAAA,EAAMG;AACpDI,WAASjB,KACP,CAACC,GAAGC,MACFgB,QAAQjB,CAAAA,IAAKiB,QAAQhB,CAAAA,MACpBpB,KAAKS,IAAIU,EAAEhB,KAAK,KAAK,MAAMH,KAAKS,IAAIW,EAAEjB,KAAK,KAAK,MACjD8B,SAAQd,EAAET,KAAKU,EAAEV,GAAG,CAAA;AAExB,SAAO;IACL6B,SAASJ;IACTK,SAASC,KAAKC,IAAI,GAAG5B,SAASiB,SAASjC,WAAAA;IACvCuC;EACF;AACF;AAxFgB1C;AA0FhB,SAASyC,QAAQ9B,OAAwB;AACvC,SAAOA,MAAMsB,WAAW,OAAO,IAAI;AACrC;AAFSQ;AAIT,SAASH,SAAQd,GAAWC,GAAS;AACnC,SAAOD,IAAIC,IAAI,KAAKD,IAAIC,IAAI,IAAI;AAClC;AAFSa,OAAAA,UAAAA;AAwBT,eAAsBU,cAAc,EAClCC,QACAC,KACAC,MAAK,GACc;AACnB,QAAMjD,SAAS,OAAO+C,OAAO/C,UAAUkD,sBAAsBC,QAAQH,GAAAA;AACrE,QAAM/C,cAAc8C,OAAO9C,eAAeL;AAI1C,QAAMwD,UAAUH,OAAOI,KAAAA,KAAU;AAGjC,QAAMC,SAASF,QAAQlB,SAAS,IAAIa,OAAOQ,SAASD,QAAQE,KAAKT,OAAOQ,QAAQ,IAAIzC;AACpF,QAAMf,UACJuD,WAAWxC,SACP,MAAMwC,OAAO;IAAEtD;IAAQiD,OAAOG;IAASK,OAAOxD;IAAa+C;EAAI,CAAA,IAC/D,MAAMD,OAAOQ,SAASG,KAAK;IAAE1D;IAAQgD;EAAI,CAAA;AAC/C,SAAO;IACLhD;IACA2D,UAAUL,WAAWxC;IACrB,GAAGhB,oBAAoB;MAAEC;MAASC;MAAQC;MAAaC,QAAQoD,WAAWxC;IAAU,CAAA;EACtF;AACF;AAvBsBgC;AAqDtB,IAAMc,mBACJ;AAEF,IAAMC,oBACJ;AAEF,IAAMC,kBACJ;AAEF,SAASC,cAAcC,SAAiBtB,SAAqC;AAC3E,MAAIA,QAAQR,WAAW,GAAG;AACxB,WAAO,CAAA;EACT;AACA,SAAO;IACL8B;OACGtB,QAAQuB,QAAQ,CAACxD,UAAU;MAC5B,MAAMA,MAAMH,KAAK,KAAKG,MAAMI,GAAG,KAAKJ,MAAMmB,IAAI;UAC1CnB,MAAMgB,aAAa,CAAA,GAAIpB,IACzB,CAACsB,WACC,eAAUA,OAAOrB,KAAK,KAAKqB,OAAOE,WAAW,UAAU,oBAAoB,aAAA,KAAkBF,OAAOC,IAAI,EAAE;KAE/G;;AAEL;AAdSmC;AAgBF,SAASG,iBAAiB,EAAExB,SAASyB,UAAUC,QAAO,GAAyB;AACpF,QAAMC,YAAYF,WACd;IACE,0EAA0EG,kBAAAA;MAE5E,CAAA;AACJ,QAAMC,OAAO;IACX;OACIH,UAAU;MAACN;QAAmB,CAAA;OAC/BO;;OAEAN,cACDH,kBACAlB,QAAQD,OAAO,CAAChC,UAAUA,MAAMqB,OAAOD,WAAW,OAAA,CAAA;OAEjDkC,cACDF,mBACAnB,QAAQD,OAAO,CAAChC,UAAUA,MAAMqB,OAAOD,WAAW,OAAA,CAAA;;AAGtD,SAAO;EAAa0C,KAAKC,KAAK,IAAA,CAAA;;AAChC;AArBgBN;AAwBT,IAAMI,qBAAqB;AAQlC,IAAMG,uBAAuB;EAC3BC,MAAM;EACNC,sBAAsB;EACtBC,UAAU;IAAC;IAAO;;EAClBC,YAAY;IACVhE,KAAK;MACH6D,MAAM;MACNI,aACE;IACJ;IACAC,MAAM;MACJL,MAAM;MACNI,aACE;IACJ;EACF;AACF;AAEA,SAASE,OAAMC,MAA2BC,SAAe;AACvD,SAAO;IAAEA;IAASD;EAAK;AACzB;AAFSD,OAAAA,QAAAA;AAcF,IAAMG,sBAAsB;EACjC,aAAa;IACXC,SAAS;IACTC,QAAQ;IACRC,UAAU,wBAACC,UAAAA;AACT,UAAI,OAAOA,UAAU,YAAYA,UAAU,MAAM;AAC/C,eAAO;UAAEC,QAAQ;YAACR,OAAM,CAAA,GAAI,mBAAA;;QAAsB;MACpD;AACA,YAAM/C,YAAYsD;AAClB,UAAI,OAAOtD,UAAUpB,QAAQ,YAAYoB,UAAUpB,IAAIqB,WAAW,GAAG;AACnE,eAAO;UAAEsD,QAAQ;YAACR,OAAM;cAAC;eAAQ,4BAAA;;QAA+B;MAClE;AACA,UAAI,OAAO/C,UAAU8C,SAAS,YAAY9C,UAAU8C,KAAK7C,WAAW,GAAG;AACrE,eAAO;UAAEsD,QAAQ;YAACR,OAAM;cAAC;eAAS,4BAAA;;QAA+B;MACnE;AACA,aAAO;QAAEO,OAAO;UAAE1E,KAAKoB,UAAUpB;UAAKkE,MAAM9C,UAAU8C;QAAK;MAAE;IAC/D,GAZU;IAaVU,YAAY;MAAEC,OAAO,6BAAMjB,sBAAN;IAA2B;EAClD;AACF;AAEO,IAAMkB,4BACX;AAQK,SAASC,yBAAAA;AACd,SAAO;IACLC,MAAMvB;IACNwB,MAAM;IACNhB,aAAaa;IACbI,aAAaZ;EACf;AACF;AAPgBS;AAoBT,SAASI,eAAe,EAAEC,OAAOC,QAAO,GAAuB;AACpE,SAAOA,UAAU;OAAID;IAAOL,uBAAAA;MAA4BK;AAC1D;AAFgBD;AAiDT,SAASG,mBAAmBC,SAA2B;AAC5D,QAAM,EAAE9F,OAAON,QAAQ6B,QAAQwE,MAAK,IAAKD;AACzC,MAAI,CAACpG,OAAOsG,SAAShG,KAAAA,GAAQ;AAC3B,WAAO;MAAEiG,SAAS;MAAOC,QAAQ,IAAIlG,KAAAA;IAA8C;EACrF;AACA,QAAMmG,MAAMC,WAAWL,KAAAA;AACvB,MAAI/F,UAAUmG,KAAK;AACjB,WAAO;MAAEF,SAAS;IAAK;EACzB;AACA,MAAI1E,OAAOiE,SAAS,SAAS;AAC3B,WAAO;MACLS,SAAS;MACTC,QAAQ,uCAAuClG,KAAAA,kCAAuCmG,GAAAA;IACxF;EACF;AACA,SAAOL,QAAQO,aAAa,OACxB;IAAEJ,SAAS;EAAK,IAChB;IAAEA,SAAS;IAAOC,QAAQ,eAAelG,KAAAA;EAA2C;AAC1F;AAlBgB6F;AAmCT,SAASS,oBAAoB,EAAEC,QAAAA,SAAQR,MAAK,GAAuB;AACxE,SAAOQ,QAAOvG,UAAUoG,WAAWL,KAAAA,IAC/B;IAAEE,SAAS;EAAK,IAChB;IACEA,SAAS;IACTC,QAAQ,IAAIK,QAAOvG,KAAK;EAC1B;AACN;AAPgBsG;AA+BhB,eAAsBE,YAAY,EAChC/D,QACAgE,QACAC,MACAhE,KACAiE,MAAK,GACY;AAMjB,QAAMC,QAAQnE,OAAOQ,SAAS2D,OAAO1D,KAAKT,OAAOQ,QAAQ;AACzD,MAAI2D,UAAUpG,QAAW;AACvB,WAAO;MAAEqG,IAAI;MAAOC,OAAO;IAA0C;EACvE;AACA,QAAMvG,MAAMmG,KAAKnG,IAAIwC,KAAI;AACzB,QAAMzB,OAAOoF,KAAKjC,KAAK1B,KAAI;AAC3B,MAAIxC,IAAIqB,WAAW,KAAKN,KAAKM,WAAW,GAAG;AACzC,WAAO;MAAEiF,IAAI;MAAOC,OAAO;IAAwC;EACrE;AACA,QAAMC,eAAetE,OAAOsE,gBAAgBxH;AAC5C,MAAI+B,KAAKM,SAASmF,cAAc;AAC9B,WAAO;MACLF,IAAI;MACJC,OAAO,4BAA4BC,YAAAA,yBAAqCzF,KAAKM,MAAM;IACrF;EACF;AACA,QAAM5B,QAAQoG,WAAW1D,IAAIqD,KAAK;AAClC,QAAMiB,UAAUnB,mBAAmB;IACjC7F;IACA+F,OAAOrD,IAAIqD;IACXrG,QAAQ+G,OAAO/G;IACf6B,QAAQ;MAAEiE,MAAM;MAASyB,UAAUvE,IAAIqD,MAAMmB;IAAG;EAClD,CAAA;AACA,MAAI,CAACF,QAAQf,SAAS;AACpB,WAAO;MAAEY,IAAI;MAAOC,OAAOE,QAAQd;IAAO;EAC5C;AACA,QAAMK,UAAS,MAAMK,MAAM;IACzBrG;IACAe;IACAtB;IACAwB,QAAQ;MAAED,QAAQ;MAAS4F,UAAUzE,IAAIyE;MAAUR;MAAOM,UAAUvE,IAAIqD,MAAMmB;IAAG;IACjFxE;EACF,CAAA;AACA,SAAO;IAAEmE,IAAI;IAAMN,QAAAA;EAAO;AAC5B;AA9CsBC;;;ACttBf,IAAMY,gBAAN,MAAMA;EADb,OACaA;;;EACMC,cAAc,oBAAIC,IAAAA;EAEnCC,SAASC,YAAmC;AAC1C,SAAKH,YAAYI,IAAID,WAAWE,MAAMF,UAAAA;EACxC;EAEAG,IAAID,MAA2C;AAC7C,WAAO,KAAKL,YAAYM,IAAID,IAAAA;EAC9B;EAEAE,IAAIF,MAAuB;AACzB,WAAO,KAAKL,YAAYO,IAAIF,IAAAA;EAC9B;EAEAG,OAA0B;AACxB,WAAO;SAAI,KAAKR,YAAYS,OAAM;;EACpC;AACF;;;ACAO,SAASC,uBAAuBC,OAAc;AACnD,SAAOA,iBAAiBC,SAASD,MAAME,KAAKC,YAAW,EAAGC,SAAS,qBAAA;AACrE;AAFgBL;;;ACVhB,IAAMM,sBAAsBC,uBAAOC,IAAI,6BAAA;AAahC,SAASC,oBAAoBC,OAAc;AAChD,SACE,OAAOA,UAAU,YACjBA,UAAU,QACTA,MAA8CJ,mBAAAA,MAAyB;AAE5E;AANgBG;;;ACVT,IAAME,uBACX;AAMK,IAAMC,6BAA6B;AAE1C,IAAMC,WACJ;AACF,IAAMC,UACJ;AAGK,SAASC,oBAAoBC,UAAiC;AACnE,QAAMC,MAAgB,CAAA;AACtB,aAAWC,WAAWF,UAAU;AAC9B,UAAMG,QAAQD,QAAQE,aAAa,CAAA;AACnC,QAAIF,QAAQG,SAAS,eAAeF,MAAMG,WAAW,GAAG;AACtD;IACF;AACA,UAAMC,UAAU,IAAIC,KAAKN,QAAQO,eAAe,CAAA,GAAIC,IAAI,CAACC,YAAWA,QAAOC,EAAE,CAAA;AAC7E,eAAWC,QAAQV,OAAO;AACxB,UAAI,CAACI,QAAQO,IAAID,KAAKD,EAAE,GAAG;AACzBX,YAAIc,KAAKF,KAAKD,EAAE;MAClB;IACF;EACF;AACA,SAAOX;AACT;AAfgBF;AAiBhB,SAASiB,UACPH,MACAI,SAAoC;AAEpC,QAAMC,OAAO;IAAEN,IAAIC,KAAKD;IAAIO,MAAMN,KAAKM;EAAK;AAC5C,UAAQF,SAASG,QAAAA;IACf,KAAK;IACL,KAAK;AACH,aAAO;QAAE,GAAGF;QAAMG,QAAQJ,QAAQI,UAAU;MAAK;IACnD,KAAK;AACH,aAAO;QAAE,GAAGH;QAAMG,QAAQ;QAAMC,OAAOL,QAAQK,SAAS3B;MAAqB;IAC/E,KAAK;AACH,aAAO;QAAE,GAAGuB;QAAMG,QAAQ;UAAEE,UAAU;QAAK;QAAGC,QAAQ;QAAMF,OAAOzB;MAAS;IAC9E,KAAK;AACH,aAAO;QACL,GAAGqB;QACHG,QAAQ;UAAEE,UAAU;UAAME,SAAS;QAAK;QACxCD,QAAQ;QACRC,SAAS;QACTH,OAAOxB;MACT;IACF;AACE,aAAO;QAAE,GAAGoB;QAAMG,QAAQ;QAAMC,OAAO3B;MAAqB;EAChE;AACF;AAxBSqB;AA0CF,SAASU,wBACd1B,UACA2B,WAAuC,CAAA,GAAE;AAEzC,QAAMC,QAAQ,IAAIC,IAAIF,SAASjB,IAAI,CAACO,YAAY;IAACA,QAAQL;IAAIK;GAAQ,CAAA;AACrE,SAAOjB,SAASU,IAAI,CAACR,YAAAA;AACnB,UAAMC,QAAQD,QAAQE,aAAa,CAAA;AACnC,QAAIF,QAAQG,SAAS,eAAeF,MAAMG,WAAW,GAAG;AACtD,aAAOJ;IACT;AACA,UAAM4B,UAAU5B,QAAQO,eAAe,CAAA;AACvC,UAAMF,UAAU,IAAIC,IAAIsB,QAAQpB,IAAI,CAACC,YAAWA,QAAOC,EAAE,CAAA;AACzD,UAAMmB,UAAU5B,MAAM6B,OAAO,CAACnB,SAAS,CAACN,QAAQO,IAAID,KAAKD,EAAE,CAAA;AAC3D,QAAImB,QAAQzB,WAAW,GAAG;AACxB,aAAOJ;IACT;AACA,WAAO;MACL,GAAGA;MACHO,aAAa;WAAIqB;WAAYC,QAAQrB,IAAI,CAACG,SAASG,UAAUH,MAAMe,MAAMK,IAAIpB,KAAKD,EAAE,CAAA,CAAA;;IACtF;EACF,CAAA;AACF;AArBgBc;;;ACnFT,IAAMQ,sBAAsB;AAG5B,IAAMC,yBACX;AAGK,IAAMC,wBAAwB;AA4BrC,eAAsBC,cAAcC,OAAmBC,OAAyB;AAC9E,QAAMC,UAAUD,MAAMC;AACtB,MAAIA,YAAYC,QAAW;AACzB,UAAMC,QAAQC,QACZL,MAAMM,eAAe;MACnBC,OAAON,MAAMM;MACbC,QAAQ;MACRC,WAAWP,QAAQQ;MACnBC,cAAcT,QAAQU;IACxB,CAAA,CAAA,EACAC,MAAM,MAAMV,MAAAA;EAChB;AACA,QAAMC,QAAQC,QACZL,MAAMc,yBAAyBb,MAAMM,OAAOQ,0BAAAA,CAAAA,EAC5CF,MAAM,MAAM,CAAA;AACd,MAAIZ,MAAMe,aAAab,QAAW;AAChC,UAAMc,iBAAiBjB,OAAOC,MAAMe,UAAUf,MAAMM,KAAK,EAAEM,MAAM,MAAMV,MAAAA;EACzE;AACF;AAlBsBJ;;;AC9Bf,SAASmB,oBAAoBC,OAAsB;AACxD,SAAO,OAAOA,UAAU,WACpB;IAAEC,OAAOD;IAAOE,UAAU;EAAM,IAChC;IAAED,OAAOD,MAAMC;IAAOC,UAAUF,MAAME,aAAa;EAAK;AAC9D;AAJgBH;AAsCT,SAASI,gBAAgBC,MAAsC;AACpE,SAAO;IACLF,UAAU;IACVG,QAAQ;IACRJ,OAAOG,KAAKH;IACZK,OAAOF,KAAKE;IACZC,MAAM,QAAQH,KAAKH,KAAK;EAC1B;AACF;AARgBE;AAWT,SAASK,kBAAkBJ,MAIjC;AACC,SAAO;IACLF,UAAU;IACVG,QAAQ;IACRJ,OAAOG,KAAKH;IACZK,OAAOF,KAAKE;IACZG,MAAML,KAAKK;EACb;AACF;AAZgBD;AAoBT,SAASE,kBAAkBN,MAKjC;AACC,SAAO;IACLF,UAAU;IACVG,QAAQD,KAAKC;IACbJ,OAAOG,KAAKH;IACZK,OAAOF,KAAKE;IACZ,GAAIF,KAAKO,UAAUC,SAAY;MAAED,OAAOP,KAAKO;IAAM,IAAI,CAAC;EAC1D;AACF;AAbgBD;AA+BhB,eAAsBG,0BAA0BT,MAO/C;AACC,QAAM,EAAEU,OAAOC,UAAUd,OAAOK,OAAOD,OAAM,IAAKD;AAClD,QAAMY,SAAS,MAAMF,MAAMG,UAAUF,SAASG,QAAQ;AACtD,MAAIF,WAAW,QAAQA,OAAOG,SAASC,KAAK,CAACC,YAAYA,QAAQf,UAAUA,KAAAA,GAAQ;AACjF;EACF;AACA,QAAMQ,MAAMQ,cAAc;IACxBJ,UAAUH,SAASG;IACnBK,MAAM;IACNC,SACEnB,WAAW,cACP,QAAQJ,KAAAA,gDACR,QAAQA,KAAAA,2CAAgDG,KAAKO,SAAS,eAAA;IAC5Ec,WAAWxB;IACXK;EACF,CAAA;AACA,QAAMQ,MAAMY,eAAe;IACzBC,YAAYZ,SAASY;IACrBtB,QAAQ;IACRuB,QAAQlB,kBAAkB;MACxBT;MACAK;MACAD;MACA,GAAID,KAAKO,UAAUC,SAAY;QAAED,OAAOP,KAAKO;MAAM,IAAI,CAAC;IAC1D,CAAA;EACF,CAAA;AACF;AAjCsBE;;;AC5Gf,SAASgB,kCAAkCC,SAA8BC,KAAW;AACzF,MAAI,CAACC,OAAOC,cAAcF,GAAAA,EAAM,OAAM,IAAIG,WAAW,+BAAA;AACrD,MAAI,OAAOJ,QAAQK,aAAa,YAAYL,QAAQK,SAASC,WAAW,EACtE,OAAM,IAAIC,UAAU,oCAAA;AACtB,MACE,CAACL,OAAOC,cAAcH,QAAQQ,OAAO,KACrCR,QAAQQ,WAAW,KACnB,CAACN,OAAOC,cAAcF,MAAMD,QAAQQ,OAAO,EAE3C,OAAM,IAAIJ,WAAW,oDAAA;AACzB;AAVgBL;AAYT,SAASU,kCAAkCT,SAA4BC,KAAW;AACvF,MAAI,CAACC,OAAOC,cAAcF,GAAAA,EAAM,OAAM,IAAIG,WAAW,+BAAA;AACrDM,4CAA0CV,OAAAA;AAC5C;AAHgBS;AAKT,SAASC,0CAA0CV,SAA0B;AAClF,MAAI,CAACE,OAAOS,UAAUX,QAAQY,KAAK,KAAKZ,QAAQY,QAAQ,KAAKZ,QAAQY,QAAQ,IAC3E,OAAM,IAAIR,WAAW,yCAAA;AACzB;AAHgBM;;;ACVT,SAASG,4BACdC,MACAC,KACAC,KAAyB,CAAA,GACzBC,MAAa;AAEb,MAAIH,KAAII,QAAS,QAAOJ;AACxB,QAAMK,YAAYL,KAAIK;AACtB,QAAMD,UAAiC;IACrCE,IAAI,GAAGN,KAAIM,EAAE;IACbC,YAAYP,KAAIM;IAChBE,gBAAgB;IAChBC,WAAWT,KAAIS;IACfC,UAAUV,KAAIU;IACdC,UAAUX,KAAIW;IACdC,aAAaZ,KAAIY;IACjBC,kBAAkBb,KAAIa;IACtBC,UAAUd,KAAIc;IACdC,UAAUf,KAAIe;IACdb;IACAc,WAAWf;IACX,GAAIE,SAASc,SAAY;MAAEd;IAAK,IAAI,CAAC;IACrC,GAAIE,WAAWa,WAAW,eAAeb,WAAWa,WAAW,WAC3D;MAAEC,iBAAiBd,UAAUa;IAAO,IACpC,CAAC;IACL,GAAIb,aAAae,OAAOC,OAAOhB,WAAW,QAAA,IAAY;MAAEiB,QAAQjB,UAAUiB;IAAO,IAAI,CAAC;IACtF,GAAIjB,WAAWkB,UAAUN,SACrB;MAAEM,OAAOlB,UAAUkB;IAAM,IACzBvB,KAAIwB,eAAeC,WAAWR,SAC5B;MAAEM,OAAOvB,KAAIwB,cAAcC;IAAO,IAClC,CAAC;EACT;AACA,SAAOC,uBAAuB;IAC5B,GAAG1B;IACHI;IACAuB,iBAAiB;MAAET,QAAQ;MAAWU,YAAY;MAAGC,OAAO;IAAK;EACnE,CAAA;AACF;AArCgB9B;AAsCT,SAAS+B,2BACd9B,MACA+B,SACA9B,KACA+B,OAAa;AAEbC,oCAAkCF,SAAS9B,GAAAA;AAC3C,QAAMiC,WAAWlC,KAAI2B;AACrB,MACE,CAAC3B,KAAII,WACL,CAAC8B,YACDA,SAAShB,WAAW,aACnBgB,SAASL,SAAS5B,MAAMiC,SAASL,MAAMM,UAExC,QAAO;AACT,QAAMP,aAAaM,SAASN,aAAa;AACzC,SAAOF,uBAAuB;IAC5B,GAAG1B;IACH2B,iBAAiB;MACf,GAAGO;MACHN;MACAC,OAAO;QAAEG;QAAOJ;QAAYQ,UAAUL,QAAQK;QAAUD,WAAWlC,MAAM8B,QAAQM;MAAQ;IAC3F;EACF,CAAA;AACF;AAxBgBP;AAyBT,SAASQ,gCACdtC,MACA+B,SACA9B,KAAW;AAEX,MAAI,CAACsC,OAAOC,cAAcvC,GAAAA,EAAM,OAAM,IAAIwC,WAAW,sBAAA;AACrD,MACE,OAAOV,QAAQC,UAAU,YACzB,CAACD,QAAQC,SACT,CAACO,OAAOC,cAAcT,QAAQH,UAAU,KACxCG,QAAQH,aAAa,KACrB,OAAOG,QAAQW,cAAc,YAC7B,CAACX,QAAQW,UAET,OAAM,IAAIC,UAAU,uBAAA;AACtB,QAAMT,WAAWlC,KAAI2B;AACrB,SACE3B,KAAII,SAASE,OAAOyB,QAAQW,aAC5BR,UAAUhB,WAAW,aACrBgB,SAASN,eAAeG,QAAQH,cAChCM,SAASL,OAAOG,UAAUD,QAAQC,SAClCE,SAASL,MAAMD,eAAeG,QAAQH,cACtC3B,MAAMiC,SAASL,MAAMM;AAEzB;AAxBgBG;AAyBhB,SAASM,eAAexC,SAA8B;AACpD,MAAIA,QAAQe,oBAAoB,YAC9B,QAAO,UAAU0B,KAAKC,UAAU1C,QAAQU,QAAQ,CAAA,wBAAyB+B,KAAKC,UAAU1C,QAAQG,UAAU,CAAA,KAAMa,OAAOC,OAAOjB,SAAS,QAAA,IAAY,YAAYyC,KAAKC,UAAU1C,QAAQkB,MAAM,CAAA,KAAM,EAAA;AACpM,MAAIlB,QAAQe,oBAAoB,SAC9B,QAAO,UAAU0B,KAAKC,UAAU1C,QAAQU,QAAQ,CAAA,qBAAsB+B,KAAKC,UAAU1C,QAAQG,UAAU,CAAA,MAAOsC,KAAKC,UAAU1C,QAAQmB,SAAS,kBAAA,CAAA;AAChJ,SAAO,UAAUsB,KAAKC,UAAU1C,QAAQU,QAAQ,CAAA,QAASV,QAAQW,QAAQ,cAAc8B,KAAKC,UAAU1C,QAAQG,UAAU,CAAA,0BAA2BH,QAAQmB,QAAQ,YAAYsB,KAAKC,UAAU1C,QAAQmB,KAAK,CAAA,KAAM,EAAA;AACnN;AANSqB;AAOF,SAASG,2BAA2B3C,SAA8B;AACvE,SAAO;IAAEK,WAAWL,QAAQK;IAAWC,UAAUN,QAAQM;IAAUC,UAAUP,QAAQO;EAAS;AAChG;AAFgBoC;AAIT,SAASC,0BAA0B5C,SAA8B;AACtE,SAAOwC,eAAexC,OAAAA,KAAYA,QAAQD,OAAO,QAAQ0C,KAAKC,UAAU1C,QAAQD,IAAI,CAAA,KAAM;AAC5F;AAFgB6C;;;ACjFT,SAASC,iBAAiBC,QAAe;AAC9C,SACE,OAAOA,WAAW,YAClBA,WAAW,QACX,eAAeA,UACf,OAAQA,OAA4B,WAAA,GAAcC,aAAa;AAEnE;AAPgBF;AAeT,SAASG,aAAaF,QAAmB;AAC9C,MAAI,CAACD,iBAAiBC,MAAAA,GAAS;AAC7B,WAAOA;EACT;AACA,QAAMG,WAAWH,OAAO,WAAA;AAExB,QAAMI,YAAYD,SAASE;AAC3B,MAAID,cAAcE,UAAa,OAAOF,UAAUG,UAAU,YAAY;AACpE,WAAOD;EACT;AACA,MAAI;AACF,WAAOF,UAAUG,MAAM;MAAEC,QAAQ;IAAW,CAAA;EAC9C,QAAQ;AACN,WAAOF;EACT;AACF;AAfgBJ;AAkBhB,eAAsBO,cACpBT,QACAU,OACAC,WAA8B;AAE9B,MAAIZ,iBAAiBC,MAAAA,GAAS;AAC5B,UAAMY,UAAS,MAAMZ,OAAO,WAAA,EAAaC,SAASS,KAAAA;AAClD,QAAIE,QAAOC,WAAWP,QAAW;AAC/B,aAAO;QAAEQ,IAAI;QAAOD,QAAQE,cAAcH,QAAOC,MAAM;MAAE;IAC3D;AACA,WAAO;MAAEC,IAAI;MAAMJ,OAAOE,QAAOF;IAAM;EACzC;AACA,QAAMG,SAASF,UAAUV,SAASD,QAAQU,KAAAA;AAC1C,SAAOG,OAAOG,SAAS,IAAI;IAAEF,IAAI;IAAOD;EAAO,IAAI;IAAEC,IAAI;IAAMJ;EAAM;AACvE;AAdsBD;AAsBf,SAASQ,kBACdjB,QACAU,OACAC,WAA8B;AAE9B,MAAI,CAACZ,iBAAiBC,MAAAA,GAAS;AAC7B,UAAMa,SAASF,UAAUV,SAASD,QAAQU,KAAAA;AAC1C,WAAOG,OAAOG,SAAS,IAAI;MAAEF,IAAI;MAAOD;IAAO,IAAI;MAAEC,IAAI;MAAMJ;IAAM;EACvE;AACA,QAAME,UAASZ,OAAO,WAAA,EAAaC,SAASS,KAAAA;AAC5C,MAAIE,mBAAkBM,SAAS;AAC7BN,IAAAA,QAAOO,MAAM,MAAMb,MAAAA;AACnB,WAAOA;EACT;AACA,SAAOM,QAAOC,WAAWP,SACrB;IAAEQ,IAAI;IAAOD,QAAQE,cAAcH,QAAOC,MAAM;EAAE,IAClD;IAAEC,IAAI;IAAMJ,OAAOE,QAAOF;EAAM;AACtC;AAjBgBO;AAmBhB,SAASF,cAAcF,QAAyC;AAC9D,SAAOA,OAAOO,IAAI,CAACC,YAAW;IAC5BC,OAAOD,OAAMC,QAAQ,CAAA,GAAIF,IAAI,CAACG,YAC5B,OAAOA,YAAY,YAAYA,YAAY,QAAQ,SAASA,UACvDA,QAAQC,MACRD,OAAAA;IAEPE,SAASJ,OAAMI;EACjB,EAAA;AACF;AATSV;AAYF,SAASW,aAAab,QAA6B;AACxD,SAAOA,OACJO,IACC,CAACC,WAAU,GAAGA,OAAMC,KAAKN,SAAS,IAAIW,WAAWN,OAAMC,IAAI,IAAI,QAAA,KAAaD,OAAMI,OAAO,EAAE,EAE5FG,KAAK,IAAA;AACV;AANgBF;AAQhB,SAASC,WAAWL,MAAkC;AACpD,SAAOA,KACJF,IAAI,CAACG,SAASM,UACb,OAAON,YAAY,WAAW,IAAIA,OAAAA,MAAaM,UAAU,IAAIN,UAAU,IAAIA,OAAAA,EAAS,EAErFK,KAAK,EAAA;AACV;AANSD;AAwDF,IAAMG,6BAAkD;EAC7DC,SAASC,QAAQC,OAAK;AACpB,UAAMC,SAAuB,CAAA;AAC7BC,UAAMH,QAAQC,OAAO,CAAA,GAAID,QAAQE,QAAQ,CAAA;AACzC,WAAOA;EACT;AACF;AAEA,IAAME,YAAY;AAElB,SAASC,OAAOJ,OAAc;AAC5B,MAAIA,UAAU,KAAM,QAAO;AAC3B,MAAIK,MAAMC,QAAQN,KAAAA,EAAQ,QAAO;AACjC,SAAO,OAAOA;AAChB;AAJSI;AAMT,SAASG,YAAYC,MAAcR,OAAc;AAC/C,UAAQQ,MAAAA;IACN,KAAK;AACH,aAAO,OAAOR,UAAU,YAAYS,OAAOC,UAAUV,KAAAA;IACvD,KAAK;AACH,aAAO,OAAOA,UAAU,YAAYS,OAAOE,SAASX,KAAAA;IACtD,KAAK;AACH,aAAO,OAAOA,UAAU,YAAYA,UAAU,QAAQ,CAACK,MAAMC,QAAQN,KAAAA;IACvE;AACE,aAAOI,OAAOJ,KAAAA,MAAWQ;EAC7B;AACF;AAXSD;AAaT,SAASK,WAAWC,MAAkBC,KAAW;AAC/C,MAAIA,QAAQ,IAAK,QAAOD;AACxB,MAAI,CAACC,IAAIC,WAAW,IAAA,EAAO,QAAOC;AAClC,MAAIC,UAAmBJ;AACvB,aAAWK,OAAOJ,IAAIK,MAAM,CAAA,EAAGC,MAAM,GAAA,GAAM;AACzC,UAAMC,MAAMH,IAAII,QAAQ,OAAO,GAAA,EAAKA,QAAQ,OAAO,GAAA;AACnD,QAAI,OAAOL,YAAY,YAAYA,YAAY,KAAM,QAAOD;AAC5DC,cAAWA,QAAoCI,GAAAA;EACjD;AACA,SAAO,OAAOJ,YAAY,YAAYA,YAAY,OAAQA,UAAyBD;AACrF;AAVSJ;AAYT,SAASW,UAAUC,GAAYC,GAAU;AACvC,MAAID,MAAMC,EAAG,QAAO;AACpB,MAAI,OAAOD,MAAM,YAAY,OAAOC,MAAM,YAAYD,MAAM,QAAQC,MAAM,KAAM,QAAO;AACvF,MAAIpB,MAAMC,QAAQkB,CAAAA,MAAOnB,MAAMC,QAAQmB,CAAAA,EAAI,QAAO;AAClD,QAAMC,QAAQC,OAAOC,KAAKJ,CAAAA;AAC1B,QAAMK,QAAQF,OAAOC,KAAKH,CAAAA;AAC1B,MAAIC,MAAMI,WAAWD,MAAMC,OAAQ,QAAO;AAC1C,SAAOJ,MAAMK,MAAM,CAACV,QAClBE,UAAWC,EAA8BH,GAAAA,GAAOI,EAA8BJ,GAAAA,CAAI,CAAA;AAEtF;AAVSE;AAYT,SAASrB,MACPH,QACAC,OACAgC,MACAnB,MACAZ,QACAgC,OAAa;AAEb,MAAIlC,WAAW,QAAQA,WAAWiB,OAAW;AAC7C,MAAIjB,WAAW,OAAO;AACpBE,WAAOiC,KAAK;MAAEF;MAAMG,SAAS;IAAiB,CAAA;AAC9C;EACF;AACA,MAAI,OAAOpC,WAAW,YAAYA,WAAW,KAAM;AACnD,MAAIkC,QAAQ9B,WAAW;AACrBF,WAAOiC,KAAK;MAAEF;MAAMG,SAAS;IAAuB,CAAA;AACpD;EACF;AACA,QAAMC,KAAIrC;AAEV,MAAI,OAAOqC,GAAEC,SAAS,UAAU;AAC9B,UAAMC,SAAS1B,WAAWC,MAAMuB,GAAEC,IAAI;AACtC,QAAIC,WAAWtB,QAAW;AACxBf,aAAOiC,KAAK;QAAEF;QAAMG,SAAS,6BAA6BC,GAAEC,IAAI;MAAG,CAAA;AACnE;IACF;AACAnC,UAAMoC,QAAQtC,OAAOgC,MAAMnB,MAAMZ,QAAQgC,QAAQ,CAAA;EACnD;AAEA,MAAIG,GAAE5B,SAASQ,QAAW;AACxB,UAAMuB,QAAQlC,MAAMC,QAAQ8B,GAAE5B,IAAI,IAAK4B,GAAE5B,OAAoB;MAAC4B,GAAE5B;;AAChE,QAAI,CAAC+B,MAAMC,KAAK,CAAChC,SAASD,YAAYC,MAAMR,KAAAA,CAAAA,GAAS;AACnDC,aAAOiC,KAAK;QAAEF;QAAMG,SAAS,WAAWI,MAAME,KAAK,MAAA,CAAA;MAAU,CAAA;AAC7D;IACF;EACF;AACA,MAAIpC,MAAMC,QAAQ8B,GAAEM,IAAI,KAAK,CAACN,GAAEM,KAAKF,KAAK,CAACG,WAAWpB,UAAUoB,QAAQ3C,KAAAA,CAAAA,GAAS;AAC/EC,WAAOiC,KAAK;MACVF;MACAG,SAAS,kBAAkBC,GAAEM,KAAKE,IAAI,CAACD,WAAWE,KAAKC,UAAUH,MAAAA,CAAAA,EAASF,KAAK,IAAA,CAAA;IACjF,CAAA;EACF;AACA,MAAI,WAAWL,MAAK,CAACb,UAAUa,GAAEW,OAAO/C,KAAAA,GAAQ;AAC9CC,WAAOiC,KAAK;MAAEF;MAAMG,SAAS,WAAWU,KAAKC,UAAUV,GAAEW,KAAK,CAAA;IAAI,CAAA;EACpE;AAEA,MAAI,OAAO/C,UAAU,UAAU;AAC7B,QAAI,OAAOoC,GAAEY,cAAc,YAAYhD,MAAM8B,SAASM,GAAEY,WAAW;AACjE/C,aAAOiC,KAAK;QAAEF;QAAMG,SAAS,oBAAoBC,GAAEY,SAAS;MAAc,CAAA;IAC5E;AACA,QAAI,OAAOZ,GAAEa,cAAc,YAAYjD,MAAM8B,SAASM,GAAEa,WAAW;AACjEhD,aAAOiC,KAAK;QAAEF;QAAMG,SAAS,mBAAmBC,GAAEa,SAAS;MAAc,CAAA;IAC3E;AACA,QAAI,OAAOb,GAAEc,YAAY,UAAU;AACjC,UAAIA;AACJ,UAAI;AACFA,kBAAU,IAAIC,OAAOf,GAAEc,SAAS,GAAA;MAClC,QAAQ;AACNA,kBAAUlC;MACZ;AACA,UAAIkC,YAAYlC,UAAa,CAACkC,QAAQE,KAAKpD,KAAAA,GAAQ;AACjDC,eAAOiC,KAAK;UAAEF;UAAMG,SAAS,cAAcC,GAAEc,OAAO;QAAG,CAAA;MACzD;IACF;EACF;AACA,MAAI,OAAOlD,UAAU,UAAU;AAC7B,QAAI,OAAOoC,GAAEiB,YAAY,YAAYrD,QAAQoC,GAAEiB,SAAS;AACtDpD,aAAOiC,KAAK;QAAEF;QAAMG,SAAS,cAAcC,GAAEiB,OAAO;MAAG,CAAA;IACzD;AACA,QAAI,OAAOjB,GAAEkB,YAAY,YAAYtD,QAAQoC,GAAEkB,SAAS;AACtDrD,aAAOiC,KAAK;QAAEF;QAAMG,SAAS,cAAcC,GAAEkB,OAAO;MAAG,CAAA;IACzD;EACF;AAEA,MAAIjD,MAAMC,QAAQN,KAAAA,GAAQ;AACxB,QAAI,OAAOoC,GAAEmB,aAAa,YAAYvD,MAAM8B,SAASM,GAAEmB,UAAU;AAC/DtD,aAAOiC,KAAK;QAAEF;QAAMG,SAAS,sBAAsBC,GAAEmB,QAAQ;MAAS,CAAA;IACxE;AACA,QAAI,OAAOnB,GAAEoB,aAAa,YAAYxD,MAAM8B,SAASM,GAAEoB,UAAU;AAC/DvD,aAAOiC,KAAK;QAAEF;QAAMG,SAAS,qBAAqBC,GAAEoB,QAAQ;MAAS,CAAA;IACvE;AACA,QAAIpB,GAAEqB,UAAUzC,UAAa,CAACX,MAAMC,QAAQ8B,GAAEqB,KAAK,GAAG;AACpDzD,YAAM0D,QAAQ,CAACC,MAAMC,UAAAA;AACnB1D,cAAMkC,GAAEqB,OAAOE,MAAM;aAAI3B;UAAM4B;WAAQ/C,MAAMZ,QAAQgC,QAAQ,CAAA;MAC/D,CAAA;IACF;EACF;AAEA,MAAI1B,YAAY,UAAUP,KAAAA,GAAQ;AAChC,UAAM6D,UAAS7D;AACf,UAAM8D,aACJ,OAAO1B,GAAE0B,eAAe,YAAY1B,GAAE0B,eAAe,OAChD1B,GAAE0B,aACH,CAAC;AACP,QAAIzD,MAAMC,QAAQ8B,GAAE2B,QAAQ,GAAG;AAC7B,iBAAW1C,OAAOe,GAAE2B,UAAsB;AACxC,YAAIF,QAAOxC,GAAAA,MAASL,QAAW;AAC7Bf,iBAAOiC,KAAK;YAAEF,MAAM;iBAAIA;cAAMX;;YAAMc,SAAS;UAAc,CAAA;QAC7D;MACF;IACF;AACA,eAAW,CAACd,KAAK2C,KAAAA,KAAUrC,OAAOsC,QAAQJ,OAAAA,GAAS;AACjD,UAAIxC,OAAOyC,YAAY;AACrB,YAAIE,UAAUhD,QAAW;AACvBd,gBAAM4D,WAAWzC,GAAAA,GAAM2C,OAAO;eAAIhC;YAAMX;aAAMR,MAAMZ,QAAQgC,QAAQ,CAAA;QACtE;MACF,WAAWG,GAAE8B,yBAAyB,OAAO;AAC3CjE,eAAOiC,KAAK;UAAEF,MAAM;eAAIA;YAAMX;;UAAMc,SAAS;QAA0B,CAAA;MACzE,WAAW,OAAOC,GAAE8B,yBAAyB,YAAY9B,GAAE8B,yBAAyB,MAAM;AACxFhE,cAAMkC,GAAE8B,sBAAsBF,OAAO;aAAIhC;UAAMX;WAAMR,MAAMZ,QAAQgC,QAAQ,CAAA;MAC7E;IACF;EACF;AAEA,MAAI5B,MAAMC,QAAQ8B,GAAE+B,KAAK,GAAG;AAC1B,eAAWC,OAAOhC,GAAE+B,MAAOjE,OAAMkE,KAAKpE,OAAOgC,MAAMnB,MAAMZ,QAAQgC,QAAQ,CAAA;EAC3E;AACA,MAAI5B,MAAMC,QAAQ8B,GAAEiC,KAAK,KAAKhE,MAAMC,QAAQ8B,GAAEkC,KAAK,GAAG;AACpD,UAAMC,UAAWlE,MAAMC,QAAQ8B,GAAEiC,KAAK,IAAIjC,GAAEiC,QAAQjC,GAAEkC;AACtD,UAAME,UAAUD,QAAQE,OAAO,CAACL,QAAAA;AAC9B,YAAMM,SAAuB,CAAA;AAC7BxE,YAAMkE,KAAKpE,OAAOgC,MAAMnB,MAAM6D,QAAQzC,QAAQ,CAAA;AAC9C,aAAOyC,OAAO5C,WAAW;IAC3B,CAAA,EAAGA;AACH,QAAIzB,MAAMC,QAAQ8B,GAAEiC,KAAK,IAAIG,YAAY,IAAIA,YAAY,GAAG;AAC1DvE,aAAOiC,KAAK;QACVF;QACAG,SAAS9B,MAAMC,QAAQ8B,GAAEiC,KAAK,IAC1B,qCACA;MACN,CAAA;IACF;EACF;AACA,MAAIjC,GAAEuC,QAAQ3D,QAAW;AACvB,UAAM0D,SAAuB,CAAA;AAC7BxE,UAAMkC,GAAEuC,KAAK3E,OAAOgC,MAAMnB,MAAM6D,QAAQzC,QAAQ,CAAA;AAChD,QAAIyC,OAAO5C,WAAW,GAAG;AACvB7B,aAAOiC,KAAK;QAAEF;QAAMG,SAAS;MAAsC,CAAA;IACrE;EACF;AACF;AA5ISjC;;;ACjLF,IAAM0E,iBAAiB;AAGvB,SAASC,gBACdC,YAAkC;AAElC,MAAI,CAACF,eAAeG,KAAKD,WAAWE,IAAI,GAAG;AACzC,UAAM,IAAIC,MACR,0BAA0BH,WAAWE,IAAI,uEAAuE;EAEpH;AACA,MACEF,WAAWI,YAAYC,WACtB,CAACC,OAAOC,cAAcP,WAAWI,OAAO,KAAKJ,WAAWI,WAAW,GAEpE,OAAM,IAAII,WAAW,0DAAA;AACvB,MAAIR,WAAWS,iBAAiBJ,UAAa,OAAOL,WAAWS,iBAAiB,WAC9E,OAAM,IAAIC,UAAU,wCAAA;AACtB,SAAOV;AACT;AAhBgBD;AA6DT,SAASY,cACdC,YACAC,UAA0B,CAAC,GAAC;AAE5B,QAAMC,SAAS,oBAAIC,IAAAA;AACnB,aAAWC,aAAaJ,YAAY;AAClCK,oBAAgBD,SAAAA;AAChB,QAAIF,OAAOI,IAAIF,UAAUG,IAAI,GAAG;AAC9B,YAAM,IAAIC,MAAM,qBAAqBJ,UAAUG,IAAI,mCAAmC;IACxF;AACAL,WAAOO,IAAIL,UAAUG,MAAMH,SAAAA;EAC7B;AACA,SAAOM,aAAaR,QAAQD,QAAQU,uBAAuBC,0BAAAA;AAC7D;AAbgBb;AAehB,SAASW,aACPR,QACAW,WAA8B;AAE9B,QAAMC,OAAOC,OAAOC,OAAO;OAAId,OAAOe,OAAM;GAAG;AAC/C,SAAO;IACLjB,YAAYc;IACZD;IACAK,KAAK,wBAACX,SAASL,OAAOgB,IAAIX,IAAAA,GAArB;IACLD,KAAK,wBAACC,SAASL,OAAOI,IAAIC,IAAAA,GAArB;IACLY,iBAAiB,6BAAML,KAAKM,OAAO,CAAChB,cAAcA,UAAUiB,aAAa,IAAA,GAAxD;IACjB,MAAMC,SAASlB,WAAWmB,OAAK;AAC7B,YAAMC,aAAatB,OAAOgB,IAAId,SAAAA;AAC9B,UAAIoB,eAAeC,QAAW;AAC5B,eAAO;UACLC,IAAI;UACJC,QAAQ;YAAC;cAAEC,MAAM,CAAA;cAAIC,SAAS,sBAAsBzB,SAAAA;YAAa;;QACnE;MACF;AACA,YAAM0B,UAAS,MAAMC,cACnBP,WAAWQ,eAAeR,WAAWD,OACrCA,OACAV,SAAAA;AAEF,aAAOiB;IACT;IACAG,aAAa7B,WAAWmB,OAAK;AAC3B,YAAMC,aAAatB,OAAOgB,IAAId,SAAAA;AAC9B,UAAIoB,eAAeC,QAAW;AAC5B,eAAO;UACLC,IAAI;UACJC,QAAQ;YAAC;cAAEC,MAAM,CAAA;cAAIC,SAAS,sBAAsBzB,SAAAA;YAAa;;QACnE;MACF;AACA,aAAO8B,kBAAkBV,WAAWQ,eAAeR,WAAWD,OAAOA,OAAOV,SAAAA;IAG9E;IACAsB,cAAc/B,WAAS;AACrB,YAAMoB,aAAatB,OAAOgB,IAAId,SAAAA;AAC9B,aAAOoB,eAAeC,SAClBA,SACAW,aAAaZ,WAAWQ,eAAeR,WAAWD,KAAK;IAC7D;IACAc,OAAOC,MAAI;AACT,YAAMC,OAAO,IAAIpC,IAAID,MAAAA;AACrB,iBAAWE,aAAakC,MAAM;AAC5BjC,wBAAgBD,SAAAA;AAChBmC,aAAK9B,IAAIL,UAAUG,MAAMH,SAAAA;MAC3B;AACA,aAAOM,aAAa6B,MAAM1B,SAAAA;IAC5B;EACF;AACF;AArDSH;;;AClHF,IAAM8B,uBAAuB;AAuBpC,eAAsBC,aACpBC,SACAC,MACAC,SAAqB,CAAC,GACtBC,QAA4B,UAAQ;AAEpC,QAAMC,WAAWF,OAAOE,YAAY;AACpC,QAAMC,WAAWH,OAAOG,YAAY;AACpC,QAAMC,SAAuB,CAAA;AAC7B,MAAIC,QAAQ;AAEZ,QAAMC,QAAQ,8BACZC,MACAC,MACAC,UAAAA;AAEAJ,aAAS;AACT,QAAIA,QAAQF,UAAU;AACpB,UAAIE,UAAUF,WAAW,GAAG;AAC1BC,eAAOM,KAAK;UAAEF;UAAMG,SAAS,0BAA0BR,QAAAA;QAAoB,CAAA;MAC7E;AACA,aAAOS;IACT;AACA,QAAIH,QAAQP,UAAU;AACpBE,aAAOM,KAAK;QAAEF;QAAMG,SAAS,kCAAkCT,QAAAA;MAAkB,CAAA;AACjF,aAAOU;IACT;AACA,QAAI,OAAOL,SAAS,YAAYA,SAAS,QAAQM,MAAMC,QAAQP,IAAAA,GAAO;AACpEH,aAAOM,KAAK;QAAEF;QAAMG,SAAS;MAAuD,CAAA;AACpF,aAAOC;IACT;AACA,UAAMG,UAAUR;AAChB,QAAI,OAAOQ,QAAQC,SAAS,UAAU;AACpCZ,aAAOM,KAAK;QAAEF,MAAM;aAAIA;UAAM;;QAASG,SAAS;MAA2B,CAAA;AAC3E,aAAOC;IACT;AACA,UAAMK,aAAanB,QAAQoB,IAAIH,QAAQC,IAAI;AAC3C,QAAIC,eAAeL,UAAaK,WAAWE,aAAa,MAAM;AAC5Df,aAAOM,KAAK;QACVF,MAAM;aAAIA;UAAM;;QAChBG,SAAS,sBAAsBI,QAAQC,IAAI,eAAelB,QACvDsB,gBAAe,EACfC,IAAI,CAACC,cAAcA,UAAUC,IAAI,EACjCC,KAAK,IAAA,CAAA;MACV,CAAA;AACA,aAAOZ;IACT;AACA,UAAMa,YACJxB,UAAU,UACJ,MAAMyB,cACNT,WAAWU,OACXZ,QAAQY,SAAS,CAAC,GAClB7B,QAAQ8B,SAAS,IAEnB,MAAM9B,QAAQ+B,SAASd,QAAQC,MAAMD,QAAQY,SAAS,CAAC,CAAA;AAC7D,QAAIA,QAAiC,CAAC;AACtC,QAAI,CAACF,UAAUK,IAAI;AACjB,iBAAWC,UAASN,UAAUrB,QAAQ;AACpCA,eAAOM,KAAK;UAAEF,MAAM;eAAIA;YAAM;eAAYuB,OAAMvB;;UAAOG,SAASoB,OAAMpB;QAAQ,CAAA;MAChF;IACF,OAAO;AACLgB,cAAQF,UAAUO;IACpB;AACA,UAAMC,cAAcC,2BAA2BnB,QAAQoB,QAAQ;AAC/D,QAAIF,gBAAgBrB,UAAaqB,gBAAgB,MAAM;AACrD,aAAO;QAAEjB,MAAMD,QAAQC;QAAMW;MAAM;IACrC;AACA,QAAI,CAACd,MAAMC,QAAQmB,WAAAA,GAAc;AAC/B7B,aAAOM,KAAK;QACVF,MAAM;aAAIA;UAAM;;QAChBG,SAAS;MACX,CAAA;AACA,aAAOC;IACT;AACA,QAAIqB,YAAYG,SAAS,KAAKnB,WAAWkB,aAAa,MAAM;AAC1D/B,aAAOM,KAAK;QACVF,MAAM;aAAIA;UAAM;;QAChBG,SAAS,GAAGI,QAAQC,IAAI;MAC1B,CAAA;AACA,aAAOJ;IACT;AACA,UAAMuB,WAA2B,CAAA;AACjC,eAAW,CAACE,OAAOC,KAAAA,KAAUL,YAAYM,QAAO,GAAI;AAClD,YAAMC,OAAO,MAAMlC,MAAMgC,OAAO;WAAI9B;QAAM;QAAY6B;SAAQ5B,QAAQ,CAAA;AACtE,UAAI+B,SAAS5B,QAAW;AACtBuB,iBAASzB,KAAK8B,IAAAA;MAChB;IACF;AACA,WAAOL,SAASC,SAAS,IACrB;MAAEpB,MAAMD,QAAQC;MAAMW;MAAOQ;IAAS,IACtC;MAAEnB,MAAMD,QAAQC;MAAMW;IAAM;EAClC,GAhFc;AAkFd,QAAMc,OAAO,MAAMnC,MAAMP,MAAM,CAAA,GAAI,CAAA;AACnC,SAAOK,OAAOgC,SAAS,KAAKK,SAAS7B,SACjC;IAAEkB,IAAI;IAAO1B,QAAQA,OAAOgC,SAAS,IAAIhC,SAAS;MAAC;QAAEI,MAAM,CAAA;QAAIG,SAAS;MAAa;;EAAG,IACxF;IAAEmB,IAAI;IAAME,OAAOS;EAAK;AAC9B;AAjGsB5C;AAuJtB,SAAS6C,2BAA2BC,OAAc;AAChD,MAAI,OAAOA,UAAU,SAAU,QAAOA;AACtC,QAAMC,UAAUD,MAAME,KAAI;AAC1B,MAAI,CAACD,QAAQE,WAAW,GAAA,EAAM,QAAOH;AACrC,SAAOI,iBAAiBH,OAAAA,KAAYD;AACtC;AALSD;AAWT,SAASK,iBAAiBC,MAAY;AACpC,MAAIC,QAAQ;AACZ,MAAIC,WAAW;AACf,MAAIC,UAAU;AACd,WAASC,QAAQ,GAAGA,QAAQJ,KAAKK,QAAQD,SAAS,GAAG;AACnD,UAAME,OAAON,KAAKI,KAAAA;AAClB,QAAIF,UAAU;AACZ,UAAIC,QAASA,WAAU;eACdG,SAAS,KAAMH,WAAU;eACzBG,SAAS,IAAKJ,YAAW;AAClC;IACF;AACA,QAAII,SAAS,IAAKJ,YAAW;aACpBI,SAAS,OAAOA,SAAS,IAAKL,UAAS;aACvCK,SAAS,OAAOA,SAAS,KAAK;AACrCL,eAAS;AACT,UAAIA,UAAU,GAAG;AACf,YAAI;AACF,gBAAMM,SAAkBC,KAAKC,MAAMT,KAAKU,MAAM,GAAGN,QAAQ,CAAA,CAAA;AACzD,iBAAOO,MAAMC,QAAQL,MAAAA,IAAUA,SAASM;QAC1C,QAAQ;AACN,iBAAOA;QACT;MACF;IACF;EACF;AACA,SAAOA;AACT;AA3BSd;;;AChMF,SAASe,gBACdC,SACAC,WACAC,OAA8B;AAE9B,MAAID,cAAcE,sBAAsB;AACtC,UAAMC,OAAOF,MAAME;AACnB,WAAOA,SAASC,SAAY,KAAKC,WAAWN,SAASI,IAAAA;EACvD;AACA,SAAOG,QAAQP,SAASC,WAAWC,KAAAA,KAAU;AAC/C;AAVgBH;AAgBhB,SAASQ,QACPP,SACAC,WACAC,OAA8B;AAE9B,QAAMM,aAAaR,QAAQS,IAAIR,SAAAA;AAC/B,QAAMS,WAAWF,YAAYG;AAC7B,MAAIC,SAAS;AACb,MAAIF,aAAaL,QAAW;AAC1B,QAAI;AACF,YAAMQ,OAAOH,SAASR,KAAAA;AACtB,UAAI,OAAOW,SAAS,YAAYA,KAAKC,KAAI,EAAGC,SAAS,EAAG,QAAOF;IACjE,QAAQ;AACND,eAAS;IACX;EACF;AACA,MAAIJ,YAAYQ,aAAa,QAAQ,CAACJ,OAAQ,QAAOP;AACrD,SAAOY,UAAUf,KAAAA;AACnB;AAlBSK;AAqBF,SAASD,WAAWN,SAAkBI,MAAkB;AAC7D,QAAMc,MAAgB,CAAA;AACtB,QAAMC,QAAQ,wBAACC,MAAoBC,UAAAA;AACjC,QAAIA,QAAQ,GAAI;AAChB,UAAMR,OAAON,QAAQP,SAASoB,KAAKE,MAAMF,KAAKlB,KAAK;AACnD,QAAIW,SAASR,OAAWa,KAAIK,KAAKV,IAAAA;AACjC,eAAWW,SAASJ,KAAKJ,YAAY,CAAA,EAAIG,OAAMK,OAAOH,QAAQ,CAAA;EAChE,GALc;AAMdF,QAAMf,MAAM,CAAA;AACZ,SAAOc,IAAIO,OAAO,CAACC,SAASA,KAAKZ,KAAI,EAAGC,SAAS,CAAA,EAAGY,KAAK,IAAA;AAC3D;AAVgBrB;AAYhB,SAASW,UAAUf,OAA8B;AAC/C,QAAM0B,QACJ,OAAO1B,MAAM0B,UAAU,YAAY1B,MAAM0B,MAAMb,SAAS,IAAI,IAAIb,MAAM0B,KAAK;IAAQ;AACrF,SAAO,GAAGA,KAAAA;EAAgBC,KAAKC,UAAU5B,OAAO,MAAM,CAAA,CAAA;;AACxD;AAJSe;;;AClDF,SAASc,uBAAuBC,OAAc;AACnD,MACE,CAACC,OAAOD,KAAAA,KACRE,OAAOC,KAAKH,KAAAA,EAAOI,KAAK,CAACC,QAAQA,QAAQ,YAAA,KACzC,CAACC,MAAMC,QAAQP,MAAMQ,UAAU,EAE/B,OAAM,IAAIC,UAAU,yBAAA;AACtB,QAAMC,OAAO,oBAAIC,IAAAA;AACjB,QAAMH,aAAaR,MAAMQ,WAAWI,IAAI,CAACC,cAAAA;AACvC,QACE,CAACZ,OAAOY,SAAAA,KACRX,OAAOC,KAAKU,SAAAA,EAAWT,KAAK,CAACC,QAAQA,QAAQ,UAAUA,QAAQ,SAAA,KAC/D,OAAOQ,UAAUC,SAAS,YAC1B,CAACC,eAAeC,KAAKH,UAAUC,IAAI,KACnC,CAACG,OAAOC,cAAcL,UAAUM,OAAO,KACvCF,OAAOJ,UAAUM,OAAO,KAAK,KAC7BT,KAAKU,IAAIP,UAAUC,IAAI,EAEvB,OAAM,IAAIL,UAAU,iCAAA;AACtBC,SAAKW,IAAIR,UAAUC,IAAI;AACvB,WAAO;MAAEA,MAAMD,UAAUC;MAAMK,SAASF,OAAOJ,UAAUM,OAAO;IAAE;EACpE,CAAA;AACA,SAAO;IAAEX;EAAW;AACtB;AAvBgBT;AAyBhB,SAASE,OAAOD,OAAc;AAC5B,SAAO,OAAOA,UAAU,YAAYA,UAAU,QAAQ,CAACM,MAAMC,QAAQP,KAAAA;AACvE;AAFSC;AAIF,SAASqB,iBAAiBC,SAAkBC,cAA6B;AAC9E,MAAIA,iBAAiBC,OAAW,QAAOF;AACvC,QAAMG,YAAY3B,uBAAuByB,YAAAA,EAAchB;AACvD,SAAOmB,cACLJ,QAAQf,WAAWoB,OAAO,CAACf,cACzBa,UAAUtB,KACR,CAACyB,UAAUA,MAAMf,SAASD,UAAUC,QAAQe,MAAMV,aAAaN,UAAUM,WAAW,EAAA,CAAA,GAGxF;IAAEW,qBAAqBP,QAAQQ;EAAU,CAAA;AAE7C;AAXgBT;AAyBhB,eAAsBU,kBACpBT,SACAC,cACAX,WACAoB,OACAd,SAAgB;AAEhB,QAAMe,WAAWZ,iBAAiBC,SAASC,YAAAA;AAC3C,MAAIX,cAAcsB,sBAAsB;AACtC,QAAIhB,YAAYM,UAAaN,YAAY,EAAG,OAAM,IAAIiB,MAAM,yBAAA;AAC5D,UAAMC,aAAY,MAAMC,aAAaf,SAASU,MAAMM,IAAI;AACxD,QAAI,CAACF,WAAUG,GAAI,OAAM,IAAIJ,MAAM,oBAAoBK,aAAaJ,WAAUK,MAAM,CAAA,EAAG;AACvF,UAAMhB,YAAY,wBAACiB,SACjBT,SAASd,IAAIuB,KAAKC,IAAI,MAAMD,KAAKE,YAAY,CAAA,GAAIC,MAAMpB,SAAAA,GADvC;AAElB,UAAMqB,WAAW,oBAAIC,IAAAA;AACrB,UAAMC,kBAAkB,wBAACN,SAAAA;AACvBI,eAASG,IAAIP,KAAKC,MAAMrB,QAAQ4B,IAAIR,KAAKC,IAAI,GAAGzB,WAAW,CAAA;AAC3D,iBAAWiC,SAAST,KAAKE,YAAY,CAAA,EAAII,iBAAgBG,KAAAA;IAC3D,GAHwB;AAIxBH,oBAAgBZ,WAAUrC,KAAK;AAC/B,WAAO0B,UAAUW,WAAUrC,KAAK,IAC5B;MACEqD,MAAM;MACNxC;MACAoB,OAAO;QAAEM,MAAMF,WAAUrC;MAAM;MAC/BmB,SAAS;MACTmC,cAAcC,WAAWhC,SAASc,WAAUrC,KAAK;MACjDwD,mBAAmBtD,OAAOuD,YAAYV,QAAAA;IACxC,IACA;MAAEM,MAAM;MAAQK,MAAMH,WAAWhC,SAASc,WAAUrC,KAAK;IAAE;EACjE;AACA,QAAM2D,aAAapC,QAAQ4B,IAAItC,SAAAA;AAC/B,MAAI8C,eAAelC,OAAW,OAAM,IAAIW,MAAM,yBAAyBvB,SAAAA,GAAY;AACnF,QAAM+C,iBAAiBD,WAAWxC,WAAW;AAC7C,MAAIA,YAAYM,UAAaN,YAAYyC,eACvC,OAAM,IAAIxB,MAAM,qCAAqCvB,SAAAA,GAAY;AACnE,QAAMwB,YAAY,MAAMd,QAAQsC,SAAShD,WAAWoB,KAAAA;AACpD,MAAI,CAACI,UAAUG,GAAI,OAAM,IAAIJ,MAAM,qBAAqBK,aAAaJ,UAAUK,MAAM,CAAA,EAAG;AACxF,SAAOR,SAASd,IAAIP,SAAAA,IAChB;IACEwC,MAAM;IACNxC;IACAoB,OAAOI,UAAUrC;IACjBmB,SAASyC;IACTN,cAAcQ,gBAAgBvC,SAASV,WAAWwB,UAAUrC,KAAK;EACnE,IACA;IAAEqD,MAAM;IAAQK,MAAMI,gBAAgBvC,SAASV,WAAWwB,UAAUrC,KAAK;EAAE;AACjF;AA/CsBgC;;;AClDtB,SAAS+B,UAAUC,OAAa;AAC9B,MAAI,CAACC,OAAOC,cAAcF,KAAAA,EACxB,OAAM,IAAIG,WAAW,8DAAA;AACzB;AAHSJ;AAIT,SAASK,YAAYJ,OAAc;AACjC,MAAI,OAAOA,UAAU,YAAYA,MAAMK,WAAW,EAChD,OAAM,IAAIC,UAAU,sDAAA;AACxB;AAHSF;AAIF,SAASG,+BAA+BC,OAA2B;AACxE,QAAMC,UAAU;IACd;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;AAEF,MAAIC,OAAOC,KAAKH,KAAAA,EAAOI,KAAK,CAACC,QAAQ,CAACJ,QAAQK,SAASD,GAAAA,CAAAA,EACrD,OAAM,IAAIP,UAAU,wCAAA;AACtB,aAAWO,OAAO;IAChB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAEAT,aAAYI,MAAMK,GAAAA,CAAI;AACxB,MAAIL,MAAMO,cAAc,QAAQ,OAAOP,MAAMO,cAAc,SACzD,OAAM,IAAIT,UAAU,8CAAA;AACtB,aAAWN,SAAS;IAACQ,MAAMQ;IAAIR,MAAMS;IAAUT,MAAMU;IAAUV,MAAMO;KAAY;AAC/E,QAAIf,UAAU,QAAQA,MAAMK,SAAS,IACnC,OAAM,IAAIF,WAAW,6DAAA;EACzB;AACA,MAAIK,MAAMW,mBAAmBC,QAAW;AACtChB,gBAAYI,MAAMW,cAAc;AAChC,QAAIX,MAAMW,eAAed,SAAS,IAChC,OAAM,IAAIF,WAAW,+CAAA;EACzB;AACA,MAAIO,OAAOW,OAAOb,OAAO,kBAAA,GAAqB;AAC5C,UAAMc,UAAUd,MAAMe;AACtB,QAAID,YAAY,QAAQ,OAAOA,YAAY,YAAYE,MAAMC,QAAQH,OAAAA,EACnE,OAAM,IAAIhB,UAAU,wCAAA;AACtB,UAAMoB,iBAAiB;MAAC;MAAa;MAAW;MAAa;MAAe;;AAC5E,QAAIhB,OAAOC,KAAKW,OAAAA,EAASV,KAAK,CAACC,QAAQ,CAACa,eAAeZ,SAASD,GAAAA,CAAAA,EAC9D,OAAM,IAAIP,UAAU,iCAAA;AACtBF,gBAAYkB,QAAQK,SAAS;AAC7B,QAAIjB,OAAOW,OAAOC,SAAS,gBAAA,EAAmBM,wBAAuBN,QAAQO,cAAc;AAC3F,QAAInB,OAAOW,OAAOC,SAAS,WAAA,EAAclB,aAAYkB,QAAQQ,SAAS;AACtE,QAAIpB,OAAOW,OAAOC,SAAS,SAAA,EAAYlB,aAAYkB,QAAQS,OAAO;AAClE,QAAIrB,OAAOW,OAAOC,SAAS,aAAA,GAAgB;AACzC,YAAMU,OAAOV,QAAQW;AACrB,UAAID,SAAS,QAAQ,OAAOA,SAAS,YAAYR,MAAMC,QAAQO,IAAAA,EAC7D,OAAM,IAAI1B,UAAU,mCAAA;AACtB,UAAII,OAAOW,OAAOW,MAAM,MAAA,KAAW,OAAOA,KAAKE,SAAS,SACtD,OAAM,IAAI5B,UAAU,mCAAA;IACxB;EACF;AACA,MAAIE,MAAM2B,cAAc,KAAMpC,WAAUS,MAAM2B,SAAS;AACvD/B,cAAYI,MAAM4B,cAAcC,KAAAA;AAChCjC,cAAYI,MAAM4B,cAAcE,IAAAA;AAChCC,8BAA4B/B,KAAAA;AAC9B;AAnEgBD;AAqET,SAASiC,gCAAgCC,QAA6B,CAAC,GAAC;AAC7E,QAAMC,QAAQD,MAAMC,UAAUtB,SAAY,MAAMqB,MAAMC;AACtD,MAAI,CAACzC,OAAO0C,UAAUD,KAAAA,KAAUA,QAAQ,KAAKA,QAAQ,IACnD,OAAM,IAAIvC,WAAW,yCAAA;AACvB,MACEsC,MAAMG,aAAaxB,UACnB,CAAC;IAAC;IAAW;IAAY;IAAY;IAAW;IAAcN,SAAS2B,MAAMG,QAAQ,EAErF,OAAM,IAAItC,UAAU,2CAAA;AACtB,MAAImC,MAAMI,UAAUzB,QAAW;AAC7B,UAAMyB,QAAQJ,MAAMI;AACpB,QACE,OAAOA,UAAU,YACjBA,UAAU,QACVrB,MAAMC,QAAQoB,KAAAA,KACdnC,OAAOC,KAAKkC,KAAAA,EAAOjC,KAAK,CAACC,QAAQA,QAAQ,eAAeA,QAAQ,IAAA,EAEhE,OAAM,IAAIP,UAAU,gCAAA;AACtBP,cAAU8C,MAAMC,SAAS;AACzB1C,gBAAYyC,MAAM7B,EAAE;AACpB,QAAI6B,MAAM7B,GAAGX,SAAS,IAAK,OAAM,IAAIC,UAAU,uCAAA;EACjD;AACA,SAAOoC;AACT;AAvBgBF;AA0BT,SAASD,4BAA4BvC,OAAc;AACxD,QAAM+C,YAAY,oBAAIC,IAAAA;AACtB,QAAMC,OAAO,wBAACC,SAAAA;AACZ,QAAIA,SAAS,QAAQ,OAAOA,SAAS,YAAY,OAAOA,SAAS,UAAW,QAAOA;AACnF,QAAI,OAAOA,SAAS,YAAYjD,OAAOkD,SAASD,IAAAA,EAAO,QAAOA;AAC9D,QAAI,OAAOA,SAAS,YAAYA,SAAS,QAAQH,UAAUK,IAAIF,IAAAA,EAC7D,OAAM,IAAI5C,UAAU,sDAAA;AACtB,UAAM+C,YAAY3C,OAAO4C,eAAeJ,IAAAA;AACxC,QAAI,CAAC1B,MAAMC,QAAQyB,IAAAA,KAASG,cAAc3C,OAAO2C,aAAaA,cAAc,KAC1E,OAAM,IAAI/C,UAAU,6CAAA;AACtByC,cAAUQ,IAAIL,IAAAA;AACd,UAAMM,SAAShC,MAAMC,QAAQyB,IAAAA,IACzB1B,MAAMiC,KAAKP,MAAMD,IAAAA,IACjBvC,OAAOgD,YACLhD,OAAOC,KAAKuC,IAAAA,EACTD,KAAI,EACJU,IAAI,CAAC9C,QAAQ;MAACA;MAAKoC,KAAMC,KAAiCrC,GAAAA,CAAI;KAAE,CAAA;AAEzEkC,cAAUa,OAAOV,IAAAA;AACjB,WAAOM;EACT,GAlBa;AAmBb,SAAOK,KAAKC,UAAUb,KAAKjD,KAAAA,CAAAA;AAC7B;AAtBgBuC;AAuBT,SAASwB,uBAA0B/D,OAAQ;AAChD,SAAO6D,KAAKG,MAAMzB,4BAA4BvC,KAAAA,CAAAA;AAChD;AAFgB+D;AAGT,SAASE,2BACdC,MACAC,OAA0B;AAE1B,SACED,KAAInD,cAAcoD,MAAMpD,aACxBmD,KAAIjD,aAAakD,MAAMlD,YACvBiD,KAAIhD,aAAaiD,MAAMjD;AAE3B;AATgB+C;AAUT,SAASG,sBAAsB5D,OAA6B6D,KAAW;AAC5E9D,iCAA+BC,KAAAA;AAC/BT,YAAUsE,GAAAA;AACV,SAAON,uBAAuB;IAC5B,GAAGvD;IACHoC,UAAU;IACV0B,eAAe;IACfC,WAAW;IACXzB,WAAWuB;IACXG,WAAWH;EACb,CAAA;AACF;AAXgBD;AAYT,SAASK,8BACdP,MACA1D,OAA2B;AAE3BD,iCAA+BC,KAAAA;AAC/B,QAAM,EACJoC,UAAU8B,WACVJ,eAAeK,QACfJ,WAAWK,YACX9B,WAAW+B,UACXL,WAAWM,UACXC,cAAcC,eACdC,SAASC,UACTC,iBAAiBC,WACjB,GAAGC,SAAAA,IACDnB;AACJ,SAAO3B,4BAA4B8C,QAAAA,MAAc9C,4BAA4B/B,KAAAA;AAC/E;AAjBgBiE;AAkBhB,SAASa,OACPC,QACAC,UAAwB;AAExB,SAAO;IAAED;IAAQC,UAAUzB,uBAAuByB,QAAAA;EAAU;AAC9D;AALSF;AAMF,SAASG,iCACdvB,MACAwB,SACArB,KAAW;AAEXtE,YAAUsE,GAAAA;AACV,MAAI,CAAC;IAAC;IAAY;IAAY;IAAWvD,SAAS4E,QAAQ9C,QAAQ,EAChE,OAAM,IAAItC,UAAU,sCAAA;AACtBF,cAAYsF,QAAQzE,QAAQ;AAC5Bb,cAAYsF,QAAQC,GAAG;AACvB,MAAID,QAAQE,WAAWxE,UAAa,OAAOsE,QAAQE,WAAW,SAC5D,OAAM,IAAItF,UAAU,yBAAA;AACtB,MAAIoF,QAAQG,aAAazE,UAAa,OAAOsE,QAAQG,aAAa,UAChE,OAAM,IAAIvF,UAAU,4BAAA;AACtB,MAAI4D,KAAItB,aAAa,WAAW;AAC9B,WAAO0C,OACLpB,KAAItB,aAAa8C,QAAQ9C,WACrB,cACAsB,KAAItB,aAAa,YACf,YACA,YACNsB,IAAAA;EAEJ;AACA,QAAM4B,OAAO/B,uBAAuBG,IAAAA;AACpC,MAAIA,KAAI/B,cAAc,QAAQkC,OAAOH,KAAI/B,WAAW;AAClD2D,SAAKlD,WAAW;AAChBkD,SAAKxB,gBAAgB;MAAErD,UAAU;MAAU0E,KAAK;MAAUI,IAAI1B;IAAI;AAClEyB,SAAKtB,YAAYH;AACjB,WAAOiB,OACLI,QAAQ9C,aAAa,YAAY,YAAY,WAC7CoD,4BAA4BF,MAAMzB,GAAAA,CAAAA;EAEtC;AACA,MAAIqB,QAAQ9C,aAAa,UAAW,QAAO0C,OAAO,YAAYpB,IAAAA;AAC9D,QAAM,EAAEtB,UAAU,GAAGqD,MAAAA,IAAUP;AAC/BI,OAAKlD,WAAWA;AAChBkD,OAAKxB,gBAAgB;IACnBrD,UAAUgF,MAAMhF;IAChB0E,KAAKM,MAAMN;IACXI,IAAI1B;IACJ,GAAI4B,MAAML,WAAWxE,SAAY,CAAC,IAAI;MAAEwE,QAAQK,MAAML;IAAO;IAC7D,GAAIK,MAAMJ,aAAazE,SAAY,CAAC,IAAI;MAAEyE,UAAUI,MAAMJ;IAAS;EACrE;AACAC,OAAKtB,YAAYH;AACjB,MAAIzB,aAAa,WAAYkD,MAAKvB,YAAY;IAAEgB,QAAQ;IAAUW,YAAY;IAAGC,OAAO;EAAK;AAC7F,SAAOb,OAAO,WAAW1C,aAAa,aAAakD,OAAOE,4BAA4BF,MAAMzB,GAAAA,CAAAA;AAC9F;AA/CgBoB;AAgDhB,SAASW,aAAaC,SAAiBhC,KAAW;AAChDtE,YAAUsE,GAAAA;AACV,MAAI,CAACpE,OAAOC,cAAcmG,OAAAA,KAAYA,WAAW,KAAK,CAACpG,OAAOC,cAAcmE,MAAMgC,OAAAA,EAChF,OAAM,IAAIlG,WAAW,qCAAA;AACzB;AAJSiG;AAKF,SAASE,8BACdpC,MACAwB,SACArB,KACAkC,OAAa;AAEbH,eAAaV,QAAQW,SAAShC,GAAAA;AAC9BjE,cAAYsF,QAAQc,QAAQ;AAC5BpG,cAAYmG,KAAAA;AACZ,QAAMhC,YAAYL,KAAIK;AACtB,MACEL,KAAItB,aAAa,cACjB,CAAC2B,aACAA,UAAUgB,WAAW,YACpB,EAAEhB,UAAUgB,WAAW,eAAehB,UAAU4B,SAAS9B,OAAOE,UAAU4B,MAAMhE,WAElF,QAAOmD,OAAO,YAAYpB,IAAAA;AAC5B,QAAM4B,OAAO/B,uBAAuBG,IAAAA;AACpC,QAAMgC,aAAa3B,UAAU2B,aAAa;AAC1CJ,OAAKvB,YAAY;IACfgB,QAAQ;IACRW;IACAC,OAAO;MAAEI;MAAOL;MAAYM,UAAUd,QAAQc;MAAUrE,WAAWkC,MAAMqB,QAAQW;IAAQ;EAC3F;AACAP,OAAKtB,YAAYH;AACjB,SAAOiB,OAAO,WAAWQ,IAAAA;AAC3B;AA1BgBQ;AA2BhB,SAASG,YACPvC,MACAwB,SACArB,KAAW;AAEXtE,YAAUsE,GAAAA;AACVjE,cAAYsF,QAAQa,KAAK;AACzB,MAAI,CAACtG,OAAOC,cAAcwF,QAAQQ,UAAU,KAAKR,QAAQQ,aAAa,EACpE,OAAM,IAAI/F,WAAW,0BAAA;AACvB,QAAMuG,OAAOxC,KAAIK;AACjB,MACEL,KAAItB,aAAa,cACjB8D,MAAMnB,WAAW,eACjB,CAACmB,KAAKP,SACNO,KAAKR,eAAeR,QAAQQ,cAC5BQ,KAAKP,MAAMD,eAAeR,QAAQQ,cAClCQ,KAAKP,MAAMI,UAAUb,QAAQa,MAE7B,QAAO;AACT,SAAOlC,OAAOqC,KAAKP,MAAMhE,YAAY,YAAY;AACnD;AApBSsE;AAqBF,SAASE,8BACdzC,MACAwB,SACArB,KAAW;AAEX+B,eAAaV,QAAQW,SAAShC,GAAAA;AAC9B,QAAMkB,SAASkB,YAAYvC,MAAKwB,SAASrB,GAAAA;AACzC,MAAIkB,WAAW,QAAS,QAAOD,OAAOC,QAAQrB,IAAAA;AAC9C,QAAM4B,OAAO/B,uBAAuBG,IAAAA;AACpC,MAAI4B,KAAKvB,WAAW4B,MAClBL,MAAKvB,UAAU4B,MAAMhE,YAAYyE,KAAKC,IACpCf,KAAKvB,UAAU4B,MAAMhE,WACrBkC,MAAMqB,QAAQW,OAAO;AAEzBP,OAAKtB,YAAYH;AACjB,SAAOiB,OAAO,WAAWQ,IAAAA;AAC3B;AAhBgBa;AAiBT,SAASG,mCACd5C,MACAwB,SACArB,KAAW;AAEXtE,YAAUsE,GAAAA;AACV,MAAIqB,QAAQH,WAAW,eAAeG,QAAQH,WAAW,SACvD,OAAM,IAAIjF,UAAU,+BAAA;AACtB,MACGoF,QAAQH,WAAW,eAAeG,QAAQqB,UAAU3F,UACpDsE,QAAQH,WAAW,aACjB,OAAOG,QAAQqB,UAAU,YAAYrB,QAAQJ,WAAWlE,QAE3D,OAAM,IAAId,UAAU,sCAAA;AACtB,QAAMiF,SAASkB,YAAYvC,MAAKwB,SAASrB,GAAAA;AACzC,MAAIkB,WAAW,QAAS,QAAOD,OAAOC,QAAQrB,IAAAA;AAC9C,QAAM4B,OAAO/B,uBAAuBG,IAAAA;AACpC4B,OAAKvB,YACHmB,QAAQH,WAAW,cACf;IACEA,QAAQ;IACRW,YAAYR,QAAQQ;IACpBC,OAAO;IACP,GAAIT,QAAQJ,WAAWlE,SAAY,CAAC,IAAI;MAAEkE,QAAQI,QAAQJ;IAAO;EACnE,IACA;IAAEC,QAAQ;IAAUW,YAAYR,QAAQQ;IAAYC,OAAO;IAAMY,OAAOrB,QAAQqB;EAAM;AAC5F,MAAIrB,QAAQsB,OAAO5F,OAAWmB,6BAA4BmD,QAAQsB,EAAE;AACpE,MAAItB,QAAQuB,SAAS7F,UAAa,OAAOsE,QAAQuB,SAAS,SACxD,OAAM,IAAI3G,UAAU,+BAAA;AACtBwF,OAAKtB,YAAYH;AACjB,SAAOiB,OAAO,WAAWU,4BAA4BF,MAAMzB,KAAKqB,QAAQsB,IAAItB,QAAQuB,IAAI,CAAA;AAC1F;AA/BgBH;AAkCT,SAASI,qCACdhD,MACAiD,aACAzB,SACArB,KAAW;AAEXtE,YAAUsE,GAAAA;AACVjE,cAAYsF,QAAQ0B,qBAAqB;AACzChH,cAAYsF,QAAQzE,QAAQ;AAC5Bb,cAAYsF,QAAQC,GAAG;AACvB,MACEwB,YAAYnG,OAAO0E,QAAQ0B,yBAC3BlD,KAAIlD,OAAOmG,YAAYnG,MACvB,CAACiD,2BAA2BC,MAAKiD,WAAAA,KACjCjD,KAAImD,aAAaF,YAAYE,YAC7B,CAACnD,KAAI/C,kBACL+C,KAAI/C,mBAAmBgG,YAAYhG,eAEnC,QAAOmE,OAAO,YAAYpB,IAAAA;AAC5B,MAAIA,KAAItB,aAAa,aACnB,QAAO0C,OAAOpB,KAAIa,iBAAiBoC,YAAYnG,KAAK,cAAc,YAAYkD,IAAAA;AAChF,MAAIA,KAAItB,aAAa,UAAW,QAAO0C,OAAO,YAAYpB,IAAAA;AAC1D,MAAIA,KAAI/B,cAAc,QAAQkC,OAAOH,KAAI/B,UACvC,QAAO;IACL,GAAGsD,iCACDvB,MACA;MAAEtB,UAAU;MAAW3B,UAAU;MAAU0E,KAAK;IAAS,GACzDtB,GAAAA;IAEFkB,QAAQ;EACV;AACF,QAAMO,OAAO/B,uBAAuB;IAClC,GAAGG;IACHtB,UAAU;IACVmC,cAAcoC,YAAYnG;IAC1BsD,eAAe;MACbrD,UAAUyE,QAAQzE;MAClB0E,KAAKD,QAAQC;MACbyB,uBAAuBD,YAAYnG;MACnC+E,IAAI1B;IACN;IACAG,WAAWH;EACb,CAAA;AACA,SAAOiB,OAAO,WAAWU,4BAA4BF,MAAMzB,GAAAA,CAAAA;AAC7D;AA5CgB6C;;;ACvUhB,IAAMI,MAAM,wBAACC,aAAsBC,QAAoB,CAAC,OAAmB;EACzEC,MAAM;EACN,GAAIF,gBAAgBG,SAAY;IAAEH;EAAY,IAAI,CAAC;EACnD,GAAGC;AACL,IAJY;AAKZ,IAAMG,MAAM,wBAACC,YAAwCC,WAAqB,CAAA,OAAoB;EAC5FJ,MAAM;EACNG;EACAC;EACAC,sBAAsB;AACxB,IALY;AAMZ,IAAMC,MAAM,wBAACC,OAAmBR,QAAoB,CAAC,OAAmB;EACtEC,MAAM;EACNO;EACA,GAAGR;AACL,IAJY;AAKZ,IAAMS,OAAmB;EAAER,MAAM;IAAC;IAAU;IAAU;IAAW;;AAAQ;AACzE,IAAMS,MAAkB;EAAET,MAAM;EAAUK,sBAAsBG;AAAK;AAErE,IAAME,IAAI,wBAACC,UAA4BA,UAAU,QAAQA,UAAUV,SAAY,KAAKW,OAAOD,KAAAA,GAAjF;AACV,IAAME,UAAU,wBAACC,UAA0BA,MAAMC,QAAQ,IAAIL,EAAEI,MAAMC,KAAK,CAAA;IAAS,IAAnE;AAGT,SAASC,UACdC,SACAC,MACAC,MAAM,IAAE;AAER,QAAMC,QAAQF,KAAKG,MAAM,GAAGF,GAAAA;AAC5B,QAAMG,SAASL,QAAQM,IAAI,CAACC,WAC1BC,KAAKC,IAAI,IAAID,KAAKN,IAAIK,OAAOG,MAAMC,QAAM,GAAKR,MAAMG,IAAI,CAACM,MAAMnB,EAAEmB,EAAEL,OAAOM,GAAG,CAAC,EAAEF,MAAM,CAAA,CAAA,CAAA;AAExF,QAAMG,SAAS,wBAACC,WACdA,OACGT,IAAI,CAACZ,OAAOsB,UAAUtB,MAAMU,MAAM,GAAGC,OAAOW,KAAAA,CAAM,EAAEC,OAAOZ,OAAOW,KAAAA,KAAU,CAAA,CAAA,EAC5EE,KAAK,IAAA,GAHK;AAIf,QAAMC,QAAQ;IACZL,OAAOd,QAAQM,IAAI,CAACC,WAAWA,OAAOG,KAAK,CAAA;IAC3CL,OAAOC,IAAI,CAACc,UAAU,IAAIC,OAAOD,KAAAA,CAAAA,EAAQF,KAAK,IAAA;OAC3Cf,MAAMG,IAAI,CAACM,MAAME,OAAOd,QAAQM,IAAI,CAACC,WAAWd,EAAEmB,EAAEL,OAAOM,GAAG,CAAC,CAAA,CAAA,CAAA;;AAEpE,MAAIZ,KAAKU,SAAST,IAAKiB,OAAMG,KAAK,UAAKrB,KAAKU,SAAST,GAAAA,YAAe;AACpE,SAAO;EAAWiB,MAAMD,KAAK,IAAA,CAAA;;AAC/B;AApBgBnB;AA4BT,SAASwB,SAASC,QAAgBC,OAAa;AACpD,QAAMC,IAAIF,OAAOG,MAAM,IAAA;AACvB,QAAMC,IAAIH,MAAME,MAAM,IAAA;AACtB,MAAID,EAAEf,SAASiB,EAAEjB,SAAS,MAAS;AACjC,WAAO;SACFe,EAAEpB,IAAI,CAACuB,UAAU;QAAEC,IAAI;QAAgBD;MAAK,EAAA;SAC5CD,EAAEtB,IAAI,CAACuB,UAAU;QAAEC,IAAI;QAAgBD;MAAK,EAAA;;EAEnD;AACA,QAAME,KAAiBC,MAAMC,KAAK;IAAEtB,QAAQe,EAAEf,SAAS;EAAE,GAAG,MAC1D,IAAIqB,MAAcJ,EAAEjB,SAAS,CAAA,EAAGuB,KAAK,CAAA,CAAA;AAEvC,QAAMC,KAAK,wBAACC,IAAWC,OAAsBN,GAAGK,EAAAA,IAAKC,EAAAA,KAAM,GAAhD;AACX,WAASD,KAAIV,EAAEf,SAAS,GAAGyB,MAAK,GAAGA,MAAK;AACtC,aAASC,KAAIT,EAAEjB,SAAS,GAAG0B,MAAK,GAAGA,MAAK;AACrCN,SAAGK,EAAAA,EAAgBC,EAAAA,IAClBX,EAAEU,EAAAA,MAAOR,EAAES,EAAAA,IAAKF,GAAGC,KAAI,GAAGC,KAAI,CAAA,IAAK,IAAI7B,KAAKN,IAAIiC,GAAGC,KAAI,GAAGC,EAAAA,GAAIF,GAAGC,IAAGC,KAAI,CAAA,CAAA;IAC5E;EACF;AACA,QAAMC,MAAkB,CAAA;AACxB,MAAIF,IAAI;AACR,MAAIC,IAAI;AACR,SAAOD,IAAIV,EAAEf,UAAU0B,IAAIT,EAAEjB,QAAQ;AACnC,QAAIe,EAAEU,CAAAA,MAAOR,EAAES,CAAAA,GAAI;AACjBC,UAAIhB,KAAK;QAAEQ,IAAI;QAAQD,MAAMH,EAAEU,CAAAA;MAAa,CAAA;AAC5CA;AACAC;IACF,WAAWF,GAAGC,IAAI,GAAGC,CAAAA,KAAMF,GAAGC,GAAGC,IAAI,CAAA,GAAI;AACvCC,UAAIhB,KAAK;QAAEQ,IAAI;QAAOD,MAAMH,EAAEU,GAAAA;MAAe,CAAA;IAC/C,OAAO;AACLE,UAAIhB,KAAK;QAAEQ,IAAI;QAAOD,MAAMD,EAAES,GAAAA;MAAe,CAAA;IAC/C;EACF;AACA,SAAOD,IAAIV,EAAEf,OAAQ2B,KAAIhB,KAAK;IAAEQ,IAAI;IAAOD,MAAMH,EAAEU,GAAAA;EAAe,CAAA;AAClE,SAAOC,IAAIT,EAAEjB,OAAQ2B,KAAIhB,KAAK;IAAEQ,IAAI;IAAOD,MAAMD,EAAES,GAAAA;EAAe,CAAA;AAClE,SAAOC;AACT;AApCgBf;AAsChB,SAASgB,IAAI7C,OAAeQ,KAAakB,QAAQ,IAAE;AACjD,QAAMoB,IAAItC,MAAM,IAAIM,KAAKiC,MAAOjC,KAAKkC,IAAIhD,KAAAA,IAASQ,MAAOkB,KAAAA,IAAS;AAClE,SAAO,SAAIC,OAAOmB,CAAAA,KAAM;AAC1B;AAHSD;AAKF,IAAMI,YAAYC,gBAAuB;EAC9CC,MAAM;EACN/C,OAAO;EACPjB,aACE;EACFgB,OAAOZ,IACL;IACEa,OAAOlB,IAAI,eAAA;IACXoB,SAASX,IACPJ,IACE;MACE4B,KAAKjC,IAAI,wBAAA;MACT8B,OAAO9B,IAAI,eAAA;MACXkE,OAAOlE,IAAII,QAAW;QAAE+D,MAAM;UAAC;UAAQ;UAAS;;MAAU,CAAA;MAC1DjC,QAAQlC,IAAI,wBAAwB;QAClCmE,MAAM;UAAC;UAAQ;UAAU;UAAY;UAAW;UAAQ;;MAC1D,CAAA;IACF,GACA;MAAC;MAAO;KAAQ,GAElB;MAAEC,UAAU;MAAGC,UAAU;IAAG,CAAA;IAE9BhD,MAAMZ,IAAIG,KAAK;MAAEyD,UAAU;IAAI,CAAA;EACjC,GACA;IAAC;IAAW;GAAO;EAErBC,cAAc,wBAACrD,UAAU,GAAGD,QAAQC,KAAAA,CAAAA,GAASE,UAAUF,MAAMG,WAAW,CAAA,GAAIH,MAAMI,QAAQ,CAAA,CAAE,CAAA,IAA9E;AAChB,CAAA;AAEO,IAAMkD,QAAQP,gBAAuB;EAC1CC,MAAM;EACN/C,OAAO;EACPjB,aACE;EACFgB,OAAOZ,IACL;IACEF,MAAMH,IAAI,cAAc;MAAEmE,MAAM;QAAC;QAAO;;IAAQ,CAAA;IAChDjD,OAAOlB,IAAAA;IACPwE,MAAMxE,IAAI,yCAAA;IACVyE,QAAQhE,IAAIJ,IAAI;MAAE4B,KAAKjC,IAAI,eAAA;MAAkB8B,OAAO9B,IAAAA;IAAM,GAAG;MAAC;KAAM,GAAG;MACrEoE,UAAU;MACVC,UAAU;IACZ,CAAA;IACAK,MAAMjE,IAAIG,KAAK;MAAEwD,UAAU;MAAGC,UAAU;IAAI,CAAA;IAC5CM,MAAM3E,IAAI,2CAAA;EACZ,GACA;IAAC;IAAQ;IAAQ;IAAU;GAAO;EAEpCsE,cAAc,wBAACrD,UAAU2D,UAAU3D,KAAAA,GAArB;AAChB,CAAA;AAOA,SAAS2D,UAAU3D,OAAY;AAC7B,QAAMwD,UAA6CxD,MAAMwD,UAAU,CAAA,GAAII,OACrE,CAACC,SAAkB,OAAQA,MAA4B7C,QAAQ,QAAA;AAEjE,QAAMyC,OAAgBzD,MAAMyD,QAAQ,CAAA;AACpC,QAAMC,OAAO1D,MAAM0D,OAAO,IAAI9D,EAAEI,MAAM0D,IAAI,CAAA,KAAM;AAChD,QAAMI,UAAU,wBAACD,SAA0CjE,EAAEiE,KAAKhD,KAAK,KAAKgD,KAAK7C,KAAjE;AAChB,MAAIhB,MAAMd,SAAS,QAAQ;AACzB,UAAMiB,UAAU;MACd;QAAEa,KAAKpB,EAAEI,MAAMuD,IAAI;QAAG1C,OAAOjB,EAAEI,MAAMuD,IAAI;MAAE;SACxCC,OAAO/C,IAAI,CAACoD,UAAU;QAAE7C,KAAK6C,KAAK7C;QAAKH,OAAO,GAAGiD,QAAQD,IAAAA,CAAAA,GAAQH,IAAAA;MAAO,EAAA;;AAE7E,WAAO,GAAG3D,QAAQC,KAAAA,CAAAA,GAASE,UAAUC,SAASsD,MAAM,EAAA,CAAA;EACtD;AACA,QAAMpD,MAAMM,KAAKN,IACf,GAAA,GACGoD,KAAKM,QAAQ,CAACC,UAAUR,OAAO/C,IAAI,CAACoD,SAASlD,KAAKkC,IAAIoB,OAAOD,MAAMH,KAAK7C,GAAG,CAAC,KAAK,CAAA,CAAA,CAAA,CAAA;AAEtF,QAAMV,QAAQmD,KAAKlD,MAAM,GAAG,EAAA;AAC5B,QAAMe,QAAkB,CAAA;AACxB,MAAIkC,OAAO1C,UAAU,GAAG;AACtB,UAAME,MAAMwC,OAAO,CAAA,GAAIxC,OAAO;AAC9B,eAAWgD,SAAS1D,OAAO;AACzBgB,YAAMG,KACJ,GAAG7B,EAAEoE,MAAMhE,MAAMuD,IAAI,CAAC,EAAEhD,MAAM,GAAG,EAAA,EAAIa,OAAO,EAAA,CAAA,IAAOsB,IAAIuB,OAAOD,MAAMhD,GAAAA,CAAI,KAAK,GAAGX,GAAAA,CAAAA,IAAQT,EAAEoE,MAAMhD,GAAAA,CAAI,CAAA,GAAI0C,IAAAA,EAAM;IAElH;EACF,OAAO;AACL,UAAMnC,QAAQZ,KAAKC,IAAI,IAAID,KAAKN,IAAG,GAAImD,OAAO/C,IAAI,CAACoD,SAASC,QAAQD,IAAAA,EAAM/C,MAAM,CAAA,CAAA;AAChF,eAAWkD,SAAS1D,OAAO;AACzBgB,YAAMG,KAAK7B,EAAEoE,MAAMhE,MAAMuD,IAAI,CAAC,EAAEhD,MAAM,GAAG,EAAA,CAAA;AACzC,iBAAWsD,QAAQL,QAAQ;AACzBlC,cAAMG,KACJ,KAAKqC,QAAQD,IAAAA,EAAMtD,MAAM,GAAGgB,KAAAA,EAAOH,OAAOG,KAAAA,CAAAA,IAAUmB,IAAIuB,OAAOD,MAAMH,KAAK7C,GAAG,CAAC,KAAK,GAAGX,GAAAA,CAAAA,IAAQT,EAAEoE,MAAMH,KAAK7C,GAAG,CAAC,CAAA,GAAI0C,IAAAA,EAAM;MAE7H;IACF;EACF;AACA,MAAID,KAAK3C,SAASR,MAAMQ,OAAQQ,OAAMG,KAAK,UAAKgC,KAAK3C,SAASR,MAAMQ,MAAM,cAAc;AACxF,SAAO,GAAGf,QAAQC,KAAAA,CAAAA;EAAiBsB,MAAMD,KAAK,IAAA,CAAA;;AAChD;AAxCSsC;AA0CF,IAAMO,WAAWnB,gBAAuB;EAC7CC,MAAM;EACN/C,OAAO;EACPjB,aAAa;EACbgB,OAAOZ,IACL;IACEa,OAAOlB,IAAAA;IACPU,OAAOD,IACLJ,IACE;MACEyB,OAAO9B,IAAAA;MACPc,OAAO;QAAEX,MAAM;UAAC;UAAU;;MAAU;MACpCiF,OAAOpF,IAAI,qBAAA;MACXqF,OAAOrF,IAAII,QAAW;QAAE+D,MAAM;UAAC;UAAM;UAAQ;;MAAQ,CAAA;MACrDmB,MAAMtF,IAAAA;IACR,GACA;MAAC;MAAS;KAAQ,GAEpB;MAAEoE,UAAU;MAAGC,UAAU;IAAE,CAAA;EAE/B,GACA;IAAC;GAAQ;EAEXC,cAAc,wBAACrD,UACb,GAAGD,QAAQC,KAAAA,CAAAA,IAAUA,MAAMP,SAAS,CAAA,GACjCgB,IACC,CAAC6D,SACC,WAAM1E,EAAE0E,KAAKzD,KAAK,CAAA,MAAOjB,EAAE0E,KAAKzE,KAAK,CAAA,GAAIyE,KAAKH,QAAQ,KAAKvE,EAAE0E,KAAKH,KAAK,CAAA,MAAO,EAAA,EAAI,EAErF9C,KAAK,IAAA,CAAA,IANI;AAOhB,CAAA;AAEO,IAAMkD,cAAcxB,gBAAuB;EAChDC,MAAM;EACN/C,OAAO;EACPjB,aAAa;EACbgB,OAAOZ,IACL;IACEa,OAAOlB,IAAAA;IACPU,OAAOD,IACLJ,IAAI;MAAEa,OAAOlB,IAAAA;MAAOyF,KAAKzF,IAAAA;MAAO0F,SAAS1F,IAAAA;MAAO2F,QAAQ3F,IAAI,mBAAA;IAAqB,GAAG;MAClF;KACD,GACD;MAAEoE,UAAU;MAAGC,UAAU;IAAG,CAAA;EAEhC,GACA;IAAC;GAAQ;EAEXC,cAAc,wBAACrD,UACb,GAAGD,QAAQC,KAAAA,CAAAA,IAAUA,MAAMP,SAAS,CAAA,GACjCgB,IACC,CAAC6D,SACC,UAAKA,KAAKE,MAAM,IAAI5E,EAAE0E,KAAKE,GAAG,CAAA,IAAK5E,EAAE0E,KAAKrE,KAAK,CAAA,MAAOL,EAAE0E,KAAKrE,KAAK,CAAA,GAAIqE,KAAKI,SAAS,WAAM9E,EAAE0E,KAAKI,MAAM,CAAA,KAAM,EAAA,EAAI,EAEpHrD,KAAK,IAAA,CAAA,IANI;AAOhB,CAAA;AAEO,IAAMsD,YAAY5B,gBAAuB;EAC9CC,MAAM;EACN/C,OAAO;EACPjB,aAAa;EACbgB,OAAOZ,IACL;IACEa,OAAOlB,IAAAA;IACPU,OAAOD,IAAIJ,IAAI;MAAEyB,OAAO9B,IAAAA;MAAO6F,MAAM;QAAE1F,MAAM;MAAU;MAAG2F,MAAM9F,IAAAA;IAAM,GAAG;MAAC;KAAQ,GAAG;MACnFoE,UAAU;MACVC,UAAU;IACZ,CAAA;EACF,GACA;IAAC;GAAQ;EAEXC,cAAc,wBAACrD,UACb,GAAGD,QAAQC,KAAAA,CAAAA,IAAUA,MAAMP,SAAS,CAAA,GACjCgB,IACC,CAAC6D,SACC,GAAGA,KAAKM,OAAO,WAAM,QAAA,IAAOhF,EAAE0E,KAAKzD,KAAK,CAAA,GAAIyD,KAAKO,OAAO,YAAOjF,EAAE0E,KAAKO,IAAI,CAAA,MAAO,EAAA,EAAI,EAExFxD,KAAK,IAAA,CAAA,IANI;AAOhB,CAAA;AAEO,IAAMyD,WAAW/B,gBAAuB;EAC7CC,MAAM;EACN/C,OAAO;EACPjB,aAAa;EACbgB,OAAOZ,IACL;IACEa,OAAOlB,IAAAA;IACPgG,QAAQvF,IAAIJ,IAAI;MAAE4F,MAAMjG,IAAAA;MAAOkB,OAAOlB,IAAAA;MAAOC,aAAaD,IAAAA;IAAM,GAAG;MAAC;KAAQ,GAAG;MAC7EoE,UAAU;MACVC,UAAU;IACZ,CAAA;EACF,GACA;IAAC;GAAS;EAEZC,cAAc,wBAACrD,UACb,GAAGD,QAAQC,KAAAA,CAAAA,IAAUA,MAAM+E,UAAU,CAAA,GAClCtE,IACC,CAACwE,UACC,UAAKA,MAAMD,OAAO,IAAIpF,EAAEqF,MAAMD,IAAI,CAAA,OAAQ,EAAA,GAAKpF,EAAEqF,MAAMhF,KAAK,CAAA,GAAIgF,MAAMjG,cAAc,WAAMY,EAAEqF,MAAMjG,WAAW,CAAA,KAAM,EAAA,EAAI,EAE1HqC,KAAK,IAAA,CAAA,IANI;AAOhB,CAAA;AAEO,IAAM6D,YAAYnC,gBAAuB;EAC9CC,MAAM;EACN/C,OAAO;EACPjB,aAAa;EACbgB,OAAOZ,IAAI;IAAEa,OAAOlB,IAAAA;IAAOoG,UAAUpG,IAAAA;IAAOqG,MAAMrG,IAAAA;EAAM,GAAG;IAAC;GAAO;EACnEsE,cAAc,wBAACrD,UAAU,GAAGD,QAAQC,KAAAA,CAAAA;EAAiBJ,EAAEI,MAAMoF,IAAI,CAAA;SAAnD;AAChB,CAAA;AAEO,IAAMC,OAAOtC,gBAAuB;EACzCC,MAAM;EACN/C,OAAO;EACPjB,aAAa;EACbgB,OAAOZ,IAAI;IAAEa,OAAOlB,IAAAA;IAAOoG,UAAUpG,IAAAA;IAAO4C,QAAQ5C,IAAAA;IAAO6C,OAAO7C,IAAAA;EAAM,GAAG;IAAC;IAAU;GAAQ;EAC9FsE,cAAc,wBAACrD,UACb,GAAGD,QAAQC,KAAAA,CAAAA;EAAiB0B,SAAS9B,EAAEI,MAAM2B,MAAM,GAAG/B,EAAEI,MAAM4B,KAAK,CAAA,EAChEnB,IAAI,CAAC6E,SAAS,GAAGA,KAAKrD,OAAO,QAAQ,MAAMqD,KAAKrD,OAAO,QAAQ,MAAM,GAAA,IAAOqD,KAAKtD,IAAI,EAAE,EACvFX,KAAK,IAAA,CAAA;SAHI;AAIhB,CAAA;AAEO,IAAMkE,UAAUxC,gBAAuB;EAC5CC,MAAM;EACN/C,OAAO;EACPjB,aAAa;EACbgB,OAAOZ,IACL;IACEoG,MAAMzG,IAAII,QAAW;MAAE+D,MAAM;QAAC;QAAQ;QAAW;QAAW;;IAAU,CAAA;IACtEjD,OAAOlB,IAAAA;IACPiD,MAAMjD,IAAAA;EACR,GACA;IAAC;GAAO;EAEVsE,cAAc,wBAACrD,UACb,GAAGA,MAAMwF,SAAS,aAAaxF,MAAMwF,SAAS,WAAW,eAAe,uBAAA,GAA0BzF,QAAQC,KAAAA,CAAAA,GAASJ,EAAEI,MAAMgC,IAAI,CAAA,IADnH;AAEhB,CAAA;AAEO,IAAMyD,QAAQ1C,gBAAuB;EAC1CC,MAAM;EACN/C,OAAO;EACPjB,aAAa;EACbgB,OAAOZ,IAAI;IAAEsG,WAAW3G,IAAII,QAAW;MAAE+D,MAAM;QAAC;QAAU;;IAAO,CAAA;IAAIyC,KAAK;MAAEzG,MAAM;IAAS;EAAE,CAAA;EAC7F0G,UAAU;EACVvC,cAAc,6BAAM,IAAN;AAChB,CAAA;AAEO,IAAMwC,OAAO9C,gBAAuB;EACzCC,MAAM;EACN/C,OAAO;EACPjB,aAAa;EACbgB,OAAOZ,IAAI;IAAEa,OAAOlB,IAAAA;IAAO+G,UAAU/G,IAAAA;EAAM,CAAA;EAC3C6G,UAAU;EACVvC,cAAc,wBAACrD,UACbA,MAAMC,QAAQ,IAAIL,EAAEI,MAAMC,KAAK,CAAA,IAAKD,MAAM8F,WAAW,WAAMlG,EAAEI,MAAM8F,QAAQ,CAAA,KAAM,EAAA,KAAO,IAD5E;AAEhB,CAAA;AAEO,IAAMC,UAAUhD,gBAAuB;EAC5CC,MAAM;EACN/C,OAAO;EACPjB,aAAa;EACbgB,OAAOZ,IAAI;IAAE4C,MAAMjD,IAAAA;EAAM,GAAG;IAAC;GAAO;EACpCsE,cAAc,wBAACrD,UAAU,IAAIJ,EAAEI,MAAMgC,IAAI,CAAA,KAA3B;AAChB,CAAA;AAEO,IAAMgE,OAAOjD,gBAAuB;EACzCC,MAAM;EACN/C,OAAO;EACPjB,aAAa;EACbgB,OAAOZ,IAAI;IAAE4C,MAAMjD,IAAAA;IAAOkH,OAAO;MAAE/G,MAAM;IAAU;EAAE,GAAG;IAAC;GAAO;EAChEmE,cAAc,wBAACrD,UAAUJ,EAAEI,MAAMgC,IAAI,GAAvB;AAChB,CAAA;AAEO,IAAMkE,QAAQnD,gBAAuB;EAC1CC,MAAM;EACN/C,OAAO;EACPjB,aAAa;EACbgB,OAAOZ,IACL;IACE4C,MAAMjD,IAAAA;IACNyG,MAAMzG,IAAII,QAAW;MAAE+D,MAAM;QAAC;QAAW;QAAS;QAAW;QAAW;;IAAU,CAAA;EACpF,GACA;IAAC;GAAO;EAEVG,cAAc,wBAACrD,UAAU,IAAIJ,EAAEI,MAAMgC,IAAI,CAAA,KAA3B;AAChB,CAAA;AAEO,IAAMmE,OAAOpD,gBAAuB;EACzCC,MAAM;EACN/C,OAAO;EACPjB,aAAa;EACbgB,OAAOZ,IAAI;IAAE4C,MAAMjD,IAAAA;IAAOyF,KAAKzF,IAAII,QAAW;MAAEiH,SAAS;IAAa,CAAA;EAAG,GAAG;IAAC;IAAQ;GAAM;EAC3F/C,cAAc,wBAACrD,UAAU,IAAIJ,EAAEI,MAAMwE,GAAG,CAAA,IAAK5E,EAAEI,MAAMgC,QAAQhC,MAAMwE,GAAG,CAAA,KAAxD;AAChB,CAAA;AAEO,IAAM6B,QAAQtD,gBAAuB;EAC1CC,MAAM;EACN/C,OAAO;EACPjB,aAAa;EACbgB,OAAOZ,IAAI;IAAEoF,KAAKzF,IAAII,QAAW;MAAEiH,SAAS;IAAY,CAAA;IAAIE,KAAKvH,IAAAA;EAAM,GAAG;IAAC;GAAM;EACjFsE,cAAc,wBAACrD,UAAUJ,EAAEI,MAAMwE,GAAG,GAAtB;AAChB,CAAA;;;AC7XO,SAAS+B,8BAAiCC,OAAQ;AACvD,QAAMC,OAAO,oBAAIC,IAAAA;AACjB,QAAMC,SAAQ,wBAACC,UAAAA;AACb,QAAIA,UAAU,QAAQ,OAAOA,UAAU,YAAY,OAAOA,UAAU,UAAW;AAC/E,QAAI,OAAOA,UAAU,YAAYC,OAAOC,SAASF,KAAAA,EAAQ;AACzD,QAAI,OAAOA,UAAU,YAAYA,UAAU,KACzC,OAAM,IAAIG,UAAU,mDAAA;AACtB,QAAIN,KAAKO,IAAIJ,KAAAA,EACX,OAAM,IAAIG,UAAU,sDAAA;AACtB,QACE,CAACE,MAAMC,QAAQN,KAAAA,KACfO,OAAOC,eAAeR,KAAAA,MAAWO,OAAOE,aACxCF,OAAOC,eAAeR,KAAAA,MAAW,KAEjC,OAAM,IAAIG,UAAU,qDAAA;AACtBN,SAAKa,IAAIV,KAAAA;AACT,eAAWW,QAAQJ,OAAOK,OAAOZ,KAAAA,EAAQD,CAAAA,OAAMY,IAAAA;AAC/Cd,SAAKgB,OAAOb,KAAAA;EACd,GAhBc;AAiBdD,EAAAA,OAAMH,KAAAA;AACN,SAAOkB,KAAKC,MAAMD,KAAKE,UAAUpB,KAAAA,CAAAA;AACnC;AArBgBD;AA+BT,SAASsB,gBACdC,YACAC,UAA0B,CAAC,GAAC;AAE5BC,kBAAgBF,UAAAA;AAChB,QAAMG,UAAUC,cAAc;IAACJ;KAAaC,OAAAA;AAC5C,QAAMI,UAAU,8BAAOC,UAAAA;AACrB,UAAMC,UAAS,MAAMC,cAAcR,WAAWM,OAAOA,OAAOH,QAAQM,SAAS;AAC7E,QAAI,CAACF,QAAOG,GACV,OAAM,IAAIC,MAAM,kBAAkBX,WAAWY,IAAI,WAAWC,aAAaN,QAAOO,MAAM,CAAA,EAAG;AAC3F,UAAMC,aAAatC,8BAA8B8B,QAAO7B,KAAK;AAC7D,QAAI,OAAOqC,eAAe,YAAYA,eAAe,QAAQ5B,MAAMC,QAAQ2B,UAAAA,EACzE,OAAM,IAAI9B,UAAU,8CAAA;AACtB,UAAM+B,WAAW,MAAMb,QAAQc,SAASjB,WAAWY,MAAMG,UAAAA;AACzD,QACE,CAACC,SAASN,MACVQ,cAAczC,8BAA8BuC,SAAStC,KAAK,CAAA,MAAOwC,cAAcH,UAAAA,GAC/E;AACA,YAAM,IAAIJ,MACR,UAAUX,WAAWY,IAAI,8DAA8D;IAE3F;AACA,WAAO;MACLO,WAAWnB,WAAWY;MACtBN,OAAOS;MACPK,SAASpB,WAAWoB,WAAW;MAC/BC,cAAcC,gBACZnB,SACAH,WAAWY,MACXG,UAAAA;IAEJ;EACF,GA1BgB;AA2BhB,SAAO1B,OAAOkC,OAAOlB,SAAS;IAAEL;EAAW,CAAA;AAC7C;AAlCgBD;AAyJT,IAAMyB,QAAQC,gBAA4BC,SAAAA;AAC1C,IAAMC,QAAQF,gBAA4BG,KAAAA;AAG1C,SAASC,0BACdC,eAAuF;AAEvF,QAAMC,QAAQC,MAAMC,QAAQH,aAAAA,IAAiBA,gBAAgB;IAACA;;AAC9D,SAAOC,MAAMG,IAAI,CAACC,SAAAA;AAChB,UAAMC,eAAeC,8BAA8BF,IAAAA;AACnD,QACE,OAAOC,iBAAiB,YACxBA,iBAAiB,QACjB,OAAOA,aAAaE,cAAc,YAClC,CAAC,8BAA8BC,KAAKH,aAAaE,SAAS,KAC1D,CAACE,OAAOC,cAAcL,aAAaM,OAAO,KAC1CN,aAAaM,WAAW,KACxB,OAAON,aAAaO,iBAAiB,YACrC,OAAOP,aAAaQ,UAAU,YAC9BR,aAAaQ,UAAU,QACvBZ,MAAMC,QAAQG,aAAaQ,KAAK,GAChC;AACA,YAAM,IAAIC,UAAU,uCAAA;IACtB;AACA,WAAOT;EACT,CAAA;AACF;AAtBgBP;AAyBhB,SAASiB,cAAcC,OAAc;AACnC,MAAIf,MAAMC,QAAQc,KAAAA,EAAQ,QAAO,IAAIA,MAAMb,IAAIY,aAAAA,EAAeE,KAAK,GAAA,CAAA;AACnE,MAAI,OAAOD,UAAU,YAAYA,UAAU,MAAM;AAC/C,UAAME,UAASF;AACf,WAAO,IAAIG,OAAOC,KAAKF,OAAAA,EACpBG,KAAI,EACJlB,IAAI,CAACmB,QAAQ,GAAGC,KAAKC,UAAUF,GAAAA,CAAAA,IAAQP,cAAcG,QAAOI,GAAAA,CAAI,CAAA,EAAG,EACnEL,KAAK,GAAA,CAAA;EACV;AACA,SAAOM,KAAKC,UAAUR,KAAAA;AACxB;AAVSD;;;AC3OT,eAAsBU,sBACpBC,SACAC,QACAC,KACAC,UAAgB;AAEhB,MAAIH,QAAQI,YAAYC,OAAW;AACnC,MAAI;AACF,UAAMC,UAAS,MAAMN,QAAQI,QAAQH,QAAQC,GAAAA;AAC7C,QAAII,YAAWD,OAAW;AAC1B,UAAME,QAAQC,0BAA0BF,OAAAA;AACxC,eAAWG,gBAAgBF,OAAO;AAChC,YAAML,IAAIQ,OAAOD,aAAaE,WAAWF,aAAaG,OAAO;QAC3DC,SAASJ,aAAaI;QACtBC,cAAcL,aAAaK;MAC7B,CAAA;IACF;EACF,SAASC,OAAO;AACd,QAAIb,IAAIc,wBAAwBX,QAAW;AACzC,UAAI;AACF,cAAMH,IAAIc,oBAAoBD,OAAO;UAAEZ;QAAS,CAAA;AAChD;MACF,SAASc,aAAa;AACpBC,gBAAQC,KAAK,SAAShB,QAAAA,wCAAgDc,WAAAA;MACxE;IACF,OAAO;AACLC,cAAQC,KAAK,SAAShB,QAAAA,oDAA4DY,KAAAA;IACpF;EACF;AACF;AA7BsBhB;;;ACgBf,IAAMqB,qBAAN,cAAiCC,MAAAA;EAnBxC,OAmBwCA;;;;EACtC,YAA4BC,UAAkB;AAC5C,UAAM,SAASA,QAAAA,gCAAwC,GAAA,KAD7BA,WAAAA;AAE1B,SAAKC,OAAO;EACd;AACF;AAWO,IAAMC,oBAAN,cAAgCH,MAAAA;EAnCvC,OAmCuCA;;;;EACrC,YAA4BC,UAAkB;AAC5C,UAAM,SAASA,QAAAA,kCAA0C,GAAA,KAD/BA,WAAAA;AAE1B,SAAKC,OAAO;EACd;AACF;AAGO,IAAME,oBAAN,cAAgCJ,MAAAA;EA3CvC,OA2CuCA;;;;EACrC,YAA4BC,UAAkB;AAC5C,UAAM,SAASA,QAAAA,qBAA6B,GAAA,KADlBA,WAAAA;AAE1B,SAAKC,OAAO;EACd;AACF;AAGO,IAAMG,wBAAN,cAAoCL,MAAAA;EAnD3C,OAmD2CA;;;;;EACzC,YACkBC,UACAK,QAChB;AACA,UACE,2BAA2BL,QAAAA,MAAcK,OAAOC,IAAI,CAACC,WAAUA,OAAMC,OAAO,EAAEC,KAAK,IAAA,CAAA,EAAO,GAAA,KAJ5ET,WAAAA,UAAAA,KACAK,SAAAA;AAKhB,SAAKJ,OAAO;EACd;AACF;AAGO,IAAMS,2BAAN,cAAuCX,MAAAA;EAhE9C,OAgE8CA;;;;;EAC5C,YACkBC,UACAW,QAChB;AACA,UAAMA,MAAAA,GAAAA,KAHUX,WAAAA,UAAAA,KACAW,SAAAA;AAGhB,SAAKV,OAAO;EACd;AACF;AAGO,IAAMW,sBAAN,cAAkCb,MAAAA;EA3EzC,OA2EyCA;;;;EACvC,YAA4BC,UAAkB;AAC5C,UAAM,SAASA,QAAAA,2CAAmD,GAAA,KADxCA,WAAAA;AAE1B,SAAKC,OAAO;EACd;AACF;AAEA,SAASY,mBAAmBZ,MAAca,OAAgBC,UAAiB;AACzE,MAAI;AACF,QAAIC,4BAA4BF,KAAAA,MAAWE,4BAA4BD,QAAAA,EAAW;EACpF,QAAQ;EAGR;AACA,QAAM,IAAIH,oBAAoBX,IAAAA;AAChC;AARSY;AAsBF,IAAMI,eAAN,MAAMA;EAxGb,OAwGaA;;;EACMC,UAAU,oBAAIC,IAAAA;EAE/BC,SAASC,MAAgBC,SAA4B;AACnD,SAAKJ,QAAQK,IAAIF,KAAKpB,MAAM;MAAEoB;MAAMC;IAAQ,CAAA;EAC9C;;EAGAE,gBAAgBvB,MAAuB;AACrC,WAAO,OAAO,KAAKiB,QAAQO,IAAIxB,IAAAA,GAAOqB,QAAQI,YAAY;EAC5D;;EAGA,MAAMC,cAAc1B,MAAc2B,QAAiBC,KAA+B;AAChF,UAAMC,QAAQ,KAAKZ,QAAQO,IAAIxB,IAAAA;AAC/B,QAAI6B,UAAUC,OAAW,OAAMC,sBAAsBF,MAAMR,SAASM,QAAQC,KAAK5B,IAAAA;EACnF;EAEAgC,IAAIhC,MAAuB;AACzB,WAAO,KAAKiB,QAAQe,IAAIhC,IAAAA;EAC1B;;;;;;;;;;EAWAiC,WAAWjC,MAAuB;AAChC,WAAO,KAAKiB,QAAQiB,OAAOlC,IAAAA;EAC7B;EAEAoB,KAAKpB,MAAoC;AACvC,WAAO,KAAKiB,QAAQO,IAAIxB,IAAAA,GAAOoB;EACjC;EAEAe,WAAuB;AACrB,WAAO;SAAI,KAAKlB,QAAQmB,OAAM;MAAI/B,IAAI,CAACwB,UAAUA,MAAMT,IAAI;EAC7D;;;;;;;;;;;;EAaA,MAAMiB,eACJC,OACAC,QACAC,cACAC,QAA0C,CAAC,GAChB;AAC3B,UAAMC,UAAU,MAAM,KAAKC,eAAeL,OAAOC,QAAQC,YAAAA;AACzD,UAAMI,cAAc,MAAMC,QAAQC,IAChCJ,QAAQrC,IAAI,OAAO,EAAEe,MAAMC,QAAO,MAAE;AAElC,YAAM0B,WACJ1B,QAAQ2B,aAAalB,SAAYA,SAAY,MAAMT,QAAQ2B,SAAS;QAAEV;QAAO,GAAGG;MAAM,CAAA;AACxF,UAAIM,UAAUE,cAAc,MAAO,QAAO;AAC1C,aAAO;QACLjD,MAAMoB,KAAKpB;QACXkD,MAAM9B,KAAK8B;QACXC,aAAaJ,UAAUI,eAAe/B,KAAK+B;QAC3CC,aAAaL,UAAUK,eAAehC,KAAKgC;MAC7C;IACF,CAAA,CAAA;AAEF,WAAOR,YAAYS,OAAO,CAACC,eAA6CA,eAAe,IAAA;EACzF;;;;;;EAOA,MAAMC,aACJjB,OACAC,QACAC,cACqB;AACrB,YAAQ,MAAM,KAAKG,eAAeL,OAAOC,QAAQC,YAAAA,GAAenC,IAAI,CAAC,EAAEe,KAAI,MAAOA,IAAAA;EACpF;EAEA,MAAcuB,eACZL,OACAC,QACAC,cACkB;AAClB,UAAMgB,cAAc,IAAIC,IACtBC,uBAAuB,KAAKvB,SAAQ,GAAIK,YAAAA,EAAcnC,IAAI,CAACe,SAASA,KAAKpB,IAAI,CAAA;AAE/E,UAAM2D,SAAS;SAAI,KAAK1C,QAAQmB,OAAM;MAAIiB,OAAO,CAACxB,UAAU2B,YAAYxB,IAAIH,MAAMT,KAAKpB,IAAI,CAAA;AAC3F,UAAM4D,OAAO,MAAMC,qBAAqBF,MAAAA;AACxC,UAAMG,gBAAgB,IAAIL,KAEtB,MAAMM,kBACJH,KAAKvD,IAAI,CAACwB,UAAUA,MAAMT,IAAI,GAC9BkB,OACAC,MAAAA,GAEFlC,IAAI,CAACe,SAASA,KAAKpB,IAAI,CAAA;AAE3B,UAAMgE,aAAaJ,KAAKP,OAAO,CAACxB,UAAUiC,cAAc9B,IAAIH,MAAMT,KAAKpB,IAAI,CAAA;AAC3E,WAAOiE,oBAAoBD,YAAY1B,KAAAA;EACzC;;;;;;EAOA,MAAM4B,OACJlE,MACAmE,OACAvC,KACAW,QACA6B,UAAyB,CAAC,GACR;AAClB,UAAM,EAAEvC,OAAOhB,OAAOe,KAAKyC,SAAQ,IAAK,MAAM,KAAKC,UAAUtE,MAAMmE,OAAOvC,KAAKW,QAAQ6B,OAAAA;AACvF,UAAMG,UAAUC,OAAOC,OAAOL,SAAS,eAAA;AACvC,QAAIG,QAAS3D,oBAAmBZ,MAAMa,OAAOuD,QAAQM,aAAa;AAClE,UAAMC,iBAAiBJ,UAAUK,uBAAuB/D,KAAAA,IAASA;AACjE,UAAMgE,YAAYN,UAAUK,uBAAuBD,cAAAA,IAAkB9D;AACrE,UAAMiE,UACJjD,MAAMT,KAAK8B,SAAS,WAChB,MAAMrB,MAAMR,QAAQ0D,YAAYF,WAAWR,UAAU;MAAEW,OAAO;IAAU,CAAA,IACxElD;AAEN,QAAIyC,QAAS3D,oBAAmBZ,MAAM6E,WAAWF,cAAAA;AACjD,QAAIG,SAAQG,WAAW,SAAU,OAAM,IAAIxE,yBAAyBT,MAAM8E,QAAOpE,MAAM;AACvF,UAAMiB,SACJmD,SAAQG,WAAW,cACfH,QAAOnD,SACP,MAAME,MAAMR,QAAQ6D,QAAQP,gBAAgBN,QAAAA;AAClD,UAAMtC,sBAAsBF,MAAMR,SAASM,QAAQ0C,UAAUrE,IAAAA;AAC7D,WAAO2B;EACT;;EAGA,MAAMwD,QACJnF,MACAmE,OACAvC,KACAW,QACA6B,UAA0B,CAAC,GACG;AAC9B,YAAQ,MAAM,KAAKgB,iBAAiBpF,MAAMmE,OAAOvC,KAAKW,QAAQ6B,OAAAA,GAAUW;EAC1E;;EAGA,MAAMK,iBACJpF,MACAmE,OACAvC,KACAW,QACA6B,UAA0B,CAAC,GACK;AAChC,UAAM,EAAEvC,OAAOhB,OAAOe,KAAKyC,SAAQ,IAAK,MAAM,KAAKC,UAAUtE,MAAMmE,OAAOvC,KAAKW,QAAQ6B,OAAAA;AACvF,UAAMiB,aAAajB,QAAQkB,kBAAkB,OAAOV,uBAAuB/D,KAAAA,IAASA;AACpF,UAAMgE,YAAYT,QAAQkB,kBAAkB,OAAOV,uBAAuBS,UAAAA,IAAcxE;AACxF,UAAMkE,aAAkClD,MAAMT,KAAK8B,SAAS,WACxD,MAAMrB,MAAMR,QAAQ0D,YAAYF,WAAWR,UAAU;MAAEW,OAAO;IAAU,CAAA,IACxElD,WAAc;MAAEmD,QAAQ;IAAQ;AAGpC,QAAIb,QAAQkB,kBAAkB,KAAM1E,oBAAmBZ,MAAM6E,WAAWQ,UAAAA;AACxE,WAAO;MAAElB,OAAOkB;MAAYN;IAAU;EACxC;EAEA,MAAcT,UACZtE,MACAmE,OACAvC,KACAW,QACA6B,SAC2D;AAC3D,UAAMvC,QAAQ,KAAKZ,QAAQO,IAAIxB,IAAAA;AAC/B,QAAI6B,UAAUC,QAAW;AACvB,YAAM,IAAI5B,kBAAkBF,IAAAA;IAC9B;AACA,QAAI,CAAE,MAAMuF,cAAc1D,MAAMT,MAAMS,MAAMR,OAAO,GAAI;AACrD,YAAM,IAAIpB,kBAAkBD,IAAAA;IAC9B;AACA,QAAI,CAAE,MAAMuC,OAAOiD,IAAI5D,IAAIU,OAAOT,MAAMT,IAAI,GAAI;AAC9C,YAAM,IAAIvB,mBAAmBG,IAAAA;IAC/B;AACA,QAAI,CAAE,MAAMyF,gBAAgB7D,IAAIU,OAAOT,MAAMR,OAAO,GAAI;AACtD,YAAM,IAAIxB,mBAAmBG,IAAAA;IAC/B;AAGA,QAAIoE,QAAQ5B,iBAAiBV,UAAa,CAACsC,QAAQ5B,aAAakD,SAAS1F,IAAAA,GAAO;AAC9E,YAAM,IAAIH,mBAAmBG,IAAAA;IAC/B;AACA,UAAM2F,aAAa,MAAM9D,MAAMT,KAAKgC,YAAY,WAAA,EAAawC,SAASzB,KAAAA;AACtE,QAAIwB,WAAWvF,WAAW0B,QAAW;AACnC,YAAM,IAAI3B,sBAAsBH,MAAM2F,WAAWvF,MAAM;IACzD;AAGA,UAAMiE,WACJ,OAAOzC,IAAIiE,WAAW,aAAajE,MAAM;MAAE,GAAGA;MAAKiE,QAAQC,iBAAiBlE,IAAImE,SAAS;IAAE;AAC7F,WAAO;MAAElE;MAAOhB,OAAO8E,WAAW9E;MAAOe,KAAKyC;IAAS;EACzD;AACF;AAmCO,IAAM2B,qBAAN,MAAMA;EA/Vb,OA+VaA;;;;;EAEFC;EAET,YACWC,eAAyB,CAAA,GAClC9B,UAA8B,CAAC,GAC/B;SAFS8B,eAAAA;AAGT,SAAKD,aAAa7B,QAAQ6B,cAAc;EAC1C;EAEAT,IAAIlD,OAAc6D,MAAyB;AACzC,QAAIA,KAAKC,YAAYtE,UAAaqE,KAAKE,UAAUvE,OAAW,QAAO;AACnE,UAAMwE,UAAUH,KAAKE,SAAS,KAAKH;AACnC,QAAII,QAAQC,WAAW,EAAG,QAAO,KAAKN,eAAe;AACrD,YAAQ3D,MAAM+D,SAAS,CAAA,GAAIG,KAAK,CAACC,SAASH,QAAQZ,SAASe,IAAAA,CAAAA;EAC7D;AACF;AAuBO,IAAMC,oBAAN,cAAgCV,mBAAAA;EAvYvC,OAuYuCA;;;EACrC,YAAYE,eAAyB,CAAA,GAAI;AACvC,UAAMA,cAAc;MAAED,YAAY;IAAO,CAAA;EAC3C;AACF;AAWO,SAASU,gBAAgBC,OAAkB;AAChD,QAAMC,WAAWD,iBAAiBZ,qBAAqBY,MAAMV,eAAe,CAAA;AAC5E,SAAO;IACLV,IAAIlD,OAAc6D,MAAc;AAC9B,UAAIA,KAAKC,YAAYtE,WAAcqE,KAAKE,SAASQ,UAAUN,WAAW,GAAG;AACvE,eAAO;MACT;AACA,aAAOK,MAAMpB,IAAIlD,OAAO6D,IAAAA;IAC1B;EACF;AACF;AAVgBQ;;;ACvZhB,SAASG,kBAAkB;AAC3B,SAASC,aAAa;;;ACetB,eAAsBC,8BACpBC,OAAyC;AAEzC,QAAMC,SAASD,MAAMC,UAAU,IAAIC,sBAAAA;AACnC,QAAMC,cAAc,MAAMF,OAAOG,eAAeJ,MAAMK,MAAML,MAAMM,OAAON,MAAMO,MAAM;AACrF,MAAI,CAACJ,YAAYK,SAAU,QAAO;IAAEC,MAAM;EAAO;AACjD,QAAMC,aAAc,MAAMV,MAAMW,MAAMC,sBAAsBZ,MAAMO,OAAOM,QAAQ,KAAM,CAAA;AACvF,MAAIH,WAAWI,SAASd,MAAMK,KAAKU,IAAI,EACrC,QAAO;IAAEN,MAAM;IAAcO,UAAUb,YAAYa;EAAS;AAC9D,QAAMC,aACJd,YAAYe,UAAUC,UAAaC,OAAOC,SAASlB,YAAYe,KAAK,IAChEI,KAAKC,MAAMpB,YAAYe,KAAK,IAC5B;AACN,MAAID,cAAc,EAAG,QAAO;IAAER,MAAM;IAAOO,UAAUb,YAAYa;EAAS;AAC1E,QAAMQ,OAAOxB,MAAMyB,SAASC,KAAKF,KAAE;AACnC,MACE,CAACJ,OAAOO,cAAcH,GAAAA,KACtB,CAACJ,OAAOO,cAAcV,UAAAA,KACtB,CAACG,OAAOO,cAAcH,MAAMP,UAAAA,EAE5B,OAAM,IAAIW,WAAW,kCAAA;AACvB,SAAO;IACLnB,MAAM;IACNO,UAAUb,YAAYa;IACtBE,OAAOD;IACPY,WAAW,IAAIH,KAAKF,MAAMP,UAAAA,EAAYa,YAAW;EACnD;AACF;AA3BsB/B;;;ACVtB,eAAsBgC,sBACpBC,UACAC,MACAC,OACAC,KACAC,QACAC,UAAyB,CAAC,GAAC;AAE3B,QAAMC,mBAAmBC,uBAAuBL,KAAAA;AAChD,QAAMM,WAAW,MAAMR,SAASS,iBAC9BR,MACAM,uBAAuBD,gBAAAA,GACvBH,KACAC,QACA;IAAE,GAAGC;IAASK,eAAe;EAAK,CAAA;AAEpC,MAAIC;AACJ,QAAMC,cAAcZ,SAASa,KAAKZ,IAAAA,GAAOU;AACzC,MAAIH,SAASM,UAAUC,WAAW,WAAWH,gBAAgBI,QAAW;AACtEL,qBACE,OAAOC,gBAAgB,WACnBA,cACA,MAAMA,YAAYL,uBAAuBC,SAASN,KAAK,GAAGC,GAAAA;AAChE,QACEQ,mBAAmBK,WAClB,OAAOL,mBAAmB,YAAY,CAACA,kBAAkBA,eAAeM,SAAS,KAElF,OAAM,IAAIC,UACR,2EAAA;EAEN;AACA,SAAO;IACL,GAAIP,mBAAmBK,SAAY;MAAEL;IAAe,IAAI,CAAC;IACzDL;IACAJ,OAAOM,SAASN;;IAEhBY,WACEN,SAASM,UAAUC,WAAW,UAC1BR,uBAAuBC,SAASM,SAAS,IACzCN,SAASM;EACjB;AACF;AAzCsBf;;;ACCf,SAASoB,sBAAsBC,YAAkB;AACtD,SAAO;IAAEA;IAAYC,QAAQ;IAAWC,UAAU;EAAM;AAC1D;AAFgBH;;;ACPhB,SAASI,YAAY;AAqNd,SAASC,uBAAuBC,SAAwB;AAC7DC,OAAK,SAAS,eAAeD,OAAAA;AAC/B;AAFgBD;AAGT,SAASG,oBAAoBF,SAA0B;AAC5DC,OAAK,SAAS,WAAWD,OAAAA;AAC3B;AAFgBE;AAGT,SAASC,qBAAqBH,SAA2B;AAC9DC,OAAK,SAAS,aAAaD,OAAAA;AAC7B;AAFgBG;AAGT,SAASC,0BAA0BJ,SAA2B;AACnEC,OAAK,SAAS,kBAAkBD,OAAAA;AAClC;AAFgBI;AAGT,SAASC,wBAAwBL,SAAyB;AAC/DC,OAAK,SAAS,gBAAgBD,OAAAA;AAChC;AAFgBK;AAGT,SAASC,sBAAsBN,SAAuB;AAC3DC,OAAK,SAAS,cAAcD,OAAAA;AAC9B;AAFgBM;AAGT,SAASC,sBAAsBP,SAAuB;AAC3DC,OAAK,SAAS,aAAaD,OAAAA;AAC7B;AAFgBO;AAGT,SAASC,sBAAsBR,SAAuB;AAC3DC,OAAK,SAAS,aAAaD,OAAAA;AAC7B;AAFgBQ;AAGT,SAASC,sBAAsBT,SAAuB;AAC3DC,OAAK,SAAS,cAAcD,OAAAA;AAC9B;AAFgBS;AAGT,SAASC,2BAA2BV,SAA4B;AACrEC,OAAK,SAAS,mBAAmBD,OAAAA;AACnC;AAFgBU;AAGT,SAASC,2BAA2BX,SAA4B;AACrEC,OAAK,SAAS,mBAAmBD,OAAAA;AACnC;AAFgBW;AAGT,SAASC,0BAA0BZ,SAA2B;AACnEC,OAAK,SAAS,kBAAkBD,OAAAA;AAClC;AAFgBY;AAmBT,IAAMC,oBAA+C;EAC1D;EACA;EACA;EACA;EACA;;AA4BK,IAAMC,0BAA2D;EACtE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AA4BK,SAASC,mBAAmBC,OAA2B;AAC5D,SAAO,SAASA,KAAAA;AAClB;AAFgBD;;;ACxUT,SAASE,4BACdC,YACAC,OACAC,gBACAC,OAAyD;AAEzD,QAAMC,YAAYC,kBAAkBL,YAAYG,KAAAA;AAChD,QAAMG,QAAQ,oBAAIC,IAAAA;AAClB,MAAIC,OAAO;AACX,SAAO;IACLC,YAAYL,UAAUK;IACtBC,MAAM,6BAAM;SAAIJ,MAAMK,OAAM;MAAIC,KAAK,IAAA,GAA/B;IACNC,SAAS,6BAAA;AACPL,aAAO;AACPF,YAAMQ,MAAK;AACXV,gBAAUS,QAAO;IACnB,GAJS;IAKTE,MAAM,8BAAOC,WAAWC,OAAOC,UAAU,CAAC,MAAC;AACzC,UAAI,CAAChB,gBAAgB;AAInB,cAAMiB,WACJlB,MAAMmB,mBAAmBC,UACzBpB,MAAMmB,eAAeX,WAAWa,KAC9B,CAACC,UAAUA,MAAMC,SAASR,aAAaO,MAAME,aAAaP,QAAQO,WAAW,EAAA;AAEjF,YAAIN,SAAU,QAAOf,UAAUW,KAAKC,WAAWC,OAAOC,OAAAA;AACtD,cAAMQ,MAAKR,QAAQQ,MAAM,GAAG1B,UAAAA,OAAiBQ,MAAAA;AAC7C,YAAIU,QAAQS,iBAAiBN,UAAaH,QAAQS,aAAaC,SAAS,GAAG;AACzEtB,gBAAMuB,IAAIH,KAAIR,QAAQS,YAAY;AAClC,gBAAMxB,QAAQ;YAAE2B,MAAM;YAAQpB,MAAMQ,QAAQS;UAAa,CAAA;QAC3D;AACA,eAAO;UAAED,IAAAA;QAAG;MACd;AACA,YAAMK,gBAAgBC,uBAAuBf,KAAAA;AAC7C,YAAMgB,kBAAkB;QAAE,GAAGf;MAAQ;AACrC,YAAMgB,UAAU,MAAMhC,eAAeD,KAAAA;AACrC,YAAMkC,WAAW,MAAMC,kBACrBF,SACAjC,MAAMmB,gBACNJ,WACAe,eACAE,gBAAgBR,OAAO;AAEzB,YAAMC,KAAKO,gBAAgBP,MAAM,GAAG1B,UAAAA,OAAiBQ,MAAAA;AACrD,UAAI2B,SAASL,SAAS,QAAQ;AAC5BxB,cAAMuB,IAAIH,IAAIS,SAASzB,IAAI;AAC3B,cAAMP,QAAQ;UAAE2B,MAAM;UAAQpB,MAAMyB,SAASzB;QAAK,CAAA;AAClD,eAAO;UAAEgB;QAAG;MACd;AACA,aAAOtB,UAAUW,KAAKoB,SAASnB,WAAWmB,SAASlB,OAAO;QACxDS;QACAD,SAASU,SAASV;QAClBE,cAAcQ,SAASR;QACvB,GAAIQ,SAASE,sBAAsBhB,SAC/B;UAAEgB,mBAAmBF,SAASE;QAAkB,IAChD,CAAC;MACP,CAAA;IACF,GA1CM;EA2CR;AACF;AA7DgBtC;;;ACIhB,SAASuC,kBAAkBC,OAAc;AACvC,MAAI,OAAOA,UAAU,YAAYA,UAAU,MAAM;AAC/C,WAAO;EACT;AACA,QAAMC,OAAO,UAAUD,QAASA,MAA4BC,OAAOC;AACnE,QAAMC,QAAQ,WAAWH,QAASA,MAA6BG,QAAQD;AACvE,QAAME,WAAW,cAAcJ,QAASA,MAAgCI,WAAWF;AACnF,MAAID,SAAS,QAAQA,SAAS,QAAQE,UAAU,QAAQA,UAAU,MAAM;AACtE,WAAO;EACT;AACA,MAAIF,SAAS,sBAAsBA,SAAS,wBAAwB;AAClE,WAAO;EACT;AACA,MAAIA,SAAS,WAAWA,SAAS,WAAWG,aAAa,WAAWA,aAAa,SAAS;AACxF,WAAO;EACT;AACA,MAAIH,SAAS,eAAe;AAC1B,WAAO;EACT;AACA,QAAMI,UAAU,aAAaL,QAASA,MAA+BK,UAAUH;AAC/E,SACE,OAAOG,YAAY,YAAY,oDAAoDC,KAAKD,OAAAA;AAE5F;AAvBSN;AA+BF,SAASQ,qBAAqBP,OAAc;AACjD,MAAIA,iBAAiBQ,yBAA0B,QAAO;AACtD,MAAIT,kBAAkBC,KAAAA,GAAQ;AAC5B,WAAO;EACT;AACA,MAAI,OAAOA,UAAU,YAAYA,UAAU,QAAQ,WAAWA,OAAO;AACnE,UAAMS,QAAST,MAA6BS;AAC5C,QAAIA,UAAUP,UAAaO,UAAUT,SAASD,kBAAkBU,KAAAA,GAAQ;AACtE,aAAO;IACT;EACF;AACA,SAAO;AACT;AAZgBF;AAeT,IAAMG,wCAAwC;AAE9C,IAAMC,0CAA0C;AA4BhD,SAASC,iCACdC,SAA8C;AAE9C,MAAIA,YAAY,OAAO;AACrB,WAAO;EACT;AACA,SAAO;IACLC,UAAUD,SAASC,YAAYJ;IAC/BK,WAAWF,SAASE,aAAaJ;EACnC;AACF;AAVgBC;AA4BhB,SAASI,MAAMC,IAAU;AACvB,SAAO,IAAIC,QAAQ,CAACC,YAAAA;AAClBC,eAAWD,SAASF,EAAAA;EACtB,CAAA;AACF;AAJSD;AAcT,eAAsBK,yBACpBC,IACAT,SACAU,SAAyC;AAEzC,MAAIV,YAAY,OAAO;AACrB,WAAOS,GAAAA;EACT;AACA,QAAMR,WAAWD,QAAQC,YAAYJ;AACrC,QAAMK,YAAYF,QAAQE,aAAaJ;AACvC,QAAMa,WAAWX,QAAQW,YAAYjB;AAErC,MAAIkB,UAAU;AACd,aAAS;AACP,QAAI;AACF,aAAO,MAAMH,GAAAA;IACf,SAAStB,OAAO;AACd,UACEA,iBAAiBQ,4BACjBkB,oBAAoB1B,KAAAA,KACpBuB,SAASI,qBAAqB3B,KAAAA,MAAW,MACzC;AACA,cAAMA;MACR;AACA,YAAM4B,iBAAiBH,UAAUX;AACjC,UAAI,CAACc,kBAAkB,CAACJ,SAASxB,KAAAA,GAAQ;AACvC,cAAMA;MACR;AACAuB,eAASM,UAAUJ,SAASzB,KAAAA;AAC5B,YAAMgB,MAAMD,YAAYU,OAAAA;AACxBA,iBAAW;IACb;EACF;AACF;AAjCsBJ;;;ANuQtB,SAASS,eACPC,OACAC,iBACAC,OAAoC;AAEpC,MAAID,oBAAoBE,QAAW;AACjC,WAAOF;EACT;AACA,SAAOC,UAAUC,SAAY,OAAOC,aAAaJ,OAAOE,KAAAA;AAC1D;AATSH;AAYT,SAASM,kBAAkBC,UAAmB;AAC5C,QAAMC,QAAQD,SACXE,IAAI,CAACC,SAASC,UAAAA;AACb,UAAMC,QAAQF,QAAQG,WAAWT,SAAY,KAAKM,QAAQG,MAAM,MAAM;AACtE,WAAO,IAAIF,QAAQ,CAAA,IAAKC,KAAAA,IAASF,QAAQI,IAAI;EAC/C,CAAA,EACCC,KAAK,MAAA;AACR,SAAO;EAAwBP,KAAAA;;;AACjC;AARSF;AAWT,SAASU,kBAAkBC,SAAe;AACxC,SAAO;EAA2BA,OAAAA;;;AACpC;AAFSD;AAeF,SAASE,UAAaC,OAAoC;AAC/D,QAAMC,UAAUD,MAAMV,IAAI,CAACY,SAASA,KAAAA,CAAAA;AACpC,SAAOC,QAAQC,IACbH,QAAQX,IAAI,CAACe,SACXA,KAAKC,KACH,CAACC,WAAW;IAAEC,IAAI;IAAMD;EAAM,IAC9B,CAACE,WAAoB;IAAED,IAAI;IAAOC;EAAM,EAAA,CAAA,CAAA;AAIhD;AAVgBV;AAqJT,IAAMW,qBAAN,cAAiCC,MAAAA;EAtkBxC,OAskBwCA;;;EACtC,cAAc;AACZ,UAAM,4BAAA;AACN,SAAKC,OAAO;EACd;AACF;AAWO,IAAMC,oBAAN,cAAgCF,MAAAA;EAtlBvC,OAslBuCA;;;EACrC,cAAc;AACZ,UAAM,eAAA;AACN,SAAKC,OAAO;EACd;AACF;AAQO,SAASE,iBAAiBL,OAAc;AAI7C,MAAIA,iBAAiBI,mBAAmB;AACtC,WAAO;EACT;AACA,MAAIJ,iBAAiBC,oBAAoB;AACvC,WAAO;EACT;AACA,MAAID,iBAAiBM,qBAAqB;AACxC,WAAO;EACT;AACA,MAAIN,iBAAiBO,uBAAuB;AAC1C,WAAO;EACT;AACA,MAAIC,uBAAuBR,KAAAA,GAAQ;AACjC,WAAO;EACT;AACA,SAAOS,gBAAgBT,KAAAA,IAAS,oBAAoB;AACtD;AApBgBK;AA2BhB,SAASI,gBAAgBT,OAAc;AACrC,MAAI,EAAEA,iBAAiBE,QAAQ;AAC7B,WAAO;EACT;AACA,SACEF,MAAMG,SAAS,+BACfH,MAAMG,SAAS,4BACfH,MAAMU,QAAQC,WAAW,qBAAA;AAE7B;AATSF;AAiBF,IAAMG,qBAAqB;AAElC,IAAIC;AAOG,SAASC,yBAAyBC,QAA2B;AAClEF,uBAAqBE;AACvB;AAFgBD;AAKhB,IAAME,eAAe,oBAAIC,IAAI;EAAC;EAAkB;EAAmB;CAA4B;AAYxF,SAASC,cAAclB,OAAc;AAC1C,QAAMmB,SAASnB,iBAAiBE,QAAQF,MAAMU,UAAUU,OAAOpB,KAAAA;AAC/D,QAAMqB,OAAOhB,iBAAiBL,KAAAA;AAC9B,MAAIgB,aAAaM,IAAID,IAAAA,GAAO;AAC1B,WAAO;MAAEA;MAAMX,SAASS;IAAO;EACjC;AACA,QAAMI,UAAUV,sBAAsBW,QAAQC,IAAIC,aAAa;AAC/D,SAAO;IAAEL;IAAMX,SAASa,UAAUJ,SAASP;EAAmB;AAChE;AARgBM;AAuBT,IAAMS,uBAAuB;AAU7B,IAAMC,gCAAgC;AAU7C,SAASC,kBAAkBC,MAI1B;AACC,QAAM,EAAEC,MAAMC,OAAOC,YAAW,IAAKH;AAMrC,QAAMI,WAAW;OACXF,MAAMG,kBAAkB,CAAA;OACxBH,MAAMI,cAAc5D,SAAY;MAACwD,MAAMI;QAAa,CAAA;;AAE1D,QAAMC,cAAcH,SAASI,OAAO,CAACnC,SAASA,SAAS8B,WAAAA,EAAaM;AACpE,QAAMC,iBAAiBT,KAAKU,uBAAuBb;AACnD,MAAIS,eAAeG,gBAAgB;AACjC,UAAME,QAAQ;SAAIR;MAAUD;MAAa9C,KAAK,UAAA;AAC9C,UAAMwD,QAAQN,cAAc;AAC5B,WAAO,sBAAsBK,KAAAA,WAAWT,WAAAA,IAAeU,KAAAA;EACzD;AACA,QAAMC,WAAWb,KAAKc,sBAAsBlB;AAC5C,OAAKK,MAAMc,mBAAmB,MAAMF,UAAU;AAC5C,WAAO,8BAA8BA,QAAAA;EACvC;AACA,SAAO;AACT;AA3BSf;AA8BT,eAAekB,cAAcC,QAAgCC,KAAkB;AAC7E,SAAO,OAAOD,WAAW,aAAaA,OAAOC,GAAAA,IAAOD;AACtD;AAFeD;AAUf,eAAeG,oBACbnB,MACAC,OACAmB,SAAgC;AAEhC,QAAMF,MAAMG,cAAcpB,OAAOmB,OAAAA;AAGjC,QAAME,WAAW;IAACF,SAASH,UAAW,MAAMD,cAAchB,KAAKuB,cAAcL,GAAAA;;AAC7E,aAAWM,cAAcxB,KAAKyB,sBAAsB,CAAA,GAAI;AACtD,UAAMC,UAAU,MAAMF,WAAWN,GAAAA;AACjC,QAAIQ,YAAY,QAAQA,QAAQlB,SAAS,GAAG;AAC1Cc,eAASK,KAAKD,OAAAA;IAChB;EACF;AACA,SAAOJ,SAASlE,KAAK,MAAA;AACvB;AAhBe+D;AAmBf,SAASS,eAAe3B,OAAoB;AAC1C,QAAM,EAAEmB,SAASS,UAAU,GAAGC,KAAAA,IAAS7B;AACvC,SAAO6B;AACT;AAHSF;AAMT,SAASP,cAAcpB,OAAsBmB,SAAgC;AAC3E,SAAO;IACLW,OAAO9B,MAAM8B;IACb1B,WAAWJ,MAAMI,aAAa;IAC9B,GAAIJ,MAAM+B,gBAAgBvF,SAAY;MAAEuF,aAAa/B,MAAM+B;IAAY,IAAI,CAAC;IAC5E,GAAI/B,MAAMgC,mBAAmBxF,SAAY;MAAEwF,gBAAgBhC,MAAMgC;IAAe,IAAI,CAAC;IACrF,GAAIb,YAAY3E,SAAY;MAAE2E,SAAS;QAAEc,IAAId,QAAQc;QAAIjF,OAAOmE,QAAQnE;MAAM;IAAE,IAAI,CAAC;EACvF;AACF;AARSoE;AAmBT,eAAec,mBACbnC,MACAC,OAAoB;AAEpB,QAAMmB,UAAUgB,YAAYpC,MAAMC,MAAMmB,OAAO;AAC/C,MAAIA,YAAY3E,QAAW;AACzB,WAAO;EACT;AACA,QAAM4F,MAAM;IAAEH,IAAId,QAAQc;IAAIjF,OAAOmE,QAAQnE;EAAM;AACnD,MAAIgE;AACJ,MAAIG,QAAQG,iBAAiB9E,QAAW;AACtC,UAAMyE,MAAMG,cAAcpB,OAAOoC,GAAAA;AACjC,UAAMC,aACJ,OAAOlB,QAAQG,iBAAiB,aAC5B,MAAMP,cAAchB,KAAKuB,cAAcL,GAAAA,IACvCzE;AACNwE,aAAS,MAAMD,cAAcI,QAAQG,cAAc;MACjD,GAAGL;MACH,GAAIoB,eAAe7F,SAAY;QAAE6F;MAAW,IAAI,CAAC;IACnD,CAAA;EACF;AACA,SAAO;IACL,GAAGD;IACH,GAAIjB,QAAQmB,iBAAiB9F,SAAY;MAAE8F,cAAc;WAAInB,QAAQmB;;IAAc,IAAI,CAAC;IACxF,GAAItB,WAAWxE,SAAY;MAAEwE;IAAO,IAAI,CAAC;EAC3C;AACF;AA1BekB;AAgCf,SAASK,eAAepB,SAAkCqB,UAAgB;AACxE,MAAIrB,SAASmB,iBAAiB9F,UAAa2E,QAAQmB,aAAaG,SAASD,QAAAA,GAAW;AAClF,WAAO;EACT;AACA,SAAO,UAAUA,QAAAA,8BAAsCrB,QAAQc,EAAE;AACnE;AALSM;AAQT,SAASG,YAAY1C,OAAc;AACjC,MAAI,OAAOA,UAAU,YAAYA,UAAU,QAAQ,UAAUA,OAAO;AAClE,UAAMvC,OAAQuC,MAA4BvC;AAC1C,QAAI,OAAOA,SAAS,UAAU;AAC5B,aAAOA;IACT;EACF;AACA,SAAOkF,KAAKC,UAAU5C,KAAAA;AACxB;AARS0C;AAUT,SAASG,YAAYC,UAAgB;AACnC,QAAMC,UAAUD,SAASE,KAAI,EAAGC,QAAQ,QAAQ,GAAA;AAChD,SAAOF,QAAQxC,SAAS,KAAK,GAAGwC,QAAQG,MAAM,GAAG,EAAA,CAAA,QAAWH,WAAW;AACzE;AAHSF;AAMT,IAAMM,mBAAN,MAAMA,0BAAyBjF,MAAAA;EAh2B/B,OAg2B+BA;;;EAC7B,YAAYsE,UAAkBY,IAAY;AACxC,UAAM,SAASZ,QAAAA,kBAA0BY,EAAAA,YAAc;AACvD,SAAKjF,OAAO;EACd;AACF;AAGO,SAASkF,gBAAmBzF,MAAkBwF,IAAYZ,UAAgB;AAC/E,SAAO,IAAI9E,QAAW,CAAC4F,SAASC,WAAAA;AAC9B,UAAMC,QAAQC,WAAW,MAAMF,OAAO,IAAIJ,iBAAiBX,UAAUY,EAAAA,CAAAA,GAAMA,EAAAA;AAC3ExF,SAAKC,KACH,CAACC,UAAAA;AACC4F,mBAAaF,KAAAA;AACbF,cAAQxF,KAAAA;IACV,GACA,CAACE,UAAAA;AACC0F,mBAAaF,KAAAA;AACbD,aAAOvF,KAAAA;IACT,CAAA;EAEJ,CAAA;AACF;AAdgBqF;AAiBhB,SAASM,eAAezG,MAAc0G,OAAa;AACjD,QAAM3G,SAASC,KAAK2G,MAAM,aAAA,IAAiB,CAAA,KAAM3G;AACjD,MAAI;AACF,UAAM4G,SAAkBnB,KAAKoB,MAAM9G,MAAAA;AACnC,QAAI+G,MAAMC,QAAQH,MAAAA,GAAS;AACzB,aAAOA,OAAOxD,OAAO,CAAC4D,SAAyB,OAAOA,SAAS,QAAA,EAAUhB,MAAM,GAAGU,KAAAA;IACpF;EACF,QAAQ;EAER;AACA,SAAO,CAAA;AACT;AAXSD;AAiBT,eAAeQ,kBACbC,OACAC,UACAT,OAAa;AAEb,QAAMU,UAAsB;IAAEC,OAAO,6BAAA;IAAO,GAAP;IAAUC,KAAK,6BAAA;IAAO,GAAP;IAAUC,MAAM,6BAAA;IAAO,GAAP;EAAS;AAC7E,QAAMC,OAAO,MAAMN,MAAMO,QAAQ;IAC/BC,QAAQ,mDAAmDhB,KAAAA;IAC3DS;IACAQ,OAAO,CAAA;IACPC,MAAMR;EACR,CAAA;AACA,SAAO;IACLS,WAAWpB,eAAee,KAAKxH,MAAM0G,KAAAA;IACrCvH,OAAOqI,KAAKrI;IACZ,GAAIqI,KAAKM,YAAYxI,SAAY;MAAEwI,SAASN,KAAKM;IAAQ,IAAI,CAAC;EAChE;AACF;AAjBeb;AAiCf,eAAec,QACbC,OACAC,OACAC,SACAC,KACAC,WAAgD;AAEhD,MAAIxH;AACJ,QAAMyH,MACJ,SACAL,OACA,YAAA;AACEpH,YAAQ,MAAMuH,IAAAA;AACd,WAAOC,UAAUxH,KAAAA;EACnB,GACAsH,SACA;IAAEI,SAASL;EAAM,CAAA;AAEnB,SAAOrH;AACT;AAnBemH;AA0BR,SAASQ,aACdN,OACAO,MACAL,KAAmC;AAEnC,SAAOJ,QAAQ,YAAYE,OAAO;IAAEA;IAAOO;EAAK,GAAGL,KAAK,CAACX,UAAU;IACjE,GAAIA,KAAKM,YAAYxI,SAAY;MAAEwI,SAASN,KAAKM;IAAQ,IAAI,CAAC;IAC9DW,aAAajB,KAAKrI,MAAMsJ;IACxBC,cAAclB,KAAKrI,MAAMuJ;IACzBC,YAAYnB,KAAKxH,KAAKqD;IACtBuF,WAAWpB,KAAKoB,UAAUvF;EAC5B,EAAA;AACF;AAZgBkF;AAmBT,SAASM,mBACdZ,OACAa,MACAX,KAAqB;AAErB,SAAOJ,QAAQ,kBAAkBE,OAAO;IAAEA;IAAO,GAAGa;EAAK,GAAGX,KAAK,OAAO,CAAC,EAAA;AAC3E;AANgBU;AA2BhB,SAASE,gBAAgB5B,UAAyB;AAChD,SAAOA,SAASxH,IAAI,CAAC6B,aAAa;IAChCwH,MAAMxH,QAAQwH;IACdC,SAASzH,QAAQyH;IACjB,GAAIzH,QAAQoH,cAActJ,SAAY;MAAEsJ,WAAWpH,QAAQoH;IAAU,IAAI,CAAC;IAC1E,GAAIpH,QAAQ0H,gBAAgB5J,SAAY;MAAE4J,aAAa1H,QAAQ0H;IAAY,IAAI,CAAC;IAChF,GAAI1H,QAAQ2H,gBAAgB7J,SAAY;MAAE6J,aAAa3H,QAAQ2H;IAAY,IAAI,CAAC;EAClF,EAAA;AACF;AARSJ;AAWT,SAASK,eAAetG,OAAoB;AAC1C,SAAO;IACLuG,UAAUvG,MAAMuG;IAChBzE,OAAO9B,MAAM8B;IACb,GAAI9B,MAAMI,cAAc5D,SAAY;MAAE4D,WAAWJ,MAAMI;IAAU,IAAI,CAAC;EACxE;AACF;AANSkG;AAST,SAASE,aACPC,QACAzG,OACAqE,UAAwB;AAExB,SAAOoC,WAAWjK,SACd;IAAEkK,MAAMrC;IAAUsC,MAAM,CAAA;EAAG,IAC3BF,OAAOG,OAAOvC,UAAUiC,eAAetG,KAAAA,CAAAA;AAC7C;AARSwG;AAuBT,eAAeK,oBACb9G,MACAC,OACA8G,OAAqB;AAErB,QAAMC,WAAW,MAAMD,MAAMpB,KAAK,eAAe,YAAA;AAC/C,UAAMsB,SAAS,MAAMC,kBAAkBlH,MAAMC,MAAMuG,QAAQ;AAG3D,UAAM,EAAEG,MAAMC,KAAI,IAAKH,aACrBzG,KAAKmH,eACLlH,OACA,MAAMmH,cAAcpH,MAAMkG,gBAAgBe,OAAO3C,QAAQ,CAAA,CAAA;AAE3D,WAAO;MACLA,UAAUqC;MACVU,SAASrH,KAAKmH,eAAe5B,cAAc9I,SAAY,CAAA,IAAKmK;MAC5DU,OAAOL,OAAOK;MACdC,qBAAqBN,OAAOM;MAC5BC,oBAAoBxH,KAAKwH,sBAAsB;IACjD;EACF,CAAA;AAIA,SAAO;IAAE,GAAGR;IAAU1C,UAAUmD,wBAAwBT,SAAS1C,QAAQ;EAAE;AAC7E;AA1BewC;AAiCf,eAAeM,cACbpH,MACAsE,UAAwB;AAExB,QAAMoD,WAAWC,oBAAoBrD,QAAAA;AACrC,MAAIoD,SAASlH,WAAW,GAAG;AACzB,WAAO8D;EACT;AACA,QAAMsD,WAAW,MAAMjK,QAAQ4F,QAAQvD,KAAK6H,MAAMC,mBAAmBJ,QAAAA,KAAa,CAAA,CAAE,EAAEK,MACpF,MAAyB,CAAA,CAAE;AAE7B,SAAON,wBAAwBnD,UAAUsD,QAAAA;AAC3C;AAZeR;AAsCf,eAAeF,kBAAkBlH,MAAqBwG,UAAgB;AACpE,QAAMwB,YAAYhI,KAAK6H;AACvB,MAAI,OAAOG,UAAUC,sBAAsB,YAAY;AACrD,UAAMC,eAAeC,iBAAiBnI,KAAKmH,aAAa;AACxD,UAAMiB,OAAO,MAAMJ,UAAUC,kBAAkB;MAC7CzB;MACA,GAAI0B,iBAAiBzL,SAAY;QAAEyL;MAAa,IAAI,CAAC;IACvD,CAAA;AACA,WAAOE,SAAS,OACZ;MAAE9D,UAAU,CAAA;MAAIgD,OAAO;MAAMC,qBAAqB;IAAM,IACxD;MACEjD,UAAU8D,KAAK9D;MACfgD,OAAOc,KAAKd;MACZC,qBAAqBa,KAAKb;IAC5B;EACN;AACA,QAAMN,SAAS,MAAMjH,KAAK6H,MAAMQ,UAAU7B,QAAAA;AAC1C,QAAM8B,SAASrB,QAAQ3C,YAAY,CAAA;AACnC,SAAO;IACLA,UAAUgE;IACVhB,OAAOL,QAAQK,SAAS;IACxBC,qBAAqBe,OAAOC,KAAK,CAAC5J,YAAYA,QAAQwH,SAAS,WAAA;EACjE;AACF;AAvBee;AAuCf,SAASiB,iBAAiBzB,QAAiC;AACzD,MAAIA,WAAWjK,UAAaiK,OAAOnB,cAAc9I,QAAW;AAC1D,WAAOA;EACT;AACA,SAAOiK,OAAO8B;AAChB;AALSL;AAYT,eAAeM,gBACbzI,MACAC,OACA8G,OAAqB;AAErB,QAAME,SAAS,MAAMF,MAAMpB,KAAK,eAAe,MAAM3F,KAAK6H,MAAMQ,UAAUpI,MAAMuG,QAAQ,CAAA;AACxF,QAAM8B,SAASrB,QAAQ3C,YAAY,CAAA;AAGnC,QAAM,EAAEqC,MAAMC,KAAI,IAAKH,aACrBzG,KAAKmH,eACLlH,OACAwH,wBAAwBvB,gBAAgBoC,MAAAA,CAAAA,CAAAA;AAE1C,SAAO;IACLhE,UAAUqC;IACVU,SAAST;IACTU,OAAOL,QAAQK,SAAS;IACxBC,qBAAqBe,OAAOC,KAAK,CAAC5J,YAAYA,QAAQwH,SAAS,WAAA;EACjE;AACF;AApBesC;AA8Bf,eAAeC,mBACbnD,WACAvF,MACAC,OACA8G,OACA4B,SAAoB;AAEpB,QAAMrL,UAAU,MAAMyJ,MAAMpB,KAAK,qBAAqB,MACpDJ,UAAUoD,QAAQtB,SAASd,eAAetG,KAAAA,CAAAA,CAAAA;AAE5C,MAAI3C,QAAQhB,UAAUG,QAAW;AAC/B,UAAMH,QAAQgB,QAAQhB;AACtB,UAAMyK,MAAMpB,KAAK,yBAAyB,MACxC3F,KAAK6H,MAAMe,YAAY;MACrBpC,UAAUvG,MAAMuG;MAChBqC,UAAU5I,MAAM8B,MAAMG;MACtB+C,SAAS3H,QAAQ2H,WAAWjF,KAAKiF,WAAW;MAC5C6D,SAAS;MACTxM;IACF,CAAA,CAAA;EAEJ;AACA,SAAO;IAAC;MAAE6J,MAAM;MAAUC,SAAS/I,kBAAkBC,QAAQH,IAAI;IAAE;OAAMwL,QAAQrE;;AACnF;AAvBeoE;AA0Bf,SAASK,iBAAiB9I,OAAsB0F,MAAY;AAC1D,SAAO;IACLa,UAAUvG,MAAMuG;IAChBzE,OAAO9B,MAAM8B;IACb4D;IACA,GAAI1F,MAAMI,cAAc5D,SAAY;MAAE4D,WAAWJ,MAAMI;IAAU,IAAI,CAAC;IACtE,GAAIJ,MAAMmB,YAAY3E,SAAY;MAAE2E,SAASnB,MAAMmB;IAAQ,IAAI,CAAC;EAClE;AACF;AARS2H;AAqBT,SAASC,kBACP1E,UACA2E,QACAC,gBAAuB;AAEvB,QAAMC,WAAyB;IAAEhD,MAAM;IAAaC,SAAS6C;EAAO;AACpE,MAAIC,gBAAgB;AAClB,WAAO;SAAI5E;MAAU6E;;EACvB;AACA,WAASnM,QAAQsH,SAAS9D,SAAS,GAAGxD,SAAS,GAAGA,SAAS,GAAG;AAC5D,UAAM2B,UAAU2F,SAAStH,KAAAA;AACzB,QAAI2B,SAASwH,SAAS,QAAQ;AAC5B,aAAO;QAACxH;QAASwK;;IACnB;EACF;AACA,SAAO;IAACA;;AACV;AAhBSH;AA2CT,eAAeI,gBACbC,QACArJ,MACAC,OACA8G,OACAzC,UACAqB,MAAY;AAEZ,QAAM2D,cAActJ,KAAKuJ,qBAAqBC;AAC9C,QAAMC,cAAc,KAAKzJ,KAAK0J,wBAAwB;AACtD,QAAMC,mBAAmB3J,KAAK2J,oBAAoB,CAAA;AAClD,MAAIC,SAA4C,CAAA;AAChD,MAAIzM,OAAO;AACX,WAAS0M,UAAU,GAAGA,UAAUJ,aAAaI,WAAW,GAAG;AACzD,UAAMhF,SAASgF,YAAY,IAAIP,cAAcQ,kBAAkBR,aAAaM,MAAAA;AAC5E,UAAMG,QAAQ,MAAMhD,MAAMpB,KAAK,cAAcA,IAAAA,IAAQkE,OAAAA,IAAW,MAC9D3E,QACE,qBACA6B,MAAM3B,OACN;MAAEA,OAAO2B,MAAM3B;MAAOO;MAAMkE;IAAQ,GACpC,YAAA;AACE,YAAMtF,UAAsB;QAAEC,OAAO,6BAAA;QAAO,GAAP;QAAUC,KAAK,6BAAA;QAAO,GAAP;QAAUC,MAAM,6BAAA;QAAO,GAAP;MAAS;AAC7E,YAAMC,OAAO,MAAM3E,KAAKqE,MAAMO,QAAQ;QACpCC;QACAP;QACAQ,OAAO,CAAA;QACPC,MAAMR;QACNyF,cAAcX;MAChB,CAAA;AACA,aAAO;QACLlM,MAAMwH,KAAKxH;QACXb,OAAOqI,KAAKrI;QACZ,GAAIqI,KAAKsF,WAAWxN,SAAY;UAAEwN,QAAQtF,KAAKsF;QAAO,IAAI,CAAC;QAC3D,GAAItF,KAAKM,YAAYxI,SAAY;UAAEwI,SAASN,KAAKM;QAAQ,IAAI,CAAC;MAChE;IACF,GACA,CAACiF,aAAY;MACXtE,aAAasE,QAAO5N,MAAMsJ;MAC1BC,cAAcqE,QAAO5N,MAAMuJ;MAC3BC,YAAYoE,QAAO/M,KAAKqD;IAC1B,EAAA,CAAA;AAGJ,UAAMuG,MAAMpB,KAAK,4BAA4BA,IAAAA,IAAQkE,OAAAA,IAAW,MAC9D7J,KAAK6H,MAAMe,YAAY;MACrBpC,UAAUvG,MAAMuG;MAChBqC,UAAU5I,MAAM8B,MAAMG;MACtB+C,SAAS8E,MAAM9E,WAAWjF,KAAKiF,WAAW;MAC1C6D,SAAS;MACTxM,OAAOyN,MAAMzN;IACf,CAAA,CAAA;AAEFa,WAAO4M,MAAM5M;AACb,QAAIwM,iBAAiBnJ,SAAS,GAAG;AAI/B,YAAM2J,OAAO,MAAMpD,MAAMpB,KAAK,6BAA6BA,IAAAA,IAAQkE,OAAAA,IAAW,MAC5EO,oBACET,kBACA;QAAExM,MAAM4M,MAAM5M;QAAM4I,WAAW,CAAA;MAAG,GAClCgD,iBAAiB9I,OAAO0F,IAAAA,CAAAA,CAAAA;AAG5B,UAAIwE,KAAKE,cAAc5N,QAAW;AAChC,cAAM,IAAI8B,oBAAoB4L,KAAKE,UAAUC,WAAWH,KAAKE,UAAUE,MAAM;MAC/E;AACApN,aAAOgN,KAAKhN;IACd;AAIA,UAAMqN,WAAWrN,SAAS4M,MAAM5M,OAAO4M,MAAME,SAASxN;AACtD,UAAMgO,UAAU,MAAMC,mBAAmBrB,QAAQlM,MAAMqN,QAAAA;AACvD,QAAIC,QAAQzM,IAAI;AACd,aAAOyM,QAAQ1M;IACjB;AACA6L,aAASa,QAAQb;EACnB;AACA,QAAM,IAAIpL,sBAAsBoL,QAAQzM,MAAMsM,WAAAA;AAChD;AAhFeL;AAsGR,SAASuB,eACdT,SACAlK,MAAkB;AAElB,SAAO;IACL,GAAGkK;IACHnE,WAAWmE,QAAOnE,UAAUjJ,IAAI,CAACmJ,SAAAA;AAE/B,YAAM,EACJ2E,WAAWC,YACXC,UAAUC,oBACVC,gBAAgBC,oBAChB,GAAGC,QAAAA,IACDjF;AACJ,aAAOiF,QAAQC,SAAS1O,SACpB;QAAE,GAAGyO;QAASC,MAAMC,aAAapL,MAAMkL,QAAQ9M,IAAI;MAAE,IACrD8M;IACN,CAAA;EACF;AACF;AAnBgBP;AA8BhB,SAASS,aAAapL,MAAoB5B,MAAY;AACpD,MAAI4B,KAAKqL,QAAQ,QAAQjN,SAASkN,eAAe;AAC/C,WAAO;EACT;AAGA,MAAItL,KAAKuL,WAAW9O,UAAa2B,SAASoN,iBAAiB;AACzD,WAAO;EACT;AACA,MAAIC,iBAAiBzL,IAAAA,KAAS5B,SAASsN,oBAAoB;AACzD,WAAO;EACT;AACA,SAAO1L,KAAK2L,SAASC,KAAKxN,IAAAA,GAAO+M,QAAQ;AAC3C;AAbSC;AAqBT,SAASK,iBAAiBzL,MAAmC;AAC3D,SAAOA,KAAK6L,QAAQC,SAAStH,UAAU/H;AACzC;AAFSgP;AAQF,SAASM,YAAY,EAC1BjH,OACAuG,IAAG,GACmD;AACtD,SAAOA,QAAQ,OAAO;OAAIvG;IAAOkH,kBAAAA;MAAuBlH;AAC1D;AALgBiH;AAoBhB,eAAeE,iBACblF,OACAmF,SACAhL,KAAc;AAEd,MAAI6F,MAAMoF,iBAAiB1P,QAAW;AACpC,WAAO2P,0BAA0B,MAAMrF,MAAMoF,aAAaD,SAAShL,GAAAA,CAAAA;EACrE;AACA,SAAOkL,0BACL,MAAMrF,MAAMsF,cACV;IAAEnK,IAAIgK,QAAQhK;IAAI9D,MAAMkN;IAAerL,OAAOiM;IAASf,MAAM;EAAM,GACnEjK,GAAAA,CAAAA;AAGN;AAde+K;AAoBR,SAASK,gBACdpL,KACAqL,YAAkB;AAElB,SAAO;IAAE,GAAGrL;IAAKqL;IAAYC,gBAAgB,GAAGtL,IAAIkE,KAAK,IAAImH,UAAAA;EAAa;AAC5E;AALgBD;AAQhB,SAASG,YAAYzM,MAAqBC,OAAsB8G,OAAqB;AACnF,SAAO;IACLhF,OAAO9B,MAAM8B;IACbyE,UAAUvG,MAAMuG;IAChBpB,OAAO2B,MAAM3B;IACbsH,WAAW3F,MAAM3B;IACjB,GAAInF,MAAMI,cAAc5D,SAAY;MAAE4D,WAAWJ,MAAMI;IAAU,IAAI,CAAC;IACtE,GAAIJ,MAAMmB,YAAY3E,SAAY;MAAE2E,SAASnB,MAAMmB;IAAQ,IAAI,CAAC;IAChE,GAAInB,MAAM+B,gBAAgBvF,SAAY;MAAEuF,aAAa/B,MAAM+B;IAAY,IAAI,CAAC;IAC5E,GAAI/B,MAAMgC,mBAAmBxF,SAAY;MAAEwF,gBAAgBhC,MAAMgC;IAAe,IAAI,CAAC;IACrF,GAAIjC,KAAK2M,SAASlQ,SAAY;MAAEkQ,MAAM3M,KAAK2M;IAAK,IAAI,CAAC;;;IAGrDC,QAAQC,iBAAiB9F,MAAM3B,KAAK;EACtC;AACF;AAfSqH;AAyBT,SAASK,cAAcC,QAAqBC,oBAA2B;AACrE,SAAOD,OAAOE,SAAS,gBAAgB,CAACD;AAC1C;AAFSF;AAkBT,eAAeI,UACbH,QACA/M,MACAC,OACA8G,OACAoG,QACAH,oBAA2B;AAE3B,QAAMI,WAAWL,OAAOK,YAAYC;AAGpC,QAAMnB,UAA8B;IAClChK,IAAI,UAAU6E,MAAM3B,KAAK;IACzBlI,QAAQ;IACRkQ;IACAE,WAAWP,OAAOO;EACpB;AACA,QAAMrH,OAAwB;IAC5B/D,IAAIgK,QAAQhK;IACZ9D,MAAMkN;IACNrL,OAAO;MAAEmN;MAAUE,WAAWP,OAAOO;IAAU;IAC/CnC,MAAM;EACR;AAGA,QAAMoC,QAAQ,MAAMxG,MAAMpB,KAAK,cAAc,YAAA;AAC3C,QAAI,CAACmH,cAAcC,QAAQC,kBAAAA,GAAqB;AAC9C,aAAO;IACT;AACA,UAAMrO,UAAU,MAAMqB,KAAK6H,MAAM2F,cAAc;MAC7ChH,UAAUvG,MAAMuG;MAChBL,MAAM;MACNC,SAASgH;MACThI,OAAO2B,MAAM3B;MACbW,WAAW;QAACE;;MACZ,GAAIhG,MAAMI,cAAc5D,SAAY;QAAE4D,WAAWJ,MAAMI;MAAU,IAAI,CAAC;MACtE,GAAIJ,MAAMmB,YAAY3E,SAAY;QAAE2E,SAASnB,MAAMmB;MAAQ,IAAI,CAAC;IAClE,CAAA;AACA,UAAMpB,KAAK6H,MAAM4F,eAAe;MAC9BlB,YAAYL,QAAQhK;MACpBwL,WAAW/O,QAAQuD;MACnBO,UAAU6I;;;;MAIVqC,UAAU;MACV1N,OAAOgG,KAAKhG;MACZ2N,QAAQ;MACRxI,OAAO2B,MAAM3B;IACf,CAAA;AACA,UAAM+H,OAAO3I,MAAMqJ,kBAAkB;MAAE1C,MAAM;MAAejJ,IAAIgK,QAAQhK;MAAIgK;IAAQ,CAAA,CAAA;AACpF,WAAO;MAAEwB,WAAW/O,QAAQuD;IAAG;EACjC,CAAA;AACA,MAAIqL,UAAU,MAAM;AAClB,WAAO;EACT;AACA,QAAMG,YAAYH,MAAMG;AACxB,QAAM3D,QAAQ,MAAMkC,iBAAiBlF,OAAOmF,SAASO,YAAYzM,MAAMC,OAAO8G,KAAAA,CAAAA;AAC9E,QAAMmD,UAAS4D,kBAAkB5B,SAASnC,KAAAA;AAC1C,QAAMhD,MAAMpB,KAAK,kBAAkB,YAAA;AACjC,UAAM3F,KAAK6H,MAAMkG,eAAe;MAC9BxB,YAAYL,QAAQhK;;;;MAIpB0L,QAAQ1D,QAAO8D,UAAU,aAAa;MACtCC,QAAQ/D;MACR,GAAIA,QAAO8D,UAAU;QAAE/P,OAAO;MAAsB,IAAI,CAAC;MACzD,GAAI8L,MAAMmE,kBAAkBzR,SAAY;QAAE0R,eAAepE,MAAMmE;MAAc,IAAI,CAAC;IACpF,CAAA;AACA,UAAMlO,KAAK6H,MAAMuG,sBAAsBV,WAAW;MAChD;QAAExL,IAAIgK,QAAQhK;QAAI9D,MAAMkN;QAAe2C,QAAQ/D;MAAO;KACvD;AACD,UAAMiD,OAAO3I,MAAMqJ,kBAAkB;MAAE1C,MAAM;MAAejJ,IAAIgK,QAAQhK;MAAI+L,QAAQ/D;IAAO,CAAA,CAAA;EAC7F,CAAA;AACA,SAAO;IACL/D,MAAM;IACNC,SAASgH;IACTrH,WAAW;MAACE;;IACZI,aAAa;MAAC;QAAEnE,IAAIgK,QAAQhK;QAAI9D,MAAMkN;QAAe2C,QAAQ/D;MAAO;;EACtE;AACF;AAjFegD;AAwFf,IAAMmB,uBAAuB;AAO7B,IAAMC,qBAAqB;AAgB3B,IAAMC,yBAAyB;AA6B/B,IAAMC,sBAAsB;AA4C5B,eAAeC,oBACbzO,MACA+G,OAAqB;AAErB,QAAM2H,aAA2B;IAC/B7C,QAAQ7L,KAAK6L,WAAWpP;IACxBkS,WAAW3O,KAAK2O,cAAclS;IAC9B8O,QAAQvL,KAAKuL,WAAW9O;EAC1B;AACA,SAAQ,OAAOsK,MAAM6H,UAAUJ,mBAAAA,KAAwB7Q,QAAQ4F,QAAQ,IAAA,KACnEwD,MAAMpB,KAAK,qBAAqB,MAAMhI,QAAQ4F,QAAQmL,UAAAA,CAAAA,IACtDA;AACN;AAZeD;AAqBf,IAAMI,kBAAgC;EAAEC,QAAQ,CAAA;EAAIC,SAAS,CAAA;EAAIC,SAAS;EAAGC,eAAe;AAAE;AAC9F,IAAMC,kBAA8B;EAAEJ,QAAQ,CAAA;EAAIC,SAAS,CAAA;EAAIC,SAAS;AAAE;AAe1E,eAAeG,gBACbpI,OACAqI,aACAhR,MAAY;AAEZ,QAAMiR,UAAUtI,MAAMuI;AACtB,MAAI,CAACF,eAAeC,YAAY5S,QAAW;AACzC;EACF;AACA,MAAI,MAAMsK,MAAMpB,KAAKvH,MAAM,MAAMiR,QAAAA,CAAAA,GAAY;AAC3C,UAAM,IAAIhR,kBAAAA;EACZ;AACF;AAZe8Q;AA+Hf,eAAeI,cACb5K,MACAsB,MAAqB;AAErB,QAAM,EAAEjG,MAAMC,OAAO8G,OAAO2G,UAAS,IAAK/I;AAC1C,QAAM6K,YAAa,MAAMzI,MAAMpB,KAAK,oBAAoBM,KAAK/D,EAAE,IAAI,YAAA;AACjE,UAAM0J,OAAO5L,KAAK2L,SAASC,KAAK3F,KAAK7H,IAAI;AACzC,UAAM+M,OAAiBlF,KAAKkF,QAAQC,aAAapL,MAAMiG,KAAK7H,IAAI;AAGhE,UAAMqR,cAActE,SAAS,YAAYA,SAAS;AAKlD,UAAMuE,sBACJ/K,KAAK6C,uBAAuB,iBAAiB2D,SAAS,WAClDpE,MAAM4I,gBAAgBlT,UAAawJ,KAAK+E,mBAAmBvO,SACzDwJ,KAAK+E,iBACL,MAAM4E,8BAA8B;MAClC7N,OAAO9B,MAAM8B;MACb8F,OAAO7H,KAAK6H;MACZgI,MAAM;QAAEzR,MAAM6H,KAAK7H;QAAM+M,MAAM;QAAU,GAAIS,SAASnP,SAAY;UAAEmP;QAAK,IAAI,CAAC;MAAG;MACjF3E,QAAQ;QACNT,UAAUvG,MAAMuG;QAChBpB,OAAO2B,MAAM3B;QACb,GAAInF,MAAMI,cAAc5D,SAAY;UAAE4D,WAAWJ,MAAMI;QAAU,IAAI,CAAC;MACxE;MACA,GAAIL,KAAK8P,mBAAmBrT,SAAY;QAAEiK,QAAQ1G,KAAK8P;MAAe,IAAI,CAAC;IAC7E,CAAA,IACFrT;AACN,QAAImO;AACJ,QAAIE;AACJ,QACEnG,KAAK6C,uBAAuB,iBAC5BvB,KAAK6E,aAAarO,UAClBsK,MAAM4I,gBAAgBlT,OAEtBqO,YAAW7E,KAAK6E;AAClB,QAAIK,SAAS,YAAYpE,MAAM4I,gBAAgBlT,UAAawJ,KAAK2E,cAAcnO,QAAW;AACxFmO,kBAAY3E,KAAK2E;IACnB,WAAWO,SAAS,YAAYpE,MAAM4I,gBAAgBlT,UAAamP,SAASnP,QAAW;AAGrFmO,kBAAY;QAAEgD,QAAQ;MAAQ;IAChC,WAAWzC,SAAS,UAAU;AAC5B,UAAI;AACF,cAAM5I,eACJoC,KAAKvD,SAASmB,iBAAiB9F,SAC3BuD,KAAK+P,gBACLC,oBAAoBhQ,KAAK+P,eAAepL,KAAKvD,QAAQmB,YAAY;AACvE,YAAImN,qBAAqBO,SAAS,OAAO;AACvCnF,qBAAW,MAAMoF,sBACflQ,KAAK2L,UACL1F,KAAK7H,MACL6H,KAAKhG,OACLqM,gBAAgBG,YAAYzM,MAAMC,OAAO8G,KAAAA,GAAQd,KAAK/D,EAAE,GACxDlC,KAAKmQ,aACL5N,iBAAiB9F,SAAY,CAAC,IAAI;YAAE8F;UAAa,CAAA;AAEnDqI,sBAAYE,SAASF;QACvB,OAAO;AACLA,sBAAY,MAAM5K,KAAK2L,SAASyE,QAC9BnK,KAAK7H,MACL6H,KAAKhG,OACLqM,gBAAgBG,YAAYzM,MAAMC,OAAO8G,KAAAA,GAAQd,KAAK/D,EAAE,GACxDlC,KAAKmQ,aACL5N,iBAAiB9F,SAAY,CAAC,IAAI;YAAE8F;UAAa,CAAA;QAErD;MACF,SAAStE,OAAO;AACd,YACE8I,MAAMsJ,qBAAqBpS,KAAAA,MAAW,QACtCqS,oBAAoBrS,KAAAA,KACpBQ,uBAAuBR,KAAAA,EAEvB,OAAMA;AACR2M,oBAAY;UACVgD,QAAQ;UACR3P,OAAOA,iBAAiBE,QAAQF,MAAMU,UAAUU,OAAOpB,KAAAA;QACzD;MACF;IACF;AACA,QAAIsS,eAAe3F,WAAWgD,WAAW,UAAUhD,UAAU2F,eAAe9T;AAC5E,UAAM+T,WACJrF,SAAS,YAAYP,WAAWgD,WAAW,UACtC8B,uBAAwB,MAAMe,cAAc9L,MAAMsB,MAAM2F,IAAAA,IACzDnP;AACN,QAAIiU;AACJ,QAAI/L,KAAK6C,uBAAuB,iBAAiBgJ,UAAUP,SAAS,OAAO;AACzE,UAAI,CAACnF,SAAU,OAAM,IAAI3M,MAAM,iDAAA;AAC/B,YAAMwS,gBAAgB3Q,KAAK6H;AAC3B,UAAI,OAAO8I,cAAcC,yBAAyB,WAChD,OAAM,IAAIzS,MAAM,+CAAA;AAClBuS,mBAAa,YAAYG,WAAW,QAAA,EACjCC,OAAOlO,KAAKC,UAAU;QAACkE,MAAM3B;QAAOa,KAAK/D;OAAG,CAAA,EAC5C6O,OAAO,KAAA,CAAA;AACV,YAAMC,UAAUT,gBACd3E,MAAMqF,cAAcC,WAAW;QAAE5J,OAAO,SAASrB,KAAK7H,IAAI;QAAK+S,MAAM;MAAU;AACjF,YAAMC,OAAO,wBAACrT,UACZA,MAAMmF,QAAQ,gBAAgB,CAACmO,QAAQC,SAAAA;AACrC,YAAIC,UAAmBzG,UAAU7K;AACjC,mBAAWuR,QAAQF,KAAKG,MAAM,GAAA,EAC5BF,WACEA,YAAY,QAAQ,OAAOA,YAAY,WAClCA,QAAoCC,IAAAA,IACrC/U;AACR,eAAO8U,YAAY9U,SAAY,KAAK4C,OAAOkS,OAAAA;MAC7C,CAAA,GATW;AAUb,YAAMG,SACJ5G,SAAS6G,mBAAmBlV,SACxBkU,cAAcC,qBAAqBgB,KAAKjB,aAAAA,KACvC,MAAA;AACC,cAAM9I,QAAQ8I;AAGd,YAAI,OAAO9I,MAAMgK,kCAAkC,WACjD,OAAM,IAAI1T,MAAM,4DAAA;AAClB,eAAO0J,MAAMgK,8BAA8BD,KAAK/J,KAAAA;MAClD,GAAA;AACN,YAAMiK,UAAU,MAAMJ,OAAO;QAC3B,GAAI5G,SAAS6G,mBAAmBlV,SAC5B;UAAEkV,gBAAgB7G,SAAS6G;QAAe,IAC1C,CAAC;QACLzP,IAAIwO;QACJqB,WAAW9R,MAAM8B,MAAMgQ,aAAa;QACpClJ,UAAU5I,MAAM8B,MAAMG;QACtBsE,UAAUvG,MAAMuG;QAChBwL,aAAajL,MAAM3B;QACnB6M,iBAAiBvE;QACjBwE,kBAAkBjM,KAAK/D;QACvBO,UAAUwD,KAAK7H;QACf6B,OAAO6K,SAAS7K;QAChBkS,kBAAkBrH,SAASqH;QAC3BC,kBAAkB;UAChB1F,WAAW3F,MAAM3B;UACjB,GAAInF,MAAMI,cAAc5D,SAAY;YAAE4D,WAAWJ,MAAMI;UAAU,IAAI,CAAC;UACtE,GAAIJ,MAAMmB,YAAY3E,SAAY;YAAE2E,SAASnB,MAAMmB;UAAQ,IAAI,CAAC;UAChE,GAAInB,MAAM+B,gBAAgBvF,SAAY;YAAEuF,aAAa/B,MAAM+B;UAAY,IAAI,CAAC;UAC5E,GAAI/B,MAAMgC,mBAAmBxF,SAAY;YAAEwF,gBAAgBhC,MAAMgC;UAAe,IAAI,CAAC;QACvF;QACAsO,cAAcA,gBAAgB;UAC5BjJ,OAAO8J,KAAKJ,QAAQ1J,KAAK;UACzB6J,MAAMC,KAAKJ,QAAQG,IAAI;UACvB,GAAIH,QAAQ5R,WAAW3C,SAAY;YAAE2C,QAAQgS,KAAKJ,QAAQ5R,MAAM;UAAE,IAAI,CAAC;QACzE;QACAiT,UAAU7B,SAAS6B;QACnBC,WAAW9B,SAAS8B,cAAc7V,SAAY,OAAO8V,KAAKvO,MAAMwM,SAAS8B,SAAS;QAClF9F,gBAAgBF,gBAAgBG,YAAYzM,MAAMC,OAAO8G,KAAAA,GAAQd,KAAK/D,EAAE,EAAEsK;MAC5E,CAAA;AACA,UAAIsF,QAAQlE,WAAW,WAAY,OAAM,IAAIzP,MAAM,yCAAA;AACnDoS,qBAAeuB,QAAQU,UAAUjC,gBAAgBA;IACnD;AACA,UAAMkC,QAAQtH,SAAS,SAAUqF,UAAUP,SAAS,SAASS,eAAejU;AAC5E,UAAMuD,KAAK6H,MAAM4F,eAAe;MAC9BlB,YAAYtG,KAAK/D;MACjBwL;MACAjL,UAAUwD,KAAK7H;MACfuP,UAAU8B,cAAc,WAAW;MACnCxP,OAAOgG,KAAKhG;MACZ2N,QAAQ8C,eAAejU,SAAY,aAAagW,QAAQ,qBAAqB;MAC7E,GAAI/B,eAAejU,SAAY;QAAEiU;MAAW,IAAI,CAAC;MACjDtL,OAAO2B,MAAM3B;MACb,GAAImL,iBAAiB9T,SAAY;QAAE8T;MAAa,IAAI,CAAC;MACrD,GAAIC,aAAa/T,UAAa+T,SAASP,SAAS,SAC5C;QAAEoC,UAAU7B,SAAS6B;MAAS,IAC9B,CAAC;MACL,GAAI7B,UAAUP,SAAS,SAASO,SAAS8B,cAAc7V,SACnD;QAAE6V,WAAW9B,SAAS8B;MAAU,IAChC,CAAC;IACP,CAAA;AACA,QAAI9B,UAAUP,SAAS,OAAO;AAG5B,YAAMtL,KAAKwI,OAAO3I,MAChBqJ,kBAAkB;QAChB1C,MAAM;QACNjJ,IAAI+D,KAAK/D;QACT,GAAIwO,eAAejU,SACf;UAAEiW,QAAQ;YAAEvH,MAAM;YAAqBuF;UAAW;QAAE,IACpD,CAAC;QACL2B,UAAU7B,SAAS6B;QACnB,GAAI9B,iBAAiB9T,SAAY;UAAE8T;QAAa,IAAI,CAAC;QACrD,GAAIC,SAAS8B,cAAc7V,SAAY;UAAE6V,WAAW9B,SAAS8B;QAAU,IAAI,CAAC;MAC9E,CAAA,CAAA;IAEJ;AACA,WAAO;MACLnH;MACA,GAAIS,MAAM1L,gBAAgBzD,SAAY;QAAEyD,aAAa0L,KAAK1L;MAAY,IAAI,CAAC;;;MAG3E,GAAI0L,MAAM+G,aAAa,OAAO;QAAEA,UAAU;MAAK,IAAI,CAAC;;;MAGpD,GAAI/G,MAAMgH,aAAa,OAAO;QAAEA,UAAU;MAAK,IAAI,CAAC;;MAEpD,GAAIhI,WAAWgD,WAAW,eAAe5N,KAAK2L,SAASkH,gBAAgB5M,KAAK7H,IAAI,IAC5E;QAAE0U,2BAA2B;MAAK,IAClC,CAAC;MACL,GAAItC,aAAa/T,SAAY;QAAE+T;MAAS,IAAI,CAAC;MAC7C,GAAI5F,cAAcnO,SAAY;QAAEmO;MAAU,IAAI,CAAC;MAC/C,GAAI8F,eAAejU,SAAY;QAAEiU;MAAW,IAAI,CAAC;IACnD;EACF,CAAA;AAYA,QAAM/C,WAAqB6B,WAAWrE,QAAQlF,KAAKkF,QAAQ;AAC3D,SAAO;IACLlF;;;IAGA8M,cAAc9M,KAAKkF,SAASwC,WAAW1H,OAAO;MAAE,GAAGA;MAAMkF,MAAMwC;IAAS;IACxEA;IACA,GAAI6B,WAAWtP,gBAAgBzD,SAAY;MAAEyD,aAAasP,UAAUtP;IAAY,IAAI,CAAC;IACrF,GAAIsP,WAAWmD,aAAa,OAAO;MAAEA,UAAU;IAAK,IAAI,CAAC;IACzD,GAAInD,WAAWoD,aAAa,OAAO;MAAEA,UAAU;IAAK,IAAI,CAAC;IACzD,GAAIpD,WAAWsD,8BAA8B,OAAO;MAAEA,2BAA2B;IAAK,IAAI,CAAC;IAC3F,GAAInF,aAAa,YAAY6B,WAAWgB,aAAa/T,SACjD;MAAE+T,UAAUhB,UAAUgB;IAAS,IAC/B,CAAC;IACL,GAAIhB,WAAW5E,cAAcnO,SAAY;MAAEmO,WAAW4E,UAAU5E;IAAU,IAAI,CAAC;IAC/E,GAAI4E,WAAWkB,eAAejU,SAAY;MAAEiU,YAAYlB,UAAUkB;IAAW,IAAI,CAAC;IAClFxP,KAAKuL,YAAYzM,MAAMC,OAAO8G,KAAAA;EAChC;AACF;AA1OewI;AAiPf,eAAekB,cACb9L,MACAsB,MACA2F,MAA0B;AAE1B,QAAM,EAAE5L,MAAMC,OAAO8G,MAAK,IAAKpC;AAC/B,QAAM+B,SAAS1G,KAAK8P,kBAAkB,IAAIkD,sBAAAA;AAC1C,QAAMC,cAAmC,MAAMvM,OAAOwM,eACpD;IAAE9U,MAAM6H,KAAK7H;IAAM+M,MAAM;IAAU,GAAIS,SAASnP,SAAY;MAAEmP;IAAK,IAAI,CAAC;EAAG,GAC3E3L,MAAM8B,OACN;IACEyE,UAAUvG,MAAMuG;IAChBpB,OAAO2B,MAAM3B;IACb,GAAInF,MAAMI,cAAc5D,SAAY;MAAE4D,WAAWJ,MAAMI;IAAU,IAAI,CAAC;EACxE,CAAA;AAEF,MAAI,CAAC4S,YAAYE,UAAU;AACzB,WAAO;MAAElD,MAAM;IAAO;EACxB;AACA,QAAMmD,aAAc,MAAMpT,KAAK6H,MAAMwL,sBAAsBpT,MAAMuG,QAAQ,KAAM,CAAA;AAC/E,MAAI4M,WAAW1Q,SAASuD,KAAK7H,IAAI,GAAG;AAClC,WAAO;MAAE6R,MAAM;MAAcoC,UAAUY,YAAYZ;IAAS;EAC9D;AACA,QAAMiB,QACJL,YAAYK,UAAU7W,UAAa8W,OAAOC,SAASP,YAAYK,KAAK,KAAKL,YAAYK,QAAQ,IACzFG,KAAKC,MAAMT,YAAYK,KAAK,IAC5B7W;AACN,SAAO;IACLwT,MAAM;IACNoC,UAAUY,YAAYZ;IACtB,GAAIiB,UAAU7W,SACV;MAAE6W;MAAOhB,WAAW,IAAIC,KAAKA,KAAKoB,IAAG,IAAKL,KAAAA,EAAOM,YAAW;IAAG,IAC/D,CAAC;EACP;AACF;AAlCenD;AA6Df,eAAeoD,kBACblP,MACAmP,SACAC,WAAiB;AAEjB,QAAM,EAAE/T,MAAMC,OAAO8G,MAAK,IAAKpC;AAC/B,QAAM,EAAEsB,KAAI,IAAK6N;AACjB,QAAME,SAAShU,KAAKuL;AACpB,QAAM0I,QAAQtP,KAAK4G;AACnB,QAAMd,UAAU,MAAM1D,MAAMpB,KAC1B,QAAQM,KAAK/D,EAAE,IACf,YAAA;AACE,QAAI8R,WAAWvX,UAAawX,UAAUxX,QAAW;AAI/C,aAAO;QAAEuB,IAAI;QAAOC,OAAO;MAA+C;IAC5E;AACA,UAAM8F,SAAS,MAAMmQ,iBAAiB,WAAA,EAAaC,SAASlO,KAAKhG,KAAK;AACtE,QAAI8D,OAAO6F,WAAWnN,QAAW;AAC/B,aAAO;QACLuB,IAAI;QACJC,OAAO,wBAAwB8F,OAAO6F,OAAO9M,IAAI,CAACsX,SAAS,IAAIA,KAAK9C,QAAQ,CAAA,GAAIlU,KAAK,GAAA,KAAQ,QAAA,KAAagX,KAAKzV,OAAO,EAAE,EAAEvB,KAAK,IAAA,CAAA;MACjI;IACF;AACA,UAAMiX,SAAS,MAAMC,UAAUN,QAAQC,OAAOlQ,OAAOhG,MAAMK,MAAMmW,aAAatU,KAAAA,CAAAA;AAC9E,QAAI,CAACoU,OAAOrW,IAAI;AACd,aAAO;QAAEA,IAAI;QAAOC,OAAOoW,OAAOpW;MAAM;IAC1C;AACA,WAAO;MACLD,IAAI;MACJiQ,QAAQ;QACN7P,MAAMiW,OAAOG,MAAMpW;QACnBqW,OAAOJ,OAAOG,MAAMC;QACpBC,MAAML,OAAOG,MAAME;QACnB,GAAIL,OAAOM,YAAYlY,SAAY;UAAEkY,SAASN,OAAOM;QAAQ,IAAI,CAAC;MACpE;IACF;EACF,CAAA;AAEF,SAAOlK,QAAQzM,KACX;IAAE4P,QAAQ;IAAYK,QAAQxD,QAAQwD;IAAQ2G,aAAarC,KAAKoB,IAAG,IAAKI;EAAU,IAClF;IAAEnG,QAAQ;IAAU3P,OAAOwM,QAAQxM;IAAO2W,aAAarC,KAAKoB,IAAG,IAAKI;EAAU;AACpF;AA3CeF;AA0Df,eAAegB,iBACblQ,MACAmP,SACAC,WAAiB;AAEjB,QAAM,EAAE/T,MAAMC,OAAO8G,MAAK,IAAKpC;AAC/B,QAAM,EAAEsB,KAAI,IAAK6N;AACjB,QAAME,SAAShU,KAAK6L;AACpB,QAAMkF,SAASpM,KAAKkH;AACpB,QAAMpB,UAAU,MAAM1D,MAAMpB,KAC1B,QAAQM,KAAK/D,EAAE,IACf,YAAA;AACE,QAAI8R,WAAWvX,UAAasU,WAAWtU,QAAW;AAIhD,aAAO;QAAEuB,IAAI;QAAOC,OAAO;MAA8C;IAC3E;AACA,UAAM8F,SAAS,MAAM+Q,oBAAoB,WAAA,EAAaX,SAASlO,KAAKhG,KAAK;AACzE,QAAI8D,OAAO6F,WAAWnN,QAAW;AAC/B,aAAO;QACLuB,IAAI;QACJC,OAAO,2BAA2B8F,OAAO6F,OAAO9M,IAAI,CAACsX,SAAS,IAAIA,KAAK9C,QAAQ,CAAA,GAAIlU,KAAK,GAAA,KAAQ,QAAA,KAAagX,KAAKzV,OAAO,EAAE,EAAEvB,KAAK,IAAA,CAAA;MACpI;IACF;AACA,WAAO,MAAM2X,YAAY;MACvBf;MACAjD;MACA9K,MAAMlC,OAAOhG;MACbmD,KAAKqT,aAAatU,KAAAA;MAClBmF,OAAO2B,MAAM3B;IACf,CAAA;EACF,CAAA;AAEF,MAAI,CAACqF,QAAQzM,IAAI;AACf,WAAO;MAAE4P,QAAQ;MAAU3P,OAAOwM,QAAQxM;MAAO2W,aAAarC,KAAKoB,IAAG,IAAKI;IAAU;EACvF;AACAiB,4BAA0B;IACxB5P,OAAO2B,MAAM3B;IACbqP,OAAOhK,QAAQwK,OAAOR;IACtBS,OAAOzK,QAAQwK,OAAO9X,KAAKqD;EAC7B,CAAA;AACA,SAAO;IAAEoN,QAAQ;IAAYK,QAAQxD,QAAQwK;IAAQL,aAAarC,KAAKoB,IAAG,IAAKI;EAAU;AAC3F;AA3Cec;AA8Cf,SAASN,aAAatU,OAAoB;AACxC,SAAO;IACL8B,OAAO9B,MAAM8B;IACbyE,UAAUvG,MAAMuG;IAChB,GAAIvG,MAAMI,cAAc5D,SAAY;MAAE4D,WAAWJ,MAAMI;IAAU,IAAI,CAAC;IACtE,GAAIJ,MAAM+B,gBAAgBvF,SAAY;MAAEuF,aAAa/B,MAAM+B;IAAY,IAAI,CAAC;IAC5E,GAAI/B,MAAMgC,mBAAmBxF,SAAY;MAAEwF,gBAAgBhC,MAAMgC;IAAe,IAAI,CAAC;EACvF;AACF;AARSsS;AAqBT,eAAeY,kBACbxQ,MACAmP,SAAwB;AAExB,QAAM,EAAE9T,MAAMC,OAAO8G,MAAK,IAAKpC;AAC/B,QAAM,EAAEsB,MAAM8M,cAAc7R,IAAG,IAAK4S;AAGpC,QAAMnG,WAAWmG,QAAQnG,aAAa,WAAW,WAAW;AAC5D,QAAMoG,YAAYxB,KAAKoB,IAAG;AAC1B,MAAI;AAGF,QAAIG,QAAQnG,aAAa,SAAS;AAChC,aAAO,MAAMkG,kBAAkBlP,MAAMmP,SAASC,SAAAA;IAChD;AACA,QAAID,QAAQnG,aAAa,UAAU;AACjC,aAAO,MAAMkH,iBAAiBlQ,MAAMmP,SAASC,SAAAA;IAC/C;AAGA,UAAMqB,kBACJzQ,KAAKvD,SAASmB,iBAAiB9F,SAC3BuD,KAAK+P,gBACLC,oBAAoBhQ,KAAK+P,eAAepL,KAAKvD,QAAQmB,YAAY;AACvE,QAAI8S;AACJ,QAAItO,MAAMuO,cAAc;AACtB,YAAMC,UAAuB;QAC3BxT,OAAO9B,MAAM8B;QACbyE,UAAUvG,MAAMuG;QAChBpB,OAAO2B,MAAM3B;QACbsH,WAAW3F,MAAM3B;QACjB,GAAInF,MAAMI,cAAc5D,SAAY;UAAE4D,WAAWJ,MAAMI;QAAU,IAAI,CAAC;QACtE,GAAIJ,MAAMmB,YAAY3E,SAAY;UAAE2E,SAASnB,MAAMmB;QAAQ,IAAI,CAAC;QAChE,GAAInB,MAAM+B,gBAAgBvF,SAAY;UAAEuF,aAAa/B,MAAM+B;QAAY,IAAI,CAAC;QAC5E,GAAI/B,MAAMgC,mBAAmBxF,SAAY;UAAEwF,gBAAgBhC,MAAMgC;QAAe,IAAI,CAAC;MACvF;AACA,YAAMuT,WAA6B;QACjC/S,UAAUwD,KAAK7H;QACf6B,OAAOgG,KAAKhG;QACZiB,KAAKqU;QACL,GAAIH,oBAAoB3Y,SAAY;UAAE8F,cAAc6S;QAAgB,IAAI,CAAC;QACzE,GAAIpV,KAAKyV,kBAAkBhZ,SAAY;UAAEiZ,WAAW1V,KAAKyV;QAAc,IAAI,CAAC;;;QAG5EE,gBAAgBC,iCAAiC5V,KAAK6V,kBAAkB;;QAExEC,WAAW;MACb;AAGAT,YAAM,MAAMtO,MAAMuO,aAAavC,cAAcyC,QAAAA;IAC/C,OAAO;AACL,YAAMO,aAAahP,MAAMpB,KAAK,QAAQM,KAAK/D,EAAE,IAAI,YAAA;AAG/C,cAAM8T,MAAKC,4BAA4BhQ,KAAK/D,IAAIhB,KAAKlB,KAAKkW,kBAAkB,CAAC/Q,UAC3ER,KAAKwI,OAAO3I,MAAMqJ,kBAAkB1I,KAAAA,CAAAA,CAAAA;AAEtC,YAAI8I;AACJ,YAAI;AACFA,UAAAA,UAAS,MAAMjI,mBACbe,MAAM3B,OACN;YAAEmH,YAAYtG,KAAK/D;YAAIO,UAAUwD,KAAK7H;YAAMuP;UAAS,GACrD,MACEwI,yBACE,MAAA;AACEH,YAAAA,IAAGI,QAAO;AACV,mBAAOpW,KAAK2L,SAAS0K,OACnBpQ,KAAK7H,MACL6H,KAAKhG,OACL;cAAE,GAAGqM,gBAAgBpL,KAAK+E,KAAK/D,EAAE;cAAG0K,QAAQoJ,IAAGM;YAAK,GACpDtW,KAAKmQ,aACLiF,oBAAoB3Y,SAAY;cAAE8F,cAAc6S;YAAgB,IAAI,CAAC,CAAA;UAEzE,GACApV,KAAK6V,sBAAsB,CAAC,GAC5B;YACE,GAAI9O,MAAMsJ,uBAAuB5T,SAC7B;cAAE4T,oBAAoBtJ,MAAMsJ;YAAmB,IAC/C,CAAC;YACLkG,SAAS,wBAAC1M,SAAS2M,eAAAA;AACjBC,oCAAsB;gBACpBhU,UAAUwD,KAAK7H;gBACfmO,YAAYtG,KAAK/D;gBACjB2H;gBACAlL,SACE6X,sBAAsBrY,QAAQqY,WAAW7X,UAAUU,OAAOmX,UAAAA;cAC9D,CAAA;YACF,GARS;UASX,CAAA,CAAA;QAGR,SAASvY,OAAO;AACd,cAAIA,iBAAiBE,SAASF,MAAMG,SAAS,2BAC3C,QAAOsY,wBAAwBzY,MAAMU,OAAO;AAC9C,gBAAMV;QACR;AACA,eAAO0Y,mBAAmB1I,SAAQ+H,IAAGY,WAAU,GAAIZ,IAAG7Y,KAAI,CAAA;MAC5D,CAAA;AACAkY,YACErV,KAAKyV,kBAAkBhZ,SACnB,MAAM6G,gBAAgByS,YAAY/V,KAAKyV,eAAexP,KAAK7H,IAAI,IAC/D,MAAM2X;IACd;AACA,UAAM,EAAE9H,QAAQ+H,IAAIa,iBAAiB1Z,KAAI,IAAK2Z,qBAAqBzB,GAAAA;AACnE,QAAIlY,KAAMwH,MAAKoS,SAASC,IAAI/Q,KAAK/D,IAAI/E,IAAAA;AACrC,QAAI0Z,oBAAoBpa,OACtB,QAAO;MAAEmR,QAAQ;MAAUrD,QAAQsM;MAAiBjC,aAAarC,KAAKoB,IAAG,IAAKI;IAAU;AAC1F,QAAIiC,GAAGxV,SAAS,GAAG;AACjBmE,WAAKsS,OAAOD,IAAI/Q,KAAK/D,IAAI8T,EAAAA;IAC3B;AACA,QAAIlC,QAAQlB,aAAa,MAAM;AAC7BjO,WAAKuS,KAAKtE,WAAW;IACvB;AACA,WAAO;MAAEhF,QAAQ;MAAYK;MAAQ2G,aAAarC,KAAKoB,IAAG,IAAKI;IAAU;EAC3E,SAAS9V,OAAO;AACd,QACE8I,MAAMsJ,qBAAqBpS,KAAAA,MAAW,QACtCqS,oBAAoBrS,KAAAA,KACpBQ,uBAAuBR,KAAAA,GACvB;AACA,YAAMA;IACR;AACA,QAAIA,iBAAiBE,SAASF,MAAMG,SAAS,4BAA4B;AACvE,aAAO;QAAEwP,QAAQ;QAAUrD,QAAQtM,MAAMU;QAASiW,aAAarC,KAAKoB,IAAG,IAAKI;MAAU;IACxF;AACA,WAAO;MACLnG,QAAQ;MACR3P,OAAOA,iBAAiBE,QAAQF,MAAMU,UAAUU,OAAOpB,KAAAA;MACvD2W,aAAarC,KAAKoB,IAAG,IAAKI;IAC5B;EACF;AACF;AArIeoB;AAwIf,eAAegC,kBACbxS,MACAmP,SACArJ,SACA2M,YACAC,MAAmB;AAEnB,QAAM,EAAErX,MAAM+G,MAAK,IAAKpC;AACxB,QAAM,EAAEsB,KAAI,IAAK6N;AACjB,QAAMnG,WAAWmG,QAAQnG,aAAa,WAAW,WAAW;AAG5D,QAAM2J,UACJD,SAAS5a,SACL,CAAC,IACD;IACE0R,eAAekJ,KAAKE;IACpB,GAAIF,KAAKG,eAAe/a,SAAY;MAAE+a,YAAYH,KAAKG;IAAW,IAAI,CAAC;IACvE,GAAIH,KAAKI,aAAa,OAAO;MAAEA,UAAU;IAAK,IAAI,CAAC;EACrD;AACN,QAAMC,SAAS,mCAAA;AACb,QAAIL,SAAS5a,UAAa,CAAC4a,KAAKM,UAAU;AACxC;IACF;AACA,UAAMhT,KAAKwI,OAAO3I,MAChBqJ,kBAAkB;MAChB1C,MAAM;MACNjJ,IAAI+D,KAAK/D;MACT0L,QAAQ;MACR,GAAIyJ,KAAKhF,aAAa5V,SAAY;QAAE4V,UAAUgF,KAAKhF;MAAS,IAAI,CAAC;MACjEkF,WAAWF,KAAKE;MAChB,GAAIF,KAAKG,eAAe/a,SAAY;QAAE+a,YAAYH,KAAKG;MAAW,IAAI,CAAC;MACvE,GAAIH,KAAKI,aAAa,OAAO;QAAEA,UAAU;MAAK,IAAI,CAAC;IACrD,CAAA,CAAA;EAEJ,GAfe;AAgBf,MAAIhN,QAAQmD,WAAW,UAAU;AAC/B,UAAM7G,MAAMpB,KAAK,sBAAsBM,KAAK/D,EAAE,IAAI,YAAA;AAChD,YAAMlC,KAAK6H,MAAMkG,eAAe;QAC9BxB,YAAYtG,KAAK/D;QACjB0L,QAAQyJ,SAAS5a,SAAY,aAAa;QAC1CwB,OAAOwM,QAAQF;QACf,GAAG+M;MACL,CAAA;AACA,YAAMI,OAAAA;IACR,CAAA;AACA,WAAO;MACLxV,IAAI+D,KAAK/D;MACT9D,MAAM6H,KAAK7H;MACX6P,QAAQ;QAAE2J,UAAU;QAAMrN,QAAQE,QAAQF;MAAO;MACjDsN,QAAQ;MACR5Z,OAAO,kDAAkDwM,QAAQF,MAAM;IACzE;EACF;AACA,MAAIE,QAAQmD,WAAW,UAAU;AAC/B,UAAM7G,MAAMpB,KAAK,oBAAoBM,KAAK/D,EAAE,IAAI,YAAA;AAC9C,YAAMlC,KAAK6H,MAAMkG,eAAe;QAC9BxB,YAAYtG,KAAK/D;QACjB0L,QAAQ;QACR3P,OAAOwM,QAAQxM;QACf2W,aAAanK,QAAQmK;QACrB,GAAG0C;MACL,CAAA;AACA,YAAMI,OAAAA;IACR,CAAA;AACAI,yBAAqB;MACnB1S,OAAO2B,MAAM3B;MACb3C,UAAUwD,KAAK7H;MACfuP;MACAC,QAAQ;MACRmK,YAAYtN,QAAQmK;IACtB,CAAA;AACA,WAAO;MAAE1S,IAAI+D,KAAK/D;MAAI9D,MAAM6H,KAAK7H;MAAM6P,QAAQ;MAAMhQ,OAAOwM,QAAQxM;IAAM;EAC5E;AACA,QAAM8I,MAAMpB,KAAK,oBAAoBM,KAAK/D,EAAE,IAAI,YAAA;AAC9C,UAAMlC,KAAK6H,MAAMkG,eAAe;MAC9BxB,YAAYtG,KAAK/D;MACjB0L,QAAQ;MACRK,QAAQxD,QAAQwD;MAChB2G,aAAanK,QAAQmK;MACrB,GAAIjH,aAAa,WAAW;QAAEQ,eAAeiJ;MAAW,IAAI,CAAC;MAC7D,GAAGE;IACL,CAAA;AACA,UAAMI,OAAAA;EACR,CAAA;AACAI,uBAAqB;IACnB1S,OAAO2B,MAAM3B;IACb3C,UAAUwD,KAAK7H;IACfuP;IACAC,QAAQ;IACRmK,YAAYtN,QAAQmK;EACtB,CAAA;AACA,SAAO;IAAE1S,IAAI+D,KAAK/D;IAAI9D,MAAM6H,KAAK7H;IAAM6P,QAAQxD,QAAQwD;EAAO;AAChE;AA7FekJ;AA0Gf,eAAea,iBACbrT,MACAmP,SAAwB;AAExB,QAAM,EAAE9T,MAAMC,OAAO8G,MAAK,IAAKpC;AAC/B,QAAM,EAAEsB,MAAM/F,cAAc+F,KAAK7H,KAAI,IAAK0V;AAC1C,QAAMpW,OAAOiF,YAAYsD,KAAKhG,KAAK;AAEnC,QAAMgY,UACJzV,eAAemC,KAAKvD,SAAS6E,KAAK7H,IAAI,KAAK0B,kBAAkB;IAAEE;IAAMC;IAAOC;EAAY,CAAA;AAC1F,QAAMgY,QAAQpE,QAAQnB,aAAa,QAAQsF,YAAY,OAAOlR,MAAMoR,aAAa1b;AACjF2b,wBAAsB;IACpBhT,OAAO2B,MAAM3B;IACbiT,SAASnY;IACT,GAAID,MAAMI,cAAc5D,SAAY;MAAE6b,WAAWrY,MAAMI;IAAU,IAAI,CAAC;IACtE,GAAI6X,UAAUzb,SAAY;MAAEkW,UAAU;IAAK,IAAI,CAAC;EAClD,CAAA;AACA,MAAI4F;AACJ,MAAIN,YAAY,MAAM;AACpBM,UAAM;MAAEpb,MAAM8a;IAAQ;EACxB,WAAWC,UAAUzb,QAAW;AAC9B,UAAMgB,UAAU,MAAMya,MAAM;MAAE7X,WAAWH;MAAaxC;MAAM6O,YAAYtG,KAAK/D;IAAG,CAAA;AAChFqW,UAAMC,gBAAgB;MAAEC,OAAOvY;MAAakF,OAAO3H,QAAQ2H;IAAM,CAAA;EACnE,WAAW2B,MAAM2R,UAAU;AACzBH,UAAM,MAAMxR,MAAM2R,SAASxY,aAAaxC,IAAAA;EAC1C,OAAO;AACL6a,UAAM;MAAEpb,MAAM,gDAAgD+C,WAAAA;IAAgB;EAChF;AACA,QAAM6G,MAAMpB,KAAK,oBAAoBM,KAAK/D,EAAE,IAAI,MAC9ClC,KAAK6H,MAAMkG,eAAe;IAAExB,YAAYtG,KAAK/D;IAAI0L,QAAQ;IAAYK,QAAQsK;EAAI,CAAA,CAAA;AAEnF,SAAO;IAAErW,IAAI+D,KAAK/D;IAAI9D,MAAM6H,KAAK7H;IAAM6P,QAAQsK;EAAI;AACrD;AAhCeP;AAgDf,eAAeW,eACbhU,MACAmP,SAAwB;AAExB,QAAM,EAAE9T,MAAM+G,MAAK,IAAKpC;AACxB,QAAM,EAAEsB,MAAM/E,IAAG,IAAK4S;AAItB,QAAM/P,SAAS,MAAM6U,eAAe,WAAA,EAAazE,SAASlO,KAAKhG,KAAK;AACpE,MAAI8D,OAAO6F,WAAWnN,QAAW;AAC/B,UAAMwB,QAAQ,sBAAsB8F,OAAO6F,OAAO9M,IAAI,CAACsX,SAAS,IAAIA,KAAK9C,QAAQ,CAAA,GAAIlU,KAAK,GAAA,KAAQ,QAAA,KAAagX,KAAKzV,OAAO,EAAE,EAAEvB,KAAK,IAAA,CAAA;AACpI,UAAM2J,MAAMpB,KAAK,oBAAoBM,KAAK/D,EAAE,IAAI,MAC9ClC,KAAK6H,MAAMkG,eAAe;MAAExB,YAAYtG,KAAK/D;MAAI0L,QAAQ;MAAU3P;IAAM,CAAA,CAAA;AAI3E,WAAO;MAAEiE,IAAI+D,KAAK/D;MAAI9D,MAAM6H,KAAK7H;MAAM6P,QAAQ;MAAMhQ;IAAM;EAC7D;AACA,QAAMiO,UAA8B;IAClChK,IAAI+D,KAAK/D;IACThF,QAAQ;IACRoQ,WAAWvJ,OAAOhG,MAAMuP;IACxB,GAAIvJ,OAAOhG,MAAMqP,aAAa3Q,SAAY;MAAE2Q,UAAUrJ,OAAOhG,MAAMqP;IAAS,IAAI,CAAC;EACnF;AACA,QAAMrG,MAAMpB,KAAK,sBAAsBM,KAAK/D,EAAE,IAAI,YAAA;AAChD,UAAMyC,KAAKwI,OAAO3I,MAAMqJ,kBAAkB;MAAE1C,MAAM;MAAejJ,IAAI+D,KAAK/D;MAAIgK;IAAQ,CAAA,CAAA;EACxF,CAAA;AACA,QAAMnC,QAAQ,MAAMkC,iBAAiBlF,OAAOmF,SAAShL,GAAAA;AACrD,QAAMgJ,UAAS4D,kBAAkB5B,SAASnC,KAAAA;AAC1C,QAAMhD,MAAMpB,KACVuE,QAAO8D,UAAU,sBAAsB/H,KAAK/D,EAAE,KAAK,oBAAoB+D,KAAK/D,EAAE,IAC9E,MACElC,KAAK6H,MAAMkG,eAAe;IACxBxB,YAAYtG,KAAK/D;IACjB0L,QAAQ1D,QAAO8D,UAAU,aAAa;IACtCC,QAAQ/D;IACR,GAAIA,QAAO8D,UAAU;MAAE/P,OAAO;IAAsB,IAAI,CAAC;IACzD,GAAI8L,MAAMmE,kBAAkBzR,SAAY;MAAE0R,eAAepE,MAAMmE;IAAc,IAAI,CAAC;EACpF,CAAA,CAAA;AAEJ4J,uBAAqB;IACnB1S,OAAO2B,MAAM3B;IACb3C,UAAUwD,KAAK7H;IACfuP,UAAU;IACVC,QAAQ1D,QAAO8D,UAAU,aAAa;EACxC,CAAA;AACA,SAAO;IAAE9L,IAAI+D,KAAK/D;IAAI9D,MAAM6H,KAAK7H;IAAM6P,QAAQ/D;EAAO;AACxD;AAhDeyO;AAmDf,eAAeE,mBACblU,MACAmP,SAAwB;AAExB,QAAM,EAAE9T,MAAMC,OAAO8G,MAAK,IAAKpC;AAC/B,QAAM,EAAEsB,MAAM0H,UAAUzM,IAAG,IAAK4S;AAChC,MAAIA,QAAQpD,eAAejU,QAAW;AACpCkI,SAAKuS,KAAK4B,sBAAsB;AAChC,WAAO;MAAE5W,IAAI+D,KAAK/D;MAAI9D,MAAM6H,KAAK7H;MAAM6P,QAAQ8K,sBAAsBjF,QAAQpD,UAAU;IAAE;EAC3F;AAGA,MAAI/C,aAAa,SAAS;AACxB,WAAOqK,iBAAiBrT,MAAMmP,OAAAA;EAChC;AAEA,MAAInG,aAAa,OAAO;AACtB,WAAOgL,eAAehU,MAAMmP,OAAAA;EAC9B;AACA,MAAIA,QAAQlJ,cAAcnO,UAAaqX,QAAQlJ,UAAUgD,WAAW,SAAS;AAC3E,UAAM1D,UAAS4J,QAAQlJ;AACvB,QAAIV,QAAO0D,WAAW,eAAekG,QAAQhB,8BAA8B,MAAM;AAE/E,YAAMuC,MAAM,MAAMtO,MAAMpB,KAAK,WAAWM,KAAK/D,EAAE,IAAI,YAAA;AACjD,cAAM8T,KAAKC,4BAA4BhQ,KAAK/D,IAAIhB,KAAKlB,KAAKkW,kBAAkB,CAAC/Q,UAC3ER,KAAKwI,OAAO3I,MAAMqJ,kBAAkB1I,KAAAA,CAAAA,CAAAA;AAEtC,cAAMnF,KAAK2L,SAASqN,cAAc/S,KAAK7H,MAAM8L,QAAO+D,QAAQ;UAC1D,GAAG3B,gBAAgBpL,KAAK+E,KAAK/D,EAAE;UAC/B0K,QAAQoJ,GAAGM;QACb,CAAA;AACA,eAAOK,mBAAmBzM,QAAO+D,QAAQ+H,GAAGY,WAAU,GAAIZ,GAAG7Y,KAAI,CAAA;MACnE,CAAA;AACA,YAAM8b,YAAYnC,qBAAqBzB,GAAAA;AACvC,UAAI4D,UAAUjD,GAAGxV,SAAS,EAAGmE,MAAKsS,OAAOD,IAAI/Q,KAAK/D,IAAI+W,UAAUjD,EAAE;AAClE,UAAIiD,UAAU9b,KAAMwH,MAAKoS,SAASC,IAAI/Q,KAAK/D,IAAI+W,UAAU9b,IAAI;IAC/D;AACA,QAAI+M,QAAO0D,WAAW,eAAekG,QAAQlB,aAAa,KAAMjO,MAAKuS,KAAKtE,WAAW;AACrF,UAAMnI,UACJP,QAAO0D,WAAW,cACd;MAAEA,QAAQ;MAAYK,QAAQ/D,QAAO+D;MAAQ2G,aAAa;IAAE,IAC5D1K,QAAO0D,WAAW,WAChB;MAAEA,QAAQ;MAAUrD,QAAQL,QAAOK;MAAQqK,aAAa;IAAE,IAC1D;MAAEhH,QAAQ;MAAU3P,OAAOiM,QAAOjM;MAAO2W,aAAa;IAAE;AAChE,WAAOuC,kBAAkBxS,MAAMmP,SAASrJ,SAASxK,MAAM8B,MAAMG,EAAE;EACjE;AAGA,MAAIkV,aAAanX,MAAM8B,MAAMG;AAC7B,MAAImV;AACJ,MAAI1J,aAAa,YAAYmG,QAAQtD,UAAUP,SAAS,cAAc;AACpEoH,WAAO;MACLhF,UAAUyB,QAAQtD,SAAS6B;MAC3BkF,WAAWtX,MAAM8B,MAAMG;MACvBsV,YAAY;MACZC,UAAU;MACVE,UAAU;IACZ;EACF,WAAWhK,aAAa,YAAYmG,QAAQtD,UAAUP,SAAS,QAAQ;AACrE,UAAMqD,QAAQQ,QAAQtD,UAAUP,SAAS,QAAQ6D,QAAQtD,SAAS8C,QAAQ7W;AAC1E,UAAMyc,WACJ5F,UAAU7W,SACN,MAAMsK,MAAMsF,cAAcpG,MAAM/E,KAAK;MAAEwU,WAAWpC;IAAM,CAAA,IACxD,MAAMvM,MAAMsF,cAAcpG,MAAM/E,GAAAA;AACtCkW,iBAAa8B,SAAS/K,iBAAiBlO,MAAM8B,MAAMG;AAGnD,UAAMiX,oBAAoBrF,QAAQtD,aAAa/T;AAC/C,QAAIyc,SAASE,YAAY,MAAM;AAC7B,aAAOC,eAAe1U,MAAMmP,OAAAA;IAC9B;AACA,QAAI,CAACoF,SAASI,UAAU;AACtB,YAAMvS,MAAMpB,KAAK,sBAAsBM,KAAK/D,EAAE,IAAI,YAAA;AAChD,cAAMlC,KAAK6H,MAAMkG,eAAe;UAC9BxB,YAAYtG,KAAK/D;UACjB0L,QAAQ;UACRO,eAAeiJ;UACf,GAAI8B,SAAS3O,WAAW9N,SAAY;YAAEwB,OAAOib,SAAS3O;UAAO,IAAI,CAAC;UAClE,GAAI2O,SAAS1B,eAAe/a,SAAY;YAAE+a,YAAY0B,SAAS1B;UAAW,IAAI,CAAC;QACjF,CAAA;AACA,YAAI2B,mBAAmB;AACrB,gBAAMxU,KAAKwI,OAAO3I,MAChBqJ,kBAAkB;YAChB1C,MAAM;YACNjJ,IAAI+D,KAAK/D;YACT0L,QAAQ;YACR2J,WAAWH;YACX,GAAI8B,SAAS1B,eAAe/a,SAAY;cAAE+a,YAAY0B,SAAS1B;YAAW,IAAI,CAAC;YAC/E,GAAI0B,SAAS3O,WAAW9N,SAAY;cAAE8N,QAAQ2O,SAAS3O;YAAO,IAAI,CAAC;UACrE,CAAA,CAAA;QAEJ;MACF,CAAA;AACAuN,2BAAqB;QACnB1S,OAAO2B,MAAM3B;QACb3C,UAAUwD,KAAK7H;QACfuP;QACAC,QAAQ;MACV,CAAA;AACA,aAAO;QACL1L,IAAI+D,KAAK/D;QACT9D,MAAM6H,KAAK7H;QACX6P,QAAQ;UAAE2J,UAAU;UAAMrN,QAAQ2O,SAAS3O,UAAUgP;QAAuB;QAC5E1B,QAAQ;;;;;;QAMR5Z,OAAOub,iBAAiBN,SAAS3O,MAAM;MACzC;IACF;AACA8M,WAAO;MACLE,WAAWH;MACX,GAAI8B,SAAS1B,eAAe/a,SAAY;QAAE+a,YAAY0B,SAAS1B;MAAW,IAAI,CAAC;MAC/E,GAAI0B,SAASzB,aAAa,OAAO;QAAEA,UAAU;MAAK,IAAI,CAAC;MACvDE,UAAUwB;IACZ;EACF;AACA,SAAOhC,kBAAkBxS,MAAMmP,SAAS,MAAMqB,kBAAkBxQ,MAAMmP,OAAAA,GAAUsD,YAAYC,IAAAA;AAC9F;AAxHewB;AAgIf,eAAeQ,eACb1U,MACAmP,SAAwB;AAExB,QAAM,EAAE9T,MAAM+G,MAAK,IAAKpC;AACxB,QAAM,EAAEsB,KAAI,IAAK6N;AACjB,QAAM/M,MAAMpB,KAAK,sBAAsBM,KAAK/D,EAAE,IAAI,YAAA;AAChD,UAAMlC,KAAK6H,MAAMkG,eAAe;MAC9BxB,YAAYtG,KAAK/D;MACjB0L,QAAQ;MACR3P,OAAOwb;IACT,CAAA;AACA,UAAM9U,KAAKwI,OAAO3I,MAChBqJ,kBAAkB;MAAE1C,MAAM;MAAoBjJ,IAAI+D,KAAK/D;MAAI0L,QAAQ;IAAU,CAAA,CAAA;EAEjF,CAAA;AACAkK,uBAAqB;IACnB1S,OAAO2B,MAAM3B;IACb3C,UAAUwD,KAAK7H;IACfuP,UAAU;IACVC,QAAQ;EACV,CAAA;AACA,SAAO;IACL1L,IAAI+D,KAAK/D;IACT9D,MAAM6H,KAAK7H;IACX6P,QAAQ;MAAE2J,UAAU;MAAMwB,SAAS;MAAM7O,QAAQkP;IAAwB;IACzE5B,QAAQ;IACRuB,SAAS;IACTnb,OAAOyb,gBAAAA;EACT;AACF;AA9BeL;AAiCR,IAAMI,0BAA0B;AAOvC,SAASC,kBAAAA;AACP,SACE;AAIJ;AANSA;AAcT,SAASC,YAAYzP,SAAkB;AACrC,MAAIA,QAAO2N,WAAW,MAAM;AAC1B,UAAMtN,SAASqP,cAAc1P,OAAAA;AAC7B,WAAO;MACLiB,MAAM;MACNjJ,IAAIgI,QAAOhI;MACX,GAAIqI,WAAW9N,SAAY;QAAE8N;MAAO,IAAI,CAAC;IAC3C;EACF;AACA,SAAOL,QAAOjM,UAAUxB,SACpB;IAAE0O,MAAM;IAAqBjJ,IAAIgI,QAAOhI;IAAIjE,OAAOiM,QAAOjM;EAAM,IAChE;IAAEkN,MAAM;IAAejJ,IAAIgI,QAAOhI;IAAI+L,QAAQ/D,QAAO+D;EAAO;AAClE;AAZS0L;AAeT,SAASC,cAAc1P,SAAkB;AACvC,QAAM,EAAE+D,OAAM,IAAK/D;AACnB,MAAI+D,WAAW,QAAQ,OAAOA,WAAW,YAAY,YAAYA,QAAQ;AACvE,UAAM1D,SAAU0D,OAA+B1D;AAC/C,WAAO,OAAOA,WAAW,YAAYA,WAAWgP,yBAAyBhP,SAAS9N;EACpF;AACA,SAAOA;AACT;AAPSmd;AAcF,IAAML,yBAAyB;AAQtC,SAASC,iBAAiBjP,QAA0B;AAClD,QAAMsP,OACJ;AAIF,SAAOtP,WAAW9N,SAAYod,OAAO,GAAGA,IAAAA,eAAmBtP,MAAAA;AAC7D;AAPSiP;AAqBT,eAAeM,2BACbnV,MACAoV,UACAjG,SAA0B;AAE1B,QAAMkG,UAAU,MAAMD,SAASjG,QAAQhX,IAAI,CAACmd,UAAU,MAAM9E,kBAAkBxQ,MAAMsV,KAAAA,CAAAA,CAAAA;AACpF,aAAWxP,WAAWuP,SAAS;AAC7B,QAAI,CAACvP,QAAQzM,IAAI;AACf,YAAMyM,QAAQxM;IAChB;EACF;AACA,QAAMic,UAAwB,CAAA;AAC9B,aAAW,CAACld,OAAOid,KAAAA,KAAUnG,QAAQ/E,QAAO,GAAI;AAC9C,UAAMtE,UAAUuP,QAAQhd,KAAAA;AACxB,QAAIyN,SAASzM,OAAO,MAAM;AACxBkc,cAAQvY,KAAK,MAAMwV,kBAAkBxS,MAAMsV,OAAOxP,QAAQ1M,OAAO4G,KAAK1E,MAAM8B,MAAMG,EAAE,CAAA;IACtF;EACF;AACA,SAAOgY;AACT;AAnBeJ;AA8Cf,eAAsBK,aACpBC,WACAC,WACAtT,OAAqB;AAMrB,QAAM3F,UACJiZ,UAAUjZ,YAAY3E,SAClBA,SACE,MAAMsK,MAAMpB,KAAK,mBAAmB,MAAMxD,mBAAmBiY,WAAWC,SAAAA,CAAAA,KAC1E5d;AAGN,QAAMwD,QACJmB,YAAY3E,UAAa2E,QAAQc,OAAOmY,UAAUjZ,UAC9CQ,eAAeyY,SAAAA,IACfA;AAGN,QAAMra,OACJC,MAAMoE,UAAU5H,SACZ2d,YACA;IACE,GAAGA;IACH/V,OAAOiW,kBAAkBF,UAAU/V,OAAOpE,MAAMoE,KAAK;IACrDY,SAAShF,MAAMoE;EACjB;AACN,QAAMkW,WAAWva,KAAKua,YAAY;AAClC,MAAI1V,SAAS,MAAM1D,oBAAoBnB,MAAMC,OAAOmB,OAAAA;AACpD,QAAMoZ,kBAAkBxa,KAAKwa,mBAAmB,CAAA;AAChD,QAAM7Q,mBAAmB3J,KAAK2J,oBAAoB,CAAA;AAKlD,QAAM8Q,WAAWC,sBAAsB/Q,gBAAAA;AACvC,QAAMgR,QAAQF,aAAa;AAC3B,QAAMG,eAAeC,oBAAoBlR,gBAAAA;AACzC,MAAImR;AAEJ,MAAI9a,KAAK+a,UAAUte,QAAW;AAC5B,UAAMse,QAAQ/a,KAAK+a;AACnB,UAAMC,QAAQ,MAAMjU,MAAMpB,KAAK,eAAe,MAAMoV,MAAME,MAAMhb,MAAM8B,MAAMG,IAAIlC,KAAKkb,GAAG,CAAA;AACxF,QAAI,CAACF,MAAMG,aAAa;AACtBC,gCAA0B;QACxBC,SAASpb,MAAM8B,MAAMG;QACrBoZ,YAAYN,MAAMM;QAClBC,aAAaP,MAAMO;MACrB,CAAA;AACA,YAAM,IAAIrd,mBAAAA;IACZ;EACF;AAEA,MAAI+B,MAAMub,eAAe,MAAM;AAG7B,UAAMzU,MAAMpB,KAAK,uBAAuB,YAAA;AACtC,YAAM8V,WAAW,MAAMzb,KAAK6H,MAAMQ,UAAUpI,MAAMuG,QAAQ;AAC1D,YAAMlC,WAAWmX,UAAUnX,YAAY,CAAA;AACvC,UAAIoX,gBAAgB;AACpB,eAAS1e,QAAQsH,SAAS9D,SAAS,GAAGxD,SAAS,GAAGA,SAAS,GAAG;AAC5D,YAAIsH,SAAStH,KAAAA,GAAQmJ,SAAS,QAAQ;AACpCuV,0BAAgB1e;AAChB;QACF;MACF;AACA,YAAM2e,eAAerX,SAASoX,gBAAgB,CAAA;AAC9C,UAAIC,iBAAiBlf,QAAW;AAC9B,cAAMuD,KAAK6H,MAAM+T,aAAa3b,MAAMuG,UAAUmV,aAAazZ,EAAE;MAC/D;IACF,CAAA;EACF,OAAO;AACL,UAAM6E,MAAMpB,KAAK,gBAAgB,MAC/B3F,KAAK6H,MAAM2F,cAAc;MACvBhH,UAAUvG,MAAMuG;MAChBL,MAAM;MACNC,SAASnG,MAAM8C;MACfqC,OAAO2B,MAAM3B;MACb,GAAInF,MAAMmB,YAAY3E,SAAY;QAAE2E,SAASnB,MAAMmB;MAAQ,IAAI,CAAC;MAChE,GAAInB,MAAMqG,gBAAgB7J,SAAY;QAAE6J,aAAarG,MAAMqG;MAAY,IAAI,CAAC;IAC9E,CAAA,CAAA;EAEJ;AAEA,QAAMqC,UAAW,OAAO5B,MAAM6H,UAAUL,sBAAAA,KAA2B5Q,QAAQ4F,QAAQ,IAAA,KAC/E,MAAMuD,oBAAoB9G,MAAMC,OAAO8G,KAAAA,IACvC,MAAM0B,gBAAgBzI,MAAMC,OAAO8G,KAAAA;AACvC,MAAI8U,gBAAgClT,QAAQrE;AAC5C,QAAMiB,YAAYvF,KAAKmH,eAAe5B,WAAWqM,KAAK5R,KAAKmH,aAAa;AACxE,MAAI5B,cAAc9I,UAAakM,QAAQtB,QAAQ7G,SAAS,GAAG;AACzDqb,oBAAgB,MAAMnT,mBAAmBnD,WAAWvF,MAAMC,OAAO8G,OAAO4B,OAAAA;EAC1E;AAEA,QAAMwE,SAAS,MAAMpG,MAAM+U,SAAQ;AACnC,MAAIC,WAAW;AACf,MAAIC,QAAQ;AACZ,MAAIC,aAAa;AACjB,MAAIC,cAAc;AAElBC,yBAAuB;IACrB/W,OAAO2B,MAAM3B;IACboB,UAAUvG,MAAMuG;IAChB6U,SAASpb,MAAM8B,MAAMG;IACrB,GAAIjC,MAAMI,cAAc5D,SAAY;MAAE4D,WAAWJ,MAAMI;IAAU,IAAI,CAAC;IACtE,GAAIJ,MAAMmB,YAAY3E,SAAY;MAAE2E,SAASnB,MAAMmB;IAAQ,IAAI,CAAC;EAClE,CAAA;AAMA,QAAMgb,SAAS,MAAM3N,oBAAoBzO,MAAM+G,KAAAA;AAI/C,QAAMgN,YAAY,MAAMhN,MAAMpB,KAAK,kBAAkB,MAAMhI,QAAQ4F,QAAQgP,KAAKoB,IAAG,CAAA,CAAA;AAEnF,QAAM5M,MAAMpB,KAAK,qBAAqB,YAAA;AAGpC,UAAM0W,aAAaxL,WAAW,QAAA,EAAUC,OAAOjM,MAAAA,EAAQkM,OAAO,KAAA;AAC9D,UAAM/Q,KAAK6H,MAAMyU,iBAAiB;MAChClX,OAAO2B,MAAM3B;MACboB,UAAUvG,MAAMuG;MAChBqC,UAAU5I,MAAM8B,MAAMG;MACtB,GAAIjC,MAAMI,cAAc5D,SAAY;QAAE4D,WAAWJ,MAAMI;MAAU,IAAI,CAAC;MACtE,GAAIJ,MAAMsc,gBAAgB9f,SAAY;QAAE8f,aAAatc,MAAMsc;MAAY,IAAI,CAAC;MAC5EF;IACF,CAAA;EACF,CAAA;AAoBA,MAAIG;AACJ,MAAIJ,OAAOvQ,QAAQ;AACjB,UAAMmI,SAAShU,KAAK6L;AACpB2Q,mBAAe,MAAMzV,MAAMpB,KAAK,iBAAiB,MAC/CqO,WAAWvX,SACPkB,QAAQ4F,QAAQsL,eAAAA,IAChB4N,cAAc;MAAEzI;MAAQ9S,KAAKqT,aAAatU,KAAAA;MAAQyc,OAAOzc,MAAM8C;IAAS,CAAA,CAAA;AAI9E,UAAMgO,SAASyL;AACf,UAAMG,QACJ5L,OAAOhC,QAAQvO,SAAS,IACpBoc,iBAAiB;MACf7N,SAASgC,OAAOhC;MAChB8N,UAAUpR,iBAAiBzL,IAAAA;MAC3B8c,SAAS/L,OAAO/B,UAAU,KAAK+B,OAAOgM,aAAa;IACrD,CAAA,IACA;AACN,QAAIJ,MAAMnc,SAAS,GAAG;AACpBqE,eAAS,GAAGA,MAAAA;;EAAa8X,KAAAA;IAC3B;AAGAK,+BAA2B;MACzB5X,OAAO2B,MAAM3B;MACb0J,QAAQiC,OAAOjC,OAAOtO;MACtByc,SAASlM,OAAOhC,QAAQvO;MACxBwO,SAAS+B,OAAO/B;MAChBC,eAAe8B,OAAO9B;MACtB8N,UAAUhM,OAAOgM,aAAa;MAC9BG,aAAaP,MAAMnc;IACrB,CAAA;EACF;AAKA,MAAI2c;AACJ,MAAIf,OAAOzN,WAAW;AACpB,UAAMA,YAAY3O,KAAK2O;AACvB,UAAMyO,OAAOpd,KAAKqd,iBAAiB;AACnC,UAAMzgB,WAAW,MAAMmK,MAAMpB,KAAK,YAAY,MAC5CT,QACE,aACA6B,MAAM3B,OACN;MAAEA,OAAO2B,MAAM3B;MAAOkY,aAAard,MAAM8C,SAASvC;MAAQ4c;IAAK,GAC/D,MAAMzO,WAAW4O,SAAStd,MAAM8C,UAAU;MAAEqa;IAAK,CAAA,KAAMzf,QAAQ4F,QAAQ,CAAA,CAAE,GACzE,CAACia,eAAe;MAAE3Z,OAAO2Z,UAAUhd;IAAO,EAAA,CAAA;AAG9C,QAAI5D,SAAS4D,SAAS,GAAG;AACvB2c,yBAAmBvgB;AACnBiI,eAAS,GAAGA,MAAAA;;EAAalI,kBAAkBC,QAAAA,CAAAA;IAC7C;AACA6gB,0BAAsB;MAAErY,OAAO2B,MAAM3B;MAAOsX,OAAOzc,MAAM8C;MAAUc,OAAOjH,SAAS4D;IAAO,CAAA;EAC5F;AAWA,MAAIkd;AACJ,MAAItB,OAAO7Q,QAAQ;AACjB,UAAMyI,SAAShU,KAAKuL;AACpBmS,iBAAa,MAAM3W,MAAMpB,KAAK,kBAAkB,MAC9CqO,WAAWvX,SACPkB,QAAQ4F,QAAQ2L,eAAAA,IAChByO,YAAY3J,QAAQO,aAAatU,KAAAA,CAAAA,CAAAA;AAIvC,UAAM0c,QAAQe,WAAW3O,QAAQvO,SAAS,IAAIod,iBAAiBF,WAAW3O,OAAO,IAAI;AACrF,QAAI4N,MAAMnc,SAAS,GAAG;AACpBqE,eAAS,GAAGA,MAAAA;;EAAa8X,KAAAA;IAC3B;AAGAkB,+BAA2B;MACzBzY,OAAO2B,MAAM3B;MACb0J,QAAQ4O,WAAW5O,OAAOtO;MAC1Byc,SAASS,WAAW3O,QAAQvO;MAC5BwO,SAAS0O,WAAW1O;MACpBkO,aAAaP,MAAMnc;IACrB,CAAA;EACF;AAIA,MAAIsd,SAA8B,CAAA;AAClC,MAAI9d,KAAK+d,iBAAiBthB,QAAW;AACnC,UAAMshB,eAAe/d,KAAK+d;AAC1BD,aAAS,MAAM/W,MAAMpB,KAAK,gBAAgB,MAAMoY,aAAaC,kBAAiB,CAAA;EAChF;AACA,QAAMC,eAAe,IAAIC,IAAIJ,OAAOhhB,IAAI,CAACN,UAAU;IAACA,MAAMyI;IAASzI;GAAM,CAAA;AAKzE,MAAIwD,KAAK+M,WAAWtQ,QAAW;AAC7B,UAAM8Q,QAAQ,MAAML,UAClBlN,KAAK+M,QACL/M,MACAC,OACA8G,OACAoG,QACAxE,QAAQpB,mBAAmB;AAE7B,QAAIgG,UAAU,MAAM;AAClBsO,oBAAcla,KAAK4L,KAAAA;IACrB;EACF;AAOA,QAAM6B,cACJrI,MAAMuI,cAAc7S,UACnB,OAAOsK,MAAM6H,UAAUN,kBAAAA,KAAuB3Q,QAAQ4F,QAAQ,IAAA;AAMjE,WAAS4a,IAAI,GAAGA,IAAI5D,UAAU4D,KAAK,GAAG;AAGpC,UAAMhP,gBAAgBpI,OAAOqI,aAAa,gBAAgB+O,CAAAA,EAAG;AAK7D,UAAMpX,MAAMpB,KAAK,qBAAqBwY,CAAAA,IAAK,YAAA;AACzC,YAAMhR,OAAO3I,MAAMqJ,kBAAkB;QAAE1C,MAAM;MAAa,CAAA,CAAA;IAC5D,CAAA;AAMA,QAAIlK,SAA0B;MAAE4D;MAAQP,UAAUuX;IAAc;AAChE,QAAIrB,gBAAgBha,SAAS,GAAG;AAC9BS,eAAS,MAAM8F,MAAMpB,KAAK,iBAAiBwY,CAAAA,IAAK,MAC9CC,mBAAmB5D,iBAAiBvZ,QAAQ8H,iBAAiB9I,OAAOke,CAAAA,CAAAA,CAAAA;IAExE;AAEA,QAAIxZ;AACJ,QAAIoC,MAAM4I,aAAa;AAQrBhL,aAAO,MAAMoC,MAAM4I,YAAYwO,GAAG;QAChC,GAAIle,MAAMI,cAAc5D,SAAY;UAAE4D,WAAWJ,MAAMI;QAAU,IAAI,CAAC;QACtEwE,QAAQ5D,OAAO4D;QACfP,UAAUrD,OAAOqD;QACjBvC,OAAO9B,MAAM8B;QACbyE,UAAUvG,MAAMuG;QAChBgB,oBAAoBmB,QAAQnB,sBAAsB;QAClD6W,kBAAkB;UAChBtc,OAAO9B,MAAM8B;UACbyE,UAAUvG,MAAMuG;UAChBpB,OAAO2B,MAAM3B;UACbsH,WAAW3F,MAAM3B;UACjB,GAAInF,MAAMI,cAAc5D,SAAY;YAAE4D,WAAWJ,MAAMI;UAAU,IAAI,CAAC;UACtE,GAAIJ,MAAMmB,YAAY3E,SAAY;YAAE2E,SAASnB,MAAMmB;UAAQ,IAAI,CAAC;UAChE,GAAInB,MAAM+B,gBAAgBvF,SAAY;YAAEuF,aAAa/B,MAAM+B;UAAY,IAAI,CAAC;UAC5E,GAAI/B,MAAMgC,mBAAmBxF,SAAY;YAAEwF,gBAAgBhC,MAAMgC;UAAe,IAAI,CAAC;QACvF;QACA,GAAI0Y,QAAQ;UAAE2D,cAAc;QAAK,IAAI,CAAC;QACtC,GAAIre,MAAMoE,UAAU5H,SAAY;UAAE4H,OAAOpE,MAAMoE;QAAM,IAAI,CAAC;QAC1D,GAAIjD,SAASmB,iBAAiB9F,SAC1B;UAAE8hB,qBAAqBnd,QAAQmB;QAAa,IAC5C,CAAC;MACP,CAAA;IACF,OAAO;AACL,YAAMuC,QAAQ0Z,eAAe;QAC3B1Z,OAAO2Z,cAAc;UACnB3Z,OAAOiH,YAAY;YACjBjH,OAAO,MAAM9E,KAAK2L,SAAS+S,eACzBze,MAAM8B,OACN/B,KAAKmQ,aACLH,oBAAoBhQ,KAAK+P,eAAe3O,SAASmB,YAAAA,GACjD;cACEiE,UAAUvG,MAAMuG;cAChB,GAAIvG,MAAMgC,mBAAmBxF,SACzB;gBAAEwF,gBAAgBhC,MAAMgC;cAAe,IACvC,CAAC;cACL,GAAIhC,MAAMI,cAAc5D,SAAY;gBAAE4D,WAAWJ,MAAMI;cAAU,IAAI,CAAC;YACxE,CAAA;YAEFgL,KAAKrL,KAAKqL;UACZ,CAAA;UACAsT,SAAS3e,KAAKuL,WAAW9O;QAC3B,CAAA;QACAkiB,SAASlT,iBAAiBzL,IAAAA;MAC5B,CAAA;AACA2E,aAAO,MAAMoC,MAAMpB,KAAK,OAAOwY,CAAAA,IAAK,YAAA;AAKlC,cAAMS,cACJnE,aAAa,gBACToE,sBAAsB;UACpBC,YAAYnV;UACZzI,KAAK6H,iBAAiB9I,OAAOke,CAAAA;UAC7BY,eAAenE;UACfzN;QACF,CAAA,IACA1Q;AACN,cAAMuiB,SAASvE,aAAa,UAAUwE,kBAAAA,IAAsBxiB;AAG5D,cAAMyiB,SAASC,kBAAkBP,aAAazR,UAAU6R,QAAQ7R,UAAUA,MAAAA;AAI1E,cAAMjD,UAASS,eACbyU,eACE,MAAM1Z,aAAaqB,MAAM3B,OAAO+Y,GAAG,MACjCne,KAAKqE,MAAMO,QAAQ;UACjBC,QAAQ5D,OAAO4D;UACfP,UAAUrD,OAAOqD;UACjBQ;UACAC,MAAMma,OAAO/R;QACf,CAAA,CAAA,GAEF+R,OAAO5hB,QAAO,CAAA,GAEhB0C,IAAAA;AAEF,YAAI4e,gBAAgBniB,QAAW;AAC7B,gBAAMmiB,YAAY5E,QAAO;AACzB,gBAAM/B,UAAU2G,YAAYvU,UAAS;AACrC,iBAAO;YACL,GAAGH;YACHmV,cAAcT,YAAYU,SAAQ;YAClC,GAAIrH,YAAYxb,SAAY;cAAE8iB,eAAetH;YAAQ,IAAI,CAAC;UAC5D;QACF;AACA,eAAO+G,WAAWviB,SAAYyN,UAAS;UAAE,GAAGA;UAAQsV,gBAAgBR,OAAOE,OAAM;QAAG;MACtF,CAAA;IACF;AAGA,QAAI7U;AACJ,QAAIsQ,OAAO;AACT,YAAMxQ,OAAO,MAAMpD,MAAMpB,KAAK,kBAAkBwY,CAAAA,IAAK,YAAA;AAKnD,cAAMmB,WAAW3a,KAAK0a;AAGtB,YAAI1a,KAAK4a,kBAAkB9iB,QAAW;AACpC,iBAAO;YAAEU,MAAMwH,KAAKxH;YAAMkN,WAAW1F,KAAK4a;UAAc;QAC1D;AACA,cAAMvF,UAAU,MAAM5P,oBACpBT,kBACA;UAAExM,MAAMwH,KAAKxH;UAAM4I,WAAWpB,KAAKoB;QAAU,GAC7CgD,iBAAiB9I,OAAOke,CAAAA,CAAAA;AAM1B,YAAInE,QAAQ3P,cAAc5N,QAAW;AACnC,cAAI6iB,aAAa7iB,QAAW;AAC1B,uBAAWgjB,SAASC,mBAAmB/a,KAAK6a,kBAAkB,CAAA,GAAIxF,QAAQ7c,IAAI,GAAG;AAC/E,oBAAMgQ,OAAO3I,MAAMib,KAAAA;YACrB;UACF,OAAO;AACL,kBAAME,OAAOC,SAASjW,kBAAkB2V,UAAUtF,QAAQ7c,IAAI;AAC9D,gBAAIwiB,KAAKnf,SAAS,GAAG;AACnB,oBAAM2M,OAAO3I,MAAMqJ,kBAAkB;gBAAE1C,MAAM;gBAAQhO,MAAMwiB;cAAK,CAAA,CAAA;YAClE;UACF;QACF;AACA,eAAO3F;MACT,CAAA;AACA3P,kBAAYF,KAAKE;AACjB1F,aAAO;QAAE,GAAGA;QAAMxH,MAAMgN,KAAKhN;MAAK;IACpC;AAEA,UAAM0iB,kBAAkBlb,KAAKM,WAAWjF,KAAKiF,WAAW;AAExD,UAAM6a,YAAYnb,KAAKM,WAAWjF,KAAKiF;AAGvC,UAAM8a,UAAU1jB,eAAesI,KAAKrI,OAAOqI,KAAKob,SAAS9B,aAAa+B,IAAIH,eAAAA,CAAAA;AAM1E,UAAMI,oBAAuCtb,KAAKoB,UAAUjJ,IAAI,CAACmJ,UAAU;MACzE,GAAGA;MACHkF,MAAMlF,KAAKkF,QAAQC,aAAapL,MAAMiG,KAAK7H,IAAI;IACjD,EAAA;AAEA,UAAM2I,MAAMpB,KAAK,iBAAiBwY,CAAAA,IAAK,MACrCne,KAAK6H,MAAMe,YAAY;MACrBpC,UAAUvG,MAAMuG;MAChBqC,UAAU5I,MAAM8B,MAAMG;MACtB+C,SAAS4a;MACT/W,SAAS;MACTxM,OAAOqI,KAAKrI;;MAEZ,GAAIqI,KAAKob,YAAYtjB,SAAY;QAAEsjB,SAASpb,KAAKob;MAAQ,IAAI,CAAC;IAChE,CAAA,CAAA;AAEF,QAAI/f,KAAK+a,UAAUte,QAAW;AAC5B,YAAMse,QAAQ/a,KAAK+a;AACnB,YAAMhU,MAAMpB,KAAK,cAAcwY,CAAAA,IAAK,MAClCpD,MAAMmF,KAAKjgB,MAAM8B,MAAMG,IAAIlC,KAAKkb,KAAKvW,KAAKrI,MAAMsJ,cAAcjB,KAAKrI,MAAMuJ,YAAY,CAAA;IAEzF;AAIA,QAAIwE,cAAc5N,QAAW;AAC3B,YAAM,IAAI8B,oBAAoB8L,UAAUC,WAAWD,UAAUE,MAAM;IACrE;AAEAyR,aAAS;AACTC,kBAActX,KAAKrI,MAAMsJ;AACzBsW,mBAAevX,KAAKrI,MAAMuJ;AAC1BkW,eAAWpX,KAAKxH;AAChBgjB,wBAAoB;MAClB/a,OAAO2B,MAAM3B;MACboB,UAAUvG,MAAMuG;MAChBL,MAAM;MACNL,YAAYnB,KAAKxH,KAAKqD;IACxB,CAAA;AAIA,UAAM4f,cAAczb,KAAKoB,UAAUvF,WAAW;AAG9C,QAAI4f,eAAepgB,KAAKgK,iBAAiBvN,QAAW;AAClDqe,mBAAa,MAAM1R,gBACjBpJ,KAAKgK,cACLhK,MACAC,OACA8G,OACAiC,kBAAkB/H,OAAOqD,UAAUK,KAAKxH,MAAM6C,KAAKqgB,yBAAyB,IAAA,GAC5ElC,CAAAA;IAEJ;AACA,QAAInZ;AACJ,QAAIob,eAAepgB,KAAKsgB,mBAAmB7jB,UAAauD,KAAKsgB,iBAAiB,GAAG;AAC/E,YAAMzc,QAAQ7D,KAAKsgB;AAGnB,YAAMC,YAAY,MAAMxZ,MAAMpB,KAAK,aAAawY,CAAAA,IAAK,MACnDjZ,QACE,cACA6B,MAAM3B,OACN;QAAEA,OAAO2B,MAAM3B;QAAOO,MAAMwY;QAAGta;MAAM,GACrC,MACEO,kBACEpE,KAAKqE,OACL;WAAIwX;QAAe;UAAE1V,MAAM;UAAaC,SAASzB,KAAKxH;QAAK;SAC3D0G,KAAAA,GAEJ,CAACqG,aAAY;QACXlF,WAAWkF,QAAOlF,UAAUxE;QAC5BoF,aAAasE,QAAO5N,MAAMsJ;QAC1BC,cAAcqE,QAAO5N,MAAMuJ;QAC3B,GAAIqE,QAAOjF,YAAYxI,SAAY;UAAEwI,SAASiF,QAAOjF;QAAQ,IAAI,CAAC;MACpE,EAAA,CAAA;AAOJ,UAAIub,cAAcD,UAAUvb;AAC5B,UAAI2E,iBAAiBnJ,SAAS,GAAG;AAC/BggB,sBAAc,MAAMzZ,MAAMpB,KAAK,4BAA4BwY,CAAAA,IAAK,MAC9DsC,cAAc9W,kBAAkB6W,aAAazX,iBAAiB9I,OAAOke,CAAAA,CAAAA,CAAAA;MAEzE;AACA,UAAIqC,YAAYhgB,SAAS,GAAG;AAC1BwE,oBAAYwb;MACd;AACA,YAAMzZ,MAAMpB,KAAK,2BAA2BwY,CAAAA,IAAK,MAC/Cne,KAAK6H,MAAMe,YAAY;QACrBpC,UAAUvG,MAAMuG;QAChBqC,UAAU5I,MAAM8B,MAAMG;QACtB+C,SAASsb,UAAUtb,WAAWjF,KAAKiF,WAAW;QAC9C6D,SAAS;QACTxM,OAAOikB,UAAUjkB;MACnB,CAAA,CAAA;IAEJ;AAQA,UAAMokB,YAAiC,CAAA;AACvC,QAAIvC,MAAM,KAAKhB,qBAAqB1gB,QAAW;AAC7C,YAAMwJ,OAAwB;QAC5B/D,IAAI,YAAY6E,MAAM3B,KAAK;QAC3BhH,MAAM;QACN6B,OAAO;UAAEyc,OAAOzc,MAAM8C;QAAS;QAC/BoI,MAAM;MACR;AACA,YAAM8C,SAAS;QAAErR,UAAUugB;MAAiB;AAC5CuD,gBAAU/e,KAAK;QACbgE,MAAM;QACNM;QACAiE,QAAQ;UAAEhI,IAAI+D,KAAK/D;UAAI9D,MAAM6H,KAAK7H;UAAM6P;QAAO;MACjD,CAAA;IACF;AACA,QAAI6M,eAAere,QAAW;AAC5B,YAAMwJ,OAAwB;QAC5B/D,IAAI,cAAc6E,MAAM3B,KAAK;QAC7BhH,MAAM;QACN6B,OAAO,CAAC;QACRkL,MAAM;MACR;AACAuV,gBAAU/e,KAAK;QACbgE,MAAM;QACNM;QACAiE,QAAQ;UAAEhI,IAAI+D,KAAK/D;UAAI9D,MAAM6H,KAAK7H;UAAM6P,QAAQ6M;QAAW;MAC7D,CAAA;IACF;AACA,UAAM6F,eAAe;SAAIV;SAAsBS,UAAU5jB,IAAI,CAACmd,UAAUA,MAAMhU,IAAI;;AAClF,UAAM2a,mBAAmBF,UAAU5jB,IAAI,CAACmd,UAAUA,MAAM/P,MAAM;AAE9D,UAAM2W,YAAY,MAAM9Z,MAAMpB,KAAK,qBAAqBwY,CAAAA,IAAK,MAC3Dne,KAAK6H,MAAM2F,cAAc;MACvBhH,UAAUvG,MAAMuG;MAChBL,MAAM;MACNC,SAASzB,KAAKxH;;;MAGdiI,OAAO2B,MAAM3B;MACb9I,OAAO;QAAE,GAAGqI,KAAKrI;QAAOyjB;MAAQ;MAChC,GAAI9f,MAAMI,cAAc5D,SAAY;QAAE4D,WAAWJ,MAAMI;MAAU,IAAI,CAAC;MACtE,GAAIJ,MAAMmB,YAAY3E,SAAY;QAAE2E,SAASnB,MAAMmB;MAAQ,IAAI,CAAC;MAChE,GAAIuD,KAAKmc,cAAcrkB,SAAY;QAAEqkB,WAAWnc,KAAKmc;MAAU,IAAI,CAAC;MACpE,GAAInc,KAAKoc,gBAAgBtkB,SAAY;QAAEskB,aAAapc,KAAKoc;MAAY,IAAI,CAAC;MAC1E,GAAIpc,KAAKqR,OAAOvZ,UAAakI,KAAKqR,GAAGxV,SAAS,IAAI;QAAEwV,IAAIrR,KAAKqR;MAAG,IAAI,CAAC;MACrE,GAAI2K,aAAangB,SAAS,IAAI;QAAEuF,WAAW4a;MAAa,IAAI,CAAC;MAC7D,GAAIC,iBAAiBpgB,SAAS,IAAI;QAAE6F,aAAaua;MAAiB,IAAI,CAAC;MACvE,GAAI5b,cAAcvI,SAAY;QAAEuI;MAAU,IAAI,CAAC;IACjD,CAAA,CAAA;AAMF,UAAMgc,mBAAiC;MACrC7a,MAAM;MACNC,SAASzB,KAAKxH;MACd,GAAIwjB,aAAangB,SAAS,IAAI;QAAEuF,WAAW4a;MAAa,IAAI,CAAC;MAC7D,GAAIC,iBAAiBpgB,SAAS,IAAI;QAAE6F,aAAaua;MAAiB,IAAI,CAAC;IACzE;AACA/E,kBAAcla,KAAKqf,gBAAAA;AAEnB,eAAW/G,SAASyG,WAAW;AAC7B,YAAM,EAAEza,MAAMiE,QAAAA,QAAM,IAAK+P;AACzB,YAAMlT,MAAMpB,KAAK,GAAGsU,MAAMtU,IAAI,IAAIkb,UAAU3e,EAAE,IAAI,YAAA;AAChD,cAAMlC,KAAK6H,MAAM4F,eAAe;UAC9BlB,YAAYtG,KAAK/D;UACjBwL,WAAWmT,UAAU3e;UACrBO,UAAUwD,KAAK7H;UACfuP,UAAU;UACV1N,OAAOgG,KAAKhG;UACZ2N,QAAQ;UACRxI,OAAO2B,MAAM3B;QACf,CAAA;AACA,cAAMpF,KAAK6H,MAAMkG,eAAe;UAC9BxB,YAAYtG,KAAK/D;UACjB0L,QAAQ;UACRK,QAAQ/D,QAAO+D;QACjB,CAAA;AAGA,cAAMd,OAAO3I,MACXqJ,kBAAkB;UAChB1C,MAAM;UACNjJ,IAAI+D,KAAK/D;UACT9D,MAAM6H,KAAK7H;UACX6B,OAAOgG,KAAKhG;UACZghB,UAAU;QACZ,CAAA,CAAA;AAEF,cAAM9T,OAAO3I,MACXqJ,kBAAkB;UAAE1C,MAAM;UAAejJ,IAAI+D,KAAK/D;UAAI+L,QAAQ/D,QAAO+D;QAAO,CAAA,CAAA;MAEhF,CAAA;IACF;AAEA,QAAImS,aAAa;AACf,YAAMrZ,MAAMpB,KAAK,sBAAsBwY,CAAAA,IAAK,YAAA;AAC1C,cAAMhR,OAAO3I,MACXqJ,kBAAkB;UAChB1C,MAAM;UACN7O,OAAOqI,KAAKrI;UACZyjB;UACA,GAAIpb,KAAKoc,gBAAgBtkB,SAAY;YAAEskB,aAAapc,KAAKoc;UAAY,IAAI,CAAC;UAC1E,GAAIjB,cAAcrjB,SAAY;YAAE4H,OAAOyb;UAAU,IAAI,CAAC;QACxD,CAAA,CAAA;MAEJ,CAAA;AACA;IACF;AAOA,UAAM3Q,gBAAgBpI,OAAOqI,aAAa,gBAAgB+O,CAAAA,EAAG;AAE7D,UAAMjE,UAAwB,CAAA;AAC9B,UAAMgH,YAA6B;MACjClhB;MACAC;MACA8G;MACA2G,WAAWmT,UAAU3e;MACrBiL;MACA8J,QAAQ,oBAAIiH,IAAAA;MACZnH,UAAU,oBAAImH,IAAAA;MACdhH,MAAM;QAAEtE,UAAU;MAAM;MACxBpL,oBAAoBmB,QAAQnB,sBAAsB;MAClD,GAAIkW,eAAejhB,SAAY;QAAE8O,QAAQmS;MAAW,IAAI,CAAC;MACzD,GAAIlB,iBAAiB/f,SAAY;QAAEoP,QAAQ2Q;MAAa,IAAI,CAAC;MAC7D,GAAIpb,YAAY3E,SAAY;QAAE2E;MAAQ,IAAI,CAAC;IAC7C;AAiBA,UAAM2Y,WAAWhT,MAAMgT;AACvB,QACEA,aAAatd,UACbwjB,kBAAkBzf,SAAS,KAC1B,OAAOuG,MAAM6H,UAAUP,oBAAAA,KAAyB1Q,QAAQ4F,QAAQ,IAAA,IACjE;AAGA,YAAMuQ,UAA6B,CAAA;AACnC,iBAAW7N,QAAQga,mBAAmB;AACpCnM,gBAAQnS,KAAK,MAAM4N,cAAc2R,WAAWjb,IAAAA,CAAAA;MAC9C;AAKA,UACE6N,QAAQqN,MACN,CAAClH,UACCA,MAAMtM,aAAa,UAAUsM,MAAMtM,aAAa,WAAWsM,MAAMtM,aAAa,QAAA,GAElF;AACAuM,gBAAQvY,KAAI,GAAK,MAAMmY,2BAA2BoH,WAAWnH,UAAUjG,OAAAA,CAAAA;MACzE,OAAO;AACL,mBAAWmG,SAASnG,SAAS;AAC3BoG,kBAAQvY,KAAK,MAAMkX,mBAAmBqI,WAAWjH,KAAAA,CAAAA;QACnD;MACF;IACF,OAAO;AACL,iBAAWhU,QAAQga,mBAAmB;AACpC/F,gBAAQvY,KAAK,MAAMkX,mBAAmBqI,WAAW,MAAM3R,cAAc2R,WAAWjb,IAAAA,CAAAA,CAAAA;MAClF;IACF;AACA,UAAMmb,iBAAiB;SAAIlH;SAAY0G;;AACvC,UAAM7J,WAAWsK,uBACfpB,kBACGnjB,IAAI,CAACmJ,SAASib,UAAUnK,SAASiJ,IAAI/Z,KAAK/D,EAAE,CAAA,EAC5C3B,OAAO,CAACpD,SAAyBA,SAASV,MAAAA,EAC1CW,KAAK,IAAA,CAAA;AAEV4jB,qBAAiB3a,cAAc+a;AAM/B,UAAMra,MAAMpB,KAAK,uBAAuBwY,CAAAA,IAAK,YAAA;AAK3C,YAAMne,KAAK6H,MAAMuG,sBAAsByS,UAAU3e,IAAIkf,cAAAA;AACrD,UAAIrK,SACF,OAAM/W,KAAK6H,MAAM2F,cAAc;QAC7BhH,UAAUvG,MAAMuG;QAChBL,MAAM;QACNC,SAAS2Q;QACT3R,OAAO2B,MAAM3B;QACb,GAAInF,MAAMI,cAAc5D,SAAY;UAAE4D,WAAWJ,MAAMI;QAAU,IAAI,CAAC;MACxE,CAAA;AAGF,YAAM4W,SAASgJ,kBAAkBqB,QAAQ,CAACrb,SAASib,UAAUjK,OAAO+I,IAAI/Z,KAAK/D,EAAE,KAAK,CAAA,CAAE;AACtF,UAAI+U,OAAOzW,SAAS,GAAG;AACrB,cAAMR,KAAK6H,MAAM0Z,eAAeV,UAAU3e,IAAIsf,QAAQ7c,KAAKqR,IAAIiB,MAAAA,CAAAA;MACjE;AACA,iBAAW/M,WAAUgQ,SAAS;AAC5B,cAAM/M,OAAO3I,MAAMqJ,kBAAkB8L,YAAYzP,OAAAA,CAAAA,CAAAA;MACnD;IACF,CAAA;AAEA,QAAI6M,UAAU;AACZ8E,oBAAcla,KAAK;QAAEwE,MAAM;QAAaC,SAAS2Q;MAAS,CAAA;AAC1DgF,kBAAY;EAAKhF,QAAAA;IACnB;AACA,UAAMhQ,MAAMpB,KAAK,sBAAsBwY,CAAAA,IAAK,YAAA;AAC1C,YAAMhR,OAAO3I,MACXqJ,kBAAkB;QAChB1C,MAAM;QACN7O,OAAOqI,KAAKrI;QACZyjB;QACA,GAAIpb,KAAKoc,gBAAgBtkB,SAAY;UAAEskB,aAAapc,KAAKoc;QAAY,IAAI,CAAC;QAC1E,GAAIjB,cAAcrjB,SAAY;UAAE4H,OAAOyb;QAAU,IAAI,CAAC;MACxD,CAAA,CAAA;IAEJ,CAAA;AAIA,QAAIoB,UAAUhK,KAAKtE,YAAYsO,UAAUhK,KAAK4B,qBAAqB;AACjE;IACF;EACF;AAEA,MAAInQ,QAAQrB,UAAU,MAAMqB,QAAQrB,UAAU,YAAY;AACxD,UAAMP,MAAMpB,KAAK,iBAAiB,MAChC3F,KAAK6H,MAAM4Z,SAASxhB,MAAMuG,UAAU1D,YAAY7C,MAAM8C,QAAQ,CAAA,CAAA;EAElE;AAEA,QAAM2e,WAAWzhB,MAAM0hB;AACvB,MAAID,aAAajlB,QAAW;AAQ1B,UAAMsK,MAAMpB,KAAK,oBAAoB,YAAA;AACnC,UAAK,MAAM3F,KAAK6H,MAAMQ,UAAUqZ,SAASlb,QAAQ,MAAO,MAAM;AAI5D;MACF;AACA,YAAMiS,QAAQxY,MAAMI,aAAa;AACjC,YAAML,KAAK6H,MAAM2F,cAAc;QAC7BhH,UAAUkb,SAASlb;QACnBL,MAAM;QACNC,SAAS2V;QACT1b,WAAWoY;QACXrT,OAAO2B,MAAM3B;MACf,CAAA;AACA,YAAMpF,KAAK6H,MAAMkG,eAAe;QAC9BxB,YAAYmV,SAASnV;QACrBqB,QAAQ;QACRK,QAAQ2T,kBAAkB;UAAEnJ;UAAOrT,OAAO2B,MAAM3B;UAAOjI,MAAM4e;QAAS,CAAA;MACxE,CAAA;IACF,CAAA;EACF;AAIA,QAAMhV,MAAMpB,KAAK,mBAAmB,YAAA;AAClC,UAAM3F,KAAK6H,MAAMga,eAAe;MAC9Bzc,OAAO2B,MAAM3B;MACbwI,QAAQ;MACRmK,YAAYxF,KAAKoB,IAAG,IAAKI;IAC3B,CAAA;EACF,CAAA;AAEA,QAAM5G,OAAO1I,IAAG;AAChBqd,0BAAwB;IACtB1c,OAAO2B,MAAM3B;IACboB,UAAUvG,MAAMuG;IAChBwV;IACApW,aAAaqW;IACbpW,cAAcqW;EAChB,CAAA;AACA,SAAO;IAAE/e,MAAM4e;IAAU,GAAIjB,eAAere,SAAY;MAAEwN,QAAQ6Q;IAAW,IAAI,CAAC;EAAG;AACvF;AAr2BsBX;;;AOt4FtB,SAAS4H,kBAAkB;AAwCpB,IAAMC,8BAAN,MAAMA;EAxCb,OAwCaA;;;EACQC,OAAO,oBAAIC,IAAAA;EACXC;EACnB,YAAYC,UAAsC,CAAC,GAAG;AACpD,SAAKD,QAAQC,QAAQD,SAASE,KAAKC;EACrC;EACA,MAAMC,qBAAqBC,OAAkE;AAC3FC,mCAA+BD,KAAAA;AAC/B,UAAME,OAAM,KAAKT,KAAKU,IAAIH,MAAMI,EAAE;AAClC,QAAIF,MAAK;AACP,UAAI,CAACG,2BAA2BH,MAAKF,KAAAA,EAAQ,QAAO;QAAEM,QAAQ;MAAW;AACzE,aAAO;QACLA,QAAQC,8BAA8BL,MAAKF,KAAAA,IAAS,cAAc;QAClEQ,UAAUC,uBAAuBP,IAAAA;MACnC;IACF;AACA,UAAMM,WAAWE,sBAAsBV,OAAO,KAAKL,MAAK,CAAA;AACxD,SAAKF,KAAKkB,IAAIX,MAAMI,IAAII,QAAAA;AACxB,WAAO;MAAEF,QAAQ;MAAWE,UAAUC,uBAAuBD,QAAAA;IAAU;EACzE;EACA,MAAMI,kBAAkBC,OAA4BT,IAA4C;AAC9F,UAAMF,OAAM,KAAKT,KAAKU,IAAIC,EAAAA;AAC1B,WAAOF,QAAOG,2BAA2BH,MAAKW,KAAAA,IAASJ,uBAAuBP,IAAAA,IAAO;EACvF;EACA,MAAMY,oBACJD,OACAE,QAA6B,CAAC,GACH;AAC3B,UAAMC,QAAQC,gCAAgCF,KAAAA;AAC9C,WAAO;SAAI,KAAKtB,KAAKyB,OAAM;MACxBC,OACC,CAACjB,SACCG,2BAA2BH,MAAKW,KAAAA,MAC/BE,MAAMK,aAAaC,UAAanB,KAAIkB,aAAaL,MAAMK,cACvDL,MAAMO,UAAUD,UACfnB,KAAIqB,YAAYR,MAAMO,MAAMC,aAC3BrB,KAAIqB,cAAcR,MAAMO,MAAMC,aAAarB,KAAIE,KAAKW,MAAMO,MAAMlB,GAAE,EAExEoB,KAAK,CAACC,GAAGC,MAAMD,EAAEF,YAAYG,EAAEH,cAAcE,EAAErB,KAAKsB,EAAEtB,KAAK,KAAKqB,EAAErB,KAAKsB,EAAEtB,KAAK,IAAI,EAAA,EAClFuB,MAAM,GAAGX,KAAAA,EACTY,IAAInB,sBAAAA;EACT;EACQoB,OACNhB,OACAT,IACA0B,YAC8B;AAC9B,UAAM5B,OAAM,KAAKT,KAAKU,IAAIC,EAAAA;AAC1B,QAAI,CAACF,QAAO,CAACG,2BAA2BH,MAAKW,KAAAA,EAAQ,QAAO;MAAEP,QAAQ;IAAY;AAClF,UAAMyB,UAASD,WAAW5B,MAAK,KAAKP,MAAK,CAAA;AACzC,QAAIoC,QAAOvB,SAAU,MAAKf,KAAKkB,IAAIP,IAAIK,uBAAuBsB,QAAOvB,QAAQ,CAAA;AAC7E,WAAOuB;EACT;EACA,MAAMC,qBACJnB,OACAT,IACA6B,SACuC;AACvC,WAAO,KAAKJ,OAAOhB,OAAOT,IAAI,CAACF,MAAKJ,QAClCoC,iCAAiChC,MAAK+B,SAASnC,GAAAA,CAAAA;EAEnD;EACA,MAAMqC,oBACJtB,OACAT,IACA6B,SACuC;AACvC,WAAO,KAAKJ,OAAOhB,OAAOT,IAAI,CAACF,MAAKJ,QAClCsC,8BAA8BlC,MAAK+B,SAASnC,KAAKuC,WAAAA,CAAAA,CAAAA;EAErD;EACA,MAAMC,0BACJzB,OACAT,IACA6B,SACuC;AACvC,WAAO,KAAKJ,OAAOhB,OAAOT,IAAI,CAACF,MAAKJ,QAAQyC,8BAA8BrC,MAAK+B,SAASnC,GAAAA,CAAAA;EAC1F;EACA,MAAM0C,qBACJ3B,OACAT,IACA6B,SACuC;AACvC,WAAO,KAAKJ,OAAOhB,OAAOT,IAAI,CAACF,MAAKJ,QAClC2C,mCAAmCvC,MAAK+B,SAASnC,GAAAA,CAAAA;EAErD;EAEA,MAAM4C,wBAAwBT,SAA8D;AAC1F,UAAMnC,MAAM,KAAKH,MAAK;AACtBgD,sCAAkCV,SAASnC,GAAAA;AAC3C,UAAM8C,aAAa;SAAI,KAAKnD,KAAKyB,OAAM;MACpCC,OACC,CAACjB,SACCA,KAAIkB,aAAa,eAChBlB,KAAI2C,WAAWvC,WAAW,YACxBJ,KAAI2C,WAAWvC,WAAW,eACzBJ,KAAI2C,UAAUC,UAAU,QACxBhD,OAAOI,KAAI2C,UAAUC,MAAMC,UAAS,EAE3CvB,KAAK,CAACC,GAAGC,MAAMD,EAAEF,YAAYG,EAAEH,cAAcE,EAAErB,KAAKsB,EAAEtB,KAAK,KAAKqB,EAAErB,KAAKsB,EAAEtB,KAAK,IAAI,EAAA,EAClFuB,MAAM,GAAG,EAAA;AACZ,eAAWqB,aAAaJ,YAAY;AAClC,YAAMK,UAAU,MAAM,KAAKd,oBAAoBa,WAAWA,UAAU5C,IAAI6B,OAAAA;AACxE,UAAIgB,QAAQ3C,WAAW,aAAa2C,QAAQzC,SAAU,QAAOyC,QAAQzC;IACvE;AACA,WAAO;EACT;EAEA,MAAM0C,sBAAsBjB,SAA6C;AACvE,UAAMnC,MAAM,KAAKH,MAAK;AACtBwD,sCAAkClB,SAASnC,GAAAA;AAC3C,UAAM8C,aAAa;SAAI,KAAKnD,KAAKyB,OAAM;MACpCC,OAAO,CAACjB,SAAQA,KAAIkB,aAAa,aAAalB,KAAI6C,cAAc,QAAQjD,OAAOI,KAAI6C,SAAS,EAC5FvB,KAAK,CAACC,GAAGC,MAAMD,EAAEF,YAAYG,EAAEH,cAAcE,EAAErB,KAAKsB,EAAEtB,KAAK,KAAKqB,EAAErB,KAAKsB,EAAEtB,KAAK,IAAI,EAAA,EAClFuB,MAAM,GAAGM,QAAQjB,KAAK;AACzB,QAAIoC,UAAU;AACd,eAAWJ,aAAaJ,YAAY;AAClC,YAAMb,UAAS,MAAM,KAAKC,qBAAqBgB,WAAWA,UAAU5C,IAAI;QACtEgB,UAAU;QACViC,UAAU;QACVC,KAAK;MACP,CAAA;AACA,UAAIvB,QAAOzB,WAAW,UAAW8C;IACnC;AACA,WAAOA;EACT;EACA,MAAMG,+BACJtB,SACuF;AACvF,UAAMnC,MAAM,KAAKH,MAAK;AACtBgD,sCAAkCV,SAASnC,GAAAA;AAC3C,UAAM8C,aAAa;SAAI,KAAKnD,KAAKyB,OAAM;MACpCC,OACC,CAACjB,SACCA,KAAIsD,iBAAiBlD,WAAW,cAC/B,CAACJ,KAAIsD,gBAAgBV,SAAShD,OAAOI,KAAIsD,gBAAgBV,MAAMC,UAAQ,EAE3EvB,KAAK,CAACC,GAAGC,MAAMD,EAAEF,YAAYG,EAAEH,cAAcE,EAAErB,KAAKsB,EAAEtB,KAAK,KAAKqB,EAAErB,KAAKsB,EAAEtB,KAAK,IAAI,EAAA,EAClFuB,MAAM,GAAG,EAAA;AACZ,eAAWqB,aAAaJ,YAAY;AAClC,YAAM1C,OAAM,KAAKT,KAAKU,IAAI6C,UAAU5C,EAAE;AACtC,UAAI,CAACF,KAAK;AACV,YAAMuD,OAAOC,2BAA2BxD,MAAK+B,SAAS,KAAKtC,MAAK,GAAI0C,WAAAA,CAAAA;AACpE,UAAI,CAACoB,MAAME,WAAW,CAACF,KAAKD,iBAAiBV,MAAO;AACpD,WAAKrD,KAAKkB,IAAI8C,KAAKrD,IAAIqD,IAAAA;AACvB,aAAO;QACLE,SAASlD,uBAAuBgD,KAAKE,OAAO;QAC5Cb,OAAO;UACLc,WAAWH,KAAKE,QAAQvD;UACxByD,OAAOJ,KAAKD,gBAAgBV,MAAMe;UAClCC,YAAYL,KAAKD,gBAAgBM;QACnC;MACF;IACF;AACA,WAAO;EACT;EAEA,MAAMC,8BACJ/D,OACqC;AACrCC,mCAA+BD,KAAAA;AAC/B,UAAMgE,WAAW,KAAKvE,KAAKU,IAAIH,MAAMI,EAAE;AACvC,QAAI4D,SAAU,QAAO,KAAKjE,qBAAqBC,KAAAA;AAC/C,UAAMQ,WAAWE,sBAAsBV,OAAO,KAAKL,MAAK,CAAA;AAExD,UAAMsE,eAAiC,CAAA;AACvC,QAAIjE,MAAMkE,eACR,YAAWhE,QAAO,KAAKT,KAAKyB,OAAM,GAAI;AACpC,UACEhB,KAAIkB,aAAa,aACjB,CAACf,2BAA2BH,MAAKF,KAAAA,KACjCE,KAAIiE,aAAanE,MAAMmE,YACvBjE,KAAIgE,mBAAmBlE,MAAMkE,eAE7B;AACF,YAAMnC,UAASqC,qCACblE,MACAM,UACA;QAAE6D,uBAAuB7D,SAASJ;QAAIiD,UAAUrD,MAAMqD;QAAUC,KAAK;MAAe,GACpF,KAAK3D,MAAK,CAAA;AAEZ,UAAIoC,QAAOvB,SAAUyD,cAAaK,KAAKvC,QAAOvB,QAAQ;IACxD;AACF,SAAKf,KAAKkB,IAAIH,SAASJ,IAAII,QAAAA;AAC3B,eAAWN,QAAO+D,aAAc,MAAKxE,KAAKkB,IAAIT,KAAIE,IAAIF,IAAAA;AACtD,WAAO;MAAEI,QAAQ;MAAWE,UAAUC,uBAAuBD,QAAAA;IAAU;EACzE;EACA,MAAM+D,wBACJ1D,OACAT,IACA6B,SACuC;AACvC,UAAMuC,cAAc,KAAK/E,KAAKU,IAAI8B,QAAQoC,qBAAqB;AAC/D,QAAI,CAACG,eAAe,CAACnE,2BAA2BmE,aAAa3D,KAAAA,EAC3D,QAAO;MAAEP,QAAQ;IAAY;AAC/B,WAAO,KAAKuB,OAAOhB,OAAOT,IAAI,CAACF,MAAKJ,QAClCsE,qCAAqClE,MAAKsE,aAAavC,SAASnC,GAAAA,CAAAA;EAEpE;AACF;;;AC7CO,IAAM2E,qBAAN,cACGC,4BAAAA;EApMV,OAoMUA;;;EAGSC,UAAU,oBAAIC,IAAAA;;EAEdC,SAAS,oBAAID,IAAAA;EACbE,SAAS,oBAAIF,IAAAA;EACbG,YAAY,oBAAIH,IAAAA;EAChBI,QAAoB,CAAA;EACpBC,OAAO,oBAAIL,IAAAA;EAEpBM,MAAc;AACpB,YAAO,oBAAIC,KAAAA,GAAOC,YAAW;EAC/B;EAEA,MAAMC,aAAaC,OAAkD;AACnE,UAAMC,KAAKD,MAAMC,MAAMC,OAAOC,WAAU;AACxC,QAAI,KAAKd,QAAQe,IAAIH,EAAAA,GAAK;AACxB,YAAM,IAAII,MAAM,UAAUJ,EAAAA,iBAAmB;IAC/C;AACA,UAAMK,KAAK,KAAKV,IAAG;AACnB,UAAMW,OAAiB;MACrBN;MACAO,UAAUR,MAAMS,MAAMR;MACtBS,WAAWV,MAAMS,MAAMC,aAAa;MACpCC,OAAOX,MAAMW,SAAS;MACtBC,WAAWZ,MAAMY,aAAa;MAC9BC,WAAWP;MACXQ,WAAWR;MACXS,UAAU,CAAA;MACV,GAAIf,MAAMgB,YAAYC,SAAY;QAAED,SAAShB,MAAMgB;MAAQ,IAAI,CAAC;IAClE;AACA,SAAK3B,QAAQ6B,IAAIjB,IAAIM,IAAAA;AACrB,WAAO,KAAKY,UAAUZ,IAAAA;EACxB;EAEA,MAAMa,UAAUC,UAAgD;AAC9D,UAAMd,OAAM,KAAKlB,QAAQiC,IAAID,QAAAA;AAC7B,QAAId,SAAQU,QAAW;AACrB,aAAO;IACT;AACA,WAAO;MACL,GAAG,KAAKE,UAAUZ,IAAAA;MAClBQ,UAAUR,KAAIQ,SAASQ,IAAI,CAACC,YAAY,KAAKC,cAAcD,OAAAA,CAAAA;;MAE3D,GAAIjB,KAAImB,mBAAmBT,SAAY;QAAEU,aAAapB,KAAImB;MAAe,IAAI,CAAC;IAChF;EACF;;EAGQD,cAAcD,SAAuC;AAC3D,UAAMI,YAAgC,CAAA;AACtC,eAAWC,QAAQ,KAAKpC,UAAUqC,OAAM,GAAI;AAC1C,UAAID,KAAKE,cAAcP,QAAQvB,IAAI;AACjC;MACF;AACA,YAAM+B,WAAWC,wBAAwB;QACvCC,YAAYL,KAAKK;QACjB,GAAIL,KAAKM,eAAelB,SAAY;UAAEkB,YAAYN,KAAKM;QAAW,IAAI,CAAC;QACvEC,QAAQP,KAAKO;QACbC,UAAUR,KAAKQ;QACfC,cAAcT,KAAKS;QACnBC,WAAWV,KAAKU;QAChBC,UAAUX,KAAKW;QACfC,eAAeZ,KAAKY;QACpBC,YAAYb,KAAKa;QACjBC,OAAOd,KAAKc;MACd,CAAA;AACA,UAAIX,aAAa,MAAM;AACrBJ,kBAAUgB,KAAKZ,QAAAA;MACjB;IACF;AACA,WAAOJ,UAAUiB,SAAS,IAAI;MAAE,GAAGrB;MAASI;IAAU,IAAIJ;EAC5D;EAEA,MAAMsB,oBAAoBzB,UAAqC;AAC7D,UAAM0B,QAAQ,oBAAIC,IAAAA;AAClB,eAAWnB,QAAQ,KAAKpC,UAAUqC,OAAM,GAAI;AAC1C,UAAID,KAAKR,aAAaA,YAAYQ,KAAKW,aAAa,MAAM;AACxDO,cAAME,IAAIpB,KAAKqB,QAAQ;MACzB;IACF;AACA,UAAMC,SAAS,KAAK9D,QAAQiC,IAAID,QAAAA;AAChC,QAAI8B,QACF;AAAA,iBAAWC,YAAY,KAAKC,KAAKvB,OAAM,EACrC,KACEsB,SAAS/B,aAAaA,YACtB+B,SAAS5C,aAAa2C,OAAO3C,YAC7B4C,SAAS1C,cAAcyC,OAAOzC,aAC9B0C,SAASE,eAAed,aAAa,SACpCY,SAASG,WAAWnB,WAAW,eAAegB,SAASG,WAAWnB,WAAW,UAE9EW,OAAME,IAAIG,SAASF,QAAQ;IAAC;AAClC,WAAO;SAAIH;;EACb;EAEA,MAAMS,cAActB,YAAsC;AACxD,WAAO,KAAKzC,UAAU6B,IAAIY,UAAAA,GAAalC,SAAS;EAClD;EAEA,MAAMyD,iBAAiBvB,YAA2D;AAChF,UAAML,OAAO,KAAKpC,UAAU6B,IAAIY,UAAAA;AAChC,QAAIL,SAASZ,QAAW;AACtB,aAAO;IACT;AACA,WAAO;MACLmB,QAAQP,KAAKO;MACbC,UAAUR,KAAKQ,YAAY;MAC3BE,WAAWV,KAAKU,aAAa;IAC/B;EACF;EAEA,MAAMmB,YAAYlD,UAAkBmD,QAAQ,IAA8B;AACxE,WAAO;SAAI,KAAKtE,QAAQyC,OAAM;MAC3B8B,OAAO,CAACrD,SAAQA,KAAIC,aAAaA,YAAY,CAACD,KAAIK,SAAS,EAC3DiD,KAAK,CAACC,GAAGC,MAAMA,EAAEjD,UAAUkD,cAAcF,EAAEhD,SAAS,CAAA,EACpDmD,MAAM,GAAGN,KAAAA,EACTpC,IAAI,CAAChB,SAAQ,KAAKY,UAAUZ,IAAAA,CAAAA;EACjC;EAEA,MAAM2D,iBAAiB7C,UAAiC;AACtD,SAAKhC,QAAQ8E,OAAO9C,QAAAA;EACtB;EAEA,MAAM+C,WAAW/C,UAAkBgD,eAA+C;AAChF,UAAMC,SAAS,KAAKjF,QAAQiC,IAAID,QAAAA;AAChC,QAAIiD,WAAWrD,QAAW;AACxB,YAAM,IAAIZ,MAAM,UAAUgB,QAAAA,YAAoB;IAChD;AACA,UAAMkD,SAASD,OAAOvD,SAASyD,UAAU,CAAChD,YAAYA,QAAQvB,OAAOoE,aAAAA;AACrE,UAAMI,OAAOF,UAAU,IAAID,OAAOvD,SAASkD,MAAM,GAAGM,SAAS,CAAA,IAAK;SAAID,OAAOvD;;AAC7E,UAAMd,KAAKC,OAAOC,WAAU;AAC5B,UAAMG,KAAK,KAAKV,IAAG;AACnB,UAAMW,OAAiB;MACrBN;MACAO,UAAU8D,OAAO9D;MACjBE,WAAW4D,OAAO5D;MAClBC,OAAO2D,OAAO3D;MACdC,WAAW;MACXC,WAAWP;MACXQ,WAAWR;;MAEXS,UAAU0D,KAAKlD,IAAI,CAAC,EAAEmD,UAAUC,WAAW,GAAGnD,QAAAA,OAAe;QAAE,GAAGA;MAAQ,EAAA;MAC1E,GAAI8C,OAAOM,gBAAgB,OAAO;QAAEA,cAAcN,OAAOM;MAAa,IAAI,CAAC;MAC3E,GAAIN,OAAOO,SAAS,OAAO;QAAEA,OAAOP,OAAOO;MAAM,IAAI,CAAC;MACtD,GAAIP,OAAOtD,WAAW,OAAO;QAAEA,SAASsD,OAAOtD;MAAQ,IAAI,CAAC;IAC9D;AACA,SAAK3B,QAAQ6B,IAAIjB,IAAIM,IAAAA;AACrB,WAAO,KAAKY,UAAUZ,IAAAA;EACxB;EAEA,MAAMuE,cAAczD,UAA0C;AAC5D,WAAO,KAAKhC,QAAQiC,IAAID,QAAAA,GAAWb,YAAY;EACjD;EAEA,MAAMuE,gBAAgB7C,YAA4C;AAChE,UAAML,OAAO,KAAKpC,UAAU6B,IAAIY,UAAAA;AAChC,QAAIL,SAASZ,QAAW;AACtB,aAAO;IACT;AACA,WAAO,KAAK5B,QAAQiC,IAAIO,KAAKR,QAAQ,GAAGb,YAAY;EACtD;EAEA,MAAMwE,eAAe9C,YAA4C;AAC/D,UAAML,OAAO,KAAKpC,UAAU6B,IAAIY,UAAAA;AAChC,QAAIL,SAASZ,QAAW;AACtB,aAAO;IACT;AACA,WAAOY,KAAKoD,SAAS,KAAK5F,QAAQiC,IAAIO,KAAKR,QAAQ,GAAGK,kBAAkB;EAC1E;EAEA,MAAMwD,oBAAoBD,OAAuC;AAC/D,eAAW1E,QAAO,KAAKlB,QAAQyC,OAAM,GAAI;AACvC,UAAIvB,KAAImB,mBAAmBuD,OAAO;AAChC,eAAO1E,KAAIC;MACb;IACF;AACA,WAAO;EACT;EAEA,MAAM2E,SAAS9D,UAAkBV,OAA8B;AAC7D,UAAMJ,OAAM,KAAKlB,QAAQiC,IAAID,QAAAA;AAC7B,QAAId,SAAQU,QAAW;AACrBV,MAAAA,KAAII,QAAQA;AACZJ,MAAAA,KAAIO,YAAY,KAAKlB,IAAG;IAC1B;EACF;EAEA,MAAMwF,aAAa/D,UAAkBgE,OAAyC;AAC5E,UAAM9E,OAAM,KAAKlB,QAAQiC,IAAID,QAAAA;AAC7B,QAAId,SAAQU,QAAW;AACrB;IACF;AACA,QAAIoE,MAAM1E,UAAUM,QAAW;AAC7BV,MAAAA,KAAII,QAAQ0E,MAAM1E;IACpB;AACA,QAAI0E,MAAMT,iBAAiB3D,QAAW;AACpCV,MAAAA,KAAIqE,eAAeS,MAAMT;IAC3B;AACA,QAAIS,MAAMR,UAAU5D,QAAW;AAC7BV,MAAAA,KAAIsE,QAAQQ,MAAMR;IACpB;AACA,QAAIQ,MAAMrE,YAAYC,QAAW;AAC/BV,MAAAA,KAAIS,UAAUqE,MAAMrE;IACtB;AACAT,IAAAA,KAAIO,YAAY,KAAKlB,IAAG;EAC1B;EAEA,MAAM0F,mBAAmBjE,UAA0C;AACjE,WAAO,KAAKhC,QAAQiC,IAAID,QAAAA,GAAWK,kBAAkB;EACvD;;;;;;EAOA,MAAM6D,sBAAsBlE,UAA0C;AACpE,WAAO,KAAKhC,QAAQiC,IAAID,QAAAA,GAAWuD,gBAAgB;EACrD;;EAGA,MAAMY,iBAAiBnE,UAA0C;AAC/D,WAAO,KAAKhC,QAAQiC,IAAID,QAAAA,GAAWL,WAAW;EAChD;;EAGA,MAAMyE,eAAepE,UAA0C;AAC7D,WAAO,KAAKhC,QAAQiC,IAAID,QAAAA,GAAWwD,SAAS;EAC9C;;;;;;;EAQA,MAAMa,eAAeC,KAAyC;AAC5D,SAAKhG,KAAKuB,IAAIyE,IAAIV,OAAO;MACvBA,OAAOU,IAAIV;MACX5D,UAAUsE,IAAItE;MACdb,UAAUmF,IAAInF;MACd4B,QAAQ;MACRwD,SAAS;MACTC,WAAW,KAAKjG,IAAG;MACnB,GAAI+F,IAAIG,cAAc7E,SAAY;QAAE6E,WAAWH,IAAIG;MAAU,IAAI,CAAC;MAClE,GAAIH,IAAII,gBAAgB9E,SAAY;QAAE8E,aAAaJ,IAAII;MAAY,IAAI,CAAC;MACxE,GAAIJ,IAAIK,eAAe/E,SAAY;QAAE+E,YAAYL,IAAIK;MAAW,IAAI,CAAC;IACvE,CAAA;EACF;;EAGA,MAAMC,aAAaC,KAMD;AAChB,UAAM3F,OAAM,KAAKZ,KAAK2B,IAAI4E,IAAIjB,KAAK;AACnC,QAAI1E,SAAQU,QAAW;AACrB;IACF;AACAV,IAAAA,KAAI6B,SAAS8D,IAAI9D;AACjB7B,IAAAA,KAAI4F,YAAY,KAAKvG,IAAG;AACxB,QAAIsG,IAAIE,eAAenF,QAAW;AAChCV,MAAAA,KAAI6F,aAAaF,IAAIE;IACvB;AACA,QAAIF,IAAIG,cAAcpF,QAAW;AAC/BV,MAAAA,KAAI8F,YAAYH,IAAIG;IACtB;AACA,QAAIH,IAAII,iBAAiBrF,QAAW;AAClCV,MAAAA,KAAI+F,eAAeJ,IAAII;IACzB;EACF;;EAGA,MAAMC,eAAetB,OAA8B;AACjD,UAAM1E,OAAM,KAAKZ,KAAK2B,IAAI2D,KAAAA;AAC1B,QAAI1E,SAAQU,QAAW;AACrBV,MAAAA,KAAIqF,WAAW;IACjB;EACF;EAEA,MAAMY,cAAcnF,UAAiC;AACnD,UAAMd,OAAM,KAAKlB,QAAQiC,IAAID,QAAAA;AAC7B,QAAId,MAAKK,WAAW;AAClBL,MAAAA,KAAIK,YAAY;AAChBL,MAAAA,KAAIO,YAAY,KAAKlB,IAAG;IAC1B;EACF;EAEA,MAAM6G,gBAAgBpF,UAAkB4D,OAAqC;AAC3E,UAAM1E,OAAM,KAAKlB,QAAQiC,IAAID,QAAAA;AAC7B,QAAId,SAAQU,QAAW;AACrB,UAAIgE,UAAU,MAAM;AAElB,eAAO1E,KAAImB;MACb,OAAO;AACLnB,QAAAA,KAAImB,iBAAiBuD;MACvB;IACF;EACF;EAEA,MAAMyB,kBACJrF,UACA4D,OACA0B,UAAkC,CAAC,GACjB;AAClB,UAAMpG,OAAM,KAAKlB,QAAQiC,IAAID,QAAAA;AAC7B,QAAId,SAAQU,QAAW;AACrB,aAAO;IACT;AACA,UAAM2F,SAASrG,KAAImB;AACnB,QAAIkF,WAAW3F,UAAa2F,WAAW3B,SAAS2B,WAAWD,QAAQE,WAAW;AAC5E,aAAO;IACT;AACAtG,IAAAA,KAAImB,iBAAiBuD;AACrB,WAAO;EACT;EAEA,MAAM6B,oBAAoBzF,UAAkB4D,OAAiC;AAC3E,UAAM1E,OAAM,KAAKlB,QAAQiC,IAAID,QAAAA;AAC7B,QAAId,MAAKmB,mBAAmBuD,OAAO;AACjC,aAAO;IACT;AAEA,WAAO1E,KAAImB;AACX,WAAO;EACT;EAEA,MAAMqF,eAAe/G,OAAoD;AACvE,UAAMM,KAAK,KAAKV,IAAG;AACnB,UAAM4B,UAAyB;MAC7BvB,IAAIC,OAAOC,WAAU;MACrBkB,UAAUrB,MAAMqB;MAChBZ,OAAOT,MAAMS;MACbuG,SAAShH,MAAMgH;MACf,GAAIhH,MAAMiH,gBAAgBhG,UAAajB,MAAMiH,YAAYpE,SAAS,IAC9D;QAAEoE,aAAajH,MAAMiH;MAAY,IACjC,CAAC;MACL,GAAIjH,MAAM8F,cAAc7E,SAAY;QAAE6E,WAAW9F,MAAM8F;MAAU,IAAI,CAAC;MACtE,GAAI9F,MAAMgB,YAAYC,SAAY;QAAED,SAAShB,MAAMgB;MAAQ,IAAI,CAAC;MAChE,GAAIhB,MAAM6E,UAAU5D,SAAY;QAAE4D,OAAO7E,MAAM6E;MAAM,IAAI,CAAC;MAC1D,GAAI7E,MAAMkH,gBAAgBjG,SAAY;QAAEiG,aAAalH,MAAMkH;MAAY,IAAI,CAAC;MAC5E,GAAIlH,MAAMmH,mBAAmBlG,SAAY;QAAEkG,gBAAgBnH,MAAMmH;MAAe,IAAI,CAAC;MACrF,GAAInH,MAAMoH,gBAAgBnG,SAAY;QAAEmG,aAAapH,MAAMoH;MAAY,IAAI,CAAC;MAC5E,GAAIpH,MAAMqH,cAAc,OAAO;QAAEA,WAAW;MAAK,IAAI,CAAC;MACtDxG,WAAWP;MACXQ,WAAWR;IACb;AACA,UAAMgH,QAAQ,KAAK/H,OAAO+B,IAAItB,MAAMqB,QAAQ,KAAK,CAAA;AACjD,QAAIrB,MAAMuH,OAAO,QAAQ;AACvBD,YAAME,QAAQhG,OAAAA;IAChB,OAAO;AACL8F,YAAM1E,KAAKpB,OAAAA;IACb;AACA,SAAKjC,OAAO2B,IAAIlB,MAAMqB,UAAUiG,KAAAA;AAChC,WAAO;MAAE,GAAG9F;IAAQ;EACtB;EAEA,MAAMiG,UAAUpG,UAA4C;AAC1D,YAAQ,KAAK9B,OAAO+B,IAAID,QAAAA,KAAa,CAAA,GAAIE,IAAI,CAACC,aAAa;MAAE,GAAGA;IAAQ,EAAA;EAC1E;EAEA,MAAMkG,iBAAiBzH,IAA2C;AAChE,UAAM0H,QAAQ,KAAKC,WAAW3H,EAAAA;AAC9B,WAAO0H,UAAU1G,SAAY,OAAO;MAAE,GAAG0G,MAAMnG;IAAQ;EACzD;EAEA,MAAMqG,oBAAoB5H,IAAYoF,OAA0D;AAC9F,UAAMsC,QAAQ,KAAKC,WAAW3H,EAAAA;AAC9B,QAAI0H,UAAU1G,QAAW;AACvB,aAAO;IACT;AACA,UAAM,EAAEO,QAAO,IAAKmG;AACpB,QAAItC,MAAM2B,YAAY/F,QAAW;AAC/BO,cAAQwF,UAAU3B,MAAM2B;IAC1B;AACA,QAAI3B,MAAM4B,gBAAgBhG,QAAW;AACnC,UAAIoE,MAAM4B,gBAAgB,QAAQ5B,MAAM4B,YAAYpE,WAAW,GAAG;AAEhE,eAAOrB,QAAQyF;MACjB,OAAO;AACLzF,gBAAQyF,cAAc5B,MAAM4B;MAC9B;IACF;AACA,QAAI5B,MAAMgC,cAAcpG,QAAW;AACjC,UAAIoE,MAAMgC,WAAW;AACnB7F,gBAAQ6F,YAAY;MACtB,OAAO;AAEL,eAAO7F,QAAQ6F;MACjB;IACF;AACA7F,YAAQV,YAAY,KAAKlB,IAAG;AAC5B,WAAO;MAAE,GAAG4B;IAAQ;EACtB;EAEA,MAAMsG,kBAAkB7H,IAAY8H,OAAiC;AACnE,UAAMJ,QAAQ,KAAKC,WAAW3H,EAAAA;AAC9B,QAAI0H,UAAU1G,QAAW;AACvB,aAAO;IACT;AACA,UAAM,EAAEqG,OAAOU,UAAUxG,QAAO,IAAKmG;AACrCL,UAAMW,OAAOD,UAAU,CAAA;AACvB,UAAME,SAASC,KAAKC,IAAI,GAAGD,KAAKE,IAAIf,MAAMzE,QAAQsF,KAAKG,MAAMP,KAAAA,CAAAA,CAAAA;AAC7DT,UAAMW,OAAOC,QAAQ,GAAG1G,OAAAA;AACxB,WAAO;EACT;EAEA,MAAM+G,oBAAoBtI,IAA8B;AACtD,UAAM0H,QAAQ,KAAKC,WAAW3H,EAAAA;AAC9B,QAAI0H,UAAU1G,QAAW;AACvB,aAAO;IACT;AACA0G,UAAML,MAAMW,OAAON,MAAMK,UAAU,CAAA;AACnC,WAAO;EACT;EAEA,MAAMQ,WAAWnH,UAAmC;AAClD,UAAMoH,QAAQ,KAAKlJ,OAAO+B,IAAID,QAAAA,GAAWwB,UAAU;AACnD,SAAKtD,OAAO4E,OAAO9C,QAAAA;AACnB,WAAOoH;EACT;EAEA,MAAMC,WAAWrH,UAA8C;AAC7D,WAAO,KAAK7B,OAAO8B,IAAID,QAAAA,KAAa;EACtC;EAEA,MAAMsH,cAActH,UAAkBuH,OAAyC;AAC7E,QAAIA,UAAU,MAAM;AAClB,WAAKpJ,OAAO2E,OAAO9C,QAAAA;IACrB,OAAO;AACL,WAAK7B,OAAO0B,IAAIG,UAAUuH,KAAAA;IAC5B;EACF;EAEQhB,WACN3H,IACkF;AAClF,eAAWqH,SAAS,KAAK/H,OAAOuC,OAAM,GAAI;AACxC,YAAMkG,WAAWV,MAAM9C,UAAU,CAAChD,aAAYA,SAAQvB,OAAOA,EAAAA;AAC7D,YAAMuB,UAAU8F,MAAMU,QAAAA;AACtB,UAAIxG,YAAYP,QAAW;AACzB,eAAO;UAAEqG;UAAOU;UAAUxG;QAAQ;MACpC;IACF;AACA,WAAOP;EACT;EAEA,MAAM4H,6BAA6BxH,UAAuD;AACxF,UAAMd,OAAM,KAAKlB,QAAQiC,IAAID,QAAAA;AAC7B,WAAOd,OAAM;MAAEc;MAAUb,UAAUD,KAAIC;MAAUE,WAAWH,KAAIG;IAAU,IAAI;EAChF;EACA,MAAMoI,2BACJC,SACsE;AACtE,UAAMxI,OAAM;SAAI,KAAK8C,KAAKvB,OAAM;MAAIkH,KAAK,CAACzI,SAAQA,KAAI0I,SAAShJ,OAAO8I,QAAQG,SAAS;AACvF,QAAI,CAAC3I,MAAK0I,WAAW,CAAC1I,KAAI4I,gBAAiB,QAAO;MAAE/G,QAAQ;IAAY;AACxE,QAAI7B,KAAI4I,gBAAgB/G,WAAW,WACjC,QAAO;MACLA,QAAQ;MACR,GAAI7B,KAAI4I,gBAAgBpH,cAAcd,SAClC;QAAEc,WAAWxB,KAAI4I,gBAAgBpH;MAAU,IAC3C,CAAC;IACP;AACF,QAAIxB,KAAI4I,gBAAgB/G,WAAW,YAAa,QAAO;MAAEA,QAAQ;IAAY;AAC7E,QAAI,CAACgH,gCAAgC7I,MAAKwI,SAAS,KAAKM,MAAK,CAAA,EAAK,QAAO;MAAEjH,QAAQ;IAAW;AAC9F,UAAMe,SAAS,KAAK9D,QAAQiC,IAAIf,KAAIc,QAAQ;AAC5C,QAAI,CAAC8B,QAAQ;AACX,WAAKE,KAAKnC,IACRX,KAAIN,IACJqJ,uBAAuB;QACrB,GAAG/I;QACH4I,iBAAiB;UAAE,GAAG5I,KAAI4I;UAAiB/G,QAAQ;UAAamH,OAAO;QAAK;MAC9E,CAAA,CAAA;AAEF,aAAO;QAAEnH,QAAQ;MAAY;IAC/B;AACA,QAAIe,OAAO3C,aAAaD,KAAIC,YAAY2C,OAAOzC,cAAcH,KAAIG,UAC/D,QAAO;MAAE0B,QAAQ;IAAW;AAC9B,QAAIe,OAAOzB,eAAgB,QAAO;MAAEU,QAAQ;IAAO;AAEnD,UAAMZ,UAAyB;MAC7BvB,IAAIC,OAAOC,WAAU;MACrBqJ,MAAM;MACNxC,SAASyC,0BAA0BlJ,KAAI0I,OAAO;MAC9CpI,WAAW,KAAKjB,IAAG;MACnB8J,uBAAuBJ,uBAAuB/I,KAAI0I,OAAO;MACzDU,IAAIL,uBAAuB/I,KAAI0I,QAAQU,EAAE;IAC3C;AACA,UAAMC,OAAON,uBAAuB;MAClC,GAAG/I;MACH4I,iBAAiB;QACf,GAAG5I,KAAI4I;QACP/G,QAAQ;QACRmH,OAAO;QACPxH,WAAWP,QAAQvB;MACrB;IACF,CAAA;AACAkD,WAAOpC,SAAS6B,KAAKpB,OAAAA;AACrB2B,WAAOrC,YAAYU,QAAQX;AAC3B,SAAKwC,KAAKnC,IAAIX,KAAIN,IAAI2J,IAAAA;AACtB,WAAO;MAAExH,QAAQ;MAAWL,WAAWP,QAAQvB;IAAG;EACpD;EACA,MAAM4J,cAAc7J,OAAmD;AACrE,UAAMO,OAAM,KAAKlB,QAAQiC,IAAItB,MAAMqB,QAAQ;AAC3C,QAAId,SAAQU,QAAW;AACrB,YAAM,IAAIZ,MAAM,UAAUL,MAAMqB,QAAQ,YAAY;IACtD;AACA,UAAMG,UAAyB;MAC7BvB,IAAIC,OAAOC,WAAU;MACrBqJ,MAAMxJ,MAAMwJ;MACZxC,SAAShH,MAAMgH;MACfnG,WAAW,KAAKjB,IAAG;MACnB,GAAII,MAAMP,cAAcwB,SAAY;QAAExB,WAAWO,MAAMP;MAAU,IAAI,CAAC;MACtE,GAAIO,MAAM8J,gBAAgB7I,SAAY;QAAE6I,aAAa9J,MAAM8J;MAAY,IAAI,CAAC;MAC5E,GAAI9J,MAAMiH,gBAAgBhG,SAAY;QAAEgG,aAAajH,MAAMiH;MAAY,IAAI,CAAC;MAC5E,GAAIjH,MAAM+J,cAAc9I,SAAY;QAAE8I,WAAW/J,MAAM+J;MAAU,IAAI,CAAC;MACtE,GAAI/J,MAAMN,UAAUuB,SAAY;QAAEvB,OAAOM,MAAMN;MAAM,IAAI,CAAC;MAC1D,GAAIM,MAAM8F,cAAc7E,SAAY;QAAE6E,WAAW9F,MAAM8F;MAAU,IAAI,CAAC;MACtE,GAAI9F,MAAMgB,YAAYC,SAAY;QAAED,SAAShB,MAAMgB;MAAQ,IAAI,CAAC;MAChE,GAAIhB,MAAMiF,UAAUhE,SAAY;QAAEgE,OAAOjF,MAAMiF;MAAM,IAAI,CAAC;MAC1D,GAAIjF,MAAMgK,cAAc/I,SAAY;QAAE+I,WAAWhK,MAAMgK;MAAU,IAAI,CAAC;MACtE,GAAIhK,MAAMiK,gBAAgBhJ,SAAY;QAAEgJ,aAAajK,MAAMiK;MAAY,IAAI,CAAC;MAC5E,GAAIjK,MAAM2J,OAAO1I,SAAY;QAAE0I,IAAI3J,MAAM2J;MAAG,IAAI,CAAC;MACjD,GAAI3J,MAAM0J,0BAA0BzI,SAChC;QAAEyI,uBAAuB1J,MAAM0J;MAAsB,IACrD,CAAC;IACP;AACAnJ,IAAAA,KAAIQ,SAAS6B,KAAKpB,OAAAA;AAClBjB,IAAAA,KAAIO,YAAYU,QAAQX;AACxB,WAAOW;EACT;EAEA,MAAM0I,sBAAsBnI,WAAmBoI,SAAsC;AACnF,eAAW5J,QAAO,KAAKlB,QAAQyC,OAAM,GAAI;AACvC,YAAMN,UAAUjB,KAAIQ,SAASiI,KAAK,CAACoB,cAAcA,UAAUnK,OAAO8B,SAAAA;AAClE,UAAIP,YAAYP,QAAW;AACzBO,gBAAQsI,cAAcK;AACtB;MACF;IACF;EACF;EAEA,MAAME,aAAatI,WAAmB4H,IAAuC;AAC3E,eAAWpJ,QAAO,KAAKlB,QAAQyC,OAAM,GAAI;AACvC,YAAMiG,QAAQxH,KAAIQ,SAASyD,UAAU,CAAC4F,cAAcA,UAAUnK,OAAO8B,SAAAA;AACrE,YAAMP,UAAUjB,KAAIQ,SAASgH,KAAAA;AAC7B,UAAIvG,YAAYP,QAAW;AACzB,cAAM,EAAE0I,IAAIW,WAAW,GAAGC,KAAAA,IAAS/I;AACnCjB,QAAAA,KAAIQ,SAASgH,KAAAA,IAAS4B,GAAG9G,SAAS,IAAI;UAAE,GAAG0H;UAAMZ;QAAG,IAAIY;AACxD;MACF;IACF;EACF;EAEA,MAAMC,gBAAgBzI,WAA2C;AAC/D,WAAO,KAAK0I,mBAAmB1I,SAAAA,KAAc;EAC/C;EAEA,MAAM2I,mBAAmB3I,WAAmB2C,UAAiD;AAC3F,eAAWnE,QAAO,KAAKlB,QAAQyC,OAAM,GAAI;AACvC,YAAMiG,QAAQxH,KAAIQ,SAASyD,UAAU,CAAC4F,cAAcA,UAAUnK,OAAO8B,SAAAA;AACrE,YAAMP,UAAUjB,KAAIQ,SAASgH,KAAAA;AAC7B,UAAIvG,YAAYP,QAAW;AACzB,cAAM,EAAEyD,UAAU4F,WAAW,GAAGC,KAAAA,IAAS/I;AACzCjB,QAAAA,KAAIQ,SAASgH,KAAAA,IAASrD,aAAa,OAAO;UAAE,GAAG6F;UAAM7F;QAAS,IAAI6F;AAClE;MACF;IACF;EACF;EAEA,MAAMI,aAAatJ,UAAkBU,WAAkC;AACrE,UAAMxB,OAAM,KAAKlB,QAAQiC,IAAID,QAAAA;AAC7B,QAAId,SAAQU,QAAW;AACrB;IACF;AACA,UAAMsD,SAAShE,KAAIQ,SAASyD,UAAU,CAAChD,YAAYA,QAAQvB,OAAO8B,SAAAA;AAClE,QAAIwC,UAAU,GAAG;AACfhE,MAAAA,KAAIQ,WAAWR,KAAIQ,SAASkD,MAAM,GAAGM,MAAAA;IACvC;EACF;;;;;;;EAQA,MAAMqG,mBAAmBpK,UAAkBqK,UAAgD;AACzF,QAAIA,SAAShI,WAAW,GAAG;AACzB,aAAO,CAAA;IACT;AACA,UAAMiI,SAAS,IAAI9H,IAAI6H,QAAAA;AACvB,UAAMlD,QAAQ,oBAAI3E,IAAAA;AAClB,eAAWG,UAAU,KAAK9D,QAAQyC,OAAM,GAAI;AAC1C,UAAIqB,OAAO3C,aAAaA,UAAU;AAChC;MACF;AAGA,YAAMuK,SAAS,KAAKxL,OAAO+B,IAAI6B,OAAOlD,EAAE,KAAK,CAAA;AAC7C,iBAAWuB,WAAW;WAAI2B,OAAOpC;WAAagK;SAAS;AACrD,mBAAWC,cAAcxJ,QAAQyF,eAAe,CAAA,GAAI;AAClD,cAAI6D,OAAO1K,IAAI4K,WAAWC,OAAO,GAAG;AAClCtD,kBAAM1E,IAAI+H,WAAWC,OAAO;UAC9B;QACF;MACF;IACF;AACA,WAAO;SAAIH;MAAQlH,OAAO,CAACqH,YAAYtD,MAAMvH,IAAI6K,OAAAA,CAAAA;EACnD;EAEA,MAAMC,eAAelL,OAA2C;AAC9D,SAAKP,UAAUyB,IAAIlB,MAAMkC,YAAY;MACnCA,YAAYlC,MAAMkC;MAClB,GAAIlC,MAAMmC,eAAelB,SAAY;QAAEkB,YAAYnC,MAAMmC;MAAW,IAAI,CAAC;MACzEJ,WAAW/B,MAAM+B;MACjBV,UAAU,KAAKoJ,mBAAmBzK,MAAM+B,SAAS,KAAK;MACtDmB,UAAUlD,MAAMkD;MAChBiI,UAAUnL,MAAMmL;MAChBnL,OAAOA,MAAMA;MACboC,QAAQpC,MAAMoC;MACdvB,WAAW,KAAKjB,IAAG;MACnB,GAAII,MAAMiF,UAAUhE,SAAY;QAAEgE,OAAOjF,MAAMiF;MAAM,IAAI,CAAC;MAC1D,GAAIjF,MAAMqC,aAAapB,SAAY;QAAEoB,UAAUrC,MAAMqC;MAAS,IAAI,CAAC;MACnE,GAAIrC,MAAMsC,iBAAiBrB,SACvB;QAAEqB,cAAc8I,gBAAgBpL,MAAMsC,YAAY;MAAE,IACpD,CAAC;MACL,GAAItC,MAAMuC,cAActB,SAAY;QAAEsB,WAAWvC,MAAMuC;MAAU,IAAI,CAAC;IACxE,CAAA;EACF;EAEA,MAAM8I,iBAAiBC,aAA4D;AACjF,UAAMC,WAA8B,CAAA;AACpC,eAAWtL,MAAMqL,aAAa;AAC5B,YAAM/K,OAAM,KAAKd,UAAU6B,IAAIrB,EAAAA;AAC/B,UAAIM,SAAQU,QAAW;AACrBsK,iBAAS3I,KAAK;UACZ3C;UACAmC,QAAQ7B,KAAI6B;UACZ,GAAI7B,KAAIiL,WAAWvK,SAAY;YAAEuK,QAAQjL,KAAIiL;UAAO,IAAI,CAAC;UACzD,GAAIjL,KAAIoC,UAAU1B,SAAY;YAAE0B,OAAOpC,KAAIoC;UAAM,IAAI,CAAC;QACxD,CAAA;MACF;IACF;AACA,WAAO4I;EACT;EAEA,MAAME,uBAAuBxG,OAAetC,OAAgC;AAC1E,QAAI+I,UAAU;AACd,eAAWnL,QAAO,KAAKd,UAAUqC,OAAM,GAAI;AACzC,UAAIvB,KAAI0E,UAAUA,SAAS1E,KAAI6B,WAAW,oBAAoB;AAC5D7B,QAAAA,KAAI6B,SAAS;AACb7B,QAAAA,KAAIoC,QAAQA;AACZ+I,mBAAW;MACb;IACF;AACA,WAAOA;EACT;EAEA,MAAMC,eAAe3L,OAA2C;AAC9D,UAAMO,OAAM,KAAKd,UAAU6B,IAAItB,MAAMkC,UAAU;AAC/C,QAAI3B,SAAQU,QAAW;AACrB;IACF;AACAV,IAAAA,KAAI6B,SAASpC,MAAMoC;AACnB,QAAIpC,MAAMwL,WAAWvK,QAAW;AAC9BV,MAAAA,KAAIiL,SAASxL,MAAMwL;IACrB;AACA,QAAIxL,MAAM2C,UAAU1B,QAAW;AAC7BV,MAAAA,KAAIoC,QAAQ3C,MAAM2C;IACpB;AACA,QAAI3C,MAAM4L,gBAAgB3K,QAAW;AACnCV,MAAAA,KAAIqL,cAAc5L,MAAM4L;IAC1B;AACA,QAAI5L,MAAMyC,kBAAkBxB,QAAW;AACrCV,MAAAA,KAAIkC,gBAAgBzC,MAAMyC;IAC5B;AACA,QAAIzC,MAAMwC,aAAavB,QAAW;AAChCV,MAAAA,KAAIiC,WAAWxC,MAAMwC;IACvB;AACA,QAAIxC,MAAM0C,eAAezB,QAAW;AAClCV,MAAAA,KAAImC,aAAa1C,MAAM0C;IACzB;EACF;EAEA,MAAMmJ,YAAY7L,OAAwC;AACxD,UAAMa,YAAY,KAAKjB,IAAG;AAC1B,SAAKF,MAAMkD,KAAK;MACdpC,UAAUR,MAAMQ;MAChBa,UAAUrB,MAAMqB;MAChByK,SAAS9L,MAAM8L;MACfC,aAAa/L,MAAMN,MAAMqM;MACzBC,cAAchM,MAAMN,MAAMsM;MAC1BC,KAAKpL,UAAUoD,MAAM,GAAG,EAAA;MACxBpD;MACA,GAAIb,MAAMN,MAAMwM,qBAAqBjL,SACjC;QAAEiL,kBAAkBlM,MAAMN,MAAMwM;MAAiB,IACjD,CAAC;MACL,GAAIlM,MAAMN,MAAMyM,oBAAoBlL,SAChC;QAAEkL,iBAAiBnM,MAAMN,MAAMyM;MAAgB,IAC/C,CAAC;MACL,GAAInM,MAAMoM,YAAYnL,SAAY;QAAEmL,SAASpM,MAAMoM;MAAQ,IAAI,CAAC;IAClE,CAAA;EACF;EAEA,MAAMC,WACJ7L,UACAyL,KACkD;AAClD,WAAO,KAAKK,aAAa9L,UAAUyL,KAAKA,GAAAA;EAC1C;EAEA,MAAMK,aACJ9L,UACA+L,SACAC,OACkD;AAClD,UAAMnJ,OAAO,KAAK3D,MAAMkE,OACtB,CAACrD,SAAQA,KAAIC,aAAaA,YAAYD,KAAI0L,OAAOM,WAAWhM,KAAI0L,OAAOO,KAAAA;AAEzE,UAAMC,aAAapJ,KAAKqJ,OAAO,CAACC,KAAKpM,SAAQoM,MAAMpM,KAAIwL,cAAcxL,KAAIyL,cAAc,CAAA;AACvF,UAAMI,UAAU/I,KAAKqJ,OAAO,CAACC,KAAKpM,SAAQoM,OAAOpM,KAAI6L,WAAW,IAAI,CAAA;AACpE,WAAO;MAAEK;MAAYL;IAAQ;EAC/B;;EAGAQ,YAAqE;AACnE,WAAO,KAAKlN,MAAM6B,IAAI,CAAChB,UAAS;MAC9BC,UAAUD,KAAIC;MACdqM,QAAQtM,KAAIwL,cAAcxL,KAAIyL;MAC9BF,SAASvL,KAAIuL;IACf,EAAA;EACF;;EAGAgB,kBAAwC;AACtC,WAAO,KAAKpN,MAAM6B,IAAI,CAAChB,UAAS;MAC9BC,UAAUD,KAAIC;MACda,UAAUd,KAAIc;MACdyK,SAASvL,KAAIuL;MACbC,aAAaxL,KAAIwL;MACjBC,cAAczL,KAAIyL;MAClBC,KAAK1L,KAAI0L;MACTpL,WAAWN,KAAIM;MACf,GAAIN,KAAI2L,qBAAqBjL,SAAY;QAAEiL,kBAAkB3L,KAAI2L;MAAiB,IAAI,CAAC;MACvF,GAAI3L,KAAI4L,oBAAoBlL,SAAY;QAAEkL,iBAAiB5L,KAAI4L;MAAgB,IAAI,CAAC;MACpF,GAAI5L,KAAI6L,YAAYnL,SAAY;QAAEmL,SAAS7L,KAAI6L;MAAQ,IAAI,CAAC;IAC9D,EAAA;EACF;;EAGAW,sBAA+C;AAC7C,WAAO;SAAI,KAAKtN,UAAUqC,OAAM;MAAIP,IAAI,CAAChB,UAAS;MAChD2B,YAAY3B,KAAI2B;MAChBgB,UAAU3C,KAAI2C;MACdiI,UAAU5K,KAAI4K;MACd/I,QAAQ7B,KAAI6B;MACZf,UAAUd,KAAIc;MACdU,WAAWxB,KAAIwB;MACflB,WAAWN,KAAIM;MACf,GAAIN,KAAIqL,gBAAgB3K,SAAY;QAAE2K,aAAarL,KAAIqL;MAAY,IAAI,CAAC;MACxE,GAAIrL,KAAIoC,UAAU1B,SAAY;QAAE0B,OAAOpC,KAAIoC;MAAM,IAAI,CAAC;MACtD,GAAIpC,KAAI0E,UAAUhE,SAAY;QAAEgE,OAAO1E,KAAI0E;MAAM,IAAI,CAAC;IACxD,EAAA;EACF;;EAGA+H,qBAA6C;AAC3C,UAAM3J,OAA+B,CAAA;AACrC,eAAWF,UAAU,KAAK9D,QAAQyC,OAAM,GAAI;AAC1C,iBAAWN,WAAW2B,OAAOpC,UAAU;AACrCsC,aAAKT,KAAK;UACRb,WAAWP,QAAQvB;UACnBoB,UAAU8B,OAAOlD;UACjBuJ,MAAMhI,QAAQgI;UACdxC,SAASxF,QAAQwF;UACjBnG,WAAWW,QAAQX;UACnB,GAAIW,QAAQsE,cAAc7E,SAAY;YAAE6E,WAAWtE,QAAQsE;UAAU,IAAI,CAAC;QAC5E,CAAA;MACF;IACF;AACA,WAAOzC;EACT;;;;;EAMA4J,6BAA6D;AAC3D,UAAM5J,OAAuC,CAAA;AAC7C,eAAWxB,QAAQ,KAAKpC,UAAUqC,OAAM,GAAI;AAC1C,UAAID,KAAKO,WAAW,oBAAoB;AACtC;MACF;AACA,YAAMe,SAAS,KAAK9D,QAAQiC,IAAIO,KAAKR,QAAQ;AAC7C,UAAI8B,WAAWlC,QAAW;AACxB;MACF;AACA,YAAMO,UAAU2B,OAAOpC,SAASiI,KAAK,CAACoB,cAAcA,UAAUnK,OAAO4B,KAAKE,SAAS;AACnFsB,WAAKT,KAAK;QACRV,YAAYL,KAAKK;QACjBgB,UAAUrB,KAAKqB;QACflD,OAAO6B,KAAK7B;QACZqB,UAAUQ,KAAKR;QACf6L,aAAa/J,OAAOxC;QACpBH,UAAU2C,OAAO3C;QACjB2M,aAAatL,KAAKhB;QAClB,GAAIW,SAASsE,cAAc7E,SAAY;UAAE6E,WAAWtE,QAAQsE;QAAU,IAAI,CAAC;QAC3E,GAAIjE,KAAKoD,UAAUhE,SAAY;UAAEgE,OAAOpD,KAAKoD;QAAM,IAAI,CAAC;MAC1D,CAAA;IACF;AACA,WAAO5B;EACT;;EAGA+J,oBAA2C;AACzC,WAAO;SAAI,KAAK/N,QAAQyC,OAAM;MAAIP,IAAI,CAAChB,UAAS;MAC9Cc,UAAUd,KAAIN;MACdU,OAAOJ,KAAII;MACXH,UAAUD,KAAIC;MACd6M,cAAc9M,KAAIQ,SAAS8B;MAC3B/B,WAAWP,KAAIO;IACjB,EAAA;EACF;;EAGAwM,iBAAqC;AACnC,WAAO;SAAI,KAAK3N,KAAKmC,OAAM;MAAIP,IAAI,CAAChB,UAAS;MAC3C0E,OAAO1E,KAAI0E;MACX5D,UAAUd,KAAIc;MACdb,UAAUD,KAAIC;MACd4B,QAAQ7B,KAAI6B;MACZwD,SAASrF,KAAIqF;MACbC,WAAWtF,KAAIsF;MACf,GAAItF,KAAIuF,cAAc7E,SAAY;QAAE6E,WAAWvF,KAAIuF;MAAU,IAAI,CAAC;MAClE,GAAIvF,KAAIwF,gBAAgB9E,SAAY;QAAE8E,aAAaxF,KAAIwF;MAAY,IAAI,CAAC;MACxE,GAAIxF,KAAI6F,eAAenF,SAAY;QAAEmF,YAAY7F,KAAI6F;MAAW,IAAI,CAAC;MACrE,GAAI7F,KAAI8F,cAAcpF,SAAY;QAAEoF,WAAW9F,KAAI8F;MAAU,IAAI,CAAC;MAClE,GAAI9F,KAAI+F,iBAAiBrF,SAAY;QAAEqF,cAAc/F,KAAI+F;MAAa,IAAI,CAAC;MAC3E,GAAI/F,KAAI4F,cAAclF,SAAY;QAAEkF,WAAW5F,KAAI4F;MAAU,IAAI,CAAC;MAClE,GAAI5F,KAAIyF,eAAe/E,SAAY;QAAE+E,YAAYzF,KAAIyF;MAAW,IAAI,CAAC;IACvE,EAAA;EACF;EAEQyE,mBAAmB1I,WAAuC;AAChE,eAAW,CAACV,UAAUd,IAAAA,KAAQ,KAAKlB,SAAS;AAC1C,UAAIkB,KAAIQ,SAASwM,KAAK,CAAC/L,YAAYA,QAAQvB,OAAO8B,SAAAA,GAAY;AAC5D,eAAOV;MACT;IACF;AACA,WAAOJ;EACT;;EAGAuM,eAcI;AACF,WAAO;SAAI,KAAK/N,UAAUqC,OAAM;MAAIP,IAAI,CAAChB,UAAS;MAChD2B,YAAY3B,KAAI2B;MAChBgB,UAAU3C,KAAI2C;MACdiI,UAAU5K,KAAI4K;MACd/I,QAAQ7B,KAAI6B;MACZpC,OAAOO,KAAIP;MACX,GAAIO,KAAIiL,WAAWvK,SAAY;QAAEuK,QAAQjL,KAAIiL;MAAO,IAAI,CAAC;MACzD,GAAIjL,KAAIoC,UAAU1B,SAAY;QAAE0B,OAAOpC,KAAIoC;MAAM,IAAI,CAAC;MACtD,GAAIpC,KAAI0E,UAAUhE,SAAY;QAAEgE,OAAO1E,KAAI0E;MAAM,IAAI,CAAC;MACtD,GAAI1E,KAAIkC,kBAAkBxB,SAAY;QAAEwB,eAAelC,KAAIkC;MAAc,IAAI,CAAC;MAC9E,GAAIlC,KAAI8B,aAAapB,SAAY;QAAEoB,UAAU9B,KAAI8B;MAAS,IAAI,CAAC;MAC/D,GAAI9B,KAAIgC,cAActB,SAAY;QAAEsB,WAAWhC,KAAIgC;MAAU,IAAI,CAAC;MAClE,GAAIhC,KAAIiC,aAAavB,SAAY;QAAEuB,UAAUjC,KAAIiC;MAAS,IAAI,CAAC;MAC/D,GAAIjC,KAAImC,eAAezB,SAAY;QAAEyB,YAAYnC,KAAImC;MAAW,IAAI,CAAC;IACvE,EAAA;EACF;EAEQvB,UAAUZ,MAA+B;AAC/C,UAAMkN,OAAOlN,KAAIQ,SAASR,KAAIQ,SAAS8B,SAAS,CAAA;AAChD,WAAO;MACL5C,IAAIM,KAAIN;MACRU,OAAOJ,KAAII;MACXC,WAAWL,KAAIK;MACfC,WAAWN,KAAIM;MACfC,WAAWP,KAAIO;MACf,GAAI2M,SAASxM,SAAY;QAAEyM,oBAAoBD,KAAKzG,QAAQ/C,MAAM,GAAG,GAAA;MAAK,IAAI,CAAC;MAC/EW,cAAcrE,KAAIqE,gBAAgB;MAClC,GAAIrE,KAAIsE,SAAS,OAAO;QAAEA,OAAOtE,KAAIsE;MAAM,IAAI,CAAC;MAChD7D,SAAST,KAAIS,WAAW;IAC1B;EACF;AACF;;;AC5kCA,SAAS2M,cAAAA,aAAYC,YAAYC,uBAAuB;AAIjD,IAAMC,yBAAyB,KAAK,KAAK;AAmBzC,SAASC,eAAcC,OAAc;AAC1C,MAAIA,UAAUC,OAAW,QAAO;AAChC,MAAID,UAAU,QAAQ,OAAOA,UAAU,SAAU,QAAOE,KAAKC,UAAUH,KAAAA,KAAU;AACjF,MAAII,MAAMC,QAAQL,KAAAA,EAAQ,QAAO,IAAIA,MAAMM,IAAIP,cAAAA,EAAeQ,KAAK,GAAA,CAAA;AACnE,MAAI,OAAQP,MAA+BQ,WAAW,YAAY;AAChE,WAAOT,eAAeC,MAAgCQ,OAAM,CAAA;EAC9D;AACA,QAAMC,UAAUC,OAAOD,QAAQT,KAAAA,EAC5BW,OAAO,CAAC,CAAA,EAAGC,KAAAA,MAAWA,UAAUX,MAAAA,EAChCY,KAAK,CAAC,CAACC,CAAAA,GAAI,CAACC,CAAAA,MAAQD,IAAIC,IAAI,KAAKD,IAAIC,IAAI,IAAI,CAAA;AAChD,SAAO,IAAIN,QAAQH,IAAI,CAAC,CAACU,KAAKJ,KAAAA,MAAW,GAAGV,KAAKC,UAAUa,GAAAA,CAAAA,IAAQjB,eAAca,KAAAA,CAAAA,EAAQ,EAAEL,KAAK,GAAA,CAAA;AAClG;AAXgBR,OAAAA,gBAAAA;AAchB,SAASkB,UAAUC,SAA8BC,WAAmBC,QAAc;AAChF,MAAIA,WAAW,IAAI;AACjB,UAAM,IAAIC,MAAM,oCAAA;EAClB;AACA,SAAOC,WAAW,UAAUF,MAAAA,EACzBG,OACCxB,eAAc;IACZ;IACAmB,QAAQM;IACRN,QAAQO;IACRP,QAAQQ,aAAa;IACrBP;IACAD,QAAQS;GACT,CAAA,EAEFC,OAAO,WAAA;AACZ;AAhBSX;AAuBF,SAASY,iBACdX,SACAY,SAA8C;AAE9C,SAAO,GAAGA,QAAQX,SAAS,IAAIF,UAAUC,SAASY,QAAQX,WAAWW,QAAQV,MAAM,CAAA;AACrF;AALgBS;AAQT,SAASE,mBAAmBC,OAAa;AAC9C,QAAMC,YAAYD,MAAME,QAAQ,GAAA;AAChC,MAAID,aAAa,EAAG,QAAOhC;AAC3B,QAAMkB,YAAYgB,OAAOH,MAAMI,MAAM,GAAGH,SAAAA,CAAAA;AACxC,SAAOE,OAAOE,cAAclB,SAAAA,KAAcA,YAAY,IAAIA,YAAYlB;AACxE;AALgB8B;AAQT,SAASO,mBACdN,OACAd,SACAY,SAAyC;AAEzC,MAAI,OAAOE,UAAU,SAAU,QAAO;AACtC,QAAMb,YAAYY,mBAAmBC,KAAAA;AACrC,MAAIb,cAAclB,UAAakB,aAAaW,QAAQS,OAAOC,KAAKD,IAAG,GAAK,QAAO;AAC/E,QAAME,WAAWC,OAAOC,KAAK1B,UAAUC,SAASC,WAAWW,QAAQV,MAAM,CAAA;AACzE,QAAMwB,QAAQF,OAAOC,KAAKX,MAAMI,MAAMJ,MAAME,QAAQ,GAAA,IAAO,CAAA,CAAA;AAC3D,SAAOO,SAASI,WAAWD,MAAMC,UAAUC,gBAAgBL,UAAUG,KAAAA;AACvE;AAXgBN;AAcT,SAASS,iBAAiBf,OAAa;AAC5C,SAAOgB,YAAW,QAAA,EAAUzB,OAAOS,KAAAA,EAAOJ,OAAO,KAAA;AACnD;AAFgBmB;AAUT,IAAME,4BAAN,MAAMA;EApGb,OAoGaA;;;EACMC,SAAS,oBAAIC,IAAAA;EAE9B,MAAMC,MAAMC,OAA4C;AACtD,UAAM,KAAKC,aAAY;AACvB,QAAI,KAAKJ,OAAOK,IAAIF,MAAMG,IAAI,EAAG,QAAO;AACxC,SAAKN,OAAOO,IAAIJ,MAAMG,MAAM;MAAE,GAAGH;IAAM,CAAA;AACvC,WAAO;EACT;EAEA,MAAMK,QAAQF,MAA6B;AACzC,SAAKN,OAAOS,OAAOH,IAAAA;EACrB;EAEA,MAAMF,aAAaf,MAAcC,KAAKD,IAAG,GAAqB;AAC5D,QAAIqB,SAAS;AACb,eAAW,CAACJ,MAAMJ,KAAAA,KAAU,KAAKF,QAAQ;AACvC,UAAIE,MAAMjC,YAAYoB,KAAK;AACzB,aAAKW,OAAOS,OAAOH,IAAAA;AACnBI,kBAAU;MACZ;IACF;AACA,WAAOA;EACT;;EAGA,IAAIC,OAAe;AACjB,WAAO,KAAKX,OAAOW;EACrB;AACF;;;AC3HO,IAAMC,uBAAN,MAAMA;EAJb,OAIaA;;;;EACF,WAAW,oBAAIC,IAAAA;EAExB,YAA6BC,aAAa,KAAQ;SAArBA,aAAAA;EAAsB;EAEnD,MAAMC,KAAW;AACf,UAAMC,QAAQ,KAAK,SAASC,IAAIF,GAAAA;AAChC,QAAIC,UAAUE,OAAW,QAAOA;AAChC,QAAIF,MAAMG,YAAYC,KAAKC,IAAG,EAAI,QAAOL;AACzC,SAAK,SAASM,OAAOP,GAAAA;AACrB,WAAOG;EACT;EAEA,KAAKH,KAAaQ,OAAsBC,OAAa;AACnD,UAAMH,MAAMD,KAAKC,IAAG;AACpB,SAAK,SAASC,OAAOP,GAAAA;AACrB,SAAK,SAASU,IAAIV,KAAK;MAAEQ;MAAOJ,WAAWE,MAAMG;IAAM,CAAA;AACvD,QAAI,KAAK,SAASE,QAAQ,KAAKZ,WAAY;AAE3C,eAAW,CAACa,QAAQX,KAAAA,KAAU,KAAK,UAAU;AAC3C,UAAI,KAAK,SAASU,QAAQ,KAAKZ,cAAcE,MAAMG,YAAYE,IAAK;AACpE,WAAK,SAASC,OAAOK,MAAAA;IACvB;EACF;EAEA,MAAMC,MAAMb,KAAaS,OAAiC;AACxD,QAAI,KAAK,MAAMT,GAAAA,MAASG,OAAW,QAAO;AAC1C,SAAK,KAAKH,KAAK,MAAMS,KAAAA;AACrB,WAAO;EACT;EAEA,MAAMP,IAAIF,KAAqC;AAC7C,WAAO,KAAK,MAAMA,GAAAA,GAAMQ,SAAS;EACnC;EAEA,MAAME,IAAIV,KAAaQ,OAAeC,OAA8B;AAClE,SAAK,KAAKT,KAAKQ,OAAOC,KAAAA;EACxB;EAEA,MAAMF,OAAOP,KAA4B;AACvC,SAAK,SAASO,OAAOP,GAAAA;EACvB;EAEA,MAAMc,aAAaR,MAAcD,KAAKC,IAAG,GAAqB;AAC5D,QAAIS,SAAS;AACb,eAAW,CAACf,KAAKC,KAAAA,KAAU,KAAK,UAAU;AACxC,UAAIA,MAAMG,aAAaE,KAAK;AAC1B,aAAK,SAASC,OAAOP,GAAAA;AACrBe,kBAAU;MACZ;IACF;AACA,WAAOA;EACT;AACF;;;AC7BA,IAAMC,mBAAoD;EACxDC,SACE;EACFC,SACE;EACFC,MAAM;AACR;AAGO,IAAMC,oBAAN,cAAgCC,MAAAA;EAtCvC,OAsCuCA;;;;EACrC,YAEWC,QACTC,SACA;AACA,UAAMA,OAAAA,GAAAA,KAHGD,SAAAA;AAIT,SAAKE,OAAO;EACd;AACF;AAkEO,IAAMC,iCAAiC;EAC5CR,SAAS;IACPS,MAAM;IACNC,aACE;EACJ;EACAC,cAAc;IACZF,MAAM;IACNC,aAAa;EACf;AACF;AAQO,IAAME,mBAAmBC,uBAAOC,IAAI,yCAAA;AAQpC,SAASC,kBAAkBC,QAAwB;AACxD,QAAMC,YAAaD,OAA4CJ,gBAAAA;AAC/D,SAAO,OAAOK,cAAc,YAAYA,cAAc,OACjDA,YACDC;AACN;AALgBH;AAOhB,SAASI,SAASC,OAAc;AAC9B,SAAO,OAAOA,UAAU,YAAYA,UAAU,QAAQ,CAACC,MAAMC,QAAQF,KAAAA;AACvE;AAFSD;AAKT,SAASI,aAAaC,OAAc;AAClC,MAAI,CAACL,SAASK,KAAAA,EAAQ,QAAO;IAAEC,MAAMD;IAAOE,QAAQ,CAAC;EAAE;AACvD,QAAM,EAAE1B,SAASW,cAAc,GAAGc,KAAAA,IAASD;AAC3C,SAAO;IACLC;IACAC,QAAQ;MACN,GAAI,OAAO1B,YAAY,YAAY;QAAEA;MAAQ,IAAI,CAAC;MAClD,GAAI,OAAOW,iBAAiB,WAAW;QAAEA;MAAa,IAAI,CAAC;IAC7D;EACF;AACF;AAVSY;AAeT,SAASI,kBAAkBX,QAAwB;AACjD,QAAMY,WAAWZ,OAAO,WAAA;AACxB,QAAMQ,QAAQI,SAASC,YAAYL;AACnC,SAAO,OAAOA,UAAU,aACpB,CAACM,YAAaN,MAA8BO,KAAKH,SAASC,YAAYC,OAAAA,IACtEZ;AACN;AANSS;AAmBF,SAASK,kBACdhB,QAAc;AAKd,QAAMiB,QAAQjB,OAAO,WAAA;AACrB,QAAMkB,kBAAkBP,kBAAkBX,MAAAA;AAC1C,QAAMmB,WAAW,wBAACL,YAAAA;AAChB,UAAMM,OAAOF,kBAAkBJ,OAAAA,KAAY;MAAEO,sBAAsB;IAAK;AACxE,WAAO;MACL,GAAGD;MACH3B,MAAM;MACN6B,YAAY;QACV,GAAInB,SAASiB,KAAKE,UAAU,IAAIF,KAAKE,aAAa,CAAC;QACnD,GAAG9B;MACL;IACF;EACF,GAViB;AAWjB,QAAM+B,UAAU;IACd,CAAC3B,gBAAAA,GAAmB;MAAEwB,MAAMpB;MAAQsB,YAAY9B;IAA+B;IAC/E,aAAa;MACXgC,SAAS;MACTC,QAAQ;MACRC,UAAU,8BAAOtB,UAAAA;AACf,YAAI,CAACD,SAASC,KAAAA,GAAQ;AACpB,iBAAO;YAAEuB,QAAQ;cAAC;gBAAErC,SAAS;cAAqB;;UAAG;QACvD;AACA,cAAMqC,SAAmC,CAAA;AAEzC,YAAIvB,MAAMpB,WAAW,QAAQ,OAAOoB,MAAMpB,YAAY,WAAW;AAC/D2C,iBAAOC,KAAK;YAAEtC,SAAS;YAAsBuC,MAAM;cAAC;;UAAW,CAAA;QACjE;AACA,YAAIzB,MAAMT,gBAAgB,QAAQ,OAAOS,MAAMT,iBAAiB,UAAU;AACxEgC,iBAAOC,KAAK;YAAEtC,SAAS;YAAqBuC,MAAM;cAAC;;UAAgB,CAAA;QACrE;AACA,cAAM,EAAEpB,MAAMC,OAAM,IAAKH,aAAaH,KAAAA;AACtC,cAAM0B,UAAS,MAAMb,MAAMS,SAASjB,IAAAA;AACpC,YAAIqB,QAAOH,WAAWzB,QAAW;AAC/B,iBAAO;YAAEyB,QAAQ;iBAAIA;iBAAWG,QAAOH;;UAAQ;QACjD;AACA,YAAIA,OAAOI,SAAS,GAAG;AACrB,iBAAO;YAAEJ;UAAO;QAClB;AACA,eAAO;UAAEvB,OAAOD,SAAS2B,QAAO1B,KAAK,IAAI;YAAE,GAAG0B,QAAO1B;YAAO,GAAGM;UAAO,IAAIoB,QAAO1B;QAAM;MACzF,GArBU;MAsBVS,YAAY;QAAEL,OAAOW;QAAUa,QAAQb;MAAS;IAClD;EACF;AACA,SAAOI;AAIT;AArDgBP;AA6FT,SAASiB,oBACdnB,SACAoB,OAAyC;AAEzC,QAAM,EAAEC,QAAQC,QAAQC,wBAAwBC,OAAOC,UAAU/B,OAAO,GAAGgC,WAAAA,IAAe1B;AAC1F,QAAM2B,OAAO;IAAE,GAAG1D;IAAkB,GAAGwD;EAAS;AAChD,QAAMG,eAAeD,KAAKzD,QAAQ2D,WAAW,aAAaC,OAAOC,KAAKC,MAAMV,QAAQ,GAAA,CAAA,CAAA;AACpF,QAAMW,YAAY,6BAAO,OAAOZ,WAAW,aAAaA,OAAAA,IAAWA,QAAjD;AAElB,QAAMa,UAAuB;IAC3B,MAAMC,QAAQ7C,OAAgB8C,KAAc;AAC1C,YAAM,EAAEzC,MAAMC,OAAM,IAAKH,aAAaH,KAAAA;AACtC,YAAM+C,UAAU;QACdC,MAAMtC,QAAQvB;QACd8D,SAASH,IAAII,MAAMC;QACnB,GAAIL,IAAII,MAAME,cAActD,SAAY;UAAEsD,WAAWN,IAAII,MAAME;QAAU,IAAI,CAAC;QAC9E/C;MACF;AACA,YAAMgD,aAAa/C,OAAO1B,YAAY;AACtC,YAAM0E,QAAQhD,OAAOf;AACrB,UAAI8D,cAAc,CAACE,mBAAmBD,OAAOP,SAAS;QAAEhB,QAAQY,UAAAA;MAAY,CAAA,GAAI;AAC9E,cAAM,IAAI5D,kBAAkB,WAAWsD,KAAKxD,OAAO;MACrD;AAEA,YAAM2E,WAAW,MAAM1B,MAAM2B,QAAQpD,MAAcyC,GAAAA;AAEnD,UAAI,CAACO,cAAcC,UAAUxD,QAAW;AACtC,cAAM4D,UAAU,MAAM5B,MAAM4B,QAAQF,UAAUV,GAAAA;AAC9C,cAAMa,YAAYC,KAAKC,IAAG,IAAK7B;AAC/B,eAAO;UACL8B,QAAQ;UACRC,SAASL,QAAQK;UACjB,GAAIL,QAAQM,SAASlE,SAAY;YAAEkE,MAAMN,QAAQM;UAAK,IAAI,CAAC;UAC3DzE,cAAc0E,iBAAiBlB,SAAS;YAAEhB,QAAQY,UAAAA;YAAagB;UAAU,CAAA;UACzEA,WAAW,IAAIC,KAAKD,SAAAA,EAAWO,YAAW;UAC1CtF,SAAS0D;QACX;MACF;AAIA,YAAM6B,OAAOC,iBAAiBd,KAAAA;AAC9B,UAAIpB,UAAUpC,QAAW;AACvB,cAAMuE,UAAU,MAAMnC,MAAMoC,MAAM;UAChCH;UACAI,UAAUzB,IAAII,MAAMC;UACpBH,MAAMtC,QAAQvB;UACdwE,WAAWa,mBAAmBlB,KAAAA,KAAUM,KAAKC,IAAG,IAAK7B;QACvD,CAAA;AACA,YAAI,CAACqC,SAAS;AACZ,gBAAM,IAAItF,kBAAkB,QAAQsD,KAAKvD,IAAI;QAC/C;MACF;AACA,UAAI;AACF,cAAM2F,OAAO,MAAM3C,MAAM4C,OAAOlB,UAAUV,GAAAA;AAC1C,eAAO;UACLgB,QAAQ;UACRC,SAASU,KAAKV;UACd,GAAIU,KAAKT,SAASlE,SAAY;YAAEkE,MAAMS,KAAKT;UAAK,IAAI,CAAC;QACvD;MACF,SAASW,OAAO;AAEd,cAAMzC,OAAO0C,QAAQT,IAAAA,EAAMU,MAAM,MAAM/E,MAAAA;AACvC,cAAM6E;MACR;IACF;EACF;AACA,SAAO;IACLG,MAAM;MAAE,GAAG1C;MAAY2C,MAAM;MAAQC,aAAapE,kBAAkBR,KAAAA;IAAO;IAC3EwC;EACF;AACF;AAvEgBf;;;ACpMhB,IAAMoD,sBAAsB;AAC5B,IAAMC,2BAA2B;AACjC,IAAMC,gCAAgC;AACtC,IAAMC,gBAAgB;AACtB,IAAMC,mBAAmB;AACzB,IAAMC,YAAY;AAClB,IAAMC,cAAc;AACpB,IAAMC,sBAAsB;AAC5B,IAAMC,kBAAkB;AAaxB,IAAMC,WAAU,IAAIC,YAAAA;AACpB,IAAMC,WAAU,IAAIC,YAAAA;AACpB,IAAMC,QAAQ,wBAACC,OAAe,IAAIC,QAAc,CAACC,YAAYC,WAAWD,SAASF,EAAAA,CAAAA,GAAnE;AAGd,SAASI,OAAOC,MAAY;AAC1B,MAAI,CAACA,KAAKC,WAAW,gBAAA,EAAmB,QAAO;AAC/C,MAAI;AACF,UAAMC,SAAkBC,KAAKC,MAAMJ,IAAAA;AACnC,QACE,OAAOE,WAAW,YAClBA,WAAW,QACXG,OAAOC,KAAKJ,MAAAA,EAAQK,WAAW,KAC9BL,OAA8BM,SAAS,UACxC,OAAQN,OAA8BO,SAAS,UAC/C;AACA,aAAQP,OAA4BO;IACtC;EACF,QAAQ;EAER;AACA,SAAO;AACT;AAjBSV;AAyCF,IAAMW,qBAAN,MAAMA;EAtJb,OAsJaA;;;;EACMC;EACAC;EACAC;EACAC;EACAC;EACAC,SAAS,oBAAIC,IAAAA;EACtBC,gBAAgB;EAExB,YACmBC,QACjBC,UAAqC,CAAC,GACtC;SAFiBD,QAAAA;AAGjB,SAAKR,iBAAiBU,KAAKC,IAAI,GAAGF,QAAQT,kBAAkB7B,wBAAAA;AAC5D,SAAK8B,qBAAqBS,KAAKC,IAC7B,KAAKX,gBACLS,QAAQR,sBAAsB7B,6BAAAA;AAEhC,SAAK8B,UAAUQ,KAAKC,IAAI,GAAGF,QAAQP,WAAW5B,gBAAAA;AAC9C,SAAK6B,aAAaM,QAAQN,cAAcjC;AACxC,SAAKkC,YAAYK,QAAQL,aAAa;EACxC;EAEQQ,UAAUC,OAA0B;AAC1C,QAAIC,QAAQ,KAAKT,OAAOU,IAAIF,KAAAA;AAC5B,QAAIC,UAAUE,QAAW;AACvBF,cAAQ;QACNhB,MAAM;QACNmB,OAAOD;QACPE,MAAMjC,QAAQC,QAAO;QACrBiC,SAAS;QACTC,SAASJ;MACX;AACA,WAAKX,OAAOgB,IAAIR,OAAOC,KAAAA;IACzB;AACA,WAAOA;EACT;;EAGQQ,QAAQT,OAAeC,OAAwB;AACrD,QACEA,MAAMK,YAAY,KAClBL,MAAMhB,SAAS,QACfgB,MAAMM,YAAYJ,UAClB,KAAKX,OAAOU,IAAIF,KAAAA,MAAWC,OAC3B;AACA,WAAKT,OAAOkB,OAAOV,KAAAA;IACrB;EACF;;EAGQW,QAAQX,OAAeC,OAAkBW,MAA0C;AACzFX,UAAMK,WAAW;AACjB,UAAMO,OAAOZ,MAAMI,KAAKS,KAAKF,IAAAA;AAC7BX,UAAMI,OAAOQ,KACVC,KACC,MAAMX,QACN,MAAMA,MAAAA,EAEPW,KAAK,MAAA;AACJb,YAAMK,WAAW;AACjB,WAAKG,QAAQT,OAAOC,KAAAA;IACtB,CAAA;AACF,WAAOY;EACT;;EAGQE,UAAUf,OAAeC,OAAiC;AAChE,QAAIA,MAAMG,UAAUD,QAAW;AAC7Ba,mBAAaf,MAAMG,KAAK;AACxBH,YAAMG,QAAQD;IAChB;AACA,QAAIF,MAAMhB,SAAS,KAAM,QAAOb,QAAQC,QAAO;AAC/C,UAAMG,OAAOV,SAAQmD,OAAOC,kBAAkB;MAAElC,MAAM;MAAQC,MAAMgB,MAAMhB;IAAK,CAAA,CAAA;AAC/EgB,UAAMhB,OAAO;AACb,WAAO,KAAK0B,QAAQX,OAAOC,OAAO,MAAM,KAAKkB,OAAOnB,OAAOxB,MAAM,IAAA,CAAA;EACnE;;EAGQ4C,aAAanB,OAAwB;AAC3C,UAAMM,UAAUN,MAAMM;AACtB,QAAIA,YAAYJ,QAAW;AACzBF,YAAMM,UAAUJ;AAChB,YAAMI,QAAQc;IAChB;EACF;;EAGA,MAAcF,OAAOnB,OAAesB,OAAsBD,OAAqC;AAC7F,aAASE,UAAU,KAAKA,WAAW,GAAG;AACpC,UAAI;AACF,cAAM,KAAK5B,MAAMwB,OAAOnB,OAAO;UAAEsB;UAAOD;UAAOG,WAAWC,KAAKC,IAAG;QAAG,CAAA;AACrE;MACF,SAASC,QAAQ;AACf,YAAIJ,WAAW1D,mBAAmB,CAAC,KAAK8B,MAAMiC,kBAAkBD,MAAAA,EAAS,OAAMA;MACjF;IACF;EACF;;EAGA,MAAcE,UAAU7B,OAAeqB,OAAqC;AAC1E,UAAMpB,QAAQ,KAAKF,UAAUC,KAAAA;AAC7B,UAAM8B,UAAU,KAAKf,UAAUf,OAAOC,KAAAA;AACtC,UAAM8B,QAAQ,KAAKpB,QAAQX,OAAOC,OAAO,MAAM,KAAKkB,OAAOnB,OAAO,MAAMqB,KAAAA,CAAAA;AACxE,UAAMjD,QAAQ4D,IAAI;MAACF;MAASC;KAAM;AAClC,SAAKX,aAAanB,KAAAA;AAClB,SAAKQ,QAAQT,OAAOC,KAAAA;AACpB,SAAKgC,kBAAiB;EACxB;;;;;;EAOAC,KAAKlC,OAA2B;AAC9B,WAAO;MACLmC,OAAO,8BAAOC,UAAAA;AACZ,cAAMnC,QAAQ,KAAKF,UAAUC,KAAAA;AAC7B,aAAKoB,aAAanB,KAAAA;AAClB,cAAMzB,OAAOV,SAAQmD,OAAOmB,KAAAA;AAC5B,cAAMnD,OAAO,KAAKI,UAAU,IAAId,OAAOC,KAAK6D,QAAO,CAAA,IAAM;AACzD,YAAIpD,SAAS,MAAM;AACjBgB,gBAAMhB,QAAQgB,MAAMhB,QAAQ,MAAMA;AAGlC,cAAIgB,MAAMG,UAAUD,QAAW;AAC7BF,kBAAMG,QAAQ9B,WAAW,MAAA;AACvB2B,oBAAMG,QAAQD;AACd,mBAAKY,UAAUf,OAAOC,KAAAA,EAAOqC,MAAM,CAACjB,UAAAA;AAClCpB,sBAAMM,UAAU;kBAAEc;gBAAM;cAC1B,CAAA;YACF,GAAG,KAAKhC,OAAO;UACjB;AACA;QACF;AACA,cAAMyC,UAAU,KAAKf,UAAUf,OAAOC,KAAAA;AACtC,cAAMsC,WAAW,KAAK5B,QAAQX,OAAOC,OAAO,MAAM,KAAKkB,OAAOnB,OAAOxB,MAAM,IAAA,CAAA;AAC3E,cAAMJ,QAAQ4D,IAAI;UAACF;UAASS;SAAS;MACvC,GAtBO;MAuBPC,OAAO,mCAAA;AACL,cAAMvC,QAAQ,KAAKF,UAAUC,KAAAA;AAC7B,cAAM8B,UAAU,KAAKf,UAAUf,OAAOC,KAAAA;AACtC,cAAM7B,QAAQ4D,IAAI;UAACF;UAAS7B,MAAMI;SAAK;AACvC,aAAKe,aAAanB,KAAAA;AAClB,aAAKQ,QAAQT,OAAOC,KAAAA;MACtB,GANO;MAOPwC,KAAK,6BAAM,KAAKZ,UAAU7B,OAAO,IAAA,GAA5B;MACL0C,MAAM,wBAACrB,UACL,KAAKQ,UAAU7B,OAAOrB,KAAKgE,UAAU;QAAEC,MAAMvB,MAAMuB;QAAMC,SAASxB,MAAMwB;MAAQ,CAAA,CAAA,GAD5E;IAER;EACF;EAEA,OAAOC,UAAU9C,OAA0C;AACzD,QAAI+C,SAAS;AACb,QAAIC,aAAavB,KAAKC,IAAG;AACzB,WAAO,MAAM;AACX,YAAMuB,OAAO,MAAM,KAAKtD,MAAMuD,KAAKlD,OAAO+C,QAAQrF,SAAAA;AAClD,iBAAWyF,QAAOF,MAAM;AACtBF,iBAASI,KAAIC;AACb,YAAID,KAAI7B,UAAU,MAAM;AACtB,cAAI6B,KAAI9B,UAAU,MAAM;AACtB,kBAAM,IAAIgC,iBAAiB1E,KAAKC,MAAMuE,KAAI9B,KAAK,CAAA;UACjD;AACA;QACF;AACA,cAAMrD,SAAQsF,OAAOH,KAAI7B,KAAK;MAChC;AACA,UAAI2B,KAAKlE,SAAS,GAAG;AACnBiE,qBAAavB,KAAKC,IAAG;AAErB,YAAIuB,KAAKlE,UAAUrB,UAAW;MAChC;AACA,YAAMQ,MACJuD,KAAKC,IAAG,IAAKsB,cAAcxF,gBAAgB,KAAK4B,qBAAqB,KAAKD,cAAc;IAE5F;EACF;;EAGAoE,IAAIvD,OAAiC;AACnC,WAAO,KAAKL,MAAM4D,IAAIvD,KAAAA;EACxB;EAEA,MAAMwD,MAAMxD,OAA8B;AACxC,UAAMC,QAAQ,KAAKT,OAAOU,IAAIF,KAAAA;AAC9B,QAAIC,UAAUE,QAAW;AACvB,UAAIF,MAAMG,UAAUD,OAAWa,cAAaf,MAAMG,KAAK;AACvDH,YAAMG,QAAQD;AACdF,YAAMhB,OAAO;AACbgB,YAAMM,UAAUJ;AAChB,YAAMF,MAAMI;AACZ,WAAKb,OAAOkB,OAAOV,KAAAA;IACrB;AACA,UAAM,KAAKL,MAAM8D,OAAO;MAACzD;KAAM;EACjC;;;;;;EAOA,MAAM0D,aAAahC,MAAcD,KAAKC,IAAG,GAAqB;AAC5D,QAAI,KAAKpC,cAAc,EAAG,QAAO;AACjC,UAAMqE,SAAS,MAAM,KAAKhE,MAAMiE,WAAWlC,MAAM,KAAKpC,aAAa,GAAA;AACnE,aAASuE,QAAQ,GAAGA,QAAQF,OAAO5E,QAAQ8E,SAASlG,aAAa;AAC/D,YAAM,KAAKgC,MAAM8D,OAAOE,OAAOG,MAAMD,OAAOA,QAAQlG,WAAAA,CAAAA;IACtD;AACA,WAAOgG,OAAO5E;EAChB;;EAGQkD,oBAA0B;AAChC,QAAI,CAAC,KAAK1C,aAAa,KAAKD,cAAc,EAAG;AAC7C,UAAMoC,MAAMD,KAAKC,IAAG;AACpB,QAAIA,MAAM,KAAKhC,gBAAgB9B,oBAAqB;AACpD,SAAK8B,gBAAgBgC;AACrB,SAAKgC,aAAahC,GAAAA,EAAKY,MAAM,MAAA;IAE7B,CAAA;EACF;AACF;;;AC3VO,SAASyB,kCACdC,MACAC,WACAC,YAAyC;AAEzC,QAAMC,UAAUC,+BAA+BJ,MAAME,UAAAA;AACrD,MAAIC,QAAQE,WAAW,YAAa,QAAOF;AAC3C,QAAM,EAAEG,UAAUC,SAAQ,IAAKJ;AAC/B,QAAMK,UAAUP,UAAUQ,OAAO,CAACC,aAAaA,SAASJ,aAAa,SAAA;AACrE,QAAMK,aAAaR,QAAQS;AAC3B,MAAID,eAAeE,QAAW;AAC5B,QAAI,CAACL,QAAQM,KAAK,CAACJ,aAAaA,SAASK,OAAOJ,UAAAA,EAAa,QAAO;MAAEN,QAAQ;IAAY;AAC1F,WAAO;MAAEA,QAAQ;MAAYO,YAAYD;MAAYL;MAAUC;IAAS;EAC1E;AACA,MAAIC,QAAQQ,WAAW,EAAG,QAAO;IAAEX,QAAQ;EAAY;AACvD,MAAIG,QAAQQ,SAAS,EAAG,QAAO;IAAEX,QAAQ;IAAaY,aAAaT,QAAQU,IAAI,CAAC,EAAEH,GAAE,MAAOA,EAAAA;EAAI;AAC/F,QAAMI,YAAYX,QAAQ,CAAA;AAC1B,MAAI,CAACW,UAAW,QAAO;IAAEd,QAAQ;EAAY;AAC7C,SAAO;IAAEA,QAAQ;IAAYO,YAAYO,UAAUJ;IAAIT;IAAUC;EAAS;AAC5E;AAnBgBR;AAoDT,IAAMqB,0CAAwE;EACnFC,SAAS;IAAC;IAAO;IAAW;IAAW;IAAY;;EACnDC,QAAQ;IAAC;IAAM;IAAU;IAAU;;EACnCf,UAAU;IAAC;;AACb;AAeO,IAAMgB,uCAAkE;EAC7EC,UAAU;EACVC,UAAU;EACVC,SAAS;EACTC,WAAW;EACXC,WAAW,wBAACC,QAAQ,oDAAoDA,IAAIC,KAAK,IAAA,CAAA,IAAtE;EACXC,SAAS;AACX;AASO,SAASC,wBACdC,SAGA3B,UACA4B,UAAqCX,sCAAoC;AAEzE,SAAOU,QAAO5B,WAAW,aAAa4B,QAAOvB,UAAUJ,aAAa,YAChE4B,QAAQR,UACRO,QAAO5B,WAAW,aAAa4B,QAAO5B,WAAW,cAC/CC,aAAa,aACX4B,QAAQV,WACRU,QAAQT,WACVS,QAAQP;AAChB;AAdgBK;AAgBhB,IAAMG,eAAe,wBAACC,SAAiBA,KAAKC,QAAQ,uBAAuB,MAAA,GAAtD;AACrB,IAAMC,eAAe,wBAACC,UACpBA,MACGrB,IAAI,CAACkB,SAASA,KAAKI,KAAI,CAAA,EACvB/B,OAAO,CAAC2B,SAASA,KAAKpB,SAAS,CAAA,EAC/BE,IAAI,CAACkB,SAASD,aAAaC,IAAAA,EAAMC,QAAQ,QAAQ,MAAA,CAAA,EACjDP,KAAK,GAAA,GALW;AAMrB,IAAMW,OAAO,wBAACL,SAAiBA,KAAKI,KAAI,EAAGE,YAAW,GAAzC;AAGN,SAAStC,+BACdJ,MACAE,aAA2CkB,yCAAuC;AAElF,MAAI,UAAUuB,KAAK3C,IAAAA,EAAO,QAAO;IAAEK,QAAQ;EAAY;AACvD,QAAMuC,QAAQN,aAAa;OAAIpC,WAAWmB;OAAYnB,WAAWoB;GAAO;AACxE,MAAIsB,MAAM5B,WAAW,EAAG,QAAO;IAAEX,QAAQ;EAAY;AACrD,QAAME,WAAW+B,aAAapC,WAAWK,QAAQ;AACjD,QAAMsC,QAAQ,IAAIC,OAChB,KAAKF,KAAAA,IAASrC,SAASS,SAAS,IAAI,QAAQT,QAAAA,QAAgB,IAAA,2BAC5D,IAAA,EACAwC,KAAK/C,KAAKwC,KAAI,CAAA;AAChB,MAAI,CAACK,MAAO,QAAO;IAAExC,QAAQ;EAAY;AACzC,QAAM2C,OAAOH,MAAM,CAAA,MAAOhC,SAAYA,SAAY4B,KAAKI,MAAM,CAAA,CAAE;AAC/D,MAAIG,SAASnC,OAAW,QAAO;IAAER,QAAQ;EAAY;AAErD,QAAMC,WAAWJ,WAAWoB,OAAOR,KAAK,CAACsB,SAASK,KAAKL,IAAAA,MAAUY,IAAAA,IAAQ,aAAa;AACtF,QAAMC,YAAYJ,MAAM,CAAA,MAAOhC,UAAagC,MAAM,CAAA,MAAO;AACzD,MAAII,aAAa3C,aAAa,WAAY,QAAO;IAAED,QAAQ;EAAY;AACvE,SAAO;IACLA,QAAQ;IACRC;IACAC,UAAU0C;IACV,GAAIJ,MAAM,CAAA,MAAOhC,SAAY;MAAED,YAAYiC,MAAM,CAAA;IAAG,IAAI,CAAC;EAC3D;AACF;AAzBgBzC;AA+BT,IAAM8C,yBAA6D;EACxEhD,YAAY;IACViD,UAAU;IACV9B,SAAS;MACP;MACA;MACA;MACA;MACA;MACA;SACGD,wCAAwCC;;IAE7CC,QAAQ;MACN;MACA;MACA;MACA;MACA;MACA;SACGF,wCAAwCE;;IAE7Cf,UAAU;MAAC;SAA4Ba,wCAAwCb;;EACjF;EACA2B,SAAS;IACPV,UAAU;IACVC,UAAU;IACVC,SAAS;IACTC,WACE;IACFC,WAAW,wBAACC,QAAQ,0DAA0DA,IAAIC,KAAK,IAAA,CAAA,IAA5E;IACXC,SAAS;EACX;AACF;;;AC3KO,SAASqB,qBAAqBC,UAAwB;AAC3D,QAAM,EACJC,WACAC,iBACAC,gBAAgBC,iBAChBC,kBAAkBC,mBAClBC,kBAAkBC,mBAClB,GAAGC,KAAAA,IACDT;AACJ,SAAO;IACL,GAAGS;IACHR,WAAWA,cAAc,OAAO,OAAOS,aAAaT,SAAAA;IACpD,GAAIC,oBAAoBS,SAAY;MAAET,iBAAiBQ,aAAaR,eAAAA;IAAiB,IAAI,CAAC;EAC5F;AACF;AAdgBH;AAiBT,SAASa,6BACdC,SAAoC;AAEpC,QAAM,EAAEb,UAAU,GAAGS,KAAAA,IAASI;AAC9B,SAAO;IACL,GAAGJ;IACH,GAAIT,aAAaW,SAAY;MAAEX,UAAUD,qBAAqBC,QAAAA;IAAU,IAAI,CAAC;EAC/E;AACF;AARgBY;AAUhB,SAASF,aAA2CI,OAAQ;AAC1D,QAAM,EAAEC,OAAOC,QAAQ,GAAGP,KAAAA,IAASK;AACnC,SAAOL;AACT;AAHSC;;;AChCF,IAAMO,yBAAN,MAAMA;EAxBb,OAwBaA;;;;EACX,YAA6BC,SAAwC;SAAxCA,UAAAA;EAAyC;EACtE,MAAMC,QAAQC,UAAkE;AAC9E,QAAIC,KAAKC,4BAA4BF,SAASG,kBAAkB;MAC9DC,OAAO;QAAEC,IAAIL,SAASM;MAAS;MAC/BC,UAAUP,SAASO;IACrB,CAAA;AACA,QAAI;AACF,YAAMH,QAAQ,MAAM,KAAKN,QAAQU,SAASC,QAAQ;QAChDH,UAAUN,SAASM;QACnBI,WAAWV,SAASU;MACtB,CAAA;AACA,UACE,CAACN,SACDA,MAAMC,OAAOL,SAASM,aACrBF,MAAMM,aAAa,UAAUV,SAASU,UAEvC,OAAM,IAAIC,MAAM,6DAAA;AAClB,YAAMC,OAAO,MAAM,KAAKd,QAAQe,iBAAiBb,UAAUI,KAAAA;AAC3D,UAAIQ,KAAKE,SAASC,KAAKf,SAASgB,QAAQ,GAAGC,SAAS,SAClD,OAAM,IAAIN,MAAM,oDAAA;AAClB,YAAMO,UAAUlB,SAASmB;AACzBlB,WAAKC,4BACHF,SAASG,kBACT;QACEC;QACAG,UAAUP,SAASO;QACnB,GAAIW,SAASE,cAAcC,SAAY;UAAED,WAAWF,QAAQE;QAAU,IAAI,CAAC;QAC3E,GAAIF,SAASI,mBAAmBD,SAC5B;UAAEC,gBAAgBJ,QAAQI;QAAe,IACzC,CAAC;MACP,GACAV,KAAKW,gBAAgB;AAEvB,YAAMC,SAAS,MAAMZ,KAAKE,SAASW,OACjCzB,SAASgB,UACTU,uBACEC,OAAOC,OAAO5B,UAAU,kBAAA,IAAsBA,SAAS6B,mBAAmB7B,SAAS8B,KAAK,GAE1F;QACE1B;QACAG,UAAUP,SAASO;QACnBwB,OAAO/B,SAASgC;QAChBC,WAAWf,SAASe,aAAajC,SAASgC;QAC1CE,YAAYlC,SAASG;QACrBgC,gBAAgBnC,SAASmC;QACzB,GAAIjB,SAASE,cAAcC,SAAY;UAAED,WAAWF,QAAQE;QAAU,IAAI,CAAC;QAC3E,GAAIF,SAASkB,YAAYf,SAAY;UAAEe,SAASlB,QAAQkB;QAAQ,IAAI,CAAC;QACrE,GAAIlB,SAASmB,gBAAgBhB,SAAY;UAAEgB,aAAanB,QAAQmB;QAAY,IAAI,CAAC;QACjF,GAAInB,SAASI,mBAAmBD,SAC5B;UAAEC,gBAAgBJ,QAAQI;QAAe,IACzC,CAAC;QACL,GAAIV,KAAK0B,SAASjB,SAAY;UAAEiB,MAAM1B,KAAK0B;QAAK,IAAI,CAAC;QACrDC,QAAQtC,GAAGuC;MACb,GACA5B,KAAK6B,aACL;QACEC,eAAe1C,SAAS8B;QACxB,GAAIlB,KAAK+B,iBAAiBtB,SAAY;UAAEsB,cAAc/B,KAAK+B;QAAa,IAAI,CAAC;MAC/E,CAAA;AAEF,aAAOjB,uBAAuB;QAC5BkB,QAAQ;QACR,GAAIpB,WAAWH,SAAY;UAAEwB,QAAQrB;QAAO,IAAI,CAAC;QACjDvB,IAAIA,GAAG6C,WAAU;QACjB,GAAI7C,GAAG8C,KAAI,IAAK;UAAEA,MAAM9C,GAAG8C,KAAI;QAAG,IAAI,CAAC;MACzC,CAAA;IACF,SAASC,OAAO;AACd,aAAO;QACLJ,QAAQ;QACRI,OAAOA,iBAAiBrC,QAAQqC,MAAMC,UAAUC,OAAOF,KAAAA;QACvD/C,IAAIA,GAAG6C,WAAU;QACjB,GAAI7C,GAAG8C,KAAI,IAAK;UAAEA,MAAM9C,GAAG8C,KAAI;QAAG,IAAI,CAAC;MACzC;IACF;EACF;AACF;;;ACtFO,IAAMI,uBAAN,MAAMA;EAAb,OAAaA;;;;EACMC;EACAC;EACAC;EACTC;EACAC,UAAU;EACDC,WAAW,oBAAIC,IAAAA;EACxBC;EACR,YAA6BC,SAAsC;SAAtCA,UAAAA;AAC3B,SAAKR,UAAUQ,QAAQR,WAAW;AAClC,SAAKC,iBAAiBO,QAAQP,kBAAkB;AAChD,SAAKC,iBAAiBM,QAAQN,kBAAkB;AAChD,eAAWO,SAAS;MAAC,KAAKT;MAAS,KAAKC;MAAgB,KAAKC;MAC3D,KAAI,CAACQ,OAAOC,cAAcF,KAAAA,KAAUA,SAAS,EAC3C,OAAM,IAAIG,WAAW,qDAAA;AACzB,QAAI,KAAKX,kBAAkB,KAAKD,UAAU,EACxC,OAAM,IAAIY,WAAW,uDAAA;AACvB,QAAI,CAACJ,QAAQK,SAAU,OAAM,IAAIC,UAAU,sBAAA;EAC7C;EACAC,QAAc;AACZ,QAAI,KAAKZ,UAAUa,UAAa,KAAKZ,QAAS;AAC9C,UAAMa,OAAO,mCAAA;AACX,UAAI,KAAKb,QAAS;AAClB,UAAI;AACF,cAAM,KAAKc,QAAO;MACpB,SAASC,OAAO;AACd,aAAKX,QAAQY,UAAUD,KAAAA;MACzB;AACA,UAAI,CAAC,KAAKf,QAAS,MAAKD,QAAQkB,WAAWJ,MAAM,KAAKhB,cAAc;IACtE,GARa;AASb,SAAKE,QAAQkB,WAAWJ,MAAM,CAAA;EAChC;EACA,MAAMK,OAAsB;AAC1B,SAAKlB,UAAU;AACf,eAAWD,SAAS,KAAKE,SAAUkB,eAAcpB,KAAAA;AACjD,SAAKE,SAASmB,MAAK;AACnB,QAAI,KAAKrB,UAAUa,OAAWS,cAAa,KAAKtB,KAAK;AACrD,UAAM,KAAKI;EACb;EACAW,UAAyB;AACvB,QAAI,KAAKX,OAAQ,QAAO,KAAKA;AAC7B,QAAI,KAAKH,QAAS,QAAOsB,QAAQC,QAAO;AACxC,UAAMC,OAAO,KAAKX,KAAI;AACtB,SAAKV,SAASqB;AACd,WAAOA,KAAKC,QAAQ,MAAA;AAClB,UAAI,KAAKtB,WAAWqB,KAAM,MAAKrB,SAASS;IAC1C,CAAA;EACF;EACA,MAAcC,OAAsB;AAClC,UAAM,KAAKT,QAAQsB,MAAMC,sBAAsB;MAAEC,OAAO;IAAI,CAAA;AAC5D,UAAMC,OAAwB,CAAA;AAC9B,aAASC,QAAQ,GAAGA,QAAQ,KAAKhC,kBAAkB,CAAC,KAAKE,SAAS8B,SAAS;AACzE,YAAMC,WAAW,MAAM,KAAK3B,QAAQsB,MAAMM,wBAAwB;QAChEvB,UAAU,KAAKL,QAAQK;QACvBb,SAAS,KAAKA;MAChB,CAAA;AACA,UAAI,CAACmC,SAAU;AACfF,WAAKI,KAAK,KAAKC,QAAQH,QAAAA,CAAAA;IACzB;AACA,UAAMT,QAAQa,IAAIN,IAAAA;AAClB,aAASC,QAAQ,GAAGA,QAAQ,MAAM,CAAC,KAAK9B,SAAS8B,SAAS;AACxD,YAAMM,WAAW,MAAM,KAAKhC,QAAQsB,MAAMW,+BAA+B;QACvE5B,UAAU,KAAKL,QAAQK;QACvBb,SAAS,KAAKA;MAChB,CAAA;AACA,UAAI,CAACwC,SAAU;AACf,YAAM,KAAKhC,QAAQsB,MAAMY,2BAA2BF,SAASG,KAAK;IACpE;EACF;EACA,MAAcL,QAAQH,UAAyC;AAC7D,UAAMQ,QAAQR,SAASS,WAAWD;AAClC,QAAI,CAACA,MAAO,OAAM,IAAIE,MAAM,sCAAA;AAC5B,QAAIC,SAAS;AACb,QAAIC;AACJ,UAAMC,QAAQ,6BAAA;AACZ,UAAID,YAAY,CAACD,OAAQ;AACzBC,iBAAW,KAAKvC,QAAQsB,MACrBmB,0BAA0Bd,UAAUA,SAASe,IAAI;QAChDC,OAAOR,MAAMQ;QACbC,YAAYT,MAAMS;QAClBpD,SAAS,KAAKA;MAChB,CAAA,EACCqD,KACC,CAACC,YAAAA;AACC,YAAIA,QAAOC,WAAW,UAAWT,UAAS;MAC5C,GACA,CAAC3B,UAAAA;AACC2B,iBAAS;AACT,aAAKtC,QAAQY,UAAUD,KAAAA;MACzB,CAAA,EAEDU,QAAQ,MAAA;AACPkB,mBAAW/B;MACb,CAAA;IACJ,GApBc;AAqBd,UAAMb,QAAQqD,YAAYR,OAAO,KAAKhD,UAAU,CAAA;AAChD,SAAKK,SAASoD,IAAItD,KAAAA;AAClB,QAAI;AACF,YAAMmD,UAAS,MAAM,KAAK9C,QAAQkD,SAASpB,QAAQH,QAAAA;AACnDZ,oBAAcpB,KAAAA;AACd,YAAM4C;AACN,UAAI,CAACD,OAAQ;AACb,YAAMa,UAAU,MAAM,KAAKnD,QAAQsB,MAAM8B,qBAAqBzB,UAAUA,SAASe,IAAI;QACnF,GAAGI;QACHH,OAAOR,MAAMQ;QACbC,YAAYT,MAAMS;MACpB,CAAA;AACA,UAAIO,QAAQJ,WAAW,aAAaI,QAAQxB,SAC1C,OAAM,KAAK3B,QAAQqD,YAAYF,QAAQxB,QAAQ;IACnD,UAAA;AACEZ,oBAAcpB,KAAAA;AACd,WAAKE,SAASyD,OAAO3D,KAAAA;AACrB,YAAM4C;IACR;EACF;AACF;;;ACnHO,SAASgB,oCACdC,OACAC,UAA6C;AAE7C,QAAMC,YAAYF;AAClB,MAAI,CAACC,YAAY,OAAOA,SAASE,YAAY,WAC3C,OAAM,IAAIC,MAAM,4DAAA;AAClB,MAAI,CAACC,iBAAiBL,KAAAA,KAAUE,UAAUI,qCAAqC,MAC7E,OAAM,IAAIF,MAAM,iEAAA;AAClB,QAAMG,WAAW;IACf;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;AAEF,MAAIA,SAASC,KAAK,CAACC,WAAW,OAAOP,UAAUO,MAAAA,MAAY,UAAA,EACzD,OAAM,IAAIL,MACR,iHAAA;AAEN;AA7BgBL;;;ACCT,SAASW,qBACdC,YAA0C;AAE1C,QAAM,EAAEC,OAAOC,SAASC,SAASC,WAAWC,WAAWC,QAAQC,UAAUC,MAAM,GAAGC,SAAAA,IAChFT;AACF,SAAO;IACLU,MAAM;MAAE,GAAGD;MAAUD,MAAMA,QAAQ;MAAQG,aAAaV;IAAM;IAC9DW,SAAS;MACPV,SAASA,QAAQW,KAAKb,UAAAA;MACtB,GAAIG,YAAYW,SAAY,CAAC,IAAI;QAAEX,SAASA,QAAQU,KAAKb,UAAAA;MAAY;MACrE,GAAII,cAAcU,SAAY,CAAC,IAAI;QAAEV,WAAWA,UAAUS,KAAKb,UAAAA;MAAY;MAC3E,GAAIK,cAAcS,SAAY,CAAC,IAAI;QAAET,WAAWA,UAAUQ,KAAKb,UAAAA;MAAY;MAC3E,GAAIM,WAAWQ,SAAY,CAAC,IAAI;QAAER,QAAQA,OAAOO,KAAKb,UAAAA;MAAY;MAClE,GAAIO,aAAaO,SAAY,CAAC,IAAI;QAAEP,UAAUA,SAASM,KAAKb,UAAAA;MAAY;IAC1E;EACF;AACF;AAhBgBD;","names":["AGENT_OPTIONS","Symbol","for","AGENT_STORE","AGENT_RUNNER","AGENT_DURABLE_RUNNER","AGENT_SINK","AGENT_MODEL","AGENT_ROLES_POLICY","AGENT_QUOTA_STORE","AGENT_TOOL_REGISTRY","AGENT_REGISTRY","AGENT_ACTOR_RESOLVER","AGENT_GOVERNANCE_QUERIES","AGENT_QUOTA_PROVIDER","AGENT_MODEL_CATALOG","AGENT_PRICING_STORE","AGENT_RETRIEVER","AGENT_EMBEDDING_PROVIDER","AGENT_DEPS_FACTORY","AGENT_PROMPT_CONTRIBUTORS","AGENT_ACTOR_DIRECTORY","AGENT_ATTACHMENT_STAGING","AGENT_APPROVAL_PORT","AGENT_SKILLS","AGENT_MEMORY","AGENT_SKILL_SOURCES","AGENT_CONFIRM_TOKEN_STORE","AGENT_CHANNEL_STORE","staticModelCatalog","view","list","findCatalogModel","id","group","providers","found","models","find","model","undefined","withSelectedModel","provider","runTurn","args","AgentStreamError","Error","code","error","message","name","encoder","TextEncoder","encodeStreamEvent","event","encode","JSON","stringify","decodeStreamEvent","line","parsed","parse","kind","observeTurnFrames","writer","now","Date","decoder","TextDecoder","pending","reasoning","reasoningMs","burstStartedAt","ui","Map","closeBurst","undefined","Math","max","observeLine","line","trim","length","event","decodeStreamEvent","kind","text","set","id","component","props","version","observe","chunk","decode","stream","newline","indexOf","slice","write","end","fail","error","summary","round","size","values","withTurnFrames","result","frames","TOOL_STEP_UI","wrapToolStepOutput","output","ui","text","reserved","length","wrapped","wrapToolPreflightDenied","reason","preflightDenied","unwrapToolStepOutput","raw","Array","isArray","createNoopEmitUi","scope","next","_component","_props","options","id","undefined","createUiCollector","toolCallId","write","pushed","Map","emit","component","props","Error","entry","JSON","parse","stringify","version","fallbackText","componentVersions","set","kind","components","values","restart","mergeUi","lists","merged","list","escapeUnsafeToolUiText","replaceAll","replace","unit","charCodeAt","toString","padStart","ALL_AGENTS","CHAT_QUEUE_METHODS","isChatQueueStore","store","candidate","every","method","releaseThreadRun","threadId","runId","releaseActiveStream","setActiveStream","queuedMessageView","message","id","content","attachments","undefined","length","agentName","persona","model","interrupt","createdAt","updatedAt","exhaustedWindow","windows","window","tokensOut","limitTokens","undefined","usedTokens","spendOut","limitUsd","usedUsd","period","reason","quotaUsedRatio","ratios","push","length","Math","max","quotaWarning","fullest","warnAt","ratio","quotaPeriodRange","now","year","getUTCFullYear","month","getUTCMonth","day","toISOString","slice","next","Date","UTC","getUTCDate","fromDay","toDay","resetsAt","first","last","seedModelPrices","store","prices","price","upsertModelPrice","DEFAULT_INCREMENTAL_LOOKBACK_CHARS","OutputRejectedError","Error","processor","reason","name","ProcessorFailedError","phase","cause","message","String","THREAD_DETAIL_CONTENT_CHARS","truncateDetailContent","content","length","truncated","slice","REQUESTER_APPROVER","DefaultApprovalPolicy","requirementFor","tool","required","kind","approver","defaultCanDecide","actor","decision","id","requesterRef","roles","includes","mayDecideApproval","policy","canDecide","undefined","toolCallApprovalFromRow","row","status","expiresAt","Date","toISOString","decided","toolCallId","proposalId","confirmation","remember","executedByRef","decidedBy","decidedVia","error","reason","estimateCost","usage","price","undefined","cacheWriteTokens","cacheReadTokens","uncachedInputTokens","inputTokens","inputPricePer1m","cacheWritePricePer1m","cacheReadPricePer1m","outputTokens","outputPricePer1m","rowCost","row","prices","costUsd","get","modelId","bucketByModel","rows","byModel","Map","bucket","requests","set","result","push","sort","left","right","localeCompare","bucketByActor","byActor","actorRef","totalTokens","threadIds","Set","add","threadId","threadCount","size","bucketByThread","threads","options","byThread","thread","includeUnknownThreads","title","slice","limit","rollupThreadUsage","rollup","bucketUsageTrend","byDay","day","dayBoundsUtc","range","start","Date","fromDay","end","toDay","isToolEnabled","spec","handler","declared","enabled","isEnabled","undefined","filterToolsByEnabled","entries","checked","Promise","all","map","entry","filter","row","canActorUseTool","actor","canUse","filterToolsByCanUse","allowed","filterToolsByRole","tools","policy","tool","can","filterToolsByAllowList","allowedTools","Set","has","name","intersectAllowLists","first","second","undefined","allowed","Set","filter","name","has","findPersona","definition","id","personas","find","persona","personaCatalogEntry","label","description","resolvePersonaAlias","definitions","aliases","includes","agent","estimateMessageTokens","message","extras","toolCalls","undefined","JSON","stringify","length","toolResults","Math","ceil","content","windowHistory","options","estimate","policy","maxMessages","select","messages","cut","max","maxTokens","tokenCut","min","keep","slice","drop","summarize","index","total","cost","DEFAULT_HISTORY_SUMMARY_INSTRUCTION","summarizeWithModel","model","instruction","dropped","discard","write","end","fail","turn","runTurn","system","tools","sink","text","usage","modelId","decoder","TextDecoder","createFrameBuffer","frames","writer","write","chunk","line","decode","split","length","push","end","fail","releaseGatedFrames","text","released","emitted","frame","event","decodeStreamEvent","kind","encodeStreamEvent","runInputProcessors","processors","prompt","ctx","current","processor","process","error","ProcessorFailedError","name","runOutputProcessors","answer","verdict","toolCalls","action","rejection","reason","gateFollowUps","followUps","kept","followUp","settled","undefined","resolveOutputGateMode","every","incremental","resolveGateLookback","lookback","Math","max","lookbackChars","DEFAULT_INCREMENTAL_LOOKBACK_CHARS","createIncrementalGate","options","raw","stalled","queue","Promise","resolve","advance","candidate","slice","startsWith","delta","handle","id","input","then","gateTail","map","join","Error","StructuredOutputError","Error","issues","text","attempts","detail","length","map","issue","message","join","name","extractJson","candidates","match","candidate","undefined","JSON","parse","validateStructured","schema","reported","ok","result","validate","value","DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION","repairInstruction","instruction","path","ELICITATION_INPUT_TYPES","questionOptions","question","options","isTypedQuestion","input","undefined","type","DATE_PATTERN","EMAIL_PATTERN","NUMBER_PATTERN","isDate","value","match","exec","year","month","day","date","Date","UTC","Number","getUTCFullYear","getUTCMonth","getUTCDate","isHttpUrl","url","URL","protocol","fullMatch","pattern","RegExp","test","asNumber","bound","isFinite","trim","validateElicitationValue","allowFreeText","some","option","number","min","max","length","validateElicitationAnswer","values","present","filter","required","multiple","problem","readElicitationInput","raw","candidate","includes","placeholder","readElicitationQuestions","questions","Array","isArray","item","id","prompt","flatMap","label","typed","defaults","push","normalizeElicitationReply","reply","answers","candidate","answeredByRef","executedByRef","answeredVia","decidedVia","approved","skipped","undefined","resolveElicitation","request","raw","defaulted","question","questions","submitted","id","defaults","push","valid","filter","value","validateElicitationValue","multiple","slice","answeredBy","settleElicitation","outcome","summary","renderElicitationAnswers","lines","map","chosen","labels","questionOptions","find","option","label","prompt","length","join","preface","ASK_TOOL_NAME","MAX_ASK_QUESTIONS","issue","path","message","parseOption","issues","hotkey","parseQuestion","input","readElicitationInput","ELICITATION_INPUT_TYPES","described","description","typed","type","Array","isArray","options","index","rawOption","entries","offered","Set","has","allowFreeText","ASK_JSON_SCHEMA","additionalProperties","properties","preamble","minItems","maxItems","items","required","enum","placeholder","min","max","pattern","maxLength","askInputSchema","version","vendor","validate","jsonSchema","ASK_TOOL_DESCRIPTION","askToolDefinition","name","kind","inputSchema","DEFAULT_INTAKE_PREAMBLE","GLOBAL_SCOPE","actorScope","actor","id","tenantScope","tenantRef","defaultScopeResolver","resolve","undefined","staticSkillProvider","skills","list","scopes","filter","skill","includes","scope","load","name","find","body","compositeSkillProvider","providers","ctx","seen","Set","merged","provider","summary","key","has","add","push","DEFAULT_MAX_SKILLS","resolveSkillCatalog","summaries","maxSkills","rank","Map","map","index","byName","existing","get","set","resolved","candidates","values","ordered","sort","a","b","winner","shadows","slice","candidate","description","length","byScope","compare","entries","omitted","Math","max","offerSkills","config","buildSkillsBlock","lines","entry","join","SKILL_TOOL_NAME","SKILL_JSON_SCHEMA","type","additionalProperties","required","properties","issue","path","message","skillInputSchema","version","vendor","validate","value","issues","jsonSchema","input","SKILL_TOOL_DESCRIPTION","skillToolDefinition","kind","inputSchema","withSkillTool","tools","enabled","loadSkill","offer","available","ok","error","skillWriteVerdict","request","author","allowed","reason","own","elevated","DEFAULT_MAX_MEMORIES","DEFAULT_MAX_FACT_CHARS","resolveMemoryDigest","records","scopes","maxMemories","ranked","rank","Map","map","scope","index","byKey","entry","has","existing","get","key","undefined","set","push","resolved","candidates","values","ordered","sort","a","b","winner","overrides","slice","beaten","text","author","origin","pinned","some","candidate","length","byPrecedence","compare","updatedAt","selected","pinRank","pinnedOmitted","filter","entries","omitted","Math","max","offerMemories","config","ctx","query","defaultScopeResolver","resolve","trimmed","trim","search","provider","bind","limit","list","recalled","ASSERTED_FRAMING","CONCLUDED_FRAMING","PARTIAL_FRAMING","memorySection","framing","flatMap","buildMemoryBlock","writable","partial","writeLine","REMEMBER_TOOL_NAME","body","join","REMEMBER_JSON_SCHEMA","type","additionalProperties","required","properties","description","fact","issue","path","message","rememberInputSchema","version","vendor","validate","value","issues","jsonSchema","input","REMEMBER_TOOL_DESCRIPTION","rememberToolDefinition","name","kind","inputSchema","withMemoryTool","tools","enabled","memoryWriteVerdict","request","actor","includes","allowed","reason","own","actorScope","elevated","memoryForgetVerdict","record","writeMemory","digest","call","runId","write","ok","error","maxFactChars","verdict","actorRef","id","threadId","AgentRegistry","definitions","Map","register","definition","set","name","get","has","list","values","isReplayIntegrityError","error","Error","name","toLowerCase","endsWith","CONTROL_FLOW_SIGNAL","Symbol","for","isControlFlowSignal","error","UNFINISHED_TOOL_CALL","RUN_ENDED_BEFORE_TOOL_CALL","DECLINED","EXPIRED","danglingToolCallIds","messages","ids","message","calls","toolCalls","role","length","settled","Set","toolResults","map","result","id","call","has","push","resultFor","outcome","base","name","status","output","error","rejected","denied","expired","settleDanglingToolCalls","outcomes","known","Map","results","missing","filter","get","RUN_NOT_ACTIVE_CODE","RUN_NOT_ACTIVE_MESSAGE","RUN_NO_LONGER_RUNNING","settleDeadRun","store","input","failure","undefined","Promise","resolve","recordRunEnd","runId","status","errorCode","code","errorMessage","message","catch","failUnsettledToolCalls","RUN_ENDED_BEFORE_TOOL_CALL","threadId","releaseThreadRun","normalizeDelegation","entry","agent","detached","detachedStarted","args","status","runId","note","detachedDelivered","text","detachedUnsettled","error","undefined","settleUnsettledDelegation","store","delivery","thread","getThread","threadId","messages","some","message","appendMessage","role","content","agentName","updateToolCall","toolCallId","output","validateActionProposalWorkerClaim","command","now","Number","isSafeInteger","RangeError","workerId","length","TypeError","leaseMs","validateActionProposalExpiryBatch","validateActionProposalDiscoveryIndexBatch","isInteger","limit","attachActionProposalOutcome","row","now","ui","text","outcome","execution","id","proposalId","outcomeVersion","tenantRef","actorRef","threadId","originRunId","originToolCallId","toolName","decision","createdAt","undefined","status","executionStatus","Object","hasOwn","result","error","decisionAudit","reason","snapshotActionProposal","outcomeDelivery","generation","lease","claimActionProposalOutcome","command","token","validateActionProposalWorkerClaim","delivery","expiresAt","workerId","leaseMs","actionProposalOutcomeFenceValid","Number","isSafeInteger","RangeError","outcomeId","TypeError","outcomeSummary","JSON","stringify","actionProposalOutcomeScope","actionProposalOutcomeText","isStandardSchema","schema","validate","toJsonSchema","standard","converter","jsonSchema","undefined","input","target","validateProps","value","validator","result","issues","ok","toGenuiIssues","length","validatePropsSync","Promise","catch","map","issue","path","segment","key","message","formatIssues","formatPath","join","index","builtinJsonSchemaValidator","validate","schema","value","issues","check","MAX_DEPTH","typeOf","Array","isArray","matchesType","type","Number","isInteger","isFinite","resolveRef","root","ref","startsWith","undefined","current","raw","slice","split","key","replace","deepEqual","a","b","keysA","Object","keys","keysB","length","every","path","depth","push","message","s","$ref","target","types","some","join","enum","option","map","JSON","stringify","const","minLength","maxLength","pattern","RegExp","test","minimum","maximum","minItems","maxItems","items","forEach","item","index","record","properties","required","entry","entries","additionalProperties","allOf","sub","anyOf","oneOf","options","passing","filter","nested","not","COMPONENT_NAME","defineComponent","definition","test","name","Error","version","undefined","Number","isSafeInteger","RangeError","fallbackText","TypeError","defineCatalog","components","options","byName","Map","component","defineComponent","has","name","Error","set","buildCatalog","jsonSchemaValidator","builtinJsonSchemaValidator","validator","list","Object","freeze","values","get","modelComponents","filter","internal","validate","props","definition","undefined","ok","issues","path","message","result","validateProps","outputProps","validateSync","validatePropsSync","jsonSchemaFor","toJsonSchema","extend","more","next","GENUI_TREE_COMPONENT","validateTree","catalog","tree","limits","phase","maxDepth","maxNodes","issues","nodes","visit","node","path","depth","push","message","undefined","Array","isArray","element","type","definition","get","internal","modelComponents","map","component","name","join","validated","validateProps","props","validator","validate","ok","issue","value","rawChildren","parseChildrenIfStringified","children","length","index","child","entries","next","root","parseChildrenIfStringified","value","trimmed","trim","startsWith","leadingJsonArray","text","depth","inString","escaped","index","length","char","parsed","JSON","parse","slice","Array","isArray","undefined","componentToText","catalog","component","props","GENUI_TREE_COMPONENT","root","undefined","treeToText","ownText","definition","get","fallback","fallbackText","failed","text","trim","length","children","jsonBlock","out","visit","node","depth","type","push","child","filter","line","join","title","JSON","stringify","validateUiCapabilities","value","record","Object","keys","some","key","Array","isArray","components","TypeError","seen","Set","map","component","name","COMPONENT_NAME","test","Number","isSafeInteger","version","has","add","negotiateCatalog","catalog","capabilities","undefined","supported","defineCatalog","filter","entry","jsonSchemaValidator","validator","prepareUiEmission","props","drawable","GENUI_TREE_COMPONENT","Error","validated","validateTree","root","ok","formatIssues","issues","node","type","children","every","versions","Map","collectVersions","set","get","child","kind","fallbackText","treeToText","componentVersions","fromEntries","text","definition","currentVersion","validate","componentToText","checkTime","value","Number","isSafeInteger","RangeError","checkString","length","TypeError","validateActionProposalCreation","input","allowed","Object","keys","some","key","includes","tenantRef","id","actorRef","threadId","replacementKey","undefined","hasOwn","context","executionContext","Array","isArray","allowedContext","requestId","validateUiCapabilities","uiCapabilities","agentName","persona","page","pageContext","kind","expiresAt","confirmation","title","verb","canonicalActionProposalJson","validateActionProposalListQuery","query","limit","isInteger","decision","after","createdAt","ancestors","Set","sort","item","isFinite","has","prototype","getPrototypeOf","add","sorted","from","fromEntries","map","delete","JSON","stringify","snapshotActionProposal","parse","actionProposalScopeMatches","row","scope","initialActionProposal","now","decisionAudit","execution","updatedAt","actionProposalCreationMatches","_decision","_audit","_execution","_created","_updated","supersededBy","_supersededBy","outcome","_outcome","outcomeDelivery","_delivery","original","result","status","proposal","transitionActionProposalDecision","command","via","reason","remember","next","at","attachActionProposalOutcome","audit","generation","lease","checkLeaseMs","leaseMs","transitionActionProposalClaim","token","workerId","leaseStatus","work","transitionActionProposalLease","Math","max","transitionActionProposalSettlement","error","ui","text","transitionActionProposalSupersession","replacement","replacementProposalId","toolName","str","description","extra","type","undefined","obj","properties","required","additionalProperties","arr","items","cell","row","s","value","String","heading","props","title","textTable","columns","rows","max","shown","slice","widths","map","column","Math","min","label","length","r","key","format","values","index","padEnd","join","lines","width","repeat","push","lineDiff","before","after","a","split","b","text","op","dp","Array","from","fill","at","i","j","out","bar","n","round","abs","DataTable","defineComponent","name","align","enum","minItems","maxItems","fallbackText","Chart","xKey","series","data","unit","chartText","filter","each","labelOf","flatMap","point","Number","KpiCards","delta","trend","hint","item","SourceCards","url","snippet","source","Checklist","done","note","Timeline","events","date","event","CodeBlock","language","code","Diff","line","Callout","tone","Stack","direction","gap","children","Card","subtitle","Heading","Text","muted","Badge","Link","pattern","Image","alt","snapshotComponentPresentation","value","seen","Set","check","entry","Number","isFinite","TypeError","has","Array","isArray","Object","getPrototypeOf","prototype","add","item","values","delete","JSON","parse","stringify","createComponent","definition","options","defineComponent","catalog","defineCatalog","factory","props","result","validateProps","validator","ok","Error","name","formatIssues","issues","normalized","portable","validate","canonicalJson","component","version","fallbackText","componentToText","assign","table","createComponent","DataTable","chart","Chart","validatePresentationBatch","presentations","batch","Array","isArray","map","item","presentation","snapshotComponentPresentation","component","test","Number","isSafeInteger","version","fallbackText","props","TypeError","canonicalJson","value","join","record","Object","keys","sort","key","JSON","stringify","emitToolPresentations","handler","output","ctx","toolName","present","undefined","result","batch","validatePresentationBatch","presentation","emitUi","component","props","version","fallbackText","error","onPresentationError","reportError","console","warn","ToolForbiddenError","Error","toolName","name","ToolDisabledError","ToolNotFoundError","ToolInputInvalidError","issues","map","issue","message","join","ToolPreflightDeniedError","reason","ToolInputDriftError","assertTrustedInput","value","approved","canonicalActionProposalJson","ToolRegistry","entries","Map","register","spec","handler","set","hasPresentation","get","present","presentOutput","output","ctx","entry","undefined","emitToolPresentations","has","unregister","delete","allSpecs","values","definitionsFor","actor","policy","allowedTools","scope","visible","visibleEntries","definitions","Promise","all","override","describe","available","kind","description","inputSchema","filter","definition","visibleSpecs","pinnedNames","Set","filterToolsByAllowList","pinned","live","filterToolsByEnabled","allowedByRole","filterToolsByRole","roleScoped","filterToolsByCanUse","invoke","input","options","withEmit","validated","trusted","Object","hasOwn","approvedInput","executionInput","snapshotActionProposal","hookInput","result","preflight","phase","status","execute","prepare","prepareValidated","normalized","snapshotInput","isToolEnabled","can","canActorUseTool","includes","validation","validate","emitUi","createNoopEmitUi","requestId","DefaultRolesPolicy","emptyRoles","defaultRoles","tool","ability","roles","allowed","length","some","role","ClosedRolesPolicy","closeEmptyRoles","inner","defaults","createHash","trace","resolveActionProposalApproval","input","policy","DefaultApprovalPolicy","requirement","requirementFor","tool","actor","thread","required","mode","remembered","store","rememberedApprovals","threadId","includes","name","approver","roundedTtl","ttlMs","undefined","Number","isFinite","Math","floor","now","clock","Date","isSafeInteger","RangeError","expiresAt","toISOString","prepareActionProposal","registry","name","input","ctx","policy","options","preparationInput","snapshotActionProposal","prepared","prepareValidated","snapshotInput","replacementKey","replacement","spec","preflight","status","undefined","length","TypeError","actionProposalReceipt","proposalId","status","executed","emit","publishAgentRunStarted","payload","emit","publishAgentMessage","publishAgentToolCall","publishAgentQuotaExceeded","publishAgentRunFinished","publishAgentRunFailed","publishAgentDelegated","publishAgentRetrieved","publishAgentToolRetry","publishAgentSkillsResolved","publishAgentMemoryResolved","publishAgentMemoryWritten","AGENT_SPAN_EVENTS","AGENT_DIAGNOSTIC_EVENTS","agentDiagnosticKey","event","createNegotiatedUiCollector","toolCallId","scope","resolveCatalog","write","collector","createUiCollector","texts","Map","next","components","text","values","join","restart","clear","emit","component","props","options","declared","uiCapabilities","undefined","some","entry","name","version","id","fallbackText","length","set","kind","capturedProps","snapshotActionProposal","capturedOptions","catalog","prepared","prepareUiEmission","componentVersions","hasTransientShape","error","code","undefined","errno","sqlState","message","test","isTransientToolError","ToolPreflightDeniedError","cause","DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS","DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS","resolveToolTransientRetryNumbers","setting","attempts","backoffMs","delay","ms","Promise","resolve","setTimeout","invokeWithTransientRetry","fn","options","classify","attempt","isControlFlowSignal","isControlFlowError","attemptsRemain","onRetry","resolveCostUsd","usage","reportedCostUsd","price","undefined","estimateCost","buildContextBlock","passages","items","map","passage","index","label","source","text","join","buildSummaryBlock","summary","settleAll","tasks","started","task","Promise","all","work","then","value","ok","error","QuotaExceededError","Error","name","RunCancelledError","agentFailureCode","OutputRejectedError","StructuredOutputError","isReplayIntegrityError","isNoOutputError","message","startsWith","RUN_FAILED_MESSAGE","streamErrorDetails","exposeStreamErrorDetails","expose","WORDED_CODES","Set","streamFailure","detail","String","code","has","exposed","process","env","NODE_ENV","MAX_DELEGATION_DEPTH","DEFAULT_MAX_AGENT_APPEARANCES","delegationRefusal","args","deps","input","targetAgent","ancestry","delegationPath","agentName","appearances","filter","length","maxAppearances","maxAgentAppearances","chain","times","maxDepth","maxDelegationDepth","delegationDepth","resolvePrompt","prompt","ctx","resolveSystemPrompt","persona","promptContext","sections","systemPrompt","contribute","promptContributors","section","push","withoutPersona","_dropped","rest","actor","pageContext","uiCapabilities","id","resolveTurnPersona","findPersona","ref","basePrompt","allowedTools","personaRefusal","toolName","includes","extractTask","JSON","stringify","deriveTitle","userText","trimmed","trim","replace","slice","ToolTimeoutError","ms","withToolTimeout","resolve","reject","timer","setTimeout","clearTimeout","parseFollowUps","count","match","parsed","parse","Array","isArray","item","generateFollowUps","model","messages","discard","write","end","fail","turn","runTurn","system","tools","sink","followUps","modelId","spanned","event","runId","payload","run","summarize","trace","traceId","traceLlmTurn","step","inputTokens","outputTokens","textLength","toolCalls","traceToolExecution","call","toModelMessages","role","content","toolResults","attachments","historyContext","threadId","splitHistory","policy","keep","drop","select","loadSelectedHistory","hooks","recorded","thread","readThreadForTurn","historyPolicy","settleHistory","dropped","title","hasAssistantMessage","actionApprovalMode","settleDanglingToolCalls","dangling","danglingToolCallIds","outcomes","store","toolCallOutcomes","catch","windowing","loadThreadForTurn","messageLimit","turnMessageLimit","page","getThread","stored","some","maxMessages","loadWholeThread","foldDroppedHistory","history","recordUsage","actorRef","purpose","processorContext","restatementPrompt","answer","fromTranscript","restated","structureAnswer","schema","instruction","outputInstruction","DEFAULT_STRUCTURED_OUTPUT_INSTRUCTION","maxAttempts","outputRepairAttempts","outputProcessors","issues","attempt","repairInstruction","reply","outputSchema","object","result","gate","runOutputProcessors","rejection","processor","reason","reported","outcome","validateStructured","stampToolKinds","preflight","_untrusted","prepared","_untrustedPrepared","actionApproval","_untrustedApproval","trusted","kind","declaredKind","ask","ASK_TOOL_NAME","skills","SKILL_TOOL_NAME","memoryIsWritable","REMEMBER_TOOL_NAME","registry","spec","memory","provider","withAskTool","askToolDefinition","awaitElicitation","request","awaitAnswers","normalizeElicitationReply","awaitApproval","toolCallContext","toolCallId","idempotencyKey","toolContext","requestId","host","emitUi","createNoopEmitUi","intakeApplies","intake","threadHasAssistant","when","runIntake","writer","preamble","DEFAULT_INTAKE_PREAMBLE","questions","asked","appendMessage","recordToolCall","messageId","toolType","status","encodeStreamEvent","settleElicitation","updateToolCall","skipped","output","answeredByRef","executedByRef","setMessageToolResults","PARALLEL_TOOLS_PATCH","CANCELLATION_PATCH","SELECTED_HISTORY_PATCH","PROMPT_STAGES_PATCH","resolvePromptStages","configured","retriever","patched","UNSERVED_MEMORY","scopes","entries","omitted","pinnedOmitted","UNSERVED_SKILLS","haltIfCancelled","cancellable","observe","cancelled","claimToolCall","persisted","awaitsHuman","independentApproval","dispatchLlm","resolveActionProposalApproval","tool","approvalPolicy","toolAllowList","intersectAllowLists","mode","prepareActionProposal","rolesPolicy","prepare","isControlFlowError","isControlFlowSignal","confirmation","approval","claimApproval","proposalId","proposalStore","createActionProposal","createHash","update","digest","display","presentation","confirm","verb","fill","_match","path","current","part","split","create","replacementKey","bind","createReplacingActionProposal","created","tenantRef","originRunId","originMessageId","originToolCallId","preparationInput","executionContext","approver","expiresAt","Date","proposal","parks","target","detached","terminal","hasPresentation","presentCompletedPreflight","resolvedCall","DefaultApprovalPolicy","requirement","requirementFor","required","remembered","rememberedApprovals","ttlMs","Number","isFinite","Math","floor","now","toISOString","loadSkillIntoTurn","claimed","startedAt","config","offer","skillInputSchema","validate","each","loaded","loadSkill","skillContext","skill","scope","body","shadows","executionMs","rememberIntoTurn","rememberInputSchema","writeMemory","publishAgentMemoryWritten","record","chars","invokeClaimedTool","invokeAllowList","raw","dispatchTool","stepCtx","envelope","toolTimeoutMs","timeoutMs","transientRetry","resolveToolTransientRetryNumbers","toolTransientRetry","collectUi","invocation","ui","createNegotiatedUiCollector","resolveUiCatalog","invokeWithTransientRetry","restart","invoke","emit","onRetry","retryError","publishAgentToolRetry","wrapToolPreflightDenied","wrapToolStepOutput","components","preflightDenied","unwrapToolStepOutput","toolText","set","toolUi","halt","recordToolOutcome","deciderRef","meta","decided","decidedBy","decidedVia","remember","settle","streamed","rejected","denied","publishAgentToolCall","durationMs","delegateToolCall","refusal","start","startAgent","publishAgentDelegated","toAgent","fromAgent","sub","detachedStarted","agent","runAgent","elicitToolCall","askInputSchema","runClaimedToolCall","independentProposal","actionProposalReceipt","presentOutput","presented","decision","streamsSettlement","expired","expireToolCall","approved","DEFAULT_REFUSAL_REASON","refusalNarrative","APPROVAL_EXPIRED_REASON","expiryNarrative","outputFrame","refusalReason","base","invokeClaimedToolsTogether","parallel","settled","entry","results","runAgentLoop","boundDeps","requested","withSelectedModel","maxSteps","inputProcessors","gateMode","resolveOutputGateMode","gated","gateLookback","resolveGateLookback","structured","quota","state","check","day","withinLimit","publishAgentQuotaExceeded","actorId","usedTokens","limitTokens","regenerate","existing","lastUserIndex","firstDropped","truncateFrom","modelMessages","openSink","lastText","steps","totalInput","totalOutput","publishAgentRunStarted","stages","promptHash","recordRunStart","parentRunId","memoryDigest","offerMemories","query","block","buildMemoryBlock","writable","partial","recalled","publishAgentMemoryResolved","offered","promptChars","injectedPassages","topK","retrievalTopK","queryLength","retrieve","retrieved","publishAgentRetrieved","skillOffer","offerSkills","buildSkillsBlock","publishAgentSkillsResolved","prices","pricingStore","listCurrentPrices","priceByModel","Map","i","runInputProcessors","preflightContext","bufferOutput","personaAllowedTools","withMemoryTool","withSkillTool","definitionsFor","enabled","incremental","createIncrementalGate","processors","lookbackChars","buffer","createFrameBuffer","frames","observeTurnFrames","withTurnFrames","releasedText","released","gateRejection","bufferedFrames","chunk","releaseGatedFrames","tail","gateTail","resolvedModelId","stepModel","costUsd","get","toolCallsWithKind","bump","publishAgentMessage","isFinalTurn","outputFromTranscript","followUpsCount","generated","suggestions","gateFollowUps","synthetic","messageCalls","syntheticResults","assistant","reasoning","reasoningMs","assistantMessage","toolKind","turnCalls","every","settledResults","escapeUnsafeToolUiText","flatMap","setMessageUi","mergeUi","setTitle","delivery","deliverTo","detachedDelivered","recordRunEnd","publishAgentRunFinished","randomUUID","InMemoryActionProposalStore","rows","Map","clock","options","Date","now","createActionProposal","input","validateActionProposalCreation","row","get","id","actionProposalScopeMatches","status","actionProposalCreationMatches","proposal","snapshotActionProposal","initialActionProposal","set","getActionProposal","scope","listActionProposals","query","limit","validateActionProposalListQuery","values","filter","decision","undefined","after","createdAt","sort","a","b","slice","map","mutate","transition","result","decideActionProposal","command","transitionActionProposalDecision","claimActionProposal","transitionActionProposalClaim","randomUUID","extendActionProposalLease","transitionActionProposalLease","settleActionProposal","transitionActionProposalSettlement","claimNextActionProposal","validateActionProposalWorkerClaim","candidates","execution","lease","expiresAt","candidate","claimed","expireActionProposals","validateActionProposalExpiryBatch","expired","actorRef","via","claimNextActionProposalOutcome","outcomeDelivery","next","claimActionProposalOutcome","outcome","outcomeId","token","generation","createReplacingActionProposal","existing","replacements","replacementKey","toolName","transitionActionProposalSupersession","replacementProposalId","push","supersedeActionProposal","replacement","InMemoryAgentStore","InMemoryActionProposalStore","threads","Map","queues","pauses","toolCalls","usage","runs","now","Date","toISOString","createThread","input","id","crypto","randomUUID","has","Error","ts","row","actorRef","actor","tenantRef","title","transient","createdAt","updatedAt","messages","persona","undefined","set","toSummary","getThread","threadId","get","map","message","withApprovals","activeStreamId","activeRunId","approvals","call","values","messageId","approval","toolCallApprovalFromRow","toolCallId","proposalId","status","approver","confirmation","expiresAt","remember","executedByRef","decidedVia","error","push","length","rememberedApprovals","names","Set","add","toolName","thread","proposal","rows","decisionAudit","execution","toolCallInput","toolCallApproval","listThreads","limit","filter","sort","a","b","localeCompare","slice","softDeleteThread","delete","forkThread","fromMessageId","source","cutoff","findIndex","kept","feedback","_feedback","defaultAgent","model","ownerOfThread","ownerOfToolCall","runForToolCall","runId","ownerOfActiveStream","setTitle","updateThread","patch","activeRunForThread","defaultAgentForThread","personaForThread","modelForThread","recordRunStart","run","retries","startedAt","agentName","parentRunId","promptHash","recordRunEnd","end","settledAt","durationMs","errorCode","errorMessage","bumpRunRetries","promoteThread","setActiveStream","claimActiveStream","options","holder","replacing","releaseActiveStream","enqueueMessage","content","attachments","pageContext","uiCapabilities","hostContext","interrupt","queue","at","unshift","listQueue","getQueuedMessage","found","findQueued","updateQueuedMessage","moveQueuedMessage","index","position","splice","target","Math","max","min","trunc","removeQueuedMessage","clearQueue","count","queuePause","setQueuePause","pause","getThreadActionProposalScope","admitActionProposalOutcome","command","find","outcome","outcomeId","outcomeDelivery","actionProposalOutcomeFenceValid","clock","snapshotActionProposal","lease","role","actionProposalOutcomeText","actionProposalOutcome","ui","next","appendMessage","toolResults","followUps","reasoning","reasoningMs","setMessageToolResults","results","candidate","setMessageUi","_previous","rest","threadOfMessage","threadIdForMessage","setMessageFeedback","truncateFrom","referencedMediaIds","mediaIds","wanted","queued","attachment","mediaId","recordToolCall","toolType","structuredClone","toolCallOutcomes","toolCallIds","outcomes","output","failUnsettledToolCalls","settled","updateToolCall","executionMs","recordUsage","modelId","inputTokens","outputTokens","day","cacheWriteTokens","cacheReadTokens","costUsd","quotaToday","usageBetween","fromDay","toDay","usedTokens","reduce","sum","usageRows","tokens","governanceUsage","governanceToolCalls","governanceMessages","governancePendingApprovals","threadTitle","requestedAt","governanceThreads","messageCount","governanceRuns","some","toolCallRows","last","lastMessagePreview","createHash","createHmac","timingSafeEqual","DEFAULT_CONFIRM_TTL_MS","canonicalJson","value","undefined","JSON","stringify","Array","isArray","map","join","toJSON","entries","Object","filter","entry","sort","a","b","key","signature","subject","expiresAt","secret","Error","createHmac","update","tool","actorId","tenantRef","args","digest","signConfirmToken","options","confirmTokenExpiry","token","separator","indexOf","Number","slice","isSafeInteger","verifyConfirmToken","now","Date","expected","Buffer","from","given","length","timingSafeEqual","hashConfirmToken","createHash","InMemoryConfirmTokenStore","claims","Map","claim","input","purgeExpired","has","hash","set","release","delete","purged","size","InMemoryChannelStore","Map","maxEntries","key","entry","get","undefined","expiresAt","Date","now","delete","value","ttlMs","set","size","stored","claim","purgeExpired","purged","DEFAULT_MESSAGES","confirm","invalid","used","ConfirmTokenError","Error","reason","message","name","CONFIRM_JSON_SCHEMA_PROPERTIES","type","description","confirmToken","SCHEMA_EXTENSION","Symbol","for","schemaExtensionOf","schema","extension","undefined","isRecord","value","Array","isArray","splitConfirm","input","args","fields","jsonSchemaInputOf","standard","jsonSchema","options","call","withConfirmFields","inner","innerJsonSchema","describe","base","additionalProperties","properties","wrapped","version","vendor","validate","issues","push","path","result","length","output","defineConfirmedTool","steps","secret","ttlMs","DEFAULT_CONFIRM_TTL_MS","store","messages","specFields","text","howToConfirm","replaceAll","String","Math","round","secretNow","handler","execute","ctx","subject","tool","actorId","actor","id","tenantRef","confirming","token","verifyConfirmToken","prepared","prepare","preview","expiresAt","Date","now","status","summary","data","signConfirmToken","toISOString","hash","hashConfirmToken","claimed","claim","actorRef","confirmTokenExpiry","done","commit","error","release","catch","spec","kind","inputSchema","DEFAULT_TTL_SECONDS","DEFAULT_POLL_INTERVAL_MS","DEFAULT_IDLE_POLL_INTERVAL_MS","IDLE_AFTER_MS","DEFAULT_FLUSH_MS","READ_PAGE","PURGE_CHUNK","AUTO_PURGE_EVERY_MS","APPEND_ATTEMPTS","decoder","TextDecoder","encoder","TextEncoder","sleep","ms","Promise","resolve","setTimeout","textOf","line","startsWith","parsed","JSON","parse","Object","keys","length","kind","text","SqlTokenStreamSink","pollIntervalMs","idlePollIntervalMs","flushMs","ttlSeconds","autoPurge","writes","Map","lastAutoPurge","table","options","Math","max","runWrites","runId","state","get","undefined","timer","tail","pending","failure","set","release","delete","enqueue","work","next","then","flushText","clearTimeout","decode","encodeStreamEvent","append","raiseFailure","error","frame","attempt","createdAt","Date","now","caught","isUniqueViolation","terminate","flushed","ended","all","purgeInBackground","open","write","chunk","trimEnd","catch","appended","flush","end","fail","stringify","code","message","subscribe","cursor","quietSince","rows","read","row","seq","AgentStreamError","encode","has","close","remove","purgeExpired","lapsed","lapsedRuns","index","slice","resolveTextActionProposalDecision","text","proposals","vocabulary","command","parseTextActionProposalCommand","status","decision","remember","pending","filter","proposal","explicitId","proposalId","undefined","some","id","length","proposalIds","map","candidate","DEFAULT_TEXT_ACTION_PROPOSAL_VOCABULARY","approve","reject","DEFAULT_TEXT_ACTION_PROPOSAL_REPLIES","approved","rejected","expired","unchanged","ambiguous","ids","join","tooMany","textActionProposalReply","result","replies","escapeRegExp","word","replace","alternatives","words","trim","fold","toLowerCase","test","verbs","match","RegExp","exec","verb","remembers","ptBrActionProposalText","language","toActionProposalView","proposal","execution","outcomeDelivery","idempotencyKey","_idempotencyKey","preparationInput","_preparationInput","executionContext","_executionContext","rest","withoutLease","undefined","toActionProposalMutationView","result","value","lease","_lease","ActionProposalExecutor","options","execute","proposal","ui","createNegotiatedUiCollector","originToolCallId","actor","id","actorRef","threadId","resolver","resolve","tenantRef","Error","deps","resolveExecution","registry","spec","toolName","kind","context","executionContext","agentName","undefined","uiCapabilities","resolveUiCatalog","output","invoke","snapshotActionProposal","Object","hasOwn","preparationInput","input","runId","originRunId","requestId","toolCallId","idempotencyKey","persona","pageContext","host","emitUi","emit","rolesPolicy","approvedInput","allowedTools","status","result","components","text","error","message","String","ActionProposalWorker","leaseMs","pollIntervalMs","maxConcurrency","timer","stopped","renewals","Set","active","options","value","Number","isSafeInteger","RangeError","workerId","TypeError","start","undefined","tick","runOnce","error","onError","setTimeout","stop","clearInterval","clear","clearTimeout","Promise","resolve","task","finally","store","expireActionProposals","limit","work","index","proposal","claimNextActionProposal","push","execute","all","delivery","claimNextActionProposalOutcome","admitActionProposalOutcome","lease","execution","Error","fenced","renewing","renew","extendActionProposalLease","id","token","generation","then","result","status","setInterval","add","executor","settled","settleActionProposal","onSettled","delete","assertIndependentActionCapabilities","store","resolver","candidate","resolve","Error","isChatQueueStore","actionProposalAdmissionSupported","required","some","method","createFunctionalTool","definition","input","execute","present","preflight","isEnabled","canUse","describe","kind","metadata","spec","inputSchema","handler","bind","undefined"]}
|