@dudousxd/nestjs-agent-core 0.37.0 → 0.38.1
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/README.md +2 -2
- package/dist/ag-ui/index.cjs.map +1 -1
- package/dist/ag-ui/index.d.cts +1 -1
- package/dist/ag-ui/index.d.ts +1 -1
- package/dist/ag-ui/index.js.map +1 -1
- package/dist/genui/index.d.cts +2 -2
- package/dist/genui/index.d.ts +2 -2
- package/dist/guardrails/index.d.cts +3 -3
- package/dist/guardrails/index.d.ts +3 -3
- package/dist/index.cjs +252 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +155 -8
- package/dist/index.d.ts +155 -8
- package/dist/index.js +251 -5
- package/dist/index.js.map +1 -1
- package/dist/{processors-D5110pit.d.ts → processors-C-FP4nDy.d.ts} +1 -1
- package/dist/{processors-C0snQzZJ.d.cts → processors-CAVevaYJ.d.cts} +1 -1
- package/dist/{stream-events-CgWqAI-1.d.cts → stream-events-rpd3d6gh.d.cts} +5 -0
- package/dist/{stream-events-CgWqAI-1.d.ts → stream-events-rpd3d6gh.d.ts} +5 -0
- package/dist/{tool-DuJ-_qXM.d.cts → tool-Dp8HA_f4.d.cts} +1 -1
- package/dist/{tool-DklsS3JX.d.ts → tool-hhssZ_HW.d.ts} +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ import type { ModelProvider, AgentStore, ToolSpec, RolesPolicy } from '@dudousxd
|
|
|
23
23
|
- `ToolHandler.describe?({ actor, threadId?, agentName? })` — **a per-turn description.** Called when the turn's tool list is built, after every gate; what it returns replaces the spec's `description` / `inputSchema` in what the model sees (`registry.definitionsFor(actor, policy, allowList, { threadId, agentName })`). The registry still validates calls against the registered schema, so a tool whose input varies per turn registers a permissive one and validates in `execute`.
|
|
24
24
|
- `@dudousxd/nestjs-agent-core/genui` (+ `/genui/builtins`) — **the generative-UI catalog**, an isomorphic entry (no server-only import; a spec holds that line) a browser imports too: `defineComponent` / `defineCatalog` (Standard Schema or JSON Schema props), validation, `catalogToModelText`, `componentToText` fallbacks, tree helpers, and `genuiTools(catalog, { mode, terminal, showTool, resolveCatalog, … })` — the tools that push components, with an optional per-request catalog resolver consulted on every call and every turn's description. NestJS apps use `AgentGenuiModule` (`@dudousxd/nestjs-agent/genui`) instead of calling `genuiTools` themselves.
|
|
25
25
|
- `AgentDefinition` — a named agent (`systemPrompt` string | `PromptBuilder`, `tools`, `delegatesTo`, `personas`, …) for multi-agent setups. `delegatesTo` holds `AgentDelegation` entries: a bare target name for the delegation that waits, `{ agent, detached: true }` for one that does not.
|
|
26
|
-
- `detachedStarted` / `detachedDelivered` / `settleUnsettledDelegation` / `AgentLoopHooks.startAgent` / `AgentRunInput.deliverTo` — **delegation that does not block the chat.** An `agent`-kind call whose spec says `detached` is STARTED rather than awaited (`hooks.startAgent`, which the durable runner maps to `ctx.startChild
|
|
26
|
+
- `detachedStarted` / `detachedDelivered` / `settleUnsettledDelegation` / `AgentLoopHooks.startAgent` / `AgentRunInput.deliverTo` — **delegation that does not block the chat.** An `agent`-kind call whose spec says `detached` is STARTED rather than awaited (`hooks.startAgent`, which the durable runner maps to a run of its own — started from a journaled `detach:<toolCallId>` step, NOT a `ctx.startChild`, so a Stop on the delegating turn does not cascade to it — and the inline one to a loop nobody awaits), and the turn ends with a `DetachedDelegationReceipt` as the call's result instead of an answer. The started run carries a `deliverTo` address — the delegating thread and the call that started it — and posts its answer there as a message of its own, stamped with its own `runId` and `agentName`, so a client renders "the research agent finished" rather than the assistant's next reply. Whether a call detaches is settled INSIDE `persist:toolcall` alongside its kind and target, never from a live registry lookup, so a replay reads the branch back rather than re-deciding it; the loop writes the same checkpoint names either way, and only the runner's own positions (`patch:agent:detached-unlinked` + `detach:` — or `spawn:` on a run journaled by `@dudousxd/nestjs-agent` 1.19.2 or earlier — versus the awaited child's `signal:child:`) differ. A detached run outlives a Stop on the turn that started it; it is stopped by its own `runId`, and the card follows it to `delivered`, `failed` or `cancelled`. A detached run streams into its OWN sink and its `action` tools park on its OWN run, so its approval reaches the pending-approvals surface instead of an inline card in whatever turn happens to be open. `settleUnsettledDelegation` is the runner's half: a run that crashed or was stopped posts a message saying so (once — a thread already holding a message from that run is left alone, so the body and the runner may both call it), because "started" is the one state a reader can neither wait on nor act on. `AgentRunInput.parentRunId` / `RecordRunStartInput.parentRunId` record the edge, so a delegation is not a run row with nothing pointing at it.
|
|
27
27
|
- `RolesPolicy.can(actor, tool): boolean | Promise<boolean>` — the tool authorization seam
|
|
28
28
|
- `HistoryPolicy` — the ceiling on how much of a thread rides into a turn. `select(messages, ctx)` must be pure; the loop runs it INSIDE `load:thread`, so the ceiling bounds the journal as well as the prompt — the checkpoint holds the selected messages rather than the whole `ThreadDetail`, and a run recorded before that keeps the old payload via `ctx.patched('agent:selected-history')`. The optional `summarize(dropped, ctx)` may call a model and runs in its own `history:summarize` checkpoint (which is also the only case where the dropped messages are journaled at all). `windowHistory`, `summarizeWithModel` and `estimateMessageTokens` are the built-ins. A policy MAY also declare `maxMessages` — the most messages `select` can ever keep — which the loop passes to `ThreadTurnReader` below as the store's read bound. Declaring it is a promise that `select` keeps at most that many, and that they are the NEWEST ones; a ceiling expressed only in tokens declares nothing, since one message can be four tokens or forty thousand and no row count follows from a budget.
|
|
29
29
|
- `ThreadTurnReader.loadThreadForTurn({ threadId, messageLimit })` — **the read a turn actually needs.** `getThread` materializes a thread's whole transcript (every message row, every attachment, every tool output it ever recorded) to build a prompt bounded to its last few messages: on a 50-turn thread whose turns each ran a 50 KB tool that is ~2.6 MB per load, over 99% of it tool output. This read is bounded by the database (`order by created_at desc, id desc limit ?`, reversed for the prompt) and projected to the columns a model turn reads — `usage`, `follow_ups` and `run_id` stay in the table. The loop probes for it STRUCTURALLY, the same way `AgentService` probes `defaultAgentForThread`: a store that does not implement it keeps working through the full read, with no config change and no warning. `messageLimit` comes from `HistoryPolicy.maxMessages`, and is omitted — meaning read everything — for a policy that summarizes (`summarize` is handed what `select` DROPPED, and a read bounded to what it keeps drops nothing) or whose ceiling is only a token budget. Which branch ran is invisible to the journal by construction: both produce the same three answers, so the payload `load:thread` records is identical either way and a deployment's choice of store can never decide a run's checkpoints. `hasAssistantMessage` is answered over the WHOLE thread, never the page — it decides a `thread-start` intake, and a window holding only the user's last questions belongs to a conversation that has still been answered.
|
|
@@ -34,7 +34,7 @@ import type { ModelProvider, AgentStore, ToolSpec, RolesPolicy } from '@dudousxd
|
|
|
34
34
|
- `Skill` / `SkillProvider` / `ScopeResolver` / `offerSkills` — authored procedures the model pulls in when a task calls for one, instead of every instruction living in the system prompt. A skill is not an agent: an `@Agent` is WHO answers, a skill is HOW one task is done, and any agent may load one. Scoping is by an opaque TOKEN (`actor:u1`, `tenant:berlin`, `global`, or a host's own `depot:north`), and which tokens apply is a host-supplied `ScopeResolver` returning them most-specific-first — so precedence falls out of the order and a new axis is a resolver change, not a schema change. `defaultScopeResolver` covers the tokens derivable from `Actor` alone (actor / tenant / global); `actorScope`, `tenantScope` and `GLOBAL_SCOPE` mint them. This package owns NO skill table: the host owns the rows behind `SkillProvider` (`list(scopes, ctx)` for the catalog, `load(name, scope, ctx)` for one body), so a consumer can relate its own `Sector` entity against the token values in its own read model without writing migrations into a schema the boot-time heal also edits. `staticSkillProvider` and `compositeSkillProvider` are the built-ins. `resolveSkillCatalog` is the pure precedence pass: most specific wins, and the loser's scope is recorded on `shadows` rather than discarded, so the model can say "your setting differs from the org default" instead of choosing silently. What enters the SYSTEM prompt is the catalog only — one line per skill, bounded by `maxSkills` (`DEFAULT_MAX_SKILLS`) — while a BODY arrives as a `skill` tool result on the transcript, where the `HistoryPolicy` ceiling already governs it. The loop spends ONE checkpoint on all of it (`skills:catalog`) holding the whole offer, and serves each load inside the ordinary `tool:<callId>` checkpoint, so both the scopes that applied and the body that entered the prompt are facts the journal holds rather than answers a replaying process's provider would give afresh. `loadSkill` refuses any name the turn's own catalog does not carry, which makes the journaled catalog the authorization boundary as well as the menu. `skillWriteVerdict` is the write rule: your own scope is yours, a wider one needs an elevated HUMAN author, and nothing but a human may ever write above its own scope — an agent that could write a `tenant:` skill is an agent whose prompt anyone in the tenant can edit by talking to it.
|
|
35
35
|
- `MemoryRecord` / `MemoryProvider` / `offerMemories` / `writeMemory` — what the assistant concluded about a person or an organisation, carried across turns and threads. Scoped by the SAME opaque tokens and the same `ScopeResolver` skills use, so a deployment has one answer to "which scopes does this actor have". A memory is a keyed fact: `{ key, text, scope, origin, updatedAt }`, and the key is what makes a conflict mechanically detectable — two memories sharing a key at different scopes are one question answered twice, and `resolveMemoryDigest` lets the narrower win. Where it does, the entry's `overrides` carries the beaten **text** and its **author**, not merely its scope (a skill's `shadows`): the model is following one procedure either way, but a memory is a VALUE, and an agent that knew only that a wider one existed could tell the user nothing except which it picked. **Not retrieval:** a passage is a document someone authored and can fix at its source, a memory is the agent's own inference about someone who never saw it written — hence `MemoryOrigin` on every record, a block that tells the model these are its own fallible notes, and `forget` being REQUIRED on the provider while `write` is optional. Every provider method and every multi-argument export here takes ONE named object (`ListMemoriesInput`, `StoreMemoryInput`, `ResolveMemoryDigestInput`, …): `key`, `text` and `scope` are all strings, and transposed positional arguments would compile clean and write a fact whose key is its value. `memoryWriteVerdict` carries the same four rules as `skillWriteVerdict`; rule three (nothing but a human may write above its own scope, whatever elevation a host grants) is enforced by SHAPE as well as by check, since `rememberToolDefinition()` takes no scope parameter. `memoryForgetVerdict` is narrower still and takes no `elevated` flag: deleting what the assistant believes about YOU needs nobody's permission. What enters the system prompt is one line per memory bounded by `maxMemories` (`DEFAULT_MAX_MEMORIES`), each capped at `maxFactChars` (`DEFAULT_MAX_FACT_CHARS`) when it is WRITTEN — so the block's ceiling is the product of two numbers an operator set, and there is no body/catalog split because a fact that cannot be stated in a line is a document. **The prompt budget is bounded; the store is not.** Once the applicable set outgrows the block, WHICH memories it carries is a decision, and making it by scope starves the widest scopes first — one person's twentieth note would end every chance their organisation's facts had, leaving only a non-zero `omitted` behind. So a provider MAY implement `search({ scopes, query, limit, ctx })` and the block is filled by relevance to the turn instead; omit it and every turn is served by `list`, selecting narrowest-then-newest as before. Scope remains a hard FILTER that gates before ranking (a record returned outside `scopes` is dropped, so a host's filter bug costs throughput rather than privacy), and `search` must return every record sharing a returned key or precedence inverts. `MemoryRecord.pinned` is the categorical always-on marker — present whatever the turn is about, spending the same budget, never set by the agent (`StoreMemoryInput` has no such field, and the `remember` tool has no such parameter), with `MemoryDigest.pinnedOmitted` naming the one omission that is a misconfiguration rather than a budget. `buildMemoryBlock` frames entries by `origin.author`: what the agent CONCLUDED is hedged ("your own notes … prefer what the user says now"), what a person STATED is not, because telling a model to prefer the user over an organisation's published policy hands any user an override of it by assertion. A `partial` block says so, so the model does not read an absence as evidence. The loop spends ONE checkpoint (`memory:digest`) holding the whole digest — the search included, since a ranking is the most re-derivable decision here — which is both what the block is rendered from and what a later `remember` call is authorized against; the write itself happens inside the ordinary `tool:<callId>` checkpoint, which is what makes it idempotent under replay. The query is the user's own turn text and nothing else: the only thing available before the first model call, already a journaled input to the run, and it fails at a turn with no topic — which is what `pinned` is for.
|
|
36
36
|
- `AgentStore.setMessageToolResults(messageId, results)` — a message's tool CALLS are known when it is appended and their outputs are not, so the loop settles them afterwards with one write of the turn's complete result list (its synthetic `retrieve` / `structured_output` calls included). Both halves live on the message because that is where a thread reader pairs them; a call whose output only ever reaches the `agent_tool_call` table renders as a tool still running. Required, not optional — a store that silently declines it breaks a client with nothing logged.
|
|
37
|
-
- `AttachmentStagingStore.list(input)` / `AgentStore.referencedMediaIds(actorRef, mediaIds)` — the two halves of attachment housekeeping, split the way ownership is. `stage()` writes bytes before any message exists, so an upload the user never sent leaves media nothing points at; the HOST can enumerate that media (it stored it) but cannot see a transcript, and this library sees every transcript but never holds bytes. `list` returns `StagedAttachment` metadata (`mediaId`, `name`, `contentType`, `sizeBytes`, `createdAt` — no `url`, since `resolve` mints those per turn precisely so they can be short-lived); `referencedMediaIds` answers which of a set of ids a message that still exists carries, scoped to one actor. The answer is DERIVED from the surviving message rows on every call, never latched: `truncateFrom` deletes messages — regenerating a turn does exactly that — so a reference disappears, and a flag set at send time would pin the bytes for ever. Both are optional; a caller that cannot get an answer must collect nothing rather than read silence as "unreferenced". `AgentService.collectableAttachments` composes them, and deletes nothing.
|
|
37
|
+
- `AttachmentStagingStore.list(input)` / `AgentStore.referencedMediaIds(actorRef, mediaIds)` — the two halves of attachment housekeeping, split the way ownership is. `stage()` writes bytes before any message exists, so an upload the user never sent leaves media nothing points at; the HOST can enumerate that media (it stored it) but cannot see a transcript, and this library sees every transcript but never holds bytes. `list` returns `StagedAttachment` metadata (`mediaId`, `name`, `contentType`, `sizeBytes`, `createdAt` — no `url`, since `resolve` mints those per turn precisely so they can be short-lived); `referencedMediaIds` answers which of a set of ids a message that still exists — or one still waiting in a thread's queue — carries, scoped to one actor. The answer is DERIVED from the surviving message rows on every call, never latched: `truncateFrom` deletes messages — regenerating a turn does exactly that — so a reference disappears, and a flag set at send time would pin the bytes for ever. Both are optional; a caller that cannot get an answer must collect nothing rather than read silence as "unreferenced". `AgentService.collectableAttachments` composes them, and deletes nothing.
|
|
38
38
|
- `agentFailureCode(error)` — the stream error code for a failed run (`cancelled`, `quota_exceeded`, `output_rejected`, `structured_output_invalid`, `replay_diverged` for the durable runtime refusing a checkpoint position, `model_no_output` for a model call that produced nothing, else `run_failed`), so a control doing its job never reads as the model breaking. `streamFailure(error)` is the `{ code, message }` a runner closes the stream with: for a crash the message is `RUN_FAILED_MESSAGE` in production and the raw text elsewhere (`exposeStreamErrorDetails` decides it outright) — the error itself belongs in the log and on the run row.
|
|
39
39
|
- `settleDanglingToolCalls(messages, outcomes?)` / `danglingToolCallIds(messages)` — give every tool call in a history a result. A turn that dies mid-step leaves an assistant message asking for tools and answered by nothing, which a provider refuses, so every later turn on the thread fails too. The loop settles them inside `load:thread` (no new position; a replay reads the recorded payload) from the calls' own rows where the store implements the optional `AgentStore.toolCallOutcomes` — a tool that DID run hands the model its real output, so it is not run again — and otherwise with `UNFINISHED_TOOL_CALL`. `AgentStore.failUnsettledToolCalls(runId, error)` (optional) is what a failing run calls so no approval card waits on it; `settleDeadRun(store, { runId, threadId?, failure? })` is the same for a caller with no journal left to write to.
|
|
40
40
|
- `AiToolCtx.idempotencyKey` (`<runId>:<toolCallId>`) / `AiToolCtx.toolCallId` — the same for every execution of one call, so a tool re-run after a worker died between its side effect and its checkpoint (or by a transient retry) can be made to land on the first attempt. `toolCallContext(ctx, toolCallId)` builds it for a runner's own dispatched step.
|
package/dist/ag-ui/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ag-ui/index.ts","../../src/ag-ui/interrupt-id.ts","../../src/ag-ui/types.ts","../../src/ag-ui/encoder.ts","../../src/ag-ui/input.ts","../../src/spi/token-stream-sink.ts","../../src/stream-events.ts","../../src/ag-ui/stream.ts"],"sourcesContent":["/**\n * AG-UI 1.0 (https://docs.ag-ui.com/spec/1.0), producer side, framework-free: the encoder that\n * projects a run's stream onto AG-UI events, the stream driver that ends a run when it stops to\n * ask, and the readers for `RunAgentInput`. `@dudousxd/nestjs-agent` serves it as\n * `POST <path>/ag-ui` (`adapters: [agUiAdapter()]`); `@adonis-agora/agent` serves the same encoder.\n */\n\nexport { AgUiEncoder, type AgUiEncoderOptions } from './encoder.js';\nexport {\n type ForwardedOptions,\n type InlineMedia,\n parseRunInput,\n planResume,\n type ResumeDecision,\n type ResumePlan,\n readAnswersPayload,\n readApprovalPayload,\n readContext,\n readForwardedProps,\n readUserTurn,\n type UserTurn,\n} from './input.js';\nexport { decodeInterruptId, encodeInterruptId, type InterruptAddress } from './interrupt-id.js';\nexport { type AgUiStreamOptions, agUiEvents, agUiFramesFromNdjson, agUiSse } from './stream.js';\nexport * from './types.js';\n","/**\n * An interrupt's id carries everything a resuming request needs, so the producer keeps NOTHING\n * between the run that stopped to ask and the run that answers — the statelessness AG-UI lets a\n * producer have, and what lets any replica serve the resume.\n *\n * It names the library run the human is answering (`parked` — a delegated sub-agent parks its OWN\n * run), the run whose stream carries the work (`stream`), the tool call, and how many of that\n * stream's frames the interrupted AG-UI run already delivered (`position`), which is where the\n * resuming run picks the stream up.\n *\n * It is an address, not a credential: the resume route checks the caller owns the run exactly as\n * the native approve/answer routes do.\n */\nexport interface InterruptAddress {\n kind: 'approval' | 'elicitation';\n /** The run to settle the call on. */\n parked: string;\n /** The run whose buffered stream the resume re-attaches to. */\n stream: string;\n toolCallId: string;\n /** Frames of `stream` already delivered when the run was reported interrupted. */\n position: number;\n}\n\nconst PREFIX = 'agora_';\n\nexport function encodeInterruptId(address: InterruptAddress): string {\n const compact = [\n address.kind === 'approval' ? 'a' : 'e',\n address.parked,\n address.stream,\n address.toolCallId,\n address.position,\n ];\n return PREFIX + Buffer.from(JSON.stringify(compact), 'utf8').toString('base64url');\n}\n\n/** The address an id names, or `null` for an id this producer did not mint. */\nexport function decodeInterruptId(id: unknown): InterruptAddress | null {\n if (typeof id !== 'string' || !id.startsWith(PREFIX)) return null;\n try {\n const parsed: unknown = JSON.parse(\n Buffer.from(id.slice(PREFIX.length), 'base64url').toString('utf8'),\n );\n if (!Array.isArray(parsed) || parsed.length !== 5) return null;\n const [kind, parked, stream, toolCallId, position] = parsed as unknown[];\n if (\n (kind !== 'a' && kind !== 'e') ||\n typeof parked !== 'string' ||\n typeof stream !== 'string' ||\n typeof toolCallId !== 'string' ||\n typeof position !== 'number' ||\n !Number.isSafeInteger(position) ||\n position < 0\n ) {\n return null;\n }\n return {\n kind: kind === 'a' ? 'approval' : 'elicitation',\n parked,\n stream,\n toolCallId,\n position,\n };\n } catch {\n return null;\n }\n}\n","import type { AgentStreamEvent } from '../stream-events.js';\n\n/**\n * The slice of AG-UI 1.0 (https://docs.ag-ui.com/spec/1.0) this producer writes and reads. Typed by\n * hand rather than imported: the agent package takes no dependency on an AG-UI SDK, and the wire\n * shape is pinned by the protocol's own JSON Schema, which the tests validate every emitted event\n * against (`src/ag-ui/fixtures/schema-1.0.json`).\n *\n * Optional members are OMITTED when there is nothing to say, never `null` — the protocol's\n * \"absent means absent\" rule.\n */\n\n/** The protocol version this producer declares on `RUN_STARTED`. */\nexport const AG_UI_PROTOCOL_VERSION = '1.0';\n\nexport type AgUiMetadata = Record<string, unknown>;\n\n/** One provider-and-model's token usage, in the protocol's single accounting. */\nexport interface AgUiTokenUsage {\n provider?: string;\n model?: string;\n /** Every prompt token, cached or not. */\n inputTokens?: number;\n /** Every generated token, reasoning included. */\n outputTokens?: number;\n totalTokens?: number;\n /** Part of `outputTokens`. */\n reasoningTokens?: number;\n /** Cache reads — part of `inputTokens`. */\n cachedInputTokens?: number;\n /** Cache writes — part of `inputTokens`, disjoint from the reads. */\n cacheWriteInputTokens?: number;\n}\n\n/** What an interrupted run is waiting for; a resume entry answers it by `id`. */\nexport interface AgUiInterrupt {\n id: string;\n /** Open string. This producer writes `tool_approval` and `input_required`. */\n reason: string;\n message?: string;\n toolCallId?: string;\n responseSchema?: Record<string, unknown>;\n expiresAt?: string;\n metadata?: AgUiMetadata;\n}\n\nexport type AgUiRunOutcome =\n | { type: 'success'; pendingToolCallIds?: string[] }\n | { type: 'interrupt'; interrupts: AgUiInterrupt[] }\n | { type: 'cancelled' };\n\ninterface Base {\n metadata?: AgUiMetadata;\n}\n\nexport type AgUiEvent =\n | (Base & { type: 'RUN_STARTED'; threadId: string; runId: string; protocolVersion?: string })\n | (Base & {\n type: 'RUN_FINISHED';\n threadId: string;\n runId: string;\n outcome?: AgUiRunOutcome;\n usage?: AgUiTokenUsage[];\n })\n | (Base & { type: 'RUN_ERROR'; message: string; code?: string; usage?: AgUiTokenUsage[] })\n | (Base & { type: 'STEP_STARTED'; stepName: string })\n | (Base & { type: 'STEP_FINISHED'; stepName: string })\n | (Base & { type: 'TEXT_MESSAGE_START'; messageId: string; role: 'assistant' })\n | (Base & { type: 'TEXT_MESSAGE_CONTENT'; messageId: string; delta: string })\n | (Base & { type: 'TEXT_MESSAGE_END'; messageId: string })\n | (Base & { type: 'REASONING_START'; messageId: string })\n | (Base & { type: 'REASONING_MESSAGE_START'; messageId: string; role: 'reasoning' })\n | (Base & { type: 'REASONING_MESSAGE_CONTENT'; messageId: string; delta: string })\n | (Base & { type: 'REASONING_MESSAGE_END'; messageId: string })\n | (Base & { type: 'REASONING_END'; messageId: string })\n | (Base & {\n type: 'TOOL_CALL_START';\n toolCallId: string;\n toolCallName: string;\n parentMessageId?: string;\n })\n | (Base & { type: 'TOOL_CALL_ARGS'; toolCallId: string; delta: string })\n | (Base & { type: 'TOOL_CALL_END'; toolCallId: string })\n | (Base & {\n type: 'TOOL_CALL_RESULT';\n messageId: string;\n toolCallId: string;\n content: string;\n role: 'tool';\n })\n | (Base & { type: 'CUSTOM'; name: string; value: unknown });\n\n/** Where a media part's bytes are. Closed set: an unknown `type` is malformed input. */\nexport type AgUiPartSource =\n | { type: 'data'; value: string; mimeType: string }\n | { type: 'url'; value: string; mimeType?: string }\n | { type: 'file'; value: string; provider?: string; mimeType?: string };\n\nexport type AgUiContentPart =\n | { type: 'text'; text: string; id?: string; metadata?: unknown }\n | {\n type: 'image' | 'audio' | 'video' | 'document';\n source: AgUiPartSource;\n id?: string;\n metadata?: unknown;\n };\n\nexport interface AgUiMessage {\n id: string;\n role: string;\n content?: string | AgUiContentPart[];\n [key: string]: unknown;\n}\n\nexport interface AgUiResumeEntry {\n interruptId: string;\n status: 'resolved' | 'cancelled';\n payload?: unknown;\n metadata?: AgUiMetadata;\n}\n\nexport interface AgUiContext {\n description: string;\n value: string;\n}\n\n/** `RunAgentInput`: the one message that travels from the application to the agent. */\nexport interface AgUiRunInput {\n threadId: string;\n runId: string;\n protocolVersion?: string;\n parentRunId?: string;\n state?: unknown;\n messages: AgUiMessage[];\n tools?: unknown[];\n context?: AgUiContext[];\n forwardedProps?: unknown;\n resume?: AgUiResumeEntry[];\n}\n\n/**\n * The names of the `CUSTOM` events this producer writes for what AG-UI does not model. Prefixed, as\n * the protocol asks of invented names; a consumer that does not know one ignores it.\n */\nexport const AG_UI_CUSTOM = {\n /** `{ runId, threadId }` — the library's own ids for the run behind this stream (cancel, re-attach). */\n run: 'agora.run',\n /** A generative-UI component (`AgentUiComponent`); a repeat `id` replaces. */\n ui: 'agora.ui',\n title: 'agora.title',\n queue: 'agora.queue',\n /** The approval request as the native protocol carries it, for a consumer that renders it live. */\n approvalRequested: 'agora.approval-requested',\n approvalSettled: 'agora.approval-settled',\n /** The whole question set of an elicitation (`ElicitationRequest`). */\n elicitation: 'agora.elicitation',\n /** `{ usage, costUsd, reasoningMs }` of one model step. */\n stepUsage: 'agora.step-usage',\n /** `{ message }` — input material this producer could not use and dropped. */\n warning: 'agora.warning',\n} as const;\n\n/**\n * What the encoder reads: one frame of a run's stream, in the shared vocabulary\n * ({@link AgentStreamEvent}) — plus the terminal failure, which the NestJS sink throws and the\n * Adonis sink writes as a frame, and three optional facts a sink may know about a parked call:\n * - `runId` — the run that is PARKED, when it is not the one whose stream this is (a delegated\n * sub-agent forwards its frames into its ancestor's stream). Absent → the stream's own run.\n * - `toolName`, `input` — the call being approved. Absent → read off the call's announcement.\n *\n * Framework-free on purpose: both servers project their own sink onto this and share one encoder.\n */\nexport type AgUiSourceFrame =\n | Exclude<\n AgentStreamEvent,\n { kind: 'approval-requested' } | { kind: 'elicitation' } | { kind: 'ui' }\n >\n | (Extract<AgentStreamEvent, { kind: 'approval-requested' }> & {\n runId?: string;\n toolName?: string;\n input?: unknown;\n })\n | (Extract<AgentStreamEvent, { kind: 'elicitation' }> & { runId?: string })\n /** A component with no `id` is numbered by its position in the stream (`ui:<n>`). */\n | (Omit<Extract<AgentStreamEvent, { kind: 'ui' }>, 'id' | 'props'> & {\n id?: string;\n props: unknown;\n })\n /** The run failed: the AG-UI run ends with `RUN_ERROR`, and nothing follows it. */\n | { kind: 'error'; code: string; message: string };\n","import type { ElicitationRequest } from '../elicitation.js';\nimport type { MessageUsage } from '../types.js';\nimport { encodeInterruptId } from './interrupt-id.js';\nimport {\n AG_UI_CUSTOM,\n AG_UI_PROTOCOL_VERSION,\n type AgUiEvent,\n type AgUiInterrupt,\n type AgUiSourceFrame,\n type AgUiTokenUsage,\n} from './types.js';\n\nexport interface AgUiEncoderOptions {\n /** The ids the consumer sent on `RunAgentInput`: every boundary event echoes them. */\n threadId: string;\n runId: string;\n /** The library run whose stream is being projected (it mints interrupt ids and the `agora.run` event). */\n streamRunId: string;\n /** The library's thread id, when it differs from what the consumer calls the thread. */\n streamThreadId?: string;\n /**\n * Frames of the library run's stream that an earlier AG-UI run already delivered (a resume). They\n * are fed to the encoder like any other — it has to know what they opened — but produce no events.\n */\n skip?: number;\n /**\n * Tool calls a resuming request just answered. The run has not necessarily said so yet — a parked\n * run takes a moment to wake — so without this the encoder would read them as still waiting and\n * report the interrupt again before the answer had any effect.\n */\n answered?: readonly string[];\n /** Model id for the usage entry when the step frames carry none. */\n model?: string;\n}\n\ninterface OpenCall {\n name: string;\n /** The arguments it was announced with, for an approval frame that does not repeat them. */\n input?: unknown;\n /** `TOOL_CALL_START` was written in THIS run (a resumed run meets results of calls it never saw open). */\n started: boolean;\n ended: boolean;\n sawDelta: boolean;\n answered: boolean;\n}\n\ninterface Pending {\n interrupt: Omit<AgUiInterrupt, 'id'>;\n kind: 'approval' | 'elicitation';\n parked: string;\n toolCallId: string;\n}\n\nconst APPROVAL_SCHEMA = {\n type: 'object',\n properties: {\n approved: { type: 'boolean' },\n reason: { type: 'string' },\n remember: { type: 'boolean' },\n },\n required: ['approved'],\n};\n\n/** The answer an elicitation expects: `{ answers: { <questionId>: string[] } }`. */\nfunction elicitationSchema(request: ElicitationRequest): Record<string, unknown> {\n const properties: Record<string, unknown> = {};\n for (const question of request.questions) {\n const options = question.options?.map((option) => option.value);\n properties[question.id] = {\n type: 'array',\n title: question.prompt,\n ...(question.description !== undefined ? { description: question.description } : {}),\n items:\n options !== undefined && options.length > 0 && question.allowFreeText !== true\n ? { type: 'string', enum: options }\n : { type: 'string' },\n ...(question.multiple === true ? {} : { maxItems: 1 }),\n ...(question.defaults !== undefined ? { default: question.defaults } : {}),\n };\n }\n return {\n type: 'object',\n properties: { answers: { type: 'object', properties } },\n required: ['answers'],\n };\n}\n\nfunction text(value: unknown): string {\n if (typeof value === 'string') return value;\n const json = JSON.stringify(value);\n return json === undefined ? '' : json;\n}\n\n/**\n * Projects one library run's stream ({@link AgUiSourceFrame}s, in buffer order) onto AG-UI 1.0 events.\n *\n * A pure state machine: the same frames always give the same events, which is what lets a resuming\n * request — served by any replica — replay the run's buffer, skip what the interrupted AG-UI run\n * already delivered, and continue. It writes nothing itself; {@link agUiEvents} drives it and\n * decides when the run has stopped to ask.\n *\n * What maps where:\n * - `text` → `TEXT_MESSAGE_*` (one message per stretch of text);\n * - `reasoning` → a reasoning span with one reasoning message;\n * - `step-start`/`step-finish` → `STEP_STARTED`/`STEP_FINISHED`, the step's usage folded into the\n * run's `usage`;\n * - `tool-input-*` → `TOOL_CALL_START`/`ARGS`/`END`; `tool-output*` → `TOOL_CALL_RESULT`;\n * - an approval or a question set the run parks on → an `Interrupt` on the closing `RUN_FINISHED`;\n * - `cancelled` → the cancelled outcome; an error frame → `RUN_ERROR`;\n * - generative UI, title, queue and the native approval/elicitation frames → `CUSTOM` events named\n * in {@link AG_UI_CUSTOM}, for what AG-UI has no event for.\n *\n * Not mapped: sub-agent attribution (`subagentRunId`) — a delegated agent's frames are projected\n * flat, as the protocol allows of a producer that does not attribute.\n */\nexport class AgUiEncoder {\n private position = 0;\n private started = false;\n private closed = false;\n private cancelled = false;\n private crossed = false;\n private messageSeq = 0;\n private stepSeq = 0;\n private openText: string | undefined;\n private openReasoning: string | undefined;\n /** The last text message of the current step: a tool call attaches to it. */\n private stepMessage: string | undefined;\n private readonly openSteps: string[] = [];\n private readonly calls = new Map<string, OpenCall>();\n private readonly pending = new Map<string, Pending>();\n private readonly usage = new Map<string, AgUiTokenUsage>();\n\n constructor(private readonly options: AgUiEncoderOptions) {}\n\n /** How many frames of the library stream this encoder has consumed. */\n get consumed(): number {\n return this.position;\n }\n\n /** The run is waiting on at least one approval or question set nobody has settled yet. */\n get waiting(): boolean {\n return this.pending.size > 0;\n }\n\n /**\n * Is anything still in flight that is NOT waiting on a person — a tool call announced and neither\n * answered nor parked? While there is, more frames are coming without anyone's help.\n */\n get busy(): boolean {\n for (const [id, call] of this.calls) {\n if (!call.answered && !this.pending.has(id)) return true;\n }\n return false;\n }\n\n /** `RUN_STARTED`, and the library's own ids for the run. Call once, before the first frame. */\n start(): AgUiEvent[] {\n if (this.started) return [];\n this.started = true;\n return [\n {\n type: 'RUN_STARTED',\n threadId: this.options.threadId,\n runId: this.options.runId,\n protocolVersion: AG_UI_PROTOCOL_VERSION,\n },\n {\n type: 'CUSTOM',\n name: AG_UI_CUSTOM.run,\n value: {\n runId: this.options.streamRunId,\n threadId: this.options.streamThreadId ?? this.options.threadId,\n },\n },\n ];\n }\n\n /** The AG-UI events the next frame of the library stream stands for (possibly none). */\n encode(frame: AgUiSourceFrame): AgUiEvent[] {\n const position = this.position;\n this.position += 1;\n if (this.closed) return [];\n const skip = this.options.skip ?? 0;\n if (!this.crossed && position >= skip) this.crossBoundary();\n const events = this.project(frame, position);\n // A frame an earlier AG-UI run already delivered still moves the state (what is open, what is\n // pending; NOT what was spent — usage is per run) but writes nothing. The last of them is the\n // boundary: crossed at once, not when the next frame happens to arrive, because a run that was\n // just answered may take a moment to write one.\n if (position < skip) {\n if (this.position >= skip) this.crossBoundary();\n return [];\n }\n return events;\n }\n\n /**\n * The replayed frames are behind us: from here on events are written. The AG-UI run that delivered\n * them closed everything it had open before it finished, so this run starts with nothing open, and\n * what the resuming request answered is no longer waiting.\n */\n private crossBoundary(): void {\n this.crossed = true;\n this.openText = undefined;\n this.openReasoning = undefined;\n this.stepMessage = undefined;\n this.openSteps.length = 0;\n for (const call of this.calls.values()) {\n call.started = false;\n call.ended = true;\n }\n for (const id of this.options.answered ?? []) this.pending.delete(id);\n }\n\n private get replaying(): boolean {\n return this.position <= (this.options.skip ?? 0);\n }\n\n private project(event: AgUiSourceFrame, position: number): AgUiEvent[] {\n switch (event.kind) {\n case 'error': {\n this.closed = true;\n const usage = this.usageEntries();\n return [\n {\n type: 'RUN_ERROR',\n message: event.message,\n code: event.code,\n ...(usage.length > 0 ? { usage } : {}),\n },\n ];\n }\n case 'ui':\n return [\n this.custom(AG_UI_CUSTOM.ui, {\n id: event.id ?? `ui:${position}`,\n component: event.component,\n props: event.props,\n ...(event.version !== undefined ? { version: event.version } : {}),\n ...(event.toolCallId !== undefined ? { toolCallId: event.toolCallId } : {}),\n }),\n ];\n case 'approval-requested': {\n const call = this.calls.get(event.id);\n const parked = event.runId ?? this.options.streamRunId;\n const toolName = event.toolName ?? call?.name ?? '';\n const input = event.input ?? call?.input ?? null;\n this.pending.set(event.id, {\n kind: 'approval',\n parked,\n toolCallId: event.id,\n interrupt: {\n reason: 'tool_approval',\n message: event.reason ?? (toolName.length > 0 ? `Approve ${toolName}?` : 'Approve?'),\n toolCallId: event.id,\n responseSchema: APPROVAL_SCHEMA,\n ...(event.expiresAt !== undefined ? { expiresAt: event.expiresAt } : {}),\n metadata: {\n 'agora.toolName': toolName,\n 'agora.input': input,\n 'agora.approver': event.approver,\n },\n },\n });\n return [\n this.custom(AG_UI_CUSTOM.approvalRequested, {\n id: event.id,\n runId: parked,\n toolName,\n input,\n approver: event.approver,\n ...(event.expiresAt !== undefined ? { expiresAt: event.expiresAt } : {}),\n ...(event.reason !== undefined ? { reason: event.reason } : {}),\n }),\n ];\n }\n case 'elicitation': {\n const parked = event.runId ?? this.options.streamRunId;\n this.pending.set(event.id, {\n kind: 'elicitation',\n parked,\n toolCallId: event.id,\n interrupt: {\n reason: 'input_required',\n message:\n event.request.preamble ?? event.request.questions[0]?.prompt ?? 'Input required',\n // An intake's question set belongs to no tool call the stream announced.\n ...(this.calls.has(event.id) ? { toolCallId: event.id } : {}),\n responseSchema: elicitationSchema(event.request),\n metadata: { 'agora.request': event.request },\n },\n });\n return [this.custom(AG_UI_CUSTOM.elicitation, { runId: parked, request: event.request })];\n }\n case 'text':\n return event.text.length > 0 ? this.textDelta(event.text) : [];\n case 'reasoning':\n return event.text.length > 0 ? this.reasoningDelta(event.text) : [];\n case 'step-start': {\n this.stepSeq += 1;\n const stepName = `step-${this.stepSeq}`;\n this.openSteps.push(stepName);\n this.stepMessage = undefined;\n return [...this.closeStreams(), { type: 'STEP_STARTED', stepName }];\n }\n case 'step-finish': {\n const out = this.closeStreams();\n if (!this.replaying) this.addUsage(event.usage, event.model);\n const stepName = this.openSteps.pop();\n if (stepName !== undefined) out.push({ type: 'STEP_FINISHED', stepName });\n if (event.usage !== undefined || event.costUsd !== undefined) {\n out.push(\n this.custom(AG_UI_CUSTOM.stepUsage, {\n ...(event.usage !== undefined ? { usage: event.usage } : {}),\n ...(event.costUsd !== undefined ? { costUsd: event.costUsd } : {}),\n ...(event.reasoningMs !== undefined ? { reasoningMs: event.reasoningMs } : {}),\n }),\n );\n }\n return out;\n }\n case 'tool-input-start': {\n if (this.calls.has(event.id)) return [];\n const out = this.closeStreams();\n this.calls.set(event.id, {\n name: event.name,\n started: true,\n ended: false,\n sawDelta: false,\n answered: false,\n });\n out.push(this.callStart(event.id, event.name));\n return out;\n }\n case 'tool-input-delta': {\n const call = this.calls.get(event.id);\n if (call === undefined || call.ended || event.delta.length === 0) return [];\n call.sawDelta = true;\n return [{ type: 'TOOL_CALL_ARGS', toolCallId: event.id, delta: event.delta }];\n }\n case 'tool-input-available': {\n const known = this.calls.get(event.id);\n if (known?.ended === true) return [];\n const out = this.closeStreams();\n const call = known ?? {\n name: event.name,\n started: false,\n ended: false,\n sawDelta: false,\n answered: false,\n };\n if (!call.started) {\n call.started = true;\n out.push(this.callStart(event.id, event.name));\n }\n if (!call.sawDelta) {\n out.push({\n type: 'TOOL_CALL_ARGS',\n toolCallId: event.id,\n delta: text(event.input ?? {}),\n });\n }\n call.ended = true;\n call.input = event.input;\n this.calls.set(event.id, call);\n out.push({ type: 'TOOL_CALL_END', toolCallId: event.id });\n return out;\n }\n case 'tool-output':\n return this.result(event.id, text(event.output));\n case 'tool-output-error':\n return this.result(event.id, event.error, { 'agora.outcome': 'error' });\n case 'tool-output-denied':\n return this.result(event.id, event.reason ?? 'denied', { 'agora.outcome': 'denied' });\n case 'approval-settled':\n this.pending.delete(event.id);\n return [this.custom(AG_UI_CUSTOM.approvalSettled, event)];\n case 'title':\n return [this.custom(AG_UI_CUSTOM.title, { title: event.title })];\n case 'queue':\n return [\n this.custom(AG_UI_CUSTOM.queue, {\n queue: event.queue,\n ...(event.started !== undefined ? { started: event.started } : {}),\n }),\n ];\n case 'cancelled':\n this.cancelled = true;\n return [];\n default:\n // A kind newer than this encoder: tolerated, as every reader of the stream must.\n return [];\n }\n }\n\n /**\n * The events that end the AG-UI run: whatever is still open is closed first, then `RUN_FINISHED`\n * with how it ended — interrupted when the run is waiting on someone, cancelled when it was\n * stopped, success otherwise. Nothing after a `RUN_ERROR`. `ended` says the library run's stream\n * itself ended, rather than this reader having stopped following it.\n */\n finish(ended = false): AgUiEvent[] {\n if (this.closed) return [];\n this.closed = true;\n if (!this.crossed) this.crossBoundary();\n // A library run that ended is waiting on no one, whatever it asked along the way.\n if (ended) this.pending.clear();\n const out = this.start();\n out.push(...this.closeStreams());\n for (const [id, call] of this.calls) {\n if (call.started && !call.ended) {\n call.ended = true;\n out.push({ type: 'TOOL_CALL_END', toolCallId: id });\n }\n }\n while (this.openSteps.length > 0) {\n out.push({ type: 'STEP_FINISHED', stepName: this.openSteps.pop() as string });\n }\n const usage = this.usageEntries();\n const interrupts = this.cancelled ? [] : this.interrupts();\n out.push({\n type: 'RUN_FINISHED',\n threadId: this.options.threadId,\n runId: this.options.runId,\n ...(this.cancelled\n ? { outcome: { type: 'cancelled' as const } }\n : interrupts.length > 0\n ? { outcome: { type: 'interrupt' as const, interrupts } }\n : {}),\n ...(usage.length > 0 ? { usage } : {}),\n });\n return out;\n }\n\n private interrupts(): AgUiInterrupt[] {\n return [...this.pending.values()].map((entry) => ({\n id: encodeInterruptId({\n kind: entry.kind,\n parked: entry.parked,\n stream: this.options.streamRunId,\n toolCallId: entry.toolCallId,\n position: this.position,\n }),\n ...entry.interrupt,\n }));\n }\n\n private custom(name: string, value: unknown): AgUiEvent {\n return { type: 'CUSTOM', name, value };\n }\n\n private nextMessageId(): string {\n this.messageSeq += 1;\n return `${this.options.runId}:m${this.messageSeq}`;\n }\n\n private textDelta(delta: string): AgUiEvent[] {\n const out: AgUiEvent[] = [];\n if (this.openReasoning !== undefined) out.push(...this.closeReasoning());\n if (this.openText === undefined) {\n this.openText = this.nextMessageId();\n this.stepMessage = this.openText;\n out.push({ type: 'TEXT_MESSAGE_START', messageId: this.openText, role: 'assistant' });\n }\n out.push({ type: 'TEXT_MESSAGE_CONTENT', messageId: this.openText, delta });\n return out;\n }\n\n private reasoningDelta(delta: string): AgUiEvent[] {\n const out: AgUiEvent[] = [];\n if (this.openText !== undefined) out.push(...this.closeText());\n if (this.openReasoning === undefined) {\n this.openReasoning = this.nextMessageId();\n out.push(\n { type: 'REASONING_START', messageId: this.openReasoning },\n { type: 'REASONING_MESSAGE_START', messageId: this.openReasoning, role: 'reasoning' },\n );\n }\n out.push({ type: 'REASONING_MESSAGE_CONTENT', messageId: this.openReasoning, delta });\n return out;\n }\n\n private closeText(): AgUiEvent[] {\n if (this.openText === undefined) return [];\n const messageId = this.openText;\n this.openText = undefined;\n return [{ type: 'TEXT_MESSAGE_END', messageId }];\n }\n\n private closeReasoning(): AgUiEvent[] {\n if (this.openReasoning === undefined) return [];\n const messageId = this.openReasoning;\n this.openReasoning = undefined;\n return [\n { type: 'REASONING_MESSAGE_END', messageId },\n { type: 'REASONING_END', messageId },\n ];\n }\n\n private closeStreams(): AgUiEvent[] {\n return [...this.closeReasoning(), ...this.closeText()];\n }\n\n private callStart(id: string, name: string): AgUiEvent {\n return {\n type: 'TOOL_CALL_START',\n toolCallId: id,\n toolCallName: name,\n ...(this.stepMessage !== undefined ? { parentMessageId: this.stepMessage } : {}),\n };\n }\n\n private result(id: string, content: string, metadata?: Record<string, unknown>): AgUiEvent[] {\n const call = this.calls.get(id);\n if (call !== undefined) call.answered = true;\n else {\n this.calls.set(id, {\n name: '',\n started: false,\n ended: true,\n sawDelta: false,\n answered: true,\n });\n }\n this.pending.delete(id);\n return [\n ...this.closeStreams(),\n {\n type: 'TOOL_CALL_RESULT',\n messageId: `${this.options.runId}:tool:${id}`,\n toolCallId: id,\n content,\n role: 'tool',\n ...(metadata !== undefined ? { metadata } : {}),\n },\n ];\n }\n\n private addUsage(usage: MessageUsage | undefined, model: unknown): void {\n if (usage === undefined) return;\n const name = typeof model === 'string' && model.length > 0 ? model : this.options.model;\n const key = name ?? '';\n const entry = this.usage.get(key) ?? (name !== undefined ? { model: name } : {});\n // The library's accounting is already the protocol's: input and output are totals, cache and\n // reasoning counts are parts of them. A count the provider did not report stays absent.\n entry.inputTokens = (entry.inputTokens ?? 0) + usage.inputTokens;\n entry.outputTokens = (entry.outputTokens ?? 0) + usage.outputTokens;\n entry.totalTokens = entry.inputTokens + entry.outputTokens;\n if (usage.cacheReadTokens !== undefined) {\n entry.cachedInputTokens = (entry.cachedInputTokens ?? 0) + usage.cacheReadTokens;\n }\n if (usage.cacheWriteTokens !== undefined) {\n entry.cacheWriteInputTokens = (entry.cacheWriteInputTokens ?? 0) + usage.cacheWriteTokens;\n }\n if (usage.reasoningTokens !== undefined) {\n entry.reasoningTokens = (entry.reasoningTokens ?? 0) + usage.reasoningTokens;\n }\n this.usage.set(key, entry);\n }\n\n private usageEntries(): AgUiTokenUsage[] {\n return [...this.usage.values()];\n }\n}\n","import { type InterruptAddress, decodeInterruptId } from './interrupt-id.js';\nimport type {\n AgUiContentPart,\n AgUiContext,\n AgUiMessage,\n AgUiResumeEntry,\n AgUiRunInput,\n} from './types.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Read a request body as a `RunAgentInput`, or say why it is not one.\n *\n * Only what this producer acts on is checked, and a KNOWN member with a value the schema rejects is\n * malformed (the run never starts). A member it does not recognise is not an error — the protocol's\n * asymmetry: a newer consumer's input must not bounce off an older producer.\n */\nexport function parseRunInput(body: unknown): AgUiRunInput | string {\n if (!isRecord(body)) return 'the body must be a RunAgentInput object';\n if (typeof body.threadId !== 'string' || body.threadId.length === 0) {\n return 'threadId must be a non-empty string';\n }\n if (body.threadId.length > 255) return 'threadId must be at most 255 characters';\n if (typeof body.runId !== 'string' || body.runId.length === 0) {\n return 'runId must be a non-empty string';\n }\n if (!Array.isArray(body.messages)) return 'messages must be an array';\n for (const message of body.messages) {\n if (!isRecord(message) || typeof message.role !== 'string') {\n return 'each message must be an object with a role';\n }\n }\n if (body.resume !== undefined) {\n if (!Array.isArray(body.resume)) return 'resume must be an array';\n for (const entry of body.resume) {\n if (\n !isRecord(entry) ||\n typeof entry.interruptId !== 'string' ||\n (entry.status !== 'resolved' && entry.status !== 'cancelled')\n ) {\n return \"each resume entry needs an interruptId and a status of 'resolved' or 'cancelled'\";\n }\n }\n }\n if (body.context !== undefined && !Array.isArray(body.context)) {\n return 'context must be an array';\n }\n return body as unknown as AgUiRunInput;\n}\n\n/** A media part carried inline, ready to be staged as an attachment. */\nexport interface InlineMedia {\n kind: 'image' | 'audio' | 'video' | 'document';\n contentType: string;\n data: Buffer;\n filename: string;\n}\n\nexport interface UserTurn {\n /** The text of the message the run answers. */\n text: string;\n media: InlineMedia[];\n /** Why a part was not used, one sentence each — reported, never fatal. */\n dropped: string[];\n}\n\nconst EXTENSIONS: Record<string, string> = {\n 'image/png': 'png',\n 'image/jpeg': 'jpg',\n 'image/gif': 'gif',\n 'image/webp': 'webp',\n 'application/pdf': 'pdf',\n 'text/plain': 'txt',\n};\n\nfunction filenameOf(part: AgUiContentPart, index: number, contentType: string): string {\n const metadata = (part as { metadata?: unknown }).metadata;\n if (isRecord(metadata)) {\n for (const key of ['filename', 'name', 'title']) {\n const value = metadata[key];\n if (typeof value === 'string' && value.trim().length > 0) return value.trim().slice(0, 200);\n }\n }\n const extension = EXTENSIONS[contentType];\n return `${part.type}-${index + 1}${extension !== undefined ? `.${extension}` : ''}`;\n}\n\n/**\n * The turn a run answers: the LAST user message of the input. The library keeps each thread's\n * history itself, so the earlier messages the consumer restates are not read back in — what the\n * agent resumes from is what it stored.\n *\n * Multimodal parts: text parts are the message's text; a media part carried inline (`data`) becomes\n * an attachment. A part by `url` or by provider `file` handle is dropped and said so — this producer\n * hands the model only bytes it staged itself, never an address a caller supplied.\n */\nexport function readUserTurn(messages: readonly AgUiMessage[]): UserTurn | null {\n let last: AgUiMessage | undefined;\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n if (messages[index]?.role === 'user') {\n last = messages[index];\n break;\n }\n }\n if (last === undefined) return null;\n if (typeof last.content === 'string') return { text: last.content, media: [], dropped: [] };\n if (!Array.isArray(last.content)) return { text: '', media: [], dropped: [] };\n\n const texts: string[] = [];\n const media: InlineMedia[] = [];\n const dropped: string[] = [];\n last.content.forEach((part, index) => {\n if (!isRecord(part)) return;\n if (part.type === 'text') {\n if (typeof part.text === 'string') texts.push(part.text);\n return;\n }\n if (\n part.type !== 'image' &&\n part.type !== 'audio' &&\n part.type !== 'video' &&\n part.type !== 'document'\n ) {\n return;\n }\n const source = part.source;\n if (!isRecord(source) || source.type !== 'data') {\n const how = isRecord(source) && typeof source.type === 'string' ? source.type : 'unknown';\n dropped.push(\n `The ${part.type} part ${index + 1} was not used: only inline data is accepted, not a ${how} source.`,\n );\n return;\n }\n if (typeof source.value !== 'string' || typeof source.mimeType !== 'string') {\n dropped.push(\n `The ${part.type} part ${index + 1} was not used: its inline data is malformed.`,\n );\n return;\n }\n const data = Buffer.from(source.value, 'base64');\n if (data.length === 0) {\n dropped.push(`The ${part.type} part ${index + 1} was not used: it carries no bytes.`);\n return;\n }\n const contentType = source.mimeType.toLowerCase();\n media.push({\n kind: part.type,\n contentType,\n data,\n filename: filenameOf(part as AgUiContentPart, index, contentType),\n });\n });\n return { text: texts.join('\\n'), media, dropped };\n}\n\n/** `context` entries as the library's page context carries them, or `undefined` for none. */\nexport function readContext(\n context: readonly AgUiContext[] | undefined,\n): AgUiContext[] | undefined {\n if (context === undefined) return undefined;\n const entries = context.filter(\n (entry) =>\n isRecord(entry) && typeof entry.description === 'string' && typeof entry.value === 'string',\n );\n return entries.length > 0 ? entries : undefined;\n}\n\n/**\n * What the library reads from `forwardedProps` — the consumer's channel for what AG-UI does not\n * model: which agent, which model, which persona, and the page context the tools see.\n */\nexport interface ForwardedOptions {\n agent?: string;\n model?: string;\n persona?: string;\n pageContext?: Record<string, unknown>;\n}\n\nexport function readForwardedProps(forwarded: unknown): ForwardedOptions {\n if (!isRecord(forwarded)) return {};\n const pick = (key: string): string | undefined => {\n const value = forwarded[key];\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n };\n const agent = pick('agent');\n const model = pick('model');\n const persona = pick('persona');\n return {\n ...(agent !== undefined ? { agent } : {}),\n ...(model !== undefined ? { model } : {}),\n ...(persona !== undefined ? { persona } : {}),\n ...(isRecord(forwarded.pageContext) ? { pageContext: forwarded.pageContext } : {}),\n };\n}\n\n/** One resume entry this producer can act on. */\nexport interface ResumeDecision {\n address: InterruptAddress;\n entry: AgUiResumeEntry;\n}\n\nexport interface ResumePlan {\n decisions: ResumeDecision[];\n /** Entries naming an interrupt this producer did not raise: skipped with a warning, never fatal. */\n unrecognised: string[];\n}\n\n/**\n * Sort a resume list into what it answers. Every recognised entry must continue the SAME library\n * run from the SAME point — they are the interrupts of one `RUN_FINISHED` — and a list that does not\n * is malformed (a string says why).\n */\nexport function planResume(resume: readonly AgUiResumeEntry[]): ResumePlan | string {\n const decisions: ResumeDecision[] = [];\n const unrecognised: string[] = [];\n for (const entry of resume) {\n const address = decodeInterruptId(entry.interruptId);\n if (address === null) {\n unrecognised.push(entry.interruptId);\n continue;\n }\n decisions.push({ address, entry });\n }\n const first = decisions[0];\n if (first === undefined) return { decisions, unrecognised };\n for (const { address } of decisions) {\n if (address.stream !== first.address.stream || address.position !== first.address.position) {\n return 'the resume entries answer interrupts of different runs';\n }\n }\n const seen = new Set<string>();\n for (const { address } of decisions) {\n if (seen.has(address.toolCallId)) return 'an interrupt is answered twice';\n seen.add(address.toolCallId);\n }\n return { decisions, unrecognised };\n}\n\n/** `{ approved, reason?, remember? }` out of an approval's resume payload. A bare boolean is accepted. */\nexport function readApprovalPayload(payload: unknown): {\n approved: boolean;\n reason?: string;\n remember?: boolean;\n} | null {\n if (typeof payload === 'boolean') return { approved: payload };\n if (!isRecord(payload) || typeof payload.approved !== 'boolean') return null;\n return {\n approved: payload.approved,\n ...(typeof payload.reason === 'string' ? { reason: payload.reason } : {}),\n ...(typeof payload.remember === 'boolean' ? { remember: payload.remember } : {}),\n };\n}\n\n/** `questionId → string[]` out of an elicitation's resume payload (`{ answers }` or the map itself). */\nexport function readAnswersPayload(payload: unknown): Record<string, string[]> | null {\n const source = isRecord(payload) && isRecord(payload.answers) ? payload.answers : payload;\n if (!isRecord(source)) return null;\n const answers: Record<string, string[]> = {};\n for (const [key, value] of Object.entries(source)) {\n if (typeof value === 'string') answers[key] = [value];\n else if (Array.isArray(value) && value.every((item) => typeof item === 'string')) {\n answers[key] = value as string[];\n } else return null;\n }\n return answers;\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\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 { 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 /**\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 /** 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 { AgentStreamError } from '../spi/token-stream-sink.js';\nimport { decodeStreamEvent } from '../stream-events.js';\nimport { AgUiEncoder, type AgUiEncoderOptions } from './encoder.js';\nimport type { AgUiEvent, AgUiSourceFrame } from './types.js';\n\nexport interface AgUiStreamOptions extends AgUiEncoderOptions {\n /**\n * How long the library stream may stay silent, while the run waits on a person AND has other work\n * announced, before the AG-UI run is reported interrupted. Default 750 ms.\n *\n * Only that mixed case needs a clock. A run whose every open tool call is waiting on someone is\n * reported at once; a run waiting on no one is never cut short.\n */\n quietMs?: number;\n /** Events to write right after `RUN_STARTED` (warnings about input that was dropped). */\n preamble?: AgUiEvent[];\n}\n\nconst DEFAULT_QUIET_MS = 750;\nconst GRACE_MS = 50;\n\ntype Next = IteratorResult<AgUiSourceFrame> | 'quiet';\n\n/**\n * One AG-UI run over a library run's stream.\n *\n * AG-UI has no mid-run channel from the consumer: a run that needs an approval or an answer does not\n * wait with the connection open — it ENDS, saying what it waits for, and a later run carries the\n * answers. The library run underneath does wait (parked, durably when the runner is durable). So this\n * stops reading when the run is waiting on someone and nothing else is moving, closes the AG-UI run\n * with the interrupt outcome, and leaves the library run parked for the resume to pick up.\n */\nexport async function* agUiEvents(\n frames: AsyncIterable<AgUiSourceFrame>,\n options: AgUiStreamOptions,\n): AsyncGenerator<AgUiEvent> {\n const encoder = new AgUiEncoder(options);\n const quietMs = options.quietMs ?? DEFAULT_QUIET_MS;\n yield* encoder.start();\n yield* options.preamble ?? [];\n const iterator = frames[Symbol.asyncIterator]();\n let upcoming: Promise<IteratorResult<AgUiSourceFrame>> | undefined;\n let ended = false;\n try {\n for (;;) {\n upcoming ??= iterator.next();\n // Frames buffered before this reader attached are replayed without a pause between them, so\n // \"is it waiting?\" is only asked of a stream that has caught up with what it already holds.\n const caughtUp = encoder.consumed >= (options.skip ?? 0);\n let next: Next;\n if (caughtUp && encoder.waiting) {\n // Nothing else in flight: only a frame already on its way (a sink that reads in batches)\n // can still arrive, so a short grace is enough. Otherwise wait out the quiet window.\n next = await raceQuiet(upcoming, encoder.busy ? quietMs : Math.min(quietMs, GRACE_MS));\n } else {\n next = await upcoming;\n }\n if (next === 'quiet') break;\n upcoming = undefined;\n if (next.done === true) {\n ended = true;\n break;\n }\n yield* encoder.encode(next.value);\n }\n } finally {\n // Stop following the library stream; the run it carries is left exactly as it is.\n void iterator.return?.();\n }\n yield* encoder.finish(ended);\n}\n\nfunction raceQuiet(upcoming: Promise<IteratorResult<AgUiSourceFrame>>, ms: number): Promise<Next> {\n return new Promise<Next>((resolve, reject) => {\n const timer = setTimeout(() => resolve('quiet'), ms);\n upcoming.then(\n (result) => {\n clearTimeout(timer);\n resolve(result);\n },\n (error: unknown) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n}\n\n/** One AG-UI event as an SSE frame: a single `data:` line, LF-terminated, as the binding pins. */\nexport function agUiSse(event: AgUiEvent): string {\n return `data: ${JSON.stringify(event)}\\n\\n`;\n}\n\n/**\n * A byte sink's stream (NDJSON {@link AgentStreamEvent}s, one per line, as the NestJS sinks carry\n * it) as the frames the encoder reads. A line that is not a stream event is bare model text — the\n * sink is a byte channel and a provider may write raw text into it. A run that failed ends the\n * sink with an {@link AgentStreamError}, which becomes the terminal `error` frame; anything else\n * thrown is rethrown, for the caller to report.\n */\nexport async function* agUiFramesFromNdjson(\n chunks: AsyncIterable<Uint8Array>,\n): AsyncGenerator<AgUiSourceFrame> {\n const decoder = new TextDecoder();\n let buffer = '';\n // Bare text has no line end of its own, so the event written after it shares its line.\n const read = (line: string): AgUiSourceFrame[] => {\n const event = decodeStreamEvent(line) as AgUiSourceFrame | null;\n if (event !== null) return [event];\n const at = line.indexOf('{\"kind\":');\n const tail = at > 0 ? (decodeStreamEvent(line.slice(at)) as AgUiSourceFrame | null) : null;\n if (tail !== null) return [{ kind: 'text', text: line.slice(0, at) }, tail];\n return [{ kind: 'text', text: line }];\n };\n try {\n for await (const chunk of chunks) {\n buffer += decoder.decode(chunk, { stream: true });\n let newline = buffer.indexOf('\\n');\n while (newline !== -1) {\n const line = buffer.slice(0, newline);\n buffer = buffer.slice(newline + 1);\n if (line.length > 0) yield* read(line);\n newline = buffer.indexOf('\\n');\n }\n }\n buffer += decoder.decode();\n if (buffer.length > 0) yield* read(buffer);\n } catch (error) {\n if (error instanceof AgentStreamError) {\n yield { kind: 'error', code: error.code, message: error.message };\n return;\n }\n throw error;\n }\n}\n"],"mappings":"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","names":["PREFIX","encodeInterruptId","address","compact","kind","parked","stream","toolCallId","position","Buffer","from","JSON","stringify","toString","decodeInterruptId","id","startsWith","parsed","parse","slice","length","Array","isArray","Number","isSafeInteger","AG_UI_PROTOCOL_VERSION","AG_UI_CUSTOM","run","ui","title","queue","approvalRequested","approvalSettled","elicitation","stepUsage","warning","APPROVAL_SCHEMA","type","properties","approved","reason","remember","required","elicitationSchema","request","question","questions","options","map","option","value","id","title","prompt","description","undefined","items","length","allowFreeText","enum","multiple","maxItems","defaults","default","answers","text","json","JSON","stringify","AgUiEncoder","position","started","closed","cancelled","crossed","messageSeq","stepSeq","openText","openReasoning","stepMessage","openSteps","calls","Map","pending","usage","consumed","waiting","size","busy","call","answered","has","start","threadId","runId","protocolVersion","AG_UI_PROTOCOL_VERSION","name","AG_UI_CUSTOM","run","streamRunId","streamThreadId","encode","frame","skip","crossBoundary","events","project","values","ended","delete","replaying","event","kind","usageEntries","message","code","custom","ui","component","props","version","toolCallId","get","parked","toolName","input","set","interrupt","responseSchema","expiresAt","metadata","approver","approvalRequested","preamble","elicitation","textDelta","reasoningDelta","stepName","push","closeStreams","out","addUsage","model","pop","costUsd","stepUsage","reasoningMs","sawDelta","callStart","delta","known","result","output","error","approvalSettled","queue","finish","clear","interrupts","outcome","entry","encodeInterruptId","stream","nextMessageId","closeReasoning","messageId","role","closeText","toolCallName","parentMessageId","content","key","inputTokens","outputTokens","totalTokens","cacheReadTokens","cachedInputTokens","cacheWriteTokens","cacheWriteInputTokens","reasoningTokens","isRecord","value","Array","isArray","parseRunInput","body","threadId","length","runId","messages","message","role","resume","undefined","entry","interruptId","status","context","EXTENSIONS","filenameOf","part","index","contentType","metadata","key","trim","slice","extension","type","readUserTurn","last","content","text","media","dropped","texts","forEach","push","source","how","mimeType","data","Buffer","from","toLowerCase","kind","filename","join","readContext","entries","filter","description","readForwardedProps","forwarded","pick","agent","model","persona","pageContext","planResume","decisions","unrecognised","address","decodeInterruptId","first","stream","position","seen","Set","has","toolCallId","add","readApprovalPayload","payload","approved","reason","remember","readAnswersPayload","answers","Object","every","item","AgentStreamError","Error","code","error","message","name","encoder","TextEncoder","decodeStreamEvent","line","parsed","JSON","parse","kind","DEFAULT_QUIET_MS","GRACE_MS","agUiEvents","frames","options","encoder","AgUiEncoder","quietMs","start","preamble","iterator","Symbol","asyncIterator","upcoming","ended","next","caughtUp","consumed","skip","waiting","raceQuiet","busy","Math","min","undefined","done","encode","value","return","finish","ms","Promise","resolve","reject","timer","setTimeout","then","result","clearTimeout","error","agUiSse","event","JSON","stringify","agUiFramesFromNdjson","chunks","decoder","TextDecoder","buffer","read","line","decodeStreamEvent","at","indexOf","tail","slice","kind","text","chunk","decode","stream","newline","length","AgentStreamError","code","message"]}
|
|
1
|
+
{"version":3,"sources":["../../src/ag-ui/index.ts","../../src/ag-ui/interrupt-id.ts","../../src/ag-ui/types.ts","../../src/ag-ui/encoder.ts","../../src/ag-ui/input.ts","../../src/spi/token-stream-sink.ts","../../src/stream-events.ts","../../src/ag-ui/stream.ts"],"sourcesContent":["/**\n * AG-UI 1.0 (https://docs.ag-ui.com/spec/1.0), producer side, framework-free: the encoder that\n * projects a run's stream onto AG-UI events, the stream driver that ends a run when it stops to\n * ask, and the readers for `RunAgentInput`. `@dudousxd/nestjs-agent` serves it as\n * `POST <path>/ag-ui` (`adapters: [agUiAdapter()]`); `@adonis-agora/agent` serves the same encoder.\n */\n\nexport { AgUiEncoder, type AgUiEncoderOptions } from './encoder.js';\nexport {\n type ForwardedOptions,\n type InlineMedia,\n parseRunInput,\n planResume,\n type ResumeDecision,\n type ResumePlan,\n readAnswersPayload,\n readApprovalPayload,\n readContext,\n readForwardedProps,\n readUserTurn,\n type UserTurn,\n} from './input.js';\nexport { decodeInterruptId, encodeInterruptId, type InterruptAddress } from './interrupt-id.js';\nexport { type AgUiStreamOptions, agUiEvents, agUiFramesFromNdjson, agUiSse } from './stream.js';\nexport * from './types.js';\n","/**\n * An interrupt's id carries everything a resuming request needs, so the producer keeps NOTHING\n * between the run that stopped to ask and the run that answers — the statelessness AG-UI lets a\n * producer have, and what lets any replica serve the resume.\n *\n * It names the library run the human is answering (`parked` — a delegated sub-agent parks its OWN\n * run), the run whose stream carries the work (`stream`), the tool call, and how many of that\n * stream's frames the interrupted AG-UI run already delivered (`position`), which is where the\n * resuming run picks the stream up.\n *\n * It is an address, not a credential: the resume route checks the caller owns the run exactly as\n * the native approve/answer routes do.\n */\nexport interface InterruptAddress {\n kind: 'approval' | 'elicitation';\n /** The run to settle the call on. */\n parked: string;\n /** The run whose buffered stream the resume re-attaches to. */\n stream: string;\n toolCallId: string;\n /** Frames of `stream` already delivered when the run was reported interrupted. */\n position: number;\n}\n\nconst PREFIX = 'agora_';\n\nexport function encodeInterruptId(address: InterruptAddress): string {\n const compact = [\n address.kind === 'approval' ? 'a' : 'e',\n address.parked,\n address.stream,\n address.toolCallId,\n address.position,\n ];\n return PREFIX + Buffer.from(JSON.stringify(compact), 'utf8').toString('base64url');\n}\n\n/** The address an id names, or `null` for an id this producer did not mint. */\nexport function decodeInterruptId(id: unknown): InterruptAddress | null {\n if (typeof id !== 'string' || !id.startsWith(PREFIX)) return null;\n try {\n const parsed: unknown = JSON.parse(\n Buffer.from(id.slice(PREFIX.length), 'base64url').toString('utf8'),\n );\n if (!Array.isArray(parsed) || parsed.length !== 5) return null;\n const [kind, parked, stream, toolCallId, position] = parsed as unknown[];\n if (\n (kind !== 'a' && kind !== 'e') ||\n typeof parked !== 'string' ||\n typeof stream !== 'string' ||\n typeof toolCallId !== 'string' ||\n typeof position !== 'number' ||\n !Number.isSafeInteger(position) ||\n position < 0\n ) {\n return null;\n }\n return {\n kind: kind === 'a' ? 'approval' : 'elicitation',\n parked,\n stream,\n toolCallId,\n position,\n };\n } catch {\n return null;\n }\n}\n","import type { AgentStreamEvent } from '../stream-events.js';\n\n/**\n * The slice of AG-UI 1.0 (https://docs.ag-ui.com/spec/1.0) this producer writes and reads. Typed by\n * hand rather than imported: the agent package takes no dependency on an AG-UI SDK, and the wire\n * shape is pinned by the protocol's own JSON Schema, which the tests validate every emitted event\n * against (`src/ag-ui/fixtures/schema-1.0.json`).\n *\n * Optional members are OMITTED when there is nothing to say, never `null` — the protocol's\n * \"absent means absent\" rule.\n */\n\n/** The protocol version this producer declares on `RUN_STARTED`. */\nexport const AG_UI_PROTOCOL_VERSION = '1.0';\n\nexport type AgUiMetadata = Record<string, unknown>;\n\n/** One provider-and-model's token usage, in the protocol's single accounting. */\nexport interface AgUiTokenUsage {\n provider?: string;\n model?: string;\n /** Every prompt token, cached or not. */\n inputTokens?: number;\n /** Every generated token, reasoning included. */\n outputTokens?: number;\n totalTokens?: number;\n /** Part of `outputTokens`. */\n reasoningTokens?: number;\n /** Cache reads — part of `inputTokens`. */\n cachedInputTokens?: number;\n /** Cache writes — part of `inputTokens`, disjoint from the reads. */\n cacheWriteInputTokens?: number;\n}\n\n/** What an interrupted run is waiting for; a resume entry answers it by `id`. */\nexport interface AgUiInterrupt {\n id: string;\n /** Open string. This producer writes `tool_approval` and `input_required`. */\n reason: string;\n message?: string;\n toolCallId?: string;\n responseSchema?: Record<string, unknown>;\n expiresAt?: string;\n metadata?: AgUiMetadata;\n}\n\nexport type AgUiRunOutcome =\n | { type: 'success'; pendingToolCallIds?: string[] }\n | { type: 'interrupt'; interrupts: AgUiInterrupt[] }\n | { type: 'cancelled' };\n\ninterface Base {\n metadata?: AgUiMetadata;\n}\n\nexport type AgUiEvent =\n | (Base & { type: 'RUN_STARTED'; threadId: string; runId: string; protocolVersion?: string })\n | (Base & {\n type: 'RUN_FINISHED';\n threadId: string;\n runId: string;\n outcome?: AgUiRunOutcome;\n usage?: AgUiTokenUsage[];\n })\n | (Base & { type: 'RUN_ERROR'; message: string; code?: string; usage?: AgUiTokenUsage[] })\n | (Base & { type: 'STEP_STARTED'; stepName: string })\n | (Base & { type: 'STEP_FINISHED'; stepName: string })\n | (Base & { type: 'TEXT_MESSAGE_START'; messageId: string; role: 'assistant' })\n | (Base & { type: 'TEXT_MESSAGE_CONTENT'; messageId: string; delta: string })\n | (Base & { type: 'TEXT_MESSAGE_END'; messageId: string })\n | (Base & { type: 'REASONING_START'; messageId: string })\n | (Base & { type: 'REASONING_MESSAGE_START'; messageId: string; role: 'reasoning' })\n | (Base & { type: 'REASONING_MESSAGE_CONTENT'; messageId: string; delta: string })\n | (Base & { type: 'REASONING_MESSAGE_END'; messageId: string })\n | (Base & { type: 'REASONING_END'; messageId: string })\n | (Base & {\n type: 'TOOL_CALL_START';\n toolCallId: string;\n toolCallName: string;\n parentMessageId?: string;\n })\n | (Base & { type: 'TOOL_CALL_ARGS'; toolCallId: string; delta: string })\n | (Base & { type: 'TOOL_CALL_END'; toolCallId: string })\n | (Base & {\n type: 'TOOL_CALL_RESULT';\n messageId: string;\n toolCallId: string;\n content: string;\n role: 'tool';\n })\n | (Base & { type: 'CUSTOM'; name: string; value: unknown });\n\n/** Where a media part's bytes are. Closed set: an unknown `type` is malformed input. */\nexport type AgUiPartSource =\n | { type: 'data'; value: string; mimeType: string }\n | { type: 'url'; value: string; mimeType?: string }\n | { type: 'file'; value: string; provider?: string; mimeType?: string };\n\nexport type AgUiContentPart =\n | { type: 'text'; text: string; id?: string; metadata?: unknown }\n | {\n type: 'image' | 'audio' | 'video' | 'document';\n source: AgUiPartSource;\n id?: string;\n metadata?: unknown;\n };\n\nexport interface AgUiMessage {\n id: string;\n role: string;\n content?: string | AgUiContentPart[];\n [key: string]: unknown;\n}\n\nexport interface AgUiResumeEntry {\n interruptId: string;\n status: 'resolved' | 'cancelled';\n payload?: unknown;\n metadata?: AgUiMetadata;\n}\n\nexport interface AgUiContext {\n description: string;\n value: string;\n}\n\n/** `RunAgentInput`: the one message that travels from the application to the agent. */\nexport interface AgUiRunInput {\n threadId: string;\n runId: string;\n protocolVersion?: string;\n parentRunId?: string;\n state?: unknown;\n messages: AgUiMessage[];\n tools?: unknown[];\n context?: AgUiContext[];\n forwardedProps?: unknown;\n resume?: AgUiResumeEntry[];\n}\n\n/**\n * The names of the `CUSTOM` events this producer writes for what AG-UI does not model. Prefixed, as\n * the protocol asks of invented names; a consumer that does not know one ignores it.\n */\nexport const AG_UI_CUSTOM = {\n /** `{ runId, threadId }` — the library's own ids for the run behind this stream (cancel, re-attach). */\n run: 'agora.run',\n /** A generative-UI component (`AgentUiComponent`); a repeat `id` replaces. */\n ui: 'agora.ui',\n title: 'agora.title',\n queue: 'agora.queue',\n /** The approval request as the native protocol carries it, for a consumer that renders it live. */\n approvalRequested: 'agora.approval-requested',\n approvalSettled: 'agora.approval-settled',\n /** The whole question set of an elicitation (`ElicitationRequest`). */\n elicitation: 'agora.elicitation',\n /** `{ usage, costUsd, reasoningMs }` of one model step. */\n stepUsage: 'agora.step-usage',\n /** `{ message }` — input material this producer could not use and dropped. */\n warning: 'agora.warning',\n} as const;\n\n/**\n * What the encoder reads: one frame of a run's stream, in the shared vocabulary\n * ({@link AgentStreamEvent}) — plus the terminal failure, which the NestJS sink throws and the\n * Adonis sink writes as a frame, and three optional facts a sink may know about a parked call:\n * - `runId` — the run that is PARKED, when it is not the one whose stream this is (a delegated\n * sub-agent forwards its frames into its ancestor's stream). Absent → the stream's own run.\n * - `toolName`, `input` — the call being approved. Absent → read off the call's announcement.\n *\n * Framework-free on purpose: both servers project their own sink onto this and share one encoder.\n */\nexport type AgUiSourceFrame =\n | Exclude<\n AgentStreamEvent,\n { kind: 'approval-requested' } | { kind: 'elicitation' } | { kind: 'ui' }\n >\n | (Extract<AgentStreamEvent, { kind: 'approval-requested' }> & {\n runId?: string;\n toolName?: string;\n input?: unknown;\n })\n | (Extract<AgentStreamEvent, { kind: 'elicitation' }> & { runId?: string })\n /** A component with no `id` is numbered by its position in the stream (`ui:<n>`). */\n | (Omit<Extract<AgentStreamEvent, { kind: 'ui' }>, 'id' | 'props'> & {\n id?: string;\n props: unknown;\n })\n /** The run failed: the AG-UI run ends with `RUN_ERROR`, and nothing follows it. */\n | { kind: 'error'; code: string; message: string };\n","import type { ElicitationRequest } from '../elicitation.js';\nimport type { MessageUsage } from '../types.js';\nimport { encodeInterruptId } from './interrupt-id.js';\nimport {\n AG_UI_CUSTOM,\n AG_UI_PROTOCOL_VERSION,\n type AgUiEvent,\n type AgUiInterrupt,\n type AgUiSourceFrame,\n type AgUiTokenUsage,\n} from './types.js';\n\nexport interface AgUiEncoderOptions {\n /** The ids the consumer sent on `RunAgentInput`: every boundary event echoes them. */\n threadId: string;\n runId: string;\n /** The library run whose stream is being projected (it mints interrupt ids and the `agora.run` event). */\n streamRunId: string;\n /** The library's thread id, when it differs from what the consumer calls the thread. */\n streamThreadId?: string;\n /**\n * Frames of the library run's stream that an earlier AG-UI run already delivered (a resume). They\n * are fed to the encoder like any other — it has to know what they opened — but produce no events.\n */\n skip?: number;\n /**\n * Tool calls a resuming request just answered. The run has not necessarily said so yet — a parked\n * run takes a moment to wake — so without this the encoder would read them as still waiting and\n * report the interrupt again before the answer had any effect.\n */\n answered?: readonly string[];\n /** Model id for the usage entry when the step frames carry none. */\n model?: string;\n}\n\ninterface OpenCall {\n name: string;\n /** The arguments it was announced with, for an approval frame that does not repeat them. */\n input?: unknown;\n /** `TOOL_CALL_START` was written in THIS run (a resumed run meets results of calls it never saw open). */\n started: boolean;\n ended: boolean;\n sawDelta: boolean;\n answered: boolean;\n}\n\ninterface Pending {\n interrupt: Omit<AgUiInterrupt, 'id'>;\n kind: 'approval' | 'elicitation';\n parked: string;\n toolCallId: string;\n}\n\nconst APPROVAL_SCHEMA = {\n type: 'object',\n properties: {\n approved: { type: 'boolean' },\n reason: { type: 'string' },\n remember: { type: 'boolean' },\n },\n required: ['approved'],\n};\n\n/** The answer an elicitation expects: `{ answers: { <questionId>: string[] } }`. */\nfunction elicitationSchema(request: ElicitationRequest): Record<string, unknown> {\n const properties: Record<string, unknown> = {};\n for (const question of request.questions) {\n const options = question.options?.map((option) => option.value);\n properties[question.id] = {\n type: 'array',\n title: question.prompt,\n ...(question.description !== undefined ? { description: question.description } : {}),\n items:\n options !== undefined && options.length > 0 && question.allowFreeText !== true\n ? { type: 'string', enum: options }\n : { type: 'string' },\n ...(question.multiple === true ? {} : { maxItems: 1 }),\n ...(question.defaults !== undefined ? { default: question.defaults } : {}),\n };\n }\n return {\n type: 'object',\n properties: { answers: { type: 'object', properties } },\n required: ['answers'],\n };\n}\n\nfunction text(value: unknown): string {\n if (typeof value === 'string') return value;\n const json = JSON.stringify(value);\n return json === undefined ? '' : json;\n}\n\n/**\n * Projects one library run's stream ({@link AgUiSourceFrame}s, in buffer order) onto AG-UI 1.0 events.\n *\n * A pure state machine: the same frames always give the same events, which is what lets a resuming\n * request — served by any replica — replay the run's buffer, skip what the interrupted AG-UI run\n * already delivered, and continue. It writes nothing itself; {@link agUiEvents} drives it and\n * decides when the run has stopped to ask.\n *\n * What maps where:\n * - `text` → `TEXT_MESSAGE_*` (one message per stretch of text);\n * - `reasoning` → a reasoning span with one reasoning message;\n * - `step-start`/`step-finish` → `STEP_STARTED`/`STEP_FINISHED`, the step's usage folded into the\n * run's `usage`;\n * - `tool-input-*` → `TOOL_CALL_START`/`ARGS`/`END`; `tool-output*` → `TOOL_CALL_RESULT`;\n * - an approval or a question set the run parks on → an `Interrupt` on the closing `RUN_FINISHED`;\n * - `cancelled` → the cancelled outcome; an error frame → `RUN_ERROR`;\n * - generative UI, title, queue and the native approval/elicitation frames → `CUSTOM` events named\n * in {@link AG_UI_CUSTOM}, for what AG-UI has no event for.\n *\n * Not mapped: sub-agent attribution (`subagentRunId`) — a delegated agent's frames are projected\n * flat, as the protocol allows of a producer that does not attribute.\n */\nexport class AgUiEncoder {\n private position = 0;\n private started = false;\n private closed = false;\n private cancelled = false;\n private crossed = false;\n private messageSeq = 0;\n private stepSeq = 0;\n private openText: string | undefined;\n private openReasoning: string | undefined;\n /** The last text message of the current step: a tool call attaches to it. */\n private stepMessage: string | undefined;\n private readonly openSteps: string[] = [];\n private readonly calls = new Map<string, OpenCall>();\n private readonly pending = new Map<string, Pending>();\n private readonly usage = new Map<string, AgUiTokenUsage>();\n\n constructor(private readonly options: AgUiEncoderOptions) {}\n\n /** How many frames of the library stream this encoder has consumed. */\n get consumed(): number {\n return this.position;\n }\n\n /** The run is waiting on at least one approval or question set nobody has settled yet. */\n get waiting(): boolean {\n return this.pending.size > 0;\n }\n\n /**\n * Is anything still in flight that is NOT waiting on a person — a tool call announced and neither\n * answered nor parked? While there is, more frames are coming without anyone's help.\n */\n get busy(): boolean {\n for (const [id, call] of this.calls) {\n if (!call.answered && !this.pending.has(id)) return true;\n }\n return false;\n }\n\n /** `RUN_STARTED`, and the library's own ids for the run. Call once, before the first frame. */\n start(): AgUiEvent[] {\n if (this.started) return [];\n this.started = true;\n return [\n {\n type: 'RUN_STARTED',\n threadId: this.options.threadId,\n runId: this.options.runId,\n protocolVersion: AG_UI_PROTOCOL_VERSION,\n },\n {\n type: 'CUSTOM',\n name: AG_UI_CUSTOM.run,\n value: {\n runId: this.options.streamRunId,\n threadId: this.options.streamThreadId ?? this.options.threadId,\n },\n },\n ];\n }\n\n /** The AG-UI events the next frame of the library stream stands for (possibly none). */\n encode(frame: AgUiSourceFrame): AgUiEvent[] {\n const position = this.position;\n this.position += 1;\n if (this.closed) return [];\n const skip = this.options.skip ?? 0;\n if (!this.crossed && position >= skip) this.crossBoundary();\n const events = this.project(frame, position);\n // A frame an earlier AG-UI run already delivered still moves the state (what is open, what is\n // pending; NOT what was spent — usage is per run) but writes nothing. The last of them is the\n // boundary: crossed at once, not when the next frame happens to arrive, because a run that was\n // just answered may take a moment to write one.\n if (position < skip) {\n if (this.position >= skip) this.crossBoundary();\n return [];\n }\n return events;\n }\n\n /**\n * The replayed frames are behind us: from here on events are written. The AG-UI run that delivered\n * them closed everything it had open before it finished, so this run starts with nothing open, and\n * what the resuming request answered is no longer waiting.\n */\n private crossBoundary(): void {\n this.crossed = true;\n this.openText = undefined;\n this.openReasoning = undefined;\n this.stepMessage = undefined;\n this.openSteps.length = 0;\n for (const call of this.calls.values()) {\n call.started = false;\n call.ended = true;\n }\n for (const id of this.options.answered ?? []) this.pending.delete(id);\n }\n\n private get replaying(): boolean {\n return this.position <= (this.options.skip ?? 0);\n }\n\n private project(event: AgUiSourceFrame, position: number): AgUiEvent[] {\n switch (event.kind) {\n case 'error': {\n this.closed = true;\n const usage = this.usageEntries();\n return [\n {\n type: 'RUN_ERROR',\n message: event.message,\n code: event.code,\n ...(usage.length > 0 ? { usage } : {}),\n },\n ];\n }\n case 'ui':\n return [\n this.custom(AG_UI_CUSTOM.ui, {\n id: event.id ?? `ui:${position}`,\n component: event.component,\n props: event.props,\n ...(event.version !== undefined ? { version: event.version } : {}),\n ...(event.toolCallId !== undefined ? { toolCallId: event.toolCallId } : {}),\n }),\n ];\n case 'approval-requested': {\n const call = this.calls.get(event.id);\n const parked = event.runId ?? this.options.streamRunId;\n const toolName = event.toolName ?? call?.name ?? '';\n const input = event.input ?? call?.input ?? null;\n this.pending.set(event.id, {\n kind: 'approval',\n parked,\n toolCallId: event.id,\n interrupt: {\n reason: 'tool_approval',\n message: event.reason ?? (toolName.length > 0 ? `Approve ${toolName}?` : 'Approve?'),\n toolCallId: event.id,\n responseSchema: APPROVAL_SCHEMA,\n ...(event.expiresAt !== undefined ? { expiresAt: event.expiresAt } : {}),\n metadata: {\n 'agora.toolName': toolName,\n 'agora.input': input,\n 'agora.approver': event.approver,\n },\n },\n });\n return [\n this.custom(AG_UI_CUSTOM.approvalRequested, {\n id: event.id,\n runId: parked,\n toolName,\n input,\n approver: event.approver,\n ...(event.expiresAt !== undefined ? { expiresAt: event.expiresAt } : {}),\n ...(event.reason !== undefined ? { reason: event.reason } : {}),\n }),\n ];\n }\n case 'elicitation': {\n const parked = event.runId ?? this.options.streamRunId;\n this.pending.set(event.id, {\n kind: 'elicitation',\n parked,\n toolCallId: event.id,\n interrupt: {\n reason: 'input_required',\n message:\n event.request.preamble ?? event.request.questions[0]?.prompt ?? 'Input required',\n // An intake's question set belongs to no tool call the stream announced.\n ...(this.calls.has(event.id) ? { toolCallId: event.id } : {}),\n responseSchema: elicitationSchema(event.request),\n metadata: { 'agora.request': event.request },\n },\n });\n return [this.custom(AG_UI_CUSTOM.elicitation, { runId: parked, request: event.request })];\n }\n case 'text':\n return event.text.length > 0 ? this.textDelta(event.text) : [];\n case 'reasoning':\n return event.text.length > 0 ? this.reasoningDelta(event.text) : [];\n case 'step-start': {\n this.stepSeq += 1;\n const stepName = `step-${this.stepSeq}`;\n this.openSteps.push(stepName);\n this.stepMessage = undefined;\n return [...this.closeStreams(), { type: 'STEP_STARTED', stepName }];\n }\n case 'step-finish': {\n const out = this.closeStreams();\n if (!this.replaying) this.addUsage(event.usage, event.model);\n const stepName = this.openSteps.pop();\n if (stepName !== undefined) out.push({ type: 'STEP_FINISHED', stepName });\n if (event.usage !== undefined || event.costUsd !== undefined) {\n out.push(\n this.custom(AG_UI_CUSTOM.stepUsage, {\n ...(event.usage !== undefined ? { usage: event.usage } : {}),\n ...(event.costUsd !== undefined ? { costUsd: event.costUsd } : {}),\n ...(event.reasoningMs !== undefined ? { reasoningMs: event.reasoningMs } : {}),\n }),\n );\n }\n return out;\n }\n case 'tool-input-start': {\n if (this.calls.has(event.id)) return [];\n const out = this.closeStreams();\n this.calls.set(event.id, {\n name: event.name,\n started: true,\n ended: false,\n sawDelta: false,\n answered: false,\n });\n out.push(this.callStart(event.id, event.name));\n return out;\n }\n case 'tool-input-delta': {\n const call = this.calls.get(event.id);\n if (call === undefined || call.ended || event.delta.length === 0) return [];\n call.sawDelta = true;\n return [{ type: 'TOOL_CALL_ARGS', toolCallId: event.id, delta: event.delta }];\n }\n case 'tool-input-available': {\n const known = this.calls.get(event.id);\n if (known?.ended === true) return [];\n const out = this.closeStreams();\n const call = known ?? {\n name: event.name,\n started: false,\n ended: false,\n sawDelta: false,\n answered: false,\n };\n if (!call.started) {\n call.started = true;\n out.push(this.callStart(event.id, event.name));\n }\n if (!call.sawDelta) {\n out.push({\n type: 'TOOL_CALL_ARGS',\n toolCallId: event.id,\n delta: text(event.input ?? {}),\n });\n }\n call.ended = true;\n call.input = event.input;\n this.calls.set(event.id, call);\n out.push({ type: 'TOOL_CALL_END', toolCallId: event.id });\n return out;\n }\n case 'tool-output':\n return this.result(event.id, text(event.output));\n case 'tool-output-error':\n return this.result(event.id, event.error, { 'agora.outcome': 'error' });\n case 'tool-output-denied':\n return this.result(event.id, event.reason ?? 'denied', { 'agora.outcome': 'denied' });\n case 'approval-settled':\n this.pending.delete(event.id);\n return [this.custom(AG_UI_CUSTOM.approvalSettled, event)];\n case 'title':\n return [this.custom(AG_UI_CUSTOM.title, { title: event.title })];\n case 'queue':\n return [\n this.custom(AG_UI_CUSTOM.queue, {\n queue: event.queue,\n ...(event.started !== undefined ? { started: event.started } : {}),\n }),\n ];\n case 'cancelled':\n this.cancelled = true;\n return [];\n default:\n // A kind newer than this encoder: tolerated, as every reader of the stream must.\n return [];\n }\n }\n\n /**\n * The events that end the AG-UI run: whatever is still open is closed first, then `RUN_FINISHED`\n * with how it ended — interrupted when the run is waiting on someone, cancelled when it was\n * stopped, success otherwise. Nothing after a `RUN_ERROR`. `ended` says the library run's stream\n * itself ended, rather than this reader having stopped following it.\n */\n finish(ended = false): AgUiEvent[] {\n if (this.closed) return [];\n this.closed = true;\n if (!this.crossed) this.crossBoundary();\n // A library run that ended is waiting on no one, whatever it asked along the way.\n if (ended) this.pending.clear();\n const out = this.start();\n out.push(...this.closeStreams());\n for (const [id, call] of this.calls) {\n if (call.started && !call.ended) {\n call.ended = true;\n out.push({ type: 'TOOL_CALL_END', toolCallId: id });\n }\n }\n while (this.openSteps.length > 0) {\n out.push({ type: 'STEP_FINISHED', stepName: this.openSteps.pop() as string });\n }\n const usage = this.usageEntries();\n const interrupts = this.cancelled ? [] : this.interrupts();\n out.push({\n type: 'RUN_FINISHED',\n threadId: this.options.threadId,\n runId: this.options.runId,\n ...(this.cancelled\n ? { outcome: { type: 'cancelled' as const } }\n : interrupts.length > 0\n ? { outcome: { type: 'interrupt' as const, interrupts } }\n : {}),\n ...(usage.length > 0 ? { usage } : {}),\n });\n return out;\n }\n\n private interrupts(): AgUiInterrupt[] {\n return [...this.pending.values()].map((entry) => ({\n id: encodeInterruptId({\n kind: entry.kind,\n parked: entry.parked,\n stream: this.options.streamRunId,\n toolCallId: entry.toolCallId,\n position: this.position,\n }),\n ...entry.interrupt,\n }));\n }\n\n private custom(name: string, value: unknown): AgUiEvent {\n return { type: 'CUSTOM', name, value };\n }\n\n private nextMessageId(): string {\n this.messageSeq += 1;\n return `${this.options.runId}:m${this.messageSeq}`;\n }\n\n private textDelta(delta: string): AgUiEvent[] {\n const out: AgUiEvent[] = [];\n if (this.openReasoning !== undefined) out.push(...this.closeReasoning());\n if (this.openText === undefined) {\n this.openText = this.nextMessageId();\n this.stepMessage = this.openText;\n out.push({ type: 'TEXT_MESSAGE_START', messageId: this.openText, role: 'assistant' });\n }\n out.push({ type: 'TEXT_MESSAGE_CONTENT', messageId: this.openText, delta });\n return out;\n }\n\n private reasoningDelta(delta: string): AgUiEvent[] {\n const out: AgUiEvent[] = [];\n if (this.openText !== undefined) out.push(...this.closeText());\n if (this.openReasoning === undefined) {\n this.openReasoning = this.nextMessageId();\n out.push(\n { type: 'REASONING_START', messageId: this.openReasoning },\n { type: 'REASONING_MESSAGE_START', messageId: this.openReasoning, role: 'reasoning' },\n );\n }\n out.push({ type: 'REASONING_MESSAGE_CONTENT', messageId: this.openReasoning, delta });\n return out;\n }\n\n private closeText(): AgUiEvent[] {\n if (this.openText === undefined) return [];\n const messageId = this.openText;\n this.openText = undefined;\n return [{ type: 'TEXT_MESSAGE_END', messageId }];\n }\n\n private closeReasoning(): AgUiEvent[] {\n if (this.openReasoning === undefined) return [];\n const messageId = this.openReasoning;\n this.openReasoning = undefined;\n return [\n { type: 'REASONING_MESSAGE_END', messageId },\n { type: 'REASONING_END', messageId },\n ];\n }\n\n private closeStreams(): AgUiEvent[] {\n return [...this.closeReasoning(), ...this.closeText()];\n }\n\n private callStart(id: string, name: string): AgUiEvent {\n return {\n type: 'TOOL_CALL_START',\n toolCallId: id,\n toolCallName: name,\n ...(this.stepMessage !== undefined ? { parentMessageId: this.stepMessage } : {}),\n };\n }\n\n private result(id: string, content: string, metadata?: Record<string, unknown>): AgUiEvent[] {\n const call = this.calls.get(id);\n if (call !== undefined) call.answered = true;\n else {\n this.calls.set(id, {\n name: '',\n started: false,\n ended: true,\n sawDelta: false,\n answered: true,\n });\n }\n this.pending.delete(id);\n return [\n ...this.closeStreams(),\n {\n type: 'TOOL_CALL_RESULT',\n messageId: `${this.options.runId}:tool:${id}`,\n toolCallId: id,\n content,\n role: 'tool',\n ...(metadata !== undefined ? { metadata } : {}),\n },\n ];\n }\n\n private addUsage(usage: MessageUsage | undefined, model: unknown): void {\n if (usage === undefined) return;\n const name = typeof model === 'string' && model.length > 0 ? model : this.options.model;\n const key = name ?? '';\n const entry = this.usage.get(key) ?? (name !== undefined ? { model: name } : {});\n // The library's accounting is already the protocol's: input and output are totals, cache and\n // reasoning counts are parts of them. A count the provider did not report stays absent.\n entry.inputTokens = (entry.inputTokens ?? 0) + usage.inputTokens;\n entry.outputTokens = (entry.outputTokens ?? 0) + usage.outputTokens;\n entry.totalTokens = entry.inputTokens + entry.outputTokens;\n if (usage.cacheReadTokens !== undefined) {\n entry.cachedInputTokens = (entry.cachedInputTokens ?? 0) + usage.cacheReadTokens;\n }\n if (usage.cacheWriteTokens !== undefined) {\n entry.cacheWriteInputTokens = (entry.cacheWriteInputTokens ?? 0) + usage.cacheWriteTokens;\n }\n if (usage.reasoningTokens !== undefined) {\n entry.reasoningTokens = (entry.reasoningTokens ?? 0) + usage.reasoningTokens;\n }\n this.usage.set(key, entry);\n }\n\n private usageEntries(): AgUiTokenUsage[] {\n return [...this.usage.values()];\n }\n}\n","import { type InterruptAddress, decodeInterruptId } from './interrupt-id.js';\nimport type {\n AgUiContentPart,\n AgUiContext,\n AgUiMessage,\n AgUiResumeEntry,\n AgUiRunInput,\n} from './types.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Read a request body as a `RunAgentInput`, or say why it is not one.\n *\n * Only what this producer acts on is checked, and a KNOWN member with a value the schema rejects is\n * malformed (the run never starts). A member it does not recognise is not an error — the protocol's\n * asymmetry: a newer consumer's input must not bounce off an older producer.\n */\nexport function parseRunInput(body: unknown): AgUiRunInput | string {\n if (!isRecord(body)) return 'the body must be a RunAgentInput object';\n if (typeof body.threadId !== 'string' || body.threadId.length === 0) {\n return 'threadId must be a non-empty string';\n }\n if (body.threadId.length > 255) return 'threadId must be at most 255 characters';\n if (typeof body.runId !== 'string' || body.runId.length === 0) {\n return 'runId must be a non-empty string';\n }\n if (!Array.isArray(body.messages)) return 'messages must be an array';\n for (const message of body.messages) {\n if (!isRecord(message) || typeof message.role !== 'string') {\n return 'each message must be an object with a role';\n }\n }\n if (body.resume !== undefined) {\n if (!Array.isArray(body.resume)) return 'resume must be an array';\n for (const entry of body.resume) {\n if (\n !isRecord(entry) ||\n typeof entry.interruptId !== 'string' ||\n (entry.status !== 'resolved' && entry.status !== 'cancelled')\n ) {\n return \"each resume entry needs an interruptId and a status of 'resolved' or 'cancelled'\";\n }\n }\n }\n if (body.context !== undefined && !Array.isArray(body.context)) {\n return 'context must be an array';\n }\n return body as unknown as AgUiRunInput;\n}\n\n/** A media part carried inline, ready to be staged as an attachment. */\nexport interface InlineMedia {\n kind: 'image' | 'audio' | 'video' | 'document';\n contentType: string;\n data: Buffer;\n filename: string;\n}\n\nexport interface UserTurn {\n /** The text of the message the run answers. */\n text: string;\n media: InlineMedia[];\n /** Why a part was not used, one sentence each — reported, never fatal. */\n dropped: string[];\n}\n\nconst EXTENSIONS: Record<string, string> = {\n 'image/png': 'png',\n 'image/jpeg': 'jpg',\n 'image/gif': 'gif',\n 'image/webp': 'webp',\n 'application/pdf': 'pdf',\n 'text/plain': 'txt',\n};\n\nfunction filenameOf(part: AgUiContentPart, index: number, contentType: string): string {\n const metadata = (part as { metadata?: unknown }).metadata;\n if (isRecord(metadata)) {\n for (const key of ['filename', 'name', 'title']) {\n const value = metadata[key];\n if (typeof value === 'string' && value.trim().length > 0) return value.trim().slice(0, 200);\n }\n }\n const extension = EXTENSIONS[contentType];\n return `${part.type}-${index + 1}${extension !== undefined ? `.${extension}` : ''}`;\n}\n\n/**\n * The turn a run answers: the LAST user message of the input. The library keeps each thread's\n * history itself, so the earlier messages the consumer restates are not read back in — what the\n * agent resumes from is what it stored.\n *\n * Multimodal parts: text parts are the message's text; a media part carried inline (`data`) becomes\n * an attachment. A part by `url` or by provider `file` handle is dropped and said so — this producer\n * hands the model only bytes it staged itself, never an address a caller supplied.\n */\nexport function readUserTurn(messages: readonly AgUiMessage[]): UserTurn | null {\n let last: AgUiMessage | undefined;\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n if (messages[index]?.role === 'user') {\n last = messages[index];\n break;\n }\n }\n if (last === undefined) return null;\n if (typeof last.content === 'string') return { text: last.content, media: [], dropped: [] };\n if (!Array.isArray(last.content)) return { text: '', media: [], dropped: [] };\n\n const texts: string[] = [];\n const media: InlineMedia[] = [];\n const dropped: string[] = [];\n last.content.forEach((part, index) => {\n if (!isRecord(part)) return;\n if (part.type === 'text') {\n if (typeof part.text === 'string') texts.push(part.text);\n return;\n }\n if (\n part.type !== 'image' &&\n part.type !== 'audio' &&\n part.type !== 'video' &&\n part.type !== 'document'\n ) {\n return;\n }\n const source = part.source;\n if (!isRecord(source) || source.type !== 'data') {\n const how = isRecord(source) && typeof source.type === 'string' ? source.type : 'unknown';\n dropped.push(\n `The ${part.type} part ${index + 1} was not used: only inline data is accepted, not a ${how} source.`,\n );\n return;\n }\n if (typeof source.value !== 'string' || typeof source.mimeType !== 'string') {\n dropped.push(\n `The ${part.type} part ${index + 1} was not used: its inline data is malformed.`,\n );\n return;\n }\n const data = Buffer.from(source.value, 'base64');\n if (data.length === 0) {\n dropped.push(`The ${part.type} part ${index + 1} was not used: it carries no bytes.`);\n return;\n }\n const contentType = source.mimeType.toLowerCase();\n media.push({\n kind: part.type,\n contentType,\n data,\n filename: filenameOf(part as AgUiContentPart, index, contentType),\n });\n });\n return { text: texts.join('\\n'), media, dropped };\n}\n\n/** `context` entries as the library's page context carries them, or `undefined` for none. */\nexport function readContext(\n context: readonly AgUiContext[] | undefined,\n): AgUiContext[] | undefined {\n if (context === undefined) return undefined;\n const entries = context.filter(\n (entry) =>\n isRecord(entry) && typeof entry.description === 'string' && typeof entry.value === 'string',\n );\n return entries.length > 0 ? entries : undefined;\n}\n\n/**\n * What the library reads from `forwardedProps` — the consumer's channel for what AG-UI does not\n * model: which agent, which model, which persona, and the page context the tools see.\n */\nexport interface ForwardedOptions {\n agent?: string;\n model?: string;\n persona?: string;\n pageContext?: Record<string, unknown>;\n}\n\nexport function readForwardedProps(forwarded: unknown): ForwardedOptions {\n if (!isRecord(forwarded)) return {};\n const pick = (key: string): string | undefined => {\n const value = forwarded[key];\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n };\n const agent = pick('agent');\n const model = pick('model');\n const persona = pick('persona');\n return {\n ...(agent !== undefined ? { agent } : {}),\n ...(model !== undefined ? { model } : {}),\n ...(persona !== undefined ? { persona } : {}),\n ...(isRecord(forwarded.pageContext) ? { pageContext: forwarded.pageContext } : {}),\n };\n}\n\n/** One resume entry this producer can act on. */\nexport interface ResumeDecision {\n address: InterruptAddress;\n entry: AgUiResumeEntry;\n}\n\nexport interface ResumePlan {\n decisions: ResumeDecision[];\n /** Entries naming an interrupt this producer did not raise: skipped with a warning, never fatal. */\n unrecognised: string[];\n}\n\n/**\n * Sort a resume list into what it answers. Every recognised entry must continue the SAME library\n * run from the SAME point — they are the interrupts of one `RUN_FINISHED` — and a list that does not\n * is malformed (a string says why).\n */\nexport function planResume(resume: readonly AgUiResumeEntry[]): ResumePlan | string {\n const decisions: ResumeDecision[] = [];\n const unrecognised: string[] = [];\n for (const entry of resume) {\n const address = decodeInterruptId(entry.interruptId);\n if (address === null) {\n unrecognised.push(entry.interruptId);\n continue;\n }\n decisions.push({ address, entry });\n }\n const first = decisions[0];\n if (first === undefined) return { decisions, unrecognised };\n for (const { address } of decisions) {\n if (address.stream !== first.address.stream || address.position !== first.address.position) {\n return 'the resume entries answer interrupts of different runs';\n }\n }\n const seen = new Set<string>();\n for (const { address } of decisions) {\n if (seen.has(address.toolCallId)) return 'an interrupt is answered twice';\n seen.add(address.toolCallId);\n }\n return { decisions, unrecognised };\n}\n\n/** `{ approved, reason?, remember? }` out of an approval's resume payload. A bare boolean is accepted. */\nexport function readApprovalPayload(payload: unknown): {\n approved: boolean;\n reason?: string;\n remember?: boolean;\n} | null {\n if (typeof payload === 'boolean') return { approved: payload };\n if (!isRecord(payload) || typeof payload.approved !== 'boolean') return null;\n return {\n approved: payload.approved,\n ...(typeof payload.reason === 'string' ? { reason: payload.reason } : {}),\n ...(typeof payload.remember === 'boolean' ? { remember: payload.remember } : {}),\n };\n}\n\n/** `questionId → string[]` out of an elicitation's resume payload (`{ answers }` or the map itself). */\nexport function readAnswersPayload(payload: unknown): Record<string, string[]> | null {\n const source = isRecord(payload) && isRecord(payload.answers) ? payload.answers : payload;\n if (!isRecord(source)) return null;\n const answers: Record<string, string[]> = {};\n for (const [key, value] of Object.entries(source)) {\n if (typeof value === 'string') answers[key] = [value];\n else if (Array.isArray(value) && value.every((item) => typeof item === 'string')) {\n answers[key] = value as string[];\n } else return null;\n }\n return answers;\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 { 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 /**\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 /** 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 { AgentStreamError } from '../spi/token-stream-sink.js';\nimport { decodeStreamEvent } from '../stream-events.js';\nimport { AgUiEncoder, type AgUiEncoderOptions } from './encoder.js';\nimport type { AgUiEvent, AgUiSourceFrame } from './types.js';\n\nexport interface AgUiStreamOptions extends AgUiEncoderOptions {\n /**\n * How long the library stream may stay silent, while the run waits on a person AND has other work\n * announced, before the AG-UI run is reported interrupted. Default 750 ms.\n *\n * Only that mixed case needs a clock. A run whose every open tool call is waiting on someone is\n * reported at once; a run waiting on no one is never cut short.\n */\n quietMs?: number;\n /** Events to write right after `RUN_STARTED` (warnings about input that was dropped). */\n preamble?: AgUiEvent[];\n}\n\nconst DEFAULT_QUIET_MS = 750;\nconst GRACE_MS = 50;\n\ntype Next = IteratorResult<AgUiSourceFrame> | 'quiet';\n\n/**\n * One AG-UI run over a library run's stream.\n *\n * AG-UI has no mid-run channel from the consumer: a run that needs an approval or an answer does not\n * wait with the connection open — it ENDS, saying what it waits for, and a later run carries the\n * answers. The library run underneath does wait (parked, durably when the runner is durable). So this\n * stops reading when the run is waiting on someone and nothing else is moving, closes the AG-UI run\n * with the interrupt outcome, and leaves the library run parked for the resume to pick up.\n */\nexport async function* agUiEvents(\n frames: AsyncIterable<AgUiSourceFrame>,\n options: AgUiStreamOptions,\n): AsyncGenerator<AgUiEvent> {\n const encoder = new AgUiEncoder(options);\n const quietMs = options.quietMs ?? DEFAULT_QUIET_MS;\n yield* encoder.start();\n yield* options.preamble ?? [];\n const iterator = frames[Symbol.asyncIterator]();\n let upcoming: Promise<IteratorResult<AgUiSourceFrame>> | undefined;\n let ended = false;\n try {\n for (;;) {\n upcoming ??= iterator.next();\n // Frames buffered before this reader attached are replayed without a pause between them, so\n // \"is it waiting?\" is only asked of a stream that has caught up with what it already holds.\n const caughtUp = encoder.consumed >= (options.skip ?? 0);\n let next: Next;\n if (caughtUp && encoder.waiting) {\n // Nothing else in flight: only a frame already on its way (a sink that reads in batches)\n // can still arrive, so a short grace is enough. Otherwise wait out the quiet window.\n next = await raceQuiet(upcoming, encoder.busy ? quietMs : Math.min(quietMs, GRACE_MS));\n } else {\n next = await upcoming;\n }\n if (next === 'quiet') break;\n upcoming = undefined;\n if (next.done === true) {\n ended = true;\n break;\n }\n yield* encoder.encode(next.value);\n }\n } finally {\n // Stop following the library stream; the run it carries is left exactly as it is.\n void iterator.return?.();\n }\n yield* encoder.finish(ended);\n}\n\nfunction raceQuiet(upcoming: Promise<IteratorResult<AgUiSourceFrame>>, ms: number): Promise<Next> {\n return new Promise<Next>((resolve, reject) => {\n const timer = setTimeout(() => resolve('quiet'), ms);\n upcoming.then(\n (result) => {\n clearTimeout(timer);\n resolve(result);\n },\n (error: unknown) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n}\n\n/** One AG-UI event as an SSE frame: a single `data:` line, LF-terminated, as the binding pins. */\nexport function agUiSse(event: AgUiEvent): string {\n return `data: ${JSON.stringify(event)}\\n\\n`;\n}\n\n/**\n * A byte sink's stream (NDJSON {@link AgentStreamEvent}s, one per line, as the NestJS sinks carry\n * it) as the frames the encoder reads. A line that is not a stream event is bare model text — the\n * sink is a byte channel and a provider may write raw text into it. A run that failed ends the\n * sink with an {@link AgentStreamError}, which becomes the terminal `error` frame; anything else\n * thrown is rethrown, for the caller to report.\n */\nexport async function* agUiFramesFromNdjson(\n chunks: AsyncIterable<Uint8Array>,\n): AsyncGenerator<AgUiSourceFrame> {\n const decoder = new TextDecoder();\n let buffer = '';\n // Bare text has no line end of its own, so the event written after it shares its line.\n const read = (line: string): AgUiSourceFrame[] => {\n const event = decodeStreamEvent(line) as AgUiSourceFrame | null;\n if (event !== null) return [event];\n const at = line.indexOf('{\"kind\":');\n const tail = at > 0 ? (decodeStreamEvent(line.slice(at)) as AgUiSourceFrame | null) : null;\n if (tail !== null) return [{ kind: 'text', text: line.slice(0, at) }, tail];\n return [{ kind: 'text', text: line }];\n };\n try {\n for await (const chunk of chunks) {\n buffer += decoder.decode(chunk, { stream: true });\n let newline = buffer.indexOf('\\n');\n while (newline !== -1) {\n const line = buffer.slice(0, newline);\n buffer = buffer.slice(newline + 1);\n if (line.length > 0) yield* read(line);\n newline = buffer.indexOf('\\n');\n }\n }\n buffer += decoder.decode();\n if (buffer.length > 0) yield* read(buffer);\n } catch (error) {\n if (error instanceof AgentStreamError) {\n yield { kind: 'error', code: error.code, message: error.message };\n return;\n }\n throw error;\n }\n}\n"],"mappings":"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","names":["PREFIX","encodeInterruptId","address","compact","kind","parked","stream","toolCallId","position","Buffer","from","JSON","stringify","toString","decodeInterruptId","id","startsWith","parsed","parse","slice","length","Array","isArray","Number","isSafeInteger","AG_UI_PROTOCOL_VERSION","AG_UI_CUSTOM","run","ui","title","queue","approvalRequested","approvalSettled","elicitation","stepUsage","warning","APPROVAL_SCHEMA","type","properties","approved","reason","remember","required","elicitationSchema","request","question","questions","options","map","option","value","id","title","prompt","description","undefined","items","length","allowFreeText","enum","multiple","maxItems","defaults","default","answers","text","json","JSON","stringify","AgUiEncoder","position","started","closed","cancelled","crossed","messageSeq","stepSeq","openText","openReasoning","stepMessage","openSteps","calls","Map","pending","usage","consumed","waiting","size","busy","call","answered","has","start","threadId","runId","protocolVersion","AG_UI_PROTOCOL_VERSION","name","AG_UI_CUSTOM","run","streamRunId","streamThreadId","encode","frame","skip","crossBoundary","events","project","values","ended","delete","replaying","event","kind","usageEntries","message","code","custom","ui","component","props","version","toolCallId","get","parked","toolName","input","set","interrupt","responseSchema","expiresAt","metadata","approver","approvalRequested","preamble","elicitation","textDelta","reasoningDelta","stepName","push","closeStreams","out","addUsage","model","pop","costUsd","stepUsage","reasoningMs","sawDelta","callStart","delta","known","result","output","error","approvalSettled","queue","finish","clear","interrupts","outcome","entry","encodeInterruptId","stream","nextMessageId","closeReasoning","messageId","role","closeText","toolCallName","parentMessageId","content","key","inputTokens","outputTokens","totalTokens","cacheReadTokens","cachedInputTokens","cacheWriteTokens","cacheWriteInputTokens","reasoningTokens","isRecord","value","Array","isArray","parseRunInput","body","threadId","length","runId","messages","message","role","resume","undefined","entry","interruptId","status","context","EXTENSIONS","filenameOf","part","index","contentType","metadata","key","trim","slice","extension","type","readUserTurn","last","content","text","media","dropped","texts","forEach","push","source","how","mimeType","data","Buffer","from","toLowerCase","kind","filename","join","readContext","entries","filter","description","readForwardedProps","forwarded","pick","agent","model","persona","pageContext","planResume","decisions","unrecognised","address","decodeInterruptId","first","stream","position","seen","Set","has","toolCallId","add","readApprovalPayload","payload","approved","reason","remember","readAnswersPayload","answers","Object","every","item","AgentStreamError","Error","code","error","message","name","encoder","TextEncoder","decodeStreamEvent","line","parsed","JSON","parse","kind","DEFAULT_QUIET_MS","GRACE_MS","agUiEvents","frames","options","encoder","AgUiEncoder","quietMs","start","preamble","iterator","Symbol","asyncIterator","upcoming","ended","next","caughtUp","consumed","skip","waiting","raceQuiet","busy","Math","min","undefined","done","encode","value","return","finish","ms","Promise","resolve","reject","timer","setTimeout","then","result","clearTimeout","error","agUiSse","event","JSON","stringify","agUiFramesFromNdjson","chunks","decoder","TextDecoder","buffer","read","line","decodeStreamEvent","at","indexOf","tail","slice","kind","text","chunk","decode","stream","newline","length","AgentStreamError","code","message"]}
|
package/dist/ag-ui/index.d.cts
CHANGED
package/dist/ag-ui/index.d.ts
CHANGED