@aparte/runner-ag-ui 0.20.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/dist/enforce.d.ts +19 -0
- package/dist/enforce.d.ts.map +1 -0
- package/dist/index.js +569 -19
- package/dist/index.js.map +1 -1
- package/dist/messages.d.ts +4 -3
- package/dist/messages.d.ts.map +1 -1
- package/dist/runner.d.ts +24 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/state.d.ts +13 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/translate.d.ts +18 -0
- package/dist/translate.d.ts.map +1 -0
- package/dist/verify.d.ts +26 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/wire.d.ts +15 -2
- package/dist/wire.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/messages.ts","../src/wire.ts","../src/runner.ts"],"sourcesContent":["import { contentToText } from '@aparte/core';\nimport type { AparteChatMessage, AparteTool } from '@aparte/core';\nimport type { AgUiMessage, AgUiRunAgentInput } from './wire.js';\n\n/**\n * aparté's history as `RunAgentInput.messages`. Every message gets an id (the protocol\n * requires one) that is stable across the runs of one turn — its position — so a resume\n * replays the same history the paused run saw. A call is `{ id, type: 'function',\n * function: { name, arguments } }` with the arguments as a JSON string, and a result is\n * a `tool` message naming its call. Content goes as text: an image part has no AG-UI\n * shape every agent reads, so it is left out rather than guessed.\n */\nexport function toAgUiMessages(messages: readonly AparteChatMessage[]): AgUiMessage[] {\n const out: AgUiMessage[] = [];\n messages.forEach((m, index) => {\n const id = `aparte-${index}`;\n const content = contentToText(m.content);\n if (m.role === 'system' || m.role === 'user') {\n out.push({ id, role: m.role, content });\n } else if (m.role === 'assistant') {\n out.push({\n id,\n role: 'assistant',\n ...(content ? { content } : {}),\n ...(m.toolCalls?.length\n ? {\n toolCalls: m.toolCalls.map((call) => ({\n id: call.id,\n type: 'function' as const,\n function: { name: call.name, arguments: JSON.stringify(call.input ?? {}) },\n })),\n }\n : {}),\n });\n } else if (m.role === 'tool' && m.toolCallId) {\n out.push({ id, role: 'tool', content, toolCallId: m.toolCallId });\n }\n });\n return out;\n}\n\n/** The page's tools as `RunAgentInput.tools`: the ones the agent may ask the browser to run. */\nexport function toAgUiTools(tools: readonly AparteTool[] | undefined): AgUiRunAgentInput['tools'] {\n return (tools ?? []).map((tool) => ({ name: tool.name, description: tool.description, parameters: tool.inputSchema }));\n}\n","/**\n * The AG-UI wire, as much of it as aparté reads — typed here rather than taken from\n * `@ag-ui/core`, whose client pulls rxjs, zod and protobuf into a bundle that only\n * needs to read JSON lines. Field names follow the protocol (docs.ag-ui.com, 1.0).\n */\n\n/** An interrupt an agent ends its run on (`RUN_FINISHED.outcome`). */\nexport interface AgUiInterrupt {\n id: string;\n /** `tool_call`, `confirmation`, `input_required`, or a producer's own string. */\n reason: string;\n message?: string;\n toolCallId?: string;\n responseSchema?: unknown;\n metadata?: Record<string, unknown>;\n}\n\n/** The events the runner maps; any other `type` is read and ignored. */\nexport type AgUiEvent =\n | { type: 'RUN_STARTED'; threadId?: string; runId?: string }\n | {\n type: 'RUN_FINISHED';\n threadId?: string;\n runId?: string;\n outcome?: { type: 'success' } | { type: 'interrupt'; interrupts: AgUiInterrupt[] };\n /** TanStack AI reports usage here, as an array. */\n usage?: unknown;\n }\n | { type: 'RUN_ERROR'; message?: string; code?: string }\n | { type: 'TEXT_MESSAGE_START'; messageId?: string; role?: string }\n | { type: 'TEXT_MESSAGE_CONTENT'; messageId?: string; delta?: string }\n | { type: 'TEXT_MESSAGE_END'; messageId?: string }\n | { type: 'TEXT_MESSAGE_CHUNK'; messageId?: string; role?: string; delta?: string }\n | { type: 'REASONING_MESSAGE_CONTENT'; messageId?: string; delta?: string }\n | { type: 'REASONING_MESSAGE_CHUNK'; messageId?: string; delta?: string }\n | { type: 'TOOL_CALL_START'; toolCallId: string; toolCallName: string; parentMessageId?: string }\n | { type: 'TOOL_CALL_ARGS'; toolCallId: string; delta?: string }\n | { type: 'TOOL_CALL_END'; toolCallId: string }\n | { type: 'TOOL_CALL_CHUNK'; toolCallId?: string; toolCallName?: string; delta?: string }\n | { type: 'TOOL_CALL_RESULT'; toolCallId: string; content?: unknown; metadata?: Record<string, unknown> };\n\n/** One message of `RunAgentInput.messages`. */\nexport type AgUiMessage =\n | { id: string; role: 'system'; content: string }\n | { id: string; role: 'user'; content: string }\n | {\n id: string;\n role: 'assistant';\n content?: string;\n toolCalls?: { id: string; type: 'function'; function: { name: string; arguments: string } }[];\n }\n | { id: string; role: 'tool'; content: string; toolCallId: string };\n\n/** One entry of `RunAgentInput.resume`: the answer to one interrupt. */\nexport interface AgUiResumeItem {\n interruptId: string;\n status: 'resolved' | 'cancelled';\n payload?: unknown;\n metadata?: Record<string, unknown>;\n}\n\n/** The request body an AG-UI agent endpoint takes. */\nexport interface AgUiRunAgentInput {\n threadId: string;\n runId: string;\n parentRunId?: string;\n state: Record<string, unknown>;\n messages: AgUiMessage[];\n tools: { name: string; description: string; parameters: unknown }[];\n context: { description: string; value: string }[];\n forwardedProps: Record<string, unknown>;\n resume?: AgUiResumeItem[];\n}\n\n/**\n * The events of an AG-UI response, in order. Server-Sent Events by default — each\n * `data:` block is one JSON event, comments and `event:` lines are skipped, and a\n * `[DONE]` sentinel ends nothing on its own. An NDJSON body (one event per line, the\n * other encoding TanStack AI serves) is read the same way. A block that is not JSON\n * is skipped: a proxy's keep-alive must not end the run.\n */\nexport async function* readAgUiEvents(\n body: ReadableStream<Uint8Array>,\n contentType: string | null,\n): AsyncGenerator<{ type: string } & Record<string, unknown>> {\n const ndjson = Boolean(contentType && /ndjson|jsonl/i.test(contentType));\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let data: string[] = [];\n const parse = (text: string): ({ type: string } & Record<string, unknown>) | undefined => {\n const trimmed = text.trim();\n if (!trimmed || trimmed === '[DONE]') return undefined;\n try {\n const value = JSON.parse(trimmed) as unknown;\n return value && typeof value === 'object' && typeof (value as { type?: unknown }).type === 'string'\n ? value as { type: string } & Record<string, unknown>\n : undefined;\n } catch {\n return undefined;\n }\n };\n const takeBlock = () => {\n const event = parse(data.join('\\n'));\n data = [];\n return event;\n };\n const line = (raw: string) => {\n const text = raw.endsWith('\\r') ? raw.slice(0, -1) : raw;\n if (ndjson) return parse(text);\n if (text === '') return takeBlock();\n if (text.startsWith('data:')) data.push(text.slice(5).replace(/^ /, ''));\n // `event:`, `id:`, `retry:` and `:` comments: AG-UI carries the type in the JSON.\n return undefined;\n };\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n let newline: number;\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const event = line(buffer.slice(0, newline));\n buffer = buffer.slice(newline + 1);\n if (event) yield event;\n }\n }\n buffer += decoder.decode();\n if (buffer) {\n const event = line(buffer);\n if (event) yield event;\n }\n if (!ndjson) {\n const event = takeBlock();\n if (event) yield event;\n }\n } finally {\n reader.releaseLock();\n }\n}\n","import { AparteError, AparteErrorCode, uuid } from '@aparte/core';\nimport type {\n AparteChatRequest,\n AparteStreamRunEvent,\n AparteStreamRunner,\n AparteStreamRunOptions,\n} from '@aparte/core';\nimport { toAgUiMessages, toAgUiTools } from './messages.js';\nimport { readAgUiEvents } from './wire.js';\nimport type { AgUiInterrupt, AgUiMessage, AgUiResumeItem, AgUiRunAgentInput } from './wire.js';\n\ntype Suspended = Extract<AparteStreamRunEvent, { type: 'run-suspended' }>;\ntype PendingCall = Suspended['pending'][number];\ntype Usage = NonNullable<Extract<AparteStreamRunEvent, { type: 'run-done' }>['usage']>;\ntype Outcome = NonNullable<NonNullable<AparteStreamRunOptions['deferral']>['outcomes']>[string];\n\nexport interface AgUiRunnerOptions {\n /** The agent's AG-UI endpoint, e.g. Agno's `/agui`, or a TanStack AI chat route. */\n endpoint: string;\n /** Sent with every request; a function is called per request (a fresh token each time). */\n headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);\n /** @default the global `fetch` */\n fetch?: typeof fetch;\n /** For a cross-origin endpoint that authenticates by cookie. */\n credentials?: RequestCredentials;\n /**\n * The AG-UI thread a turn runs in. Give the conversation's id when the agent keeps\n * state per thread (Agno's session); a function receives the run's options. A paused\n * run is always resumed in its own thread, whatever this returns.\n * @default a new thread per turn — the agent gets the whole history every time\n */\n threadId?: string | ((opts: AparteStreamRunOptions) => string);\n /** `RunAgentInput.forwardedProps`: settings your agent reads from the request. */\n forwardedProps?: Record<string, unknown>;\n /** `RunAgentInput.context`: extra context entries for the agent. */\n context?: { description: string; value: string }[];\n}\n\n/**\n * What a paused run hands the page and gets back with the answers — `deferral.token`.\n * Opaque to the client; the runner reads it to resume in the same thread, after the\n * run it continues, with the interrupts it must answer.\n */\ninterface Ticket {\n v: 1;\n threadId: string;\n runId: string;\n interrupts: { id: string; toolCallId: string; kind: 'approval' | 'external' }[];\n}\n\nfunction readTicket(token: string | undefined): Ticket | undefined {\n if (!token) return undefined;\n try {\n const ticket = JSON.parse(token) as Ticket;\n return ticket && ticket.v === 1 && typeof ticket.threadId === 'string' && typeof ticket.runId === 'string'\n && Array.isArray(ticket.interrupts) ? ticket : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** An interrupt's reason, as what the page must do about its call. */\nfunction interruptKind(interrupt: AgUiInterrupt): 'approval' | 'external' | undefined {\n if (interrupt.reason === 'tool_call' || interrupt.reason === 'confirmation') return 'approval';\n if (/client_tool/.test(interrupt.reason)) return 'external';\n return undefined;\n}\n\n/**\n * Usage as AG-UI agents report it — an object, or TanStack AI's array of model steps — as\n * the LAST step's report. That is what the page's own loop reports for a run of several\n * turns, and what the context gauge reads: the size of the conversation the model last saw.\n * Summed, a three-step run read as three times the context it used.\n */\nfunction readUsage(value: unknown): Usage | undefined {\n const entries = (Array.isArray(value) ? value : value && typeof value === 'object' ? [value] : [])\n .filter((u): u is Record<string, unknown> => Boolean(u) && typeof u === 'object');\n const last = entries.at(-1);\n if (!last) return undefined;\n const num = (key: string): number => (typeof last[key] === 'number' ? last[key] as number : 0);\n const cached = num('cachedInputTokens');\n return {\n inputTokens: num('inputTokens'),\n outputTokens: num('outputTokens'),\n totalTokens: num('totalTokens') || undefined,\n ...(cached ? { cacheReadTokens: cached } : {}),\n } as Usage;\n}\n\n/** A call's streamed arguments as its input: `{}` for none, the raw text when not JSON. */\nfunction parseArgs(args: string): unknown {\n if (!args.trim()) return {};\n try { return JSON.parse(args); } catch { return { arguments: args }; }\n}\n\n/** A tool result as the row shows it: text as is, anything else as JSON. */\nfunction resultText(content: unknown): string {\n if (typeof content === 'string') return content;\n if (content === undefined || content === null) return '';\n return JSON.stringify(content);\n}\n\n/** What the model reads about a refusal: the person's words, else core's fixed sentence. */\nfunction rejectionText(decision: { reason?: string; instruction?: string }): string {\n return decision.reason?.trim()\n || (decision.instruction ? `The user rejected this tool call and said: ${decision.instruction}` : 'Tool execution was rejected by the user.');\n}\n\n/** The answer a resumed interrupt carries, in the shape AG-UI (and TanStack AI) reads. */\nfunction resumeItem(interrupt: Ticket['interrupts'][number], outcome: Outcome | undefined): AgUiResumeItem {\n if (!outcome) return { interruptId: interrupt.id, status: 'cancelled' };\n if (outcome.kind === 'decision' && interrupt.kind === 'external' && !outcome.approved) {\n // A client tool the page refused to run (its `needsApproval`, its policy). An\n // execution interrupt answered `{ approved: false }` reads as a successful OUTPUT —\n // TanStack AI's `clientToolResult` takes any resolved payload without the error\n // state as `output-available` — so the model would read the decision as the tool's\n // result and lose the reason. It goes back as the tool's error, with the sentence.\n return {\n interruptId: interrupt.id,\n status: 'resolved',\n payload: { error: rejectionText(outcome) },\n metadata: { tanstack: { state: 'output-error' } },\n };\n }\n if (outcome.kind === 'decision') {\n return { interruptId: interrupt.id, status: 'resolved', payload: { approved: outcome.approved } };\n }\n if (outcome.kind === 'failed') {\n return {\n interruptId: interrupt.id,\n status: 'resolved',\n payload: { error: outcome.error },\n metadata: { tanstack: { state: 'output-error' } },\n };\n }\n return {\n interruptId: interrupt.id,\n status: 'resolved',\n payload: outcome.structuredContent !== undefined ? outcome.structuredContent : outcome.content,\n };\n}\n\n/**\n * An `AparteStreamRunner` for an agent served over AG-UI — Agno, LangGraph, Mastra,\n * CrewAI, Pydantic AI, CopilotKit's runtime, TanStack AI. The agent runs on its server,\n * with its own tools; this runner turns its event stream into the rows, text and\n * approvals `AparteClient` draws.\n *\n * ```ts\n * const client = new AparteClient({ streamRunner: createAgUiRunner({ endpoint: '/agui' }) });\n * ```\n *\n * Tools the PAGE registers go to the agent as AG-UI frontend tools. When the agent calls\n * one — or pauses on a call that needs a person (an AG-UI interrupt) — the run ends on\n * `run-suspended`; the client runs the tool or asks through its approval panel, then\n * calls this runner again with the answers, which go back as `tool` messages or as one\n * `resume` batch for the interrupts.\n */\nexport function createAgUiRunner(options: AgUiRunnerOptions): AparteStreamRunner {\n return async (opts) => {\n const doFetch = options.fetch ?? fetch;\n const headers = typeof options.headers === 'function' ? await options.headers() : options.headers ?? {};\n const request = opts.baseRequest as AparteChatRequest;\n const ticket = readTicket(opts.deferral?.token);\n const outcomes = opts.deferral?.outcomes ?? {};\n const threadId = ticket?.threadId\n ?? (typeof options.threadId === 'function' ? options.threadId(opts) : options.threadId)\n ?? `aparte-${uuid()}`;\n const runId = `aparte-run-${uuid()}`;\n const interrupted = new Set((ticket?.interrupts ?? []).map((i) => i.toolCallId));\n\n // Answers to calls the agent left to the browser without an interrupt go back as\n // `tool` messages after the history; answers to interrupts go in one `resume`\n // batch, since the protocol refuses a partial one.\n const messages: AgUiMessage[] = toAgUiMessages(request.messages);\n for (const [toolCallId, outcome] of Object.entries(outcomes)) {\n if (interrupted.has(toolCallId)) continue;\n // A page tool the page refused (its `needsApproval`, its policy): the refusal is\n // the call's result, the sentence the model reads. An approval needs no message.\n if (outcome.kind === 'decision' && outcome.approved) continue;\n messages.push({\n id: `aparte-result-${toolCallId}`,\n role: 'tool',\n toolCallId,\n content: outcome.kind === 'failed' ? `Error: ${outcome.error}`\n : outcome.kind === 'decision' ? rejectionText(outcome)\n : outcome.content,\n });\n }\n const resume = ticket?.interrupts.length\n ? ticket.interrupts.map((interrupt) => resumeItem(interrupt, outcomes[interrupt.toolCallId]))\n : undefined;\n\n const body: AgUiRunAgentInput = {\n threadId,\n runId,\n ...(ticket ? { parentRunId: ticket.runId } : {}),\n state: {},\n messages,\n tools: toAgUiTools(request.tools),\n context: options.context ?? [],\n forwardedProps: options.forwardedProps ?? {},\n ...(resume ? { resume } : {}),\n };\n const response = await doFetch(options.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Accept: 'text/event-stream', ...headers },\n body: JSON.stringify(body),\n signal: opts.signal,\n ...(options.credentials ? { credentials: options.credentials } : {}),\n });\n if (!response.ok || !response.body) {\n const text = await response.text().catch(() => '');\n throw new AparteError(\n text.trim().slice(0, 300) || `The agent endpoint answered HTTP ${response.status}.`,\n AparteError.codeForStatus(response.status) ?? AparteErrorCode.PROVIDER_ERROR,\n undefined, undefined, response.status,\n );\n }\n\n // Calls the history already declares: a resumed run answers them, it does not\n // start them again (no second row).\n const history = new Map(request.messages.flatMap((m) => (m.toolCalls ?? []).map((c) => [c.id, { name: c.name, input: c.input ?? {} }] as const)));\n const known = new Set(history.keys());\n const browserTools = new Set((request.tools ?? []).map((t) => t.name));\n const calls = new Map<string, { name: string; args: string }>();\n const started = new Map<string, { name: string; input: unknown }>();\n const answered = new Set<string>();\n const rejected = new Set<string>();\n const settledByPage = new Set<string>();\n let textOpen = false;\n let usage: Usage | undefined;\n let finished: { runId: string; outcome?: { type?: string; interrupts?: AgUiInterrupt[] } } | undefined;\n const emit = opts.emitter;\n\n const startTool = (toolCallId: string) => {\n const call = calls.get(toolCallId);\n if (!call || started.has(toolCallId) || known.has(toolCallId)) return;\n const input = parseArgs(call.args);\n started.set(toolCallId, { name: call.name, input });\n if (textOpen) { emit({ type: 'text-flush' }); textOpen = false; }\n emit({ type: 'tool-start', toolCallId, name: call.name, input });\n stepEnded = true;\n };\n\n // A model step ends on a tool call, or on a RUN_FINISHED (TanStack AI closes each\n // step with one). What the next step draws, its reasoning or its text, opens a new\n // turn, the way the in-page loop opens one per model call. Drawn into the old turn,\n // a second step's reasoning landed in the first step's thinking block, above the\n // tool row.\n let stepEnded = false;\n const nextStep = () => {\n if (!stepEnded) return;\n stepEnded = false;\n if (textOpen) { emit({ type: 'text-flush' }); textOpen = false; }\n emit({ type: 'turn-start' });\n };\n\n /** The call an interrupt is about: started in this run, else in the history, else as the interrupt describes it. */\n const callOf = (interrupt: AgUiInterrupt & { toolCallId: string }): { name: string; input: unknown } => {\n const here = started.get(interrupt.toolCallId) ?? history.get(interrupt.toolCallId);\n if (here) return here;\n const streamed = calls.get(interrupt.toolCallId);\n if (streamed) return { name: streamed.name, input: parseArgs(streamed.args) };\n // TanStack AI describes the call on the interrupt itself.\n const meta = interrupt.metadata as { toolName?: unknown; input?: unknown } | undefined;\n return { name: typeof meta?.toolName === 'string' ? meta.toolName : '', input: meta?.input ?? {} };\n };\n\n // A stream that closes between two steps is cut, not finished: TanStack AI sends a\n // RUN_FINISHED per step, so having seen one says nothing about the last.\n let endedOnFinish = false;\n\n // The run opens on its FIRST event, whatever it is: a resumed TanStack AI run sends\n // the approved call's TOOL_CALL_RESULT before RUN_STARTED, and settling that row\n // after its result put it back to pending. The answers this run carries settle\n // their rows before anything else.\n let begun = false;\n const begin = () => {\n if (begun) return;\n begun = true;\n emit({ type: 'run-start' });\n emit({ type: 'turn-start' });\n for (const [toolCallId, outcome] of Object.entries(outcomes)) {\n // A tool the PAGE ran: its row settles here, with the result the page holds —\n // a plain AG-UI agent never echoes a frontend tool's result, so nothing\n // else would, and an echo that does come is not drawn twice.\n if (outcome.kind === 'result') {\n emit({\n type: 'tool-resolved',\n toolCallId,\n result: outcome.content,\n ...(outcome.structuredContent !== undefined ? { structuredResult: outcome.structuredContent } : {}),\n });\n settledByPage.add(toolCallId);\n continue;\n }\n if (outcome.kind === 'failed') {\n emit({ type: 'tool-failed', toolCallId, error: outcome.error });\n settledByPage.add(toolCallId);\n continue;\n }\n if (outcome.approved) {\n emit({ type: 'tool-approved', toolCallId });\n } else {\n emit({ type: 'tool-rejected', toolCallId, reason: rejectionText(outcome) });\n rejected.add(toolCallId);\n }\n }\n };\n\n for await (const event of readAgUiEvents(response.body, response.headers.get('content-type'))) {\n begin();\n if (/^(TEXT_MESSAGE|REASONING|TOOL_CALL)_/.test(event.type)) endedOnFinish = false;\n switch (event.type) {\n case 'RUN_STARTED':\n break;\n case 'TEXT_MESSAGE_START':\n case 'REASONING_START':\n case 'REASONING_MESSAGE_START':\n nextStep();\n break;\n case 'TEXT_MESSAGE_CONTENT':\n case 'TEXT_MESSAGE_CHUNK': {\n const delta = typeof event['delta'] === 'string' ? event['delta'] : '';\n if (delta) { nextStep(); emit({ type: 'text-delta', delta }); textOpen = true; }\n break;\n }\n case 'TEXT_MESSAGE_END': {\n if (textOpen) { emit({ type: 'text-flush' }); textOpen = false; }\n break;\n }\n case 'REASONING_MESSAGE_CONTENT':\n case 'REASONING_MESSAGE_CHUNK': {\n const delta = typeof event['delta'] === 'string' ? event['delta'] : '';\n if (delta) { nextStep(); emit({ type: 'thinking-delta', delta }); }\n break;\n }\n case 'TOOL_CALL_START': {\n const id = String(event['toolCallId']);\n calls.set(id, { name: String(event['toolCallName'] ?? ''), args: '' });\n break;\n }\n case 'TOOL_CALL_ARGS': {\n const call = calls.get(String(event['toolCallId']));\n if (call && typeof event['delta'] === 'string') call.args += event['delta'];\n break;\n }\n case 'TOOL_CALL_CHUNK': {\n const id = typeof event['toolCallId'] === 'string' ? event['toolCallId'] : [...calls.keys()].at(-1);\n if (!id) break;\n const call = calls.get(id) ?? { name: '', args: '' };\n if (typeof event['toolCallName'] === 'string' && event['toolCallName']) call.name = event['toolCallName'];\n if (typeof event['delta'] === 'string') call.args += event['delta'];\n calls.set(id, call);\n break;\n }\n case 'TOOL_CALL_END': {\n startTool(String(event['toolCallId']));\n break;\n }\n case 'TOOL_CALL_RESULT': {\n const toolCallId = String(event['toolCallId']);\n startTool(toolCallId);\n if (rejected.has(toolCallId) || settledByPage.has(toolCallId)) break; // already settled\n answered.add(toolCallId);\n const content = resultText(event['content']);\n const meta = event['metadata'] as { tanstack?: { state?: unknown } } | undefined;\n if (meta?.tanstack?.state === 'output-error') {\n emit({ type: 'tool-failed', toolCallId, error: content });\n } else {\n emit({ type: 'tool-resolved', toolCallId, result: content });\n }\n break;\n }\n case 'RUN_ERROR': {\n throw new AparteError(\n typeof event['message'] === 'string' && event['message'] ? event['message'] : 'The agent run failed.',\n AparteErrorCode.PROVIDER_ERROR,\n typeof event['code'] === 'string' ? { code: event['code'] } : undefined,\n );\n }\n case 'RUN_FINISHED': {\n // Not the end of the stream: TanStack AI closes each model step with a\n // RUN_FINISHED of its own (`finishReason: tool_calls`), then streams the\n // tool results and the next step. The LAST one says how the run ended.\n for (const id of calls.keys()) startTool(id);\n if (textOpen) { emit({ type: 'text-flush' }); textOpen = false; }\n usage = readUsage(event['usage']) ?? usage; // the last step's report wins\n stepEnded = true;\n endedOnFinish = true;\n finished = {\n runId: typeof event['runId'] === 'string' ? event['runId'] : runId,\n outcome: event['outcome'] as { type?: string; interrupts?: AgUiInterrupt[] } | undefined,\n };\n break;\n }\n default:\n // STEP_*, STATE_*, MESSAGES_SNAPSHOT, ACTIVITY_*, RAW, CUSTOM, SUBAGENT_*:\n // agent state aparté does not draw.\n break;\n }\n }\n if (opts.signal.aborted) return usage;\n if (!finished) {\n throw new AparteError('The agent stream ended without RUN_FINISHED.', AparteErrorCode.PROVIDER_ERROR);\n }\n if (!endedOnFinish) {\n throw new AparteError('The agent stream was cut: it ended in the middle of a step, after a RUN_FINISHED.', AparteErrorCode.PROVIDER_ERROR);\n }\n if (textOpen) emit({ type: 'text-flush' });\n\n const pending: PendingCall[] = [];\n const interrupts: Ticket['interrupts'] = [];\n if (finished.outcome?.type === 'interrupt') {\n for (const interrupt of finished.outcome.interrupts ?? []) {\n const kind = interruptKind(interrupt);\n if (!kind || !interrupt.toolCallId) {\n throw new AparteError(\n `The agent paused for something aparté cannot answer yet (interrupt reason \"${interrupt.reason}\").`,\n AparteErrorCode.PROVIDER_ERROR,\n );\n }\n // A resumed run can pause again on a call an earlier run started (TanStack AI\n // asks to approve a client tool, then to run it): its name comes from there.\n const call = callOf(interrupt as AgUiInterrupt & { toolCallId: string });\n if (kind === 'approval') {\n emit({ type: 'tool-awaiting-approval', toolCallId: interrupt.toolCallId, name: call.name, input: call.input });\n }\n interrupts.push({ id: interrupt.id, toolCallId: interrupt.toolCallId, kind });\n pending.push({ toolCallId: interrupt.toolCallId, name: call.name, input: call.input, reason: kind });\n }\n } else {\n // Plain AG-UI: the calls left to the browser are the ones the agent names\n // (`pendingToolCallIds`, AG-UI 1.0), else the page's own tools nobody answered.\n // Any other call without a result has nobody left to answer it: its row stops\n // waiting rather than spinning after the run. A cancelled run leaves nothing.\n const outcome = finished.outcome as { type?: string; pendingToolCallIds?: unknown } | undefined;\n const named = Array.isArray(outcome?.pendingToolCallIds)\n ? new Set(outcome.pendingToolCallIds.filter((id): id is string => typeof id === 'string'))\n : undefined;\n for (const [toolCallId, call] of started) {\n if (answered.has(toolCallId)) continue;\n const forPage = outcome?.type !== 'cancelled' && (named ? named.has(toolCallId) : browserTools.has(call.name));\n if (forPage) pending.push({ toolCallId, name: call.name, input: call.input, reason: 'external' });\n else emit({ type: 'tool-aborted', toolCallId });\n }\n }\n if (pending.length > 0) {\n const next: Ticket = { v: 1, threadId, runId: finished.runId, interrupts };\n emit({ type: 'run-suspended', pending, ...(usage ? { usage } : {}), ticket: JSON.stringify(next) } as Suspended);\n } else {\n emit({ type: 'run-done', ...(usage ? { usage } : {}) });\n }\n return usage;\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/messages.ts","../src/enforce.ts","../src/state.ts","../src/translate.ts","../src/verify.ts","../src/wire.ts","../src/runner.ts"],"sourcesContent":["import { contentToText } from '@aparte/core';\nimport type { AparteChatMessage, AparteContentPart, AparteTool } from '@aparte/core';\nimport type { AgUiInputContent, AgUiMessage, AgUiRunAgentInput } from './wire.js';\n\n/**\n * An aparté image as AG-UI 1.0 content: a base64 data URL becomes a `data` source, whose\n * value AG-UI defines as base64; anything else — a link, or a data URL that is not base64,\n * such as a percent-encoded SVG — goes whole as a `url` source.\n */\nfunction imagePart(part: Extract<AparteContentPart, { type: 'image' }>): AgUiInputContent {\n const data = /^data:([^;,]*)(?:;[^;,]*)*;base64,(.*)$/s.exec(part.image);\n if (data) return { type: 'image', source: { type: 'data', value: data[2]!, mimeType: part.mimeType ?? (data[1] || 'application/octet-stream') } };\n return { type: 'image', source: { type: 'url', value: part.image, ...(part.mimeType ? { mimeType: part.mimeType } : {}) } };\n}\n\n/**\n * aparté's history as `RunAgentInput.messages`. Every message gets an id (the protocol\n * requires one) that is stable across the runs of one turn — its position — so a resume\n * replays the same history the paused run saw. A call is `{ id, type: 'function',\n * function: { name, arguments } }` with the arguments as a JSON string, and a result is\n * a `tool` message naming its call. A user message with an image goes as AG-UI 1.0\n * content parts; toward a peer that predates them (`flatten`), as its text alone — which\n * drops the image, and says so.\n */\nexport function toAgUiMessages(\n messages: readonly AparteChatMessage[],\n flatten: boolean,\n warn: (message: string) => void,\n): AgUiMessage[] {\n const out: AgUiMessage[] = [];\n messages.forEach((m, index) => {\n const id = `aparte-${index}`;\n const content = contentToText(m.content);\n const images = Array.isArray(m.content) && m.content.some((part) => part.type === 'image');\n if (m.role === 'user' && images && !flatten) {\n out.push({\n id,\n role: 'user',\n content: (m.content as AparteContentPart[]).map((part) => (part.type === 'image' ? imagePart(part) : { type: 'text', text: part.text })),\n });\n } else if (m.role === 'system' || m.role === 'user') {\n if (images) warn(`the agent's AG-UI version takes text only, which DROPS non-text parts: the images of message ${index} are not sent.`);\n out.push({ id, role: m.role, content });\n } else if (m.role === 'assistant') {\n out.push({\n id,\n role: 'assistant',\n ...(content ? { content } : {}),\n ...(m.toolCalls?.length\n ? {\n toolCalls: m.toolCalls.map((call) => ({\n id: call.id,\n type: 'function' as const,\n function: { name: call.name, arguments: JSON.stringify(call.input ?? {}) },\n })),\n }\n : {}),\n });\n } else if (m.role === 'tool' && m.toolCallId) {\n out.push({ id, role: 'tool', content, toolCallId: m.toolCallId });\n }\n });\n return out;\n}\n\n/** The page's tools as `RunAgentInput.tools`: the ones the agent may ask the browser to run. */\nexport function toAgUiTools(tools: readonly AparteTool[] | undefined): AgUiRunAgentInput['tools'] {\n return (tools ?? []).map((tool) => ({ name: tool.name, description: tool.description, parameters: tool.inputSchema }));\n}\n","type AgUiEvent = { type: string } & Record<string, unknown>;\n\n/** What every AG-UI event may carry. */\nconst BASE = ['type', 'timestamp', 'rawEvent', 'metadata'];\n\n/**\n * The properties AG-UI 1.0 describes on each event, beyond `BASE`. Written out rather than\n * read from `@ag-ui/core`'s schemas, which would ship zod to every page; a test holds this\n * table to those schemas, so a protocol update that adds a field fails it.\n */\nexport const EVENT_KEYS: Record<string, readonly string[]> = {\n RUN_STARTED: ['threadId', 'runId', 'parentRunId', 'protocolVersion', 'input'],\n RUN_FINISHED: ['threadId', 'runId', 'outcome', 'result', 'usage'],\n RUN_ERROR: ['message', 'code', 'usage'],\n STEP_STARTED: ['stepName', 'subagentRunId'],\n STEP_FINISHED: ['stepName', 'subagentRunId'],\n TEXT_MESSAGE_START: ['messageId', 'role', 'name', 'subagentRunId'],\n TEXT_MESSAGE_CONTENT: ['messageId', 'delta', 'subagentRunId'],\n TEXT_MESSAGE_END: ['messageId', 'subagentRunId'],\n TEXT_MESSAGE_CHUNK: ['messageId', 'role', 'name', 'delta', 'subagentRunId'],\n TOOL_CALL_START: ['toolCallId', 'toolCallName', 'parentMessageId', 'subagentRunId'],\n TOOL_CALL_ARGS: ['toolCallId', 'delta', 'subagentRunId'],\n TOOL_CALL_END: ['toolCallId', 'subagentRunId'],\n TOOL_CALL_CHUNK: ['toolCallId', 'toolCallName', 'parentMessageId', 'delta', 'subagentRunId'],\n TOOL_CALL_RESULT: ['messageId', 'toolCallId', 'content', 'role', 'subagentRunId'],\n REASONING_START: ['messageId', 'subagentRunId'],\n REASONING_END: ['messageId', 'subagentRunId'],\n REASONING_MESSAGE_START: ['messageId', 'role', 'subagentRunId'],\n REASONING_MESSAGE_CONTENT: ['messageId', 'delta', 'subagentRunId'],\n REASONING_MESSAGE_END: ['messageId', 'subagentRunId'],\n REASONING_MESSAGE_CHUNK: ['messageId', 'delta', 'subagentRunId'],\n REASONING_ENCRYPTED_VALUE: ['subtype', 'entityId', 'encryptedValue', 'subagentRunId'],\n STATE_SNAPSHOT: ['snapshot', 'subagentRunId'],\n STATE_DELTA: ['delta', 'subagentRunId'],\n MESSAGES_SNAPSHOT: ['messages'],\n ACTIVITY_SNAPSHOT: ['messageId', 'activityType', 'content', 'replace', 'subagentRunId'],\n ACTIVITY_DELTA: ['messageId', 'activityType', 'patch', 'subagentRunId'],\n RAW: ['event', 'source', 'subagentRunId'],\n CUSTOM: ['name', 'value', 'subagentRunId'],\n SUBAGENT_STARTED: ['subagentRunId', 'name', 'description', 'parentMessageId', 'parentToolCallId', 'parentSubagentRunId'],\n SUBAGENT_FINISHED: ['subagentRunId', 'outcome', 'result'],\n SUBAGENT_ERROR: ['subagentRunId', 'message', 'code'],\n};\n\n/** The closed sets 1.0 names: a member outside them is stripped, as the protocol asks. */\nconst TEXT_ROLES = new Set(['developer', 'system', 'assistant', 'user']);\nconst OUTCOMES = new Set(['success', 'interrupt', 'cancelled']);\nconst CONTENT_PARTS = new Set(['text', 'image', 'audio', 'video', 'document']);\n\n/**\n * AG-UI's rule for what a consumer does not recognise: survive it. An unknown event is\n * dropped, an undescribed property or an unknown member of a closed set is stripped, an\n * unknown element of a list is removed from it — each told to `warn` by its path, the\n * event otherwise left intact. A value of the wrong SHAPE is not unknown, it is\n * malformed, and is left for the verifier to reject.\n */\nexport function enforce(event: AgUiEvent, warn: (message: string) => void): AgUiEvent | undefined {\n const keys = EVENT_KEYS[event.type];\n if (!keys) {\n warn(`dropped an event of a type this runner does not know: ${event.type}.`);\n return undefined;\n }\n const out: AgUiEvent = { ...event };\n for (const key of Object.keys(out)) {\n if (!BASE.includes(key) && !keys.includes(key)) {\n delete out[key];\n warn(`stripped /${key} from ${event.type}: AG-UI 1.0 does not describe it.`);\n }\n }\n if ((out.type === 'TEXT_MESSAGE_START' || out.type === 'TEXT_MESSAGE_CHUNK') && typeof out['role'] === 'string' && !TEXT_ROLES.has(out['role'])) {\n warn(`stripped /role from ${out.type}: \"${out['role']}\" is not a message role.`);\n delete out['role'];\n }\n const outcome = out['outcome'];\n if (out.type === 'RUN_FINISHED' && outcome && typeof outcome === 'object' && !Array.isArray(outcome) && !OUTCOMES.has(String((outcome as { type?: unknown }).type))) {\n warn(`stripped /outcome from RUN_FINISHED: \"${String((outcome as { type?: unknown }).type)}\" is not an outcome AG-UI 1.0 describes; the run ends as a plain one.`);\n delete out['outcome'];\n }\n if (out.type === 'MESSAGES_SNAPSHOT' && Array.isArray(out['messages'])) {\n out['messages'] = (out['messages'] as unknown[]).map((message, i) => {\n const content = (message as { content?: unknown } | null)?.content;\n if (!Array.isArray(content)) return message;\n const kept = content.filter((part, j) => {\n const known = CONTENT_PARTS.has(String((part as { type?: unknown } | null)?.type));\n if (!known) warn(`stripped /messages/${i}/content/${j} from MESSAGES_SNAPSHOT: \"${String((part as { type?: unknown } | null)?.type)}\" is not a content part.`);\n return known;\n });\n return { ...(message as object), content: kept };\n });\n }\n return out;\n}\n","/**\n * The agent's shared state, as AG-UI streams it: `STATE_SNAPSHOT` replaces it whole\n * (any JSON value, `null` and `0` included) and `STATE_DELTA` patches it with an\n * RFC 6902 JSON Patch. The runner keeps the result per thread and sends it back as the\n * next run's `state`, so a stateful agent finds what it left.\n */\n\ntype Container = Record<string, unknown> | unknown[];\n\nconst OPS = new Set(['add', 'remove', 'replace', 'move', 'copy', 'test']);\n\n/** An RFC 6901 JSON Pointer as its reference tokens. */\nfunction tokens(pointer: string): string[] {\n if (pointer === '') return [];\n if (!pointer.startsWith('/')) throw new Error(`\"${pointer}\" is not a JSON Pointer`);\n return pointer.slice(1).split('/').map((t) => t.replace(/~1/g, '/').replace(/~0/g, '~'));\n}\n\nfunction isContainer(value: unknown): value is Container {\n return typeof value === 'object' && value !== null;\n}\n\n/** The array index a token names; `-` (past the end) only where `append` allows it. */\nfunction index(list: unknown[], token: string, append: boolean): number {\n if (append && token === '-') return list.length;\n if (!/^(0|[1-9]\\d*)$/.test(token)) throw new Error(`\"${token}\" is not an array index`);\n const i = Number(token);\n if (i > list.length || (!append && i === list.length)) throw new Error(`index ${i} is out of range`);\n return i;\n}\n\n/** The container a pointer's last token lives in, and that token. */\nfunction parentOf(doc: unknown, path: string): { parent: Container; key: string } {\n const all = tokens(path);\n const key = all.pop()!;\n let node = doc;\n for (const t of all) {\n if (!isContainer(node)) throw new Error(`\"${path}\" does not resolve`);\n node = Array.isArray(node) ? node[index(node, t, false)] : (Object.hasOwn(node, t) ? node[t] : undefined);\n if (node === undefined) throw new Error(`\"${path}\" does not resolve`);\n }\n if (!isContainer(node)) throw new Error(`\"${path}\" does not resolve`);\n return { parent: node, key };\n}\n\nfunction get(doc: unknown, path: string): unknown {\n if (path === '') return doc;\n const { parent, key } = parentOf(doc, path);\n const value = Array.isArray(parent) ? parent[index(parent, key, false)] : (Object.hasOwn(parent, key) ? parent[key] : undefined);\n if (value === undefined) throw new Error(`\"${path}\" does not resolve`);\n return value;\n}\n\nfunction add(doc: unknown, path: string, value: unknown): unknown {\n if (path === '') return value;\n const { parent, key } = parentOf(doc, path);\n if (Array.isArray(parent)) parent.splice(index(parent, key, true), 0, value);\n else parent[key] = value;\n return doc;\n}\n\nfunction remove(doc: unknown, path: string): unknown {\n if (path === '') throw new Error('the whole document cannot be removed');\n const { parent, key } = parentOf(doc, path);\n if (Array.isArray(parent)) parent.splice(index(parent, key, false), 1);\n else if (Object.hasOwn(parent, key)) delete parent[key];\n else throw new Error(`\"${path}\" does not resolve`);\n return doc;\n}\n\nfunction replace(doc: unknown, path: string, value: unknown): unknown {\n if (path === '') return value;\n const { parent, key } = parentOf(doc, path);\n if (Array.isArray(parent)) parent[index(parent, key, false)] = value;\n else if (Object.hasOwn(parent, key)) parent[key] = value;\n else throw new Error(`\"${path}\" does not resolve`);\n return doc;\n}\n\n/** JSON equality, as RFC 6902's `test` means it: key order does not count, array order does. */\nfunction equal(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (!isContainer(a) || !isContainer(b) || Array.isArray(a) !== Array.isArray(b)) return false;\n if (Array.isArray(a)) return a.length === (b as unknown[]).length && a.every((v, i) => equal(v, (b as unknown[])[i]));\n const ka = Object.keys(a);\n const kb = Object.keys(b);\n return ka.length === kb.length && ka.every((k) => Object.hasOwn(b, k) && equal((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k]));\n}\n\n/** One operation, on a document it may change in place; returns the document. */\nfunction step(doc: unknown, op: Record<string, unknown>): unknown {\n const path = op['path'];\n if (typeof path !== 'string') throw new Error('an operation has no path');\n const from = typeof op['from'] === 'string' ? op['from'] : undefined;\n if ((op['op'] === 'add' || op['op'] === 'replace' || op['op'] === 'test') && !('value' in op)) throw new Error(`${String(op['op'])} has no value`);\n switch (op['op']) {\n case 'add': return add(doc, path, structuredClone(op['value']));\n case 'remove': return remove(doc, path);\n case 'replace': return replace(doc, path, structuredClone(op['value']));\n case 'move': {\n if (from === undefined) throw new Error('move has no from');\n // §4.4: a location cannot move into one of its own children.\n if (path.startsWith(`${from}/`)) throw new Error(`\"${from}\" cannot move into its own child \"${path}\"`);\n const value = get(doc, from);\n return add(remove(doc, from), path, value);\n }\n case 'copy': { if (from === undefined) throw new Error('copy has no from'); return add(doc, path, structuredClone(get(doc, from))); }\n case 'test': if (!equal(get(doc, path), op['value'])) throw new Error(`test failed at \"${path}\"`); return doc;\n default: throw new Error(`unknown operation \"${String(op['op'])}\"`);\n }\n}\n\n/**\n * The state after a `STATE_DELTA`. Applied whole or not at all: a patch whose operation\n * fails leaves the state as it was. An operation RFC 6902 does not define is dropped\n * from the patch, the rest applies. Both are told to `warn`; neither fails the run.\n */\nexport function applyStateDelta(state: unknown, delta: unknown, warn: (message: string) => void): unknown {\n if (!Array.isArray(delta)) {\n warn('Failed to apply state patch: STATE_DELTA carried no list of operations; the state is left as it was.');\n return state;\n }\n const ops: Record<string, unknown>[] = [];\n delta.forEach((op, i) => {\n if (isContainer(op) && !Array.isArray(op) && OPS.has(String(op['op']))) ops.push(op);\n else warn(`dropped /delta/${i}: ${JSON.stringify(op)} is not a JSON Patch operation.`);\n });\n try {\n let doc = structuredClone(state);\n for (const op of ops) doc = step(doc, op);\n return doc;\n } catch (error) {\n warn(`Failed to apply state patch: ${(error as Error).message}; the state is left as it was.`);\n return state;\n }\n}\n","type AgUiEvent = { type: string } & Record<string, unknown>;\n\n/** Negative, zero or positive, as `a` is older than, equal to or newer than `b`. */\nfunction compare(a: readonly number[], b: readonly number[]): number {\n for (let i = 0; i < Math.max(a.length, b.length); i++) {\n const d = (a[i] ?? 0) - (b[i] ?? 0);\n if (d !== 0) return d;\n }\n return 0;\n}\n\n/**\n * What older AG-UI shapes become before the runner reads them — a middleware, run before\n * anything is stripped, as the protocol requires of a translation:\n *\n * - The retired `THINKING_*` events are always translated into their `REASONING_*`\n * replacements: a producer may still send them whatever it declares. The span's title\n * has no place in the replacement, so the translation says so.\n * - A peer of 0.0.57 or older predates subagents: `SUBAGENT_*` events are dropped and\n * attribution removed, with a warning, rather than read as 1.0 material.\n *\n * `peer` is the configured peer version as numbers; undefined is a 1.0 peer.\n */\nexport function createTranslator(peer: readonly number[] | undefined, warn: (message: string) => void): (event: AgUiEvent) => AgUiEvent[] {\n const beforeSubagents = peer !== undefined && compare(peer, [0, 0, 57]) <= 0;\n let thought = 0;\n let span: string | undefined;\n let message: string | undefined;\n const warned = new Set<string>();\n const once = (key: string, text: string) => {\n if (warned.has(key)) return;\n warned.add(key);\n warn(text);\n };\n\n return (event) => {\n switch (event.type) {\n case 'THINKING_START':\n span = `thinking-${++thought}`;\n once('THINKING_START', `translated the retired THINKING_START into REASONING_START${typeof event['title'] === 'string' ? `, dropping its title \"${event['title']}\"` : ''}; the agent should send REASONING_* events.`);\n return [{ type: 'REASONING_START', messageId: span }];\n case 'THINKING_END': {\n const id = span ?? `thinking-${++thought}`;\n span = undefined;\n return [{ type: 'REASONING_END', messageId: id }];\n }\n case 'THINKING_TEXT_MESSAGE_START':\n message = `thinking-message-${++thought}`;\n return [{ type: 'REASONING_MESSAGE_START', messageId: message, role: 'reasoning' }];\n case 'THINKING_TEXT_MESSAGE_CONTENT':\n return [{ type: 'REASONING_MESSAGE_CONTENT', messageId: message ?? `thinking-message-${thought}`, delta: event['delta'] }];\n case 'THINKING_TEXT_MESSAGE_END': {\n const id = message ?? `thinking-message-${thought}`;\n message = undefined;\n return [{ type: 'REASONING_MESSAGE_END', messageId: id }];\n }\n }\n if (beforeSubagents) {\n if (event.type.startsWith('SUBAGENT_')) {\n once(event.type, `dropping ${event.type}: the agent's AG-UI version predates subagents (0.0.57 or older).`);\n return [];\n }\n if ('subagentRunId' in event) {\n const { subagentRunId: _dropped, ...rest } = event;\n return [rest as AgUiEvent];\n }\n }\n return [event];\n };\n}\n","import { AparteError, AparteErrorCode } from '@aparte/core';\n\ntype AgUiEvent = { type: string } & Record<string, unknown>;\n\n/** A stream AG-UI 1.0 says a client must reject. */\nfunction malformed(reason: string): AparteError {\n return new AparteError(`The agent stream is malformed: ${reason}.`, AparteErrorCode.PROVIDER_ERROR, { agUi: 'malformed' });\n}\n\n/** Events whose `delta` the protocol defines as a string (STATE_DELTA's is a patch). */\nconst STRING_DELTA = new Set([\n 'TEXT_MESSAGE_CONTENT', 'TEXT_MESSAGE_CHUNK', 'TOOL_CALL_ARGS', 'TOOL_CALL_CHUNK',\n 'REASONING_MESSAGE_CONTENT', 'REASONING_MESSAGE_CHUNK',\n]);\n\n/** Fields the protocol defines as strings, wherever they appear. */\nconst STRING_FIELDS = [\n 'messageId', 'toolCallId', 'toolCallName', 'parentMessageId', 'stepName', 'subagentRunId', 'threadId', 'runId',\n 'parentRunId', 'protocolVersion', 'name', 'role', 'message', 'code', 'activityType', 'entityId', 'encryptedValue',\n 'subtype', 'description', 'parentToolCallId', 'parentSubagentRunId',\n];\n\n/** What identifies each event, without which it cannot be read: absent is malformed. */\nconst REQUIRED: Record<string, readonly string[]> = {\n TEXT_MESSAGE_START: ['messageId'], TEXT_MESSAGE_CONTENT: ['messageId', 'delta'], TEXT_MESSAGE_END: ['messageId'],\n TOOL_CALL_START: ['toolCallId', 'toolCallName'], TOOL_CALL_ARGS: ['toolCallId', 'delta'], TOOL_CALL_END: ['toolCallId'],\n TOOL_CALL_RESULT: ['toolCallId'],\n REASONING_START: ['messageId'], REASONING_END: ['messageId'],\n REASONING_MESSAGE_START: ['messageId'], REASONING_MESSAGE_CONTENT: ['messageId', 'delta'], REASONING_MESSAGE_END: ['messageId'],\n STEP_STARTED: ['stepName'], STEP_FINISHED: ['stepName'],\n SUBAGENT_STARTED: ['subagentRunId'], SUBAGENT_FINISHED: ['subagentRunId'], SUBAGENT_ERROR: ['subagentRunId'],\n};\n\n/** The run-framing rejections end on the lever that reads such a stream, since one well-known producer needs it. */\nconst FRAMING_HINT = ' (TanStack AI frames runs this way: give createAgUiRunner relaxedRunFraming: true to read it)';\n\nexport interface Verifier {\n (event: AgUiEvent): void;\n /** The stream is over. Under a relaxed run framing, what is still open is refused here, not at each RUN_FINISHED. */\n end(): void;\n}\n\n/**\n * The stream rules of AG-UI 1.0 a consumer enforces before anything is drawn: a run is\n * framed by RUN_STARTED and RUN_FINISHED (or RUN_ERROR, which ends what was open), a\n * message, a tool call, a step or a subagent is opened before it continues and closed\n * before the run finishes, a chunk stream starts with its identity and keeps it, and a\n * known field has its type. What is open is tracked per owner — the run, or each subagent\n * invocation — as the protocol requires: a parent and a subagent may each have a step of\n * the same name open, and one invocation ending closes none of another's.\n *\n * `relaxed` reads the run framing with the older rules — a peer older than 1.0, or a\n * producer named as framing runs its own way (TanStack AI closes each step with a\n * RUN_FINISHED and answers a resume before its RUN_STARTED): the framing is not checked,\n * and what is still open is refused at the end of the stream rather than at each\n * RUN_FINISHED. Every other rule holds.\n */\nexport function createVerifier(relaxed: boolean): Verifier {\n let seen = false;\n let running = false;\n /** How the last run closed, until a new RUN_STARTED: after a finish only RUN_STARTED or a late RUN_ERROR may come, after an error only RUN_STARTED. */\n let closed: 'finished' | 'error' | undefined;\n const text = new Map<string, unknown>();\n const reasoning = new Map<string, unknown>();\n const tools = new Map<string, unknown>();\n const steps = new Set<string>();\n const subagents = new Set<string>();\n /** The chunk stream in progress, per owner. A non-chunk event of that owner closes it, except RAW. */\n const chunks = new Map<string, { type: string; id: string; label?: string }>();\n\n const ownerOf = (event: AgUiEvent): string => (typeof event['subagentRunId'] === 'string' ? event['subagentRunId'] : '');\n const stepKey = (owner: string, name: string) => `${owner}\\u0000${name}`;\n const nothingOpen = () => { text.clear(); reasoning.clear(); tools.clear(); steps.clear(); subagents.clear(); chunks.clear(); };\n const stillOpen = (): string[] => [...text.keys()].map((id) => `text message \"${id}\"`)\n .concat([...reasoning.keys()].map((id) => `reasoning message \"${id}\"`))\n .concat([...tools.keys()].map((id) => `tool call \"${id}\"`))\n .concat([...steps].map((key) => `step \"${key.split('\\u0000')[1]}\"`))\n .concat([...subagents].map((id) => `subagent \"${id}\"`));\n\n /** A continuation must not disagree with the owner its opener named; an untagged one continues the opener. */\n const agrees = (id: string, opened: Map<string, unknown>, event: AgUiEvent) => {\n const by = event['subagentRunId'];\n if (by === undefined) return;\n const at = opened.get(id);\n if (at !== undefined && at !== by) throw malformed(`${event.type} for \"${id}\" is attributed to \"${String(by)}\", but \"${id}\" started attributed to \"${String(at)}\"`);\n };\n\n const verify = ((event: AgUiEvent) => {\n const type = event.type;\n const first = !seen;\n seen = true;\n\n for (const key of REQUIRED[type] ?? []) if (event[key] === undefined) throw malformed(`${type} needs \"${key}\"`);\n for (const key of STRING_FIELDS) if (key in event && event[key] !== undefined && typeof event[key] !== 'string') throw malformed(`\"${key}\" must be a string on ${type}`);\n if (STRING_DELTA.has(type) && 'delta' in event && typeof event['delta'] !== 'string') throw malformed(`\"delta\" must be a string on ${type}`);\n\n // Lifecycle: the run's framing.\n if (type === 'RUN_STARTED') {\n if (running && !relaxed) throw malformed('RUN_STARTED while a run is still active');\n running = true;\n closed = undefined;\n nothingOpen(); // a new run starts with nothing open\n return;\n }\n if (!relaxed) {\n // A RUN_ERROR may open a stream: an agent that could not start says so.\n if (first && type !== 'RUN_ERROR') throw malformed(`the first event must be RUN_STARTED, not ${type}${FRAMING_HINT}`);\n if (closed === 'finished' && type !== 'RUN_ERROR') throw malformed(`${type} after the run finished${FRAMING_HINT}`);\n if (closed === 'error') throw malformed(`${type} after the run ended with RUN_ERROR`);\n }\n if (type === 'RUN_ERROR') {\n // Ends the run, and whatever was still open with it.\n running = false;\n if (closed !== 'finished') closed = 'error';\n nothingOpen();\n return;\n }\n\n const owner = ownerOf(event);\n // A chunk stream closes on anything but another chunk of its kind from its owner, or RAW.\n const open = chunks.get(owner);\n if (open && type !== open.type && type !== 'RAW') chunks.delete(owner);\n if (type === 'SUBAGENT_FINISHED' || type === 'SUBAGENT_ERROR') chunks.delete(String(event['subagentRunId']));\n\n switch (type) {\n case 'TEXT_MESSAGE_START':\n text.set(String(event['messageId']), event['subagentRunId']);\n break;\n case 'TEXT_MESSAGE_CONTENT':\n case 'TEXT_MESSAGE_END': {\n const id = String(event['messageId']);\n if (!text.has(id)) throw malformed(`${type} for \"${id}\", but no open text message has that id`);\n agrees(id, text, event);\n if (type === 'TEXT_MESSAGE_END') text.delete(id);\n break;\n }\n case 'TEXT_MESSAGE_CHUNK':\n case 'REASONING_MESSAGE_CHUNK': {\n const id = typeof event['messageId'] === 'string' ? event['messageId'] : undefined;\n const role = typeof event['role'] === 'string' ? event['role'] : undefined;\n const current = chunks.get(owner);\n if (!current || (id !== undefined && id !== current.id)) {\n if (id === undefined) throw malformed(`the first ${type} of a stream needs a messageId`);\n chunks.set(owner, { type, id, ...(role !== undefined ? { label: role } : {}) });\n } else if (role !== undefined && current.label !== undefined && role !== current.label) {\n throw malformed(`${type} changes its role from \"${current.label}\" to \"${role}\" in the middle of message \"${current.id}\"`);\n }\n break;\n }\n case 'TOOL_CALL_CHUNK': {\n const id = typeof event['toolCallId'] === 'string' ? event['toolCallId'] : undefined;\n const name = typeof event['toolCallName'] === 'string' ? event['toolCallName'] : undefined;\n const current = chunks.get(owner);\n if (!current || (id !== undefined && id !== current.id)) {\n if (id === undefined || name === undefined) throw malformed('the first TOOL_CALL_CHUNK of a call needs a toolCallId and a toolCallName');\n chunks.set(owner, { type, id, label: name });\n } else if (name !== undefined && name !== current.label) {\n throw malformed(`TOOL_CALL_CHUNK changes its toolCallName from \"${current.label}\" to \"${name}\" in the middle of call \"${current.id}\"`);\n }\n break;\n }\n case 'TOOL_CALL_START':\n tools.set(String(event['toolCallId']), event['subagentRunId']);\n break;\n case 'TOOL_CALL_ARGS':\n case 'TOOL_CALL_END': {\n const id = String(event['toolCallId']);\n if (!tools.has(id)) throw malformed(`${type} for \"${id}\", but no open tool call has that id`);\n agrees(id, tools, event);\n if (type === 'TOOL_CALL_END') tools.delete(id);\n break;\n }\n case 'REASONING_MESSAGE_START': {\n const id = String(event['messageId']);\n if (event['role'] !== undefined && event['role'] !== 'reasoning') {\n throw malformed(`REASONING_MESSAGE_START \"${id}\" has the role \"${String(event['role'])}\", where only role \"reasoning\" is allowed`);\n }\n reasoning.set(id, event['subagentRunId']);\n break;\n }\n case 'REASONING_MESSAGE_CONTENT':\n case 'REASONING_MESSAGE_END': {\n const id = String(event['messageId']);\n if (!reasoning.has(id)) throw malformed(`${type} for \"${id}\", but no open reasoning message has that id`);\n agrees(id, reasoning, event);\n if (type === 'REASONING_MESSAGE_END') reasoning.delete(id);\n break;\n }\n case 'STEP_STARTED':\n steps.add(stepKey(owner, String(event['stepName'])));\n break;\n case 'STEP_FINISHED': {\n const key = stepKey(owner, String(event['stepName']));\n if (!steps.has(key)) throw malformed(`STEP_FINISHED for step \"${String(event['stepName'])}\", which was not started${owner ? ` by \"${owner}\"` : ''}`);\n steps.delete(key);\n break;\n }\n case 'SUBAGENT_STARTED': {\n const id = String(event['subagentRunId']);\n if (typeof event['name'] !== 'string' || !event['name']) throw malformed(`SUBAGENT_STARTED \"${id}\" needs a name`);\n subagents.add(id);\n break;\n }\n case 'SUBAGENT_FINISHED':\n case 'SUBAGENT_ERROR': {\n const id = String(event['subagentRunId']);\n if (!subagents.has(id)) throw malformed(`${type} for subagent \"${id}\", which was not started`);\n subagents.delete(id);\n break;\n }\n case 'RUN_FINISHED': {\n const outcome = event['outcome'];\n if (outcome !== undefined && (typeof outcome !== 'object' || outcome === null || Array.isArray(outcome))) {\n throw malformed('RUN_FINISHED.outcome must be an object');\n }\n if (!relaxed) {\n const left = stillOpen();\n if (left.length) throw malformed(`${left.join(', ')} still running at RUN_FINISHED`);\n closed = 'finished';\n }\n chunks.clear();\n running = false;\n break;\n }\n }\n }) as Verifier;\n\n verify.end = () => {\n if (!relaxed) return;\n const left = stillOpen();\n if (left.length) throw malformed(`${left.join(', ')} still running at the end of the stream`);\n };\n return verify;\n}\n","/**\n * The AG-UI wire, as much of it as aparté reads — typed here rather than taken from\n * `@ag-ui/core`, whose client pulls rxjs, zod and protobuf into a bundle that only\n * needs to read JSON lines. Field names follow the protocol (docs.ag-ui.com, 1.0).\n */\n\n/** An interrupt an agent ends its run on (`RUN_FINISHED.outcome`). */\nexport interface AgUiInterrupt {\n id: string;\n /** `tool_call`, `confirmation`, `input_required`, or a producer's own string. */\n reason: string;\n message?: string;\n toolCallId?: string;\n responseSchema?: unknown;\n metadata?: Record<string, unknown>;\n}\n\n/** The events the runner maps; any other `type` is read and ignored. */\nexport type AgUiEvent =\n | { type: 'RUN_STARTED'; threadId?: string; runId?: string }\n | {\n type: 'RUN_FINISHED';\n threadId?: string;\n runId?: string;\n outcome?: { type: 'success' } | { type: 'interrupt'; interrupts: AgUiInterrupt[] };\n /** TanStack AI reports usage here, as an array. */\n usage?: unknown;\n }\n | { type: 'RUN_ERROR'; message?: string; code?: string }\n | { type: 'TEXT_MESSAGE_START'; messageId?: string; role?: string }\n | { type: 'TEXT_MESSAGE_CONTENT'; messageId?: string; delta?: string }\n | { type: 'TEXT_MESSAGE_END'; messageId?: string }\n | { type: 'TEXT_MESSAGE_CHUNK'; messageId?: string; role?: string; delta?: string }\n | { type: 'REASONING_MESSAGE_CONTENT'; messageId?: string; delta?: string }\n | { type: 'REASONING_MESSAGE_CHUNK'; messageId?: string; delta?: string }\n | { type: 'TOOL_CALL_START'; toolCallId: string; toolCallName: string; parentMessageId?: string }\n | { type: 'TOOL_CALL_ARGS'; toolCallId: string; delta?: string }\n | { type: 'TOOL_CALL_END'; toolCallId: string }\n | { type: 'TOOL_CALL_CHUNK'; toolCallId?: string; toolCallName?: string; delta?: string }\n | { type: 'TOOL_CALL_RESULT'; toolCallId: string; content?: unknown; metadata?: Record<string, unknown> };\n\n/** A part of a user message's content, as AG-UI 1.0 describes it — the two aparté sends. */\nexport type AgUiInputContent =\n | { type: 'text'; text: string }\n | { type: 'image'; source: { type: 'data' | 'url'; value: string; mimeType?: string } };\n\n/** One message of `RunAgentInput.messages`. */\nexport type AgUiMessage =\n | { id: string; role: 'system'; content: string }\n | { id: string; role: 'user'; content: string | AgUiInputContent[] }\n | {\n id: string;\n role: 'assistant';\n content?: string;\n toolCalls?: { id: string; type: 'function'; function: { name: string; arguments: string } }[];\n }\n | { id: string; role: 'tool'; content: string; toolCallId: string };\n\n/** One entry of `RunAgentInput.resume`: the answer to one interrupt. */\nexport interface AgUiResumeItem {\n interruptId: string;\n status: 'resolved' | 'cancelled';\n payload?: unknown;\n metadata?: Record<string, unknown>;\n}\n\n/** The request body an AG-UI agent endpoint takes. */\nexport interface AgUiRunAgentInput {\n threadId: string;\n runId: string;\n protocolVersion?: string;\n parentRunId?: string;\n state: unknown;\n messages: AgUiMessage[];\n tools: { name: string; description: string; parameters: unknown }[];\n context: { description: string; value: string }[];\n forwardedProps: Record<string, unknown>;\n resume?: AgUiResumeItem[];\n}\n\n/**\n * The events of an AG-UI response, in order. Server-Sent Events by default — each\n * `data:` block is one JSON event, comments and `event:` lines are skipped, and a\n * `[DONE]` sentinel ends nothing on its own. An NDJSON body (one event per line, the\n * other encoding TanStack AI serves) is read the same way. A block that is not JSON\n * is skipped: a proxy's keep-alive must not end the run.\n */\nexport async function* readAgUiEvents(\n body: ReadableStream<Uint8Array>,\n contentType: string | null,\n): AsyncGenerator<{ type: string } & Record<string, unknown>> {\n const ndjson = Boolean(contentType && /ndjson|jsonl/i.test(contentType));\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let data: string[] = [];\n const parse = (text: string): ({ type: string } & Record<string, unknown>) | undefined => {\n const trimmed = text.trim();\n if (!trimmed || trimmed === '[DONE]') return undefined;\n try {\n const value = JSON.parse(trimmed) as unknown;\n return value && typeof value === 'object' && typeof (value as { type?: unknown }).type === 'string'\n ? value as { type: string } & Record<string, unknown>\n : undefined;\n } catch {\n return undefined;\n }\n };\n const takeBlock = () => {\n const event = parse(data.join('\\n'));\n data = [];\n return event;\n };\n const line = (raw: string) => {\n const text = raw.endsWith('\\r') ? raw.slice(0, -1) : raw;\n if (ndjson) return parse(text);\n if (text === '') return takeBlock();\n if (text.startsWith('data:')) data.push(text.slice(5).replace(/^ /, ''));\n // `event:`, `id:`, `retry:` and `:` comments: AG-UI carries the type in the JSON.\n return undefined;\n };\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n let newline: number;\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const event = line(buffer.slice(0, newline));\n buffer = buffer.slice(newline + 1);\n if (event) yield event;\n }\n }\n buffer += decoder.decode();\n if (buffer) {\n const event = line(buffer);\n if (event) yield event;\n }\n if (!ndjson) {\n const event = takeBlock();\n if (event) yield event;\n }\n } finally {\n reader.releaseLock();\n }\n}\n","import { AparteError, AparteErrorCode, uuid } from '@aparte/core';\nimport type {\n AparteChatRequest,\n AparteStreamRunEvent,\n AparteStreamRunner,\n AparteStreamRunOptions,\n} from '@aparte/core';\nimport { toAgUiMessages, toAgUiTools } from './messages.js';\nimport { enforce } from './enforce.js';\nimport { applyStateDelta } from './state.js';\nimport { createTranslator } from './translate.js';\nimport { createVerifier } from './verify.js';\nimport { readAgUiEvents } from './wire.js';\nimport type { AgUiInterrupt, AgUiMessage, AgUiResumeItem, AgUiRunAgentInput } from './wire.js';\n\ntype Suspended = Extract<AparteStreamRunEvent, { type: 'run-suspended' }>;\ntype PendingCall = Suspended['pending'][number];\ntype Usage = NonNullable<Extract<AparteStreamRunEvent, { type: 'run-done' }>['usage']>;\ntype Outcome = NonNullable<NonNullable<AparteStreamRunOptions['deferral']>['outcomes']>[string];\n\nexport interface AgUiRunnerOptions {\n /** The agent's AG-UI endpoint, e.g. Agno's `/agui`, or a TanStack AI chat route. */\n endpoint: string;\n /** Sent with every request; a function is called per request (a fresh token each time). */\n headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);\n /** @default the global `fetch` */\n fetch?: typeof fetch;\n /** For a cross-origin endpoint that authenticates by cookie. */\n credentials?: RequestCredentials;\n /**\n * The AG-UI thread a turn runs in. Give the conversation's id when the agent keeps\n * state per thread (Agno's session); a function receives the run's options. A paused\n * run is always resumed in its own thread, whatever this returns.\n * @default a new thread per turn — the agent gets the whole history every time\n */\n threadId?: string | ((opts: AparteStreamRunOptions) => string);\n /** `RunAgentInput.forwardedProps`: settings your agent reads from the request. */\n forwardedProps?: Record<string, unknown>;\n /** `RunAgentInput.context`: extra context entries for the agent. */\n context?: { description: string; value: string }[];\n /**\n * The AG-UI version the agent speaks, when it is older than 1.0 and does not say so\n * itself, e.g. `'0.0.47'`. The protocol forbids guessing a peer's age, so an older\n * agent has to be named here. The runner then reads its stream with that version's\n * rules (its run framing, its retired shapes) and leaves `protocolVersion` out of the\n * request, a field that agent predates.\n * @default the agent speaks 1.0\n */\n peerProtocolVersion?: string;\n /**\n * Read a stream whose runs are framed otherwise than AG-UI 1.0 frames them: a\n * `RUN_FINISHED` per model step with more events after it, or a resume answered before\n * its `RUN_STARTED`. TanStack AI does both, so its routes need this; every other rule\n * of the protocol still holds. By default such a stream is rejected, as 1.0 asks.\n * @default false\n */\n relaxedRunFraming?: boolean;\n /**\n * Told what the runner dropped or could not read in the agent's stream — an event\n * type it does not know, a translation that lost something. For the developer, not\n * the person chatting.\n * @default `console.warn`\n */\n onWarning?: (message: string) => void;\n}\n\n/** The AG-UI version this runner speaks, and declares on every request. */\nconst PROTOCOL_VERSION = '1.0';\n\n/** A version identifier as numbers, compared component by component; undefined when it is not one. */\nfunction versionParts(version: string): number[] | undefined {\n return /^\\d+(\\.\\d+)*$/.test(version) ? version.split('.').map(Number) : undefined;\n}\n\n/** Negative, zero or positive, as `a` is older than, equal to or newer than `b`. */\nfunction compareVersions(a: number[], b: number[]): number {\n for (let i = 0; i < Math.max(a.length, b.length); i++) {\n const d = (a[i] ?? 0) - (b[i] ?? 0);\n if (d !== 0) return d;\n }\n return 0;\n}\n\n/**\n * What a paused run hands the page and gets back with the answers — `deferral.token`.\n * Opaque to the client; the runner reads it to resume in the same thread, after the\n * run it continues, with the interrupts it must answer.\n */\ninterface Ticket {\n v: 1;\n threadId: string;\n runId: string;\n /** `unanswerable`: an interrupt the page could not answer, cancelled in this batch. */\n interrupts: { id: string; toolCallId: string; kind: 'approval' | 'external' | 'unanswerable' }[];\n}\n\nfunction readTicket(token: string | undefined): Ticket | undefined {\n if (!token) return undefined;\n try {\n const ticket = JSON.parse(token) as Ticket;\n return ticket && ticket.v === 1 && typeof ticket.threadId === 'string' && typeof ticket.runId === 'string'\n && Array.isArray(ticket.interrupts) ? ticket : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** An interrupt's reason, as what the page must do about its call. */\nfunction interruptKind(interrupt: AgUiInterrupt): 'approval' | 'external' | undefined {\n if (interrupt.reason === 'tool_call' || interrupt.reason === 'confirmation') return 'approval';\n if (/client_tool/.test(interrupt.reason)) return 'external';\n return undefined;\n}\n\n/**\n * Usage as AG-UI agents report it — an object, or TanStack AI's array of model steps — as\n * the LAST step's report. That is what the page's own loop reports for a run of several\n * turns, and what the context gauge reads: the size of the conversation the model last saw.\n * Summed, a three-step run read as three times the context it used.\n */\nfunction readUsage(value: unknown): Usage | undefined {\n const entries = (Array.isArray(value) ? value : value && typeof value === 'object' ? [value] : [])\n .filter((u): u is Record<string, unknown> => Boolean(u) && typeof u === 'object');\n const last = entries.at(-1);\n if (!last) return undefined;\n const num = (key: string): number => (typeof last[key] === 'number' ? last[key] as number : 0);\n const cached = num('cachedInputTokens');\n return {\n inputTokens: num('inputTokens'),\n outputTokens: num('outputTokens'),\n totalTokens: num('totalTokens') || undefined,\n ...(cached ? { cacheReadTokens: cached } : {}),\n } as Usage;\n}\n\n/** A call's streamed arguments as its input: `{}` for none, the raw text when not JSON. */\nfunction parseArgs(args: string): unknown {\n if (!args.trim()) return {};\n try { return JSON.parse(args); } catch { return { arguments: args }; }\n}\n\n/** A tool result as the row shows it: text as is, the text of content parts, anything else as JSON. */\nfunction resultText(content: unknown): string {\n if (typeof content === 'string') return content;\n if (content === undefined || content === null) return '';\n if (Array.isArray(content)) {\n const text = content\n .filter((part): part is { type: 'text'; text: string } => (part as { type?: unknown })?.type === 'text' && typeof (part as { text?: unknown }).text === 'string')\n .map((part) => part.text);\n if (text.length) return text.join('\\n');\n }\n return JSON.stringify(content);\n}\n\n/** What the model reads about a refusal: the person's words, else core's fixed sentence. */\nfunction rejectionText(decision: { reason?: string; instruction?: string }): string {\n return decision.reason?.trim()\n || (decision.instruction ? `The user rejected this tool call and said: ${decision.instruction}` : 'Tool execution was rejected by the user.');\n}\n\n/** The answer a resumed interrupt carries, in the shape AG-UI (and TanStack AI) reads. */\nfunction resumeItem(interrupt: Ticket['interrupts'][number], outcome: Outcome | undefined): AgUiResumeItem {\n if (!outcome) return { interruptId: interrupt.id, status: 'cancelled' };\n if (outcome.kind === 'decision' && interrupt.kind === 'external' && !outcome.approved) {\n // A client tool the page refused to run (its `needsApproval`, its policy). An\n // execution interrupt answered `{ approved: false }` reads as a successful OUTPUT —\n // TanStack AI's `clientToolResult` takes any resolved payload without the error\n // state as `output-available` — so the model would read the decision as the tool's\n // result and lose the reason. It goes back as the tool's error, with the sentence.\n return {\n interruptId: interrupt.id,\n status: 'resolved',\n payload: { error: rejectionText(outcome) },\n metadata: { tanstack: { state: 'output-error' } },\n };\n }\n if (outcome.kind === 'decision') {\n return { interruptId: interrupt.id, status: 'resolved', payload: { approved: outcome.approved } };\n }\n if (outcome.kind === 'failed') {\n return {\n interruptId: interrupt.id,\n status: 'resolved',\n payload: { error: outcome.error },\n metadata: { tanstack: { state: 'output-error' } },\n };\n }\n return {\n interruptId: interrupt.id,\n status: 'resolved',\n payload: outcome.structuredContent !== undefined ? outcome.structuredContent : outcome.content,\n };\n}\n\n/**\n * An `AparteStreamRunner` for an agent served over AG-UI — Agno, LangGraph, Mastra,\n * CrewAI, Pydantic AI, CopilotKit's runtime, TanStack AI. The agent runs on its server,\n * with its own tools; this runner turns its event stream into the rows, text and\n * approvals `AparteClient` draws.\n *\n * ```ts\n * const client = new AparteClient({ streamRunner: createAgUiRunner({ endpoint: '/agui' }) });\n * ```\n *\n * Tools the PAGE registers go to the agent as AG-UI frontend tools. When the agent calls\n * one — or pauses on a call that needs a person (an AG-UI interrupt) — the run ends on\n * `run-suspended`; the client runs the tool or asks through its approval panel, then\n * calls this runner again with the answers, which go back as `tool` messages or as one\n * `resume` batch for the interrupts.\n */\nexport function createAgUiRunner(options: AgUiRunnerOptions): AparteStreamRunner {\n const warn = options.onWarning ?? ((message: string) => console.warn(`[aparte] AG-UI: ${message}`));\n const peer = options.peerProtocolVersion ? versionParts(options.peerProtocolVersion) : undefined;\n // A peer configured older than 1.0 predates `RunAgentInput.protocolVersion`, and its\n // run framing is read with the older rules.\n const declare = !peer || compareVersions(peer, [1, 0]) >= 0;\n // A peer of 0.0.39 or older takes a user message's content as text only.\n const flatten = peer !== undefined && compareVersions(peer, [0, 0, 39]) <= 0;\n // The agent's state, per thread: what its last snapshot and deltas left, sent back as\n // the next run's `state`. A thread minted for one turn is forgotten when the turn ends\n // — only a resume reuses it.\n const states = new Map<string, unknown>();\n const stableThread = options.threadId !== undefined;\n /** Interrupts a finished run left that the page could not answer, per thread: cancelled on its next run. */\n const unanswered = new Map<string, string[]>();\n const runOnce = async (opts: AparteStreamRunOptions, track: { threadId?: string; suspended: boolean }): Promise<Usage | undefined> => {\n const doFetch = options.fetch ?? fetch;\n const headers = typeof options.headers === 'function' ? await options.headers() : options.headers ?? {};\n const request = opts.baseRequest as AparteChatRequest;\n const ticket = readTicket(opts.deferral?.token);\n const outcomes = opts.deferral?.outcomes ?? {};\n const threadId = ticket?.threadId\n ?? (typeof options.threadId === 'function' ? options.threadId(opts) : options.threadId)\n ?? `aparte-${uuid()}`;\n track.threadId = threadId;\n const runId = `aparte-run-${uuid()}`;\n const interrupted = new Set((ticket?.interrupts ?? []).map((i) => i.toolCallId));\n\n // Answers to calls the agent left to the browser without an interrupt go back as\n // `tool` messages after the history; answers to interrupts go in one `resume`\n // batch, since the protocol refuses a partial one.\n const messages: AgUiMessage[] = toAgUiMessages(request.messages, flatten, warn);\n for (const [toolCallId, outcome] of Object.entries(outcomes)) {\n if (interrupted.has(toolCallId)) continue;\n // A page tool the page refused (its `needsApproval`, its policy): the refusal is\n // the call's result, the sentence the model reads. An approval needs no message.\n if (outcome.kind === 'decision' && outcome.approved) continue;\n messages.push({\n id: `aparte-result-${toolCallId}`,\n role: 'tool',\n toolCallId,\n content: outcome.kind === 'failed' ? `Error: ${outcome.error}`\n : outcome.kind === 'decision' ? rejectionText(outcome)\n : outcome.content,\n });\n }\n const left = ticket ? [] : (unanswered.get(threadId) ?? []);\n unanswered.delete(threadId);\n const resume = ticket?.interrupts.length\n ? ticket.interrupts.map((interrupt) => resumeItem(interrupt, interrupt.kind === 'unanswerable' ? undefined : outcomes[interrupt.toolCallId]))\n : left.length ? left.map((interruptId): AgUiResumeItem => ({ interruptId, status: 'cancelled' })) : undefined;\n\n const body: AgUiRunAgentInput = {\n threadId,\n runId,\n ...(declare ? { protocolVersion: PROTOCOL_VERSION } : {}),\n ...(ticket ? { parentRunId: ticket.runId } : {}),\n state: states.has(threadId) ? states.get(threadId) : {},\n messages,\n tools: toAgUiTools(request.tools),\n context: options.context ?? [],\n forwardedProps: options.forwardedProps ?? {},\n ...(resume ? { resume } : {}),\n };\n const response = await doFetch(options.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Accept: 'text/event-stream', ...headers },\n body: JSON.stringify(body),\n signal: opts.signal,\n ...(options.credentials ? { credentials: options.credentials } : {}),\n });\n if (!response.ok || !response.body) {\n const text = await response.text().catch(() => '');\n throw new AparteError(\n text.trim().slice(0, 300) || `The agent endpoint answered HTTP ${response.status}.`,\n AparteError.codeForStatus(response.status) ?? AparteErrorCode.PROVIDER_ERROR,\n undefined, undefined, response.status,\n );\n }\n\n // Calls the history already declares: a resumed run answers them, it does not\n // start them again (no second row).\n const history = new Map(request.messages.flatMap((m) => (m.toolCalls ?? []).map((c) => [c.id, { name: c.name, input: c.input ?? {} }] as const)));\n const known = new Set(history.keys());\n const browserTools = new Set((request.tools ?? []).map((t) => t.name));\n const calls = new Map<string, { name: string; args: string }>();\n const started = new Map<string, { name: string; input: unknown }>();\n const answered = new Set<string>();\n const rejected = new Set<string>();\n const settledByPage = new Set<string>();\n let textOpen = false;\n let runError: AparteError | undefined;\n let usage: Usage | undefined;\n let finished: { runId: string; outcome?: { type?: string; interrupts?: AgUiInterrupt[] } } | undefined;\n const emit = opts.emitter;\n\n const startTool = (toolCallId: string) => {\n const call = calls.get(toolCallId);\n if (!call || started.has(toolCallId) || known.has(toolCallId)) return;\n const input = parseArgs(call.args);\n started.set(toolCallId, { name: call.name, input });\n if (textOpen) { emit({ type: 'text-flush' }); textOpen = false; }\n emit({ type: 'tool-start', toolCallId, name: call.name, input });\n stepEnded = true;\n };\n\n // A model step ends on a tool call, or on a RUN_FINISHED (TanStack AI closes each\n // step with one). What the next step draws, its reasoning or its text, opens a new\n // turn, the way the in-page loop opens one per model call. Drawn into the old turn,\n // a second step's reasoning landed in the first step's thinking block, above the\n // tool row.\n let stepEnded = false;\n const nextStep = () => {\n if (!stepEnded) return;\n stepEnded = false;\n if (textOpen) { emit({ type: 'text-flush' }); textOpen = false; }\n emit({ type: 'turn-start' });\n };\n\n /** The call an interrupt is about: started in this run, else in the history, else as the interrupt describes it. */\n const callOf = (interrupt: AgUiInterrupt & { toolCallId: string }): { name: string; input: unknown } => {\n const here = started.get(interrupt.toolCallId) ?? history.get(interrupt.toolCallId);\n if (here) return here;\n const streamed = calls.get(interrupt.toolCallId);\n if (streamed) return { name: streamed.name, input: parseArgs(streamed.args) };\n // TanStack AI describes the call on the interrupt itself.\n const meta = interrupt.metadata as { toolName?: unknown; input?: unknown } | undefined;\n return { name: typeof meta?.toolName === 'string' ? meta.toolName : '', input: meta?.input ?? {} };\n };\n\n // A stream that closes between two steps is cut, not finished: TanStack AI sends a\n // RUN_FINISHED per step, so having seen one says nothing about the last.\n let endedOnFinish = false;\n\n // The run opens on its FIRST event, whatever it is: a resumed TanStack AI run sends\n // the approved call's TOOL_CALL_RESULT before RUN_STARTED, and settling that row\n // after its result put it back to pending. The answers this run carries settle\n // their rows before anything else.\n let begun = false;\n const begin = () => {\n if (begun) return;\n begun = true;\n emit({ type: 'run-start' });\n emit({ type: 'turn-start' });\n for (const [toolCallId, outcome] of Object.entries(outcomes)) {\n // A tool the PAGE ran: its row settles here, with the result the page holds —\n // a plain AG-UI agent never echoes a frontend tool's result, so nothing\n // else would, and an echo that does come is not drawn twice.\n if (outcome.kind === 'result') {\n emit({\n type: 'tool-resolved',\n toolCallId,\n result: outcome.content,\n ...(outcome.structuredContent !== undefined ? { structuredResult: outcome.structuredContent } : {}),\n });\n settledByPage.add(toolCallId);\n continue;\n }\n if (outcome.kind === 'failed') {\n emit({ type: 'tool-failed', toolCallId, error: outcome.error });\n settledByPage.add(toolCallId);\n continue;\n }\n if (outcome.approved) {\n emit({ type: 'tool-approved', toolCallId });\n } else {\n emit({ type: 'tool-rejected', toolCallId, reason: rejectionText(outcome) });\n rejected.add(toolCallId);\n }\n }\n };\n\n const verify = createVerifier(!declare || options.relaxedRunFraming === true);\n const translate = createTranslator(peer, warn);\n // Older shapes are translated first; then what 1.0 does not describe is dropped or\n // stripped, with a warning — the order the protocol requires of a consumer.\n async function* incoming(body: ReadableStream<Uint8Array>, contentType: string | null) {\n for await (const raw of readAgUiEvents(body, contentType)) {\n for (const translated of translate(raw)) {\n const event = enforce(translated, warn);\n if (event) yield event;\n }\n }\n }\n for await (const event of incoming(response.body, response.headers.get('content-type'))) {\n // A stream 1.0 says to reject is rejected before its event is drawn; what was\n // drawn before it stays, and the error lands below it.\n verify(event);\n begin();\n if (/^(TEXT_MESSAGE|REASONING|TOOL_CALL)_/.test(event.type)) endedOnFinish = false;\n switch (event.type) {\n case 'RUN_STARTED': {\n // A run after a failed one supersedes it: the stream ran again, and the new\n // run decides how the reply ends. The failure is the developer's to know;\n // the calls the failed run left are stopped, nobody will answer them.\n if (runError) {\n warn(`the agent's run failed (\"${runError.message}\") and the stream ran it again; the reply shows the new run.`);\n for (const [toolCallId] of started) {\n if (answered.has(toolCallId)) continue;\n emit({ type: 'tool-aborted', toolCallId });\n answered.add(toolCallId);\n }\n runError = undefined;\n }\n // The producer's own version. Newer, or not a version at all: proceed\n // under 1.0's rules and say so, as the protocol asks of a consumer.\n const declared = event['protocolVersion'];\n if (typeof declared === 'string') {\n const parts = versionParts(declared);\n if (!parts) warn(`the agent declares protocol version \"${declared}\", which this runner cannot interpret; reading its stream as ${PROTOCOL_VERSION}.`);\n else if (compareVersions(parts, versionParts(PROTOCOL_VERSION)!) > 0) warn(`the agent speaks AG-UI ${declared}, newer than the ${PROTOCOL_VERSION} this runner speaks; reading its stream as ${PROTOCOL_VERSION}.`);\n }\n break;\n }\n case 'TEXT_MESSAGE_START':\n case 'REASONING_START':\n case 'REASONING_MESSAGE_START':\n nextStep();\n break;\n case 'TEXT_MESSAGE_CONTENT':\n case 'TEXT_MESSAGE_CHUNK': {\n const delta = typeof event['delta'] === 'string' ? event['delta'] : '';\n if (delta) { nextStep(); emit({ type: 'text-delta', delta }); textOpen = true; }\n break;\n }\n case 'TEXT_MESSAGE_END': {\n if (textOpen) { emit({ type: 'text-flush' }); textOpen = false; }\n break;\n }\n case 'REASONING_MESSAGE_CONTENT':\n case 'REASONING_MESSAGE_CHUNK': {\n const delta = typeof event['delta'] === 'string' ? event['delta'] : '';\n if (delta) { nextStep(); emit({ type: 'thinking-delta', delta }); }\n break;\n }\n case 'TOOL_CALL_START': {\n const id = String(event['toolCallId']);\n calls.set(id, { name: String(event['toolCallName'] ?? ''), args: '' });\n break;\n }\n case 'TOOL_CALL_ARGS': {\n const call = calls.get(String(event['toolCallId']));\n if (call && typeof event['delta'] === 'string') call.args += event['delta'];\n break;\n }\n case 'TOOL_CALL_CHUNK': {\n const id = typeof event['toolCallId'] === 'string' ? event['toolCallId'] : [...calls.keys()].at(-1);\n if (!id) break;\n const call = calls.get(id) ?? { name: '', args: '' };\n if (typeof event['toolCallName'] === 'string' && event['toolCallName']) call.name = event['toolCallName'];\n if (typeof event['delta'] === 'string') call.args += event['delta'];\n calls.set(id, call);\n break;\n }\n case 'TOOL_CALL_END': {\n startTool(String(event['toolCallId']));\n break;\n }\n case 'TOOL_CALL_RESULT': {\n const toolCallId = String(event['toolCallId']);\n startTool(toolCallId);\n if (rejected.has(toolCallId) || settledByPage.has(toolCallId)) break; // already settled\n answered.add(toolCallId);\n const content = resultText(event['content']);\n const meta = event['metadata'] as { tanstack?: { state?: unknown } } | undefined;\n if (meta?.tanstack?.state === 'output-error') {\n emit({ type: 'tool-failed', toolCallId, error: content });\n } else {\n // A result in content parts keeps them for a renderer; the model reads their text.\n const parts = Array.isArray(event['content']) ? { structuredResult: event['content'] } : {};\n emit({ type: 'tool-resolved', toolCallId, result: content, ...parts });\n }\n break;\n }\n case 'RUN_ERROR': {\n // The agent reporting its own failure does not end the stream: a\n // RUN_STARTED may follow and run again, and a late one can come after a\n // run that finished. What was drawn stays; the failure is said once the\n // stream is over, and core appends it below the reply.\n runError = new AparteError(\n typeof event['message'] === 'string' && event['message'] ? event['message'] : 'The agent run failed.',\n AparteErrorCode.PROVIDER_ERROR,\n { agUi: 'run-error', ...(typeof event['code'] === 'string' ? { code: event['code'] } : {}) },\n );\n break;\n }\n case 'STATE_SNAPSHOT':\n states.set(threadId, event['snapshot']);\n break;\n case 'STATE_DELTA':\n states.set(threadId, applyStateDelta(states.has(threadId) ? states.get(threadId) : {}, event['delta'], warn));\n break;\n case 'RUN_FINISHED': {\n // Not the end of the stream: TanStack AI closes each model step with a\n // RUN_FINISHED of its own (`finishReason: tool_calls`), then streams the\n // tool results and the next step. The LAST one says how the run ended.\n for (const id of calls.keys()) startTool(id);\n if (textOpen) { emit({ type: 'text-flush' }); textOpen = false; }\n usage = readUsage(event['usage']) ?? usage; // the last step's report wins\n stepEnded = true;\n endedOnFinish = true;\n finished = {\n runId: typeof event['runId'] === 'string' ? event['runId'] : runId,\n outcome: event['outcome'] as { type?: string; interrupts?: AgUiInterrupt[] } | undefined,\n };\n break;\n }\n default:\n // STEP_*, STATE_*, MESSAGES_SNAPSHOT, ACTIVITY_*, RAW, CUSTOM, SUBAGENT_*:\n // agent state aparté does not draw.\n break;\n }\n }\n if (opts.signal.aborted) return usage;\n if (runError) {\n for (const [toolCallId] of started) if (!answered.has(toolCallId)) emit({ type: 'tool-aborted', toolCallId });\n if (textOpen) emit({ type: 'text-flush' });\n throw runError;\n }\n if (!finished) {\n throw new AparteError('The agent stream ended without RUN_FINISHED.', AparteErrorCode.PROVIDER_ERROR);\n }\n if (!endedOnFinish) {\n throw new AparteError('The agent stream was cut: it ended in the middle of a step, after a RUN_FINISHED.', AparteErrorCode.PROVIDER_ERROR);\n }\n verify.end();\n if (textOpen) emit({ type: 'text-flush' });\n\n const pending: PendingCall[] = [];\n const interrupts: Ticket['interrupts'] = [];\n // Interrupts the page has no way to answer — no call to approve or run, or a reason\n // it does not know. The run ends without failing; they are answered `cancelled`\n // in the next resume of the thread, which a paused thread needs to continue.\n const unanswerable: string[] = [];\n if (finished.outcome?.type === 'interrupt') {\n for (const interrupt of finished.outcome.interrupts ?? []) {\n const kind = interruptKind(interrupt);\n if (!kind || !interrupt.toolCallId) {\n unanswerable.push(interrupt.id);\n continue;\n }\n // A resumed run can pause again on a call an earlier run started (TanStack AI\n // asks to approve a client tool, then to run it): its name comes from there.\n const call = callOf(interrupt as AgUiInterrupt & { toolCallId: string });\n if (kind === 'approval') {\n emit({ type: 'tool-awaiting-approval', toolCallId: interrupt.toolCallId, name: call.name, input: call.input });\n }\n interrupts.push({ id: interrupt.id, toolCallId: interrupt.toolCallId, kind });\n pending.push({ toolCallId: interrupt.toolCallId, name: call.name, input: call.input, reason: kind });\n }\n } else {\n // Plain AG-UI: the calls left to the browser are the ones the agent names\n // (`pendingToolCallIds`, AG-UI 1.0), else the page's own tools nobody answered.\n // Any other call without a result has nobody left to answer it: its row stops\n // waiting rather than spinning after the run. A cancelled run leaves nothing.\n const outcome = finished.outcome as { type?: string; pendingToolCallIds?: unknown } | undefined;\n const named = Array.isArray(outcome?.pendingToolCallIds)\n ? new Set(outcome.pendingToolCallIds.filter((id): id is string => typeof id === 'string'))\n : undefined;\n for (const [toolCallId, call] of started) {\n if (answered.has(toolCallId)) continue;\n const forPage = outcome?.type !== 'cancelled' && (named ? named.has(toolCallId) : browserTools.has(call.name));\n if (forPage) pending.push({ toolCallId, name: call.name, input: call.input, reason: 'external' });\n else emit({ type: 'tool-aborted', toolCallId });\n }\n }\n if (pending.length > 0) {\n const cancelled = unanswerable.map((id) => ({ id, toolCallId: '', kind: 'unanswerable' as const }));\n const next: Ticket = { v: 1, threadId, runId: finished.runId, interrupts: [...interrupts, ...cancelled] };\n track.suspended = true;\n emit({ type: 'run-suspended', pending, ...(usage ? { usage } : {}), ticket: JSON.stringify(next) } as Suspended);\n } else {\n if (unanswerable.length && stableThread) unanswered.set(threadId, unanswerable);\n emit({ type: 'run-done', ...(usage ? { usage } : {}) });\n }\n return usage;\n };\n return async (opts) => {\n const track: { threadId?: string; suspended: boolean } = { suspended: false };\n try {\n return await runOnce(opts, track);\n } finally {\n // A thread minted for one turn is forgotten when the turn ends, however it ends —\n // done, failed or stopped — unless it paused, since only a resume reuses it.\n if (track.threadId && !stableThread && !track.suspended) states.delete(track.threadId);\n }\n };\n}\n"],"names":["index","body"],"mappings":"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"}
|
package/dist/messages.d.ts
CHANGED
|
@@ -5,10 +5,11 @@ import type { AgUiMessage, AgUiRunAgentInput } from './wire.js';
|
|
|
5
5
|
* requires one) that is stable across the runs of one turn — its position — so a resume
|
|
6
6
|
* replays the same history the paused run saw. A call is `{ id, type: 'function',
|
|
7
7
|
* function: { name, arguments } }` with the arguments as a JSON string, and a result is
|
|
8
|
-
* a `tool` message naming its call.
|
|
9
|
-
*
|
|
8
|
+
* a `tool` message naming its call. A user message with an image goes as AG-UI 1.0
|
|
9
|
+
* content parts; toward a peer that predates them (`flatten`), as its text alone — which
|
|
10
|
+
* drops the image, and says so.
|
|
10
11
|
*/
|
|
11
|
-
export declare function toAgUiMessages(messages: readonly AparteChatMessage[]): AgUiMessage[];
|
|
12
|
+
export declare function toAgUiMessages(messages: readonly AparteChatMessage[], flatten: boolean, warn: (message: string) => void): AgUiMessage[];
|
|
12
13
|
/** The page's tools as `RunAgentInput.tools`: the ones the agent may ask the browser to run. */
|
|
13
14
|
export declare function toAgUiTools(tools: readonly AparteTool[] | undefined): AgUiRunAgentInput['tools'];
|
|
14
15
|
//# sourceMappingURL=messages.d.ts.map
|
package/dist/messages.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAqB,UAAU,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,KAAK,EAAoB,WAAW,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAalF;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC1B,QAAQ,EAAE,SAAS,iBAAiB,EAAE,EACtC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAChC,WAAW,EAAE,CAmCf;AAED,gGAAgG;AAChG,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,SAAS,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAEhG"}
|
package/dist/runner.d.ts
CHANGED
|
@@ -22,6 +22,30 @@ export interface AgUiRunnerOptions {
|
|
|
22
22
|
description: string;
|
|
23
23
|
value: string;
|
|
24
24
|
}[];
|
|
25
|
+
/**
|
|
26
|
+
* The AG-UI version the agent speaks, when it is older than 1.0 and does not say so
|
|
27
|
+
* itself, e.g. `'0.0.47'`. The protocol forbids guessing a peer's age, so an older
|
|
28
|
+
* agent has to be named here. The runner then reads its stream with that version's
|
|
29
|
+
* rules (its run framing, its retired shapes) and leaves `protocolVersion` out of the
|
|
30
|
+
* request, a field that agent predates.
|
|
31
|
+
* @default the agent speaks 1.0
|
|
32
|
+
*/
|
|
33
|
+
peerProtocolVersion?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Read a stream whose runs are framed otherwise than AG-UI 1.0 frames them: a
|
|
36
|
+
* `RUN_FINISHED` per model step with more events after it, or a resume answered before
|
|
37
|
+
* its `RUN_STARTED`. TanStack AI does both, so its routes need this; every other rule
|
|
38
|
+
* of the protocol still holds. By default such a stream is rejected, as 1.0 asks.
|
|
39
|
+
* @default false
|
|
40
|
+
*/
|
|
41
|
+
relaxedRunFraming?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Told what the runner dropped or could not read in the agent's stream — an event
|
|
44
|
+
* type it does not know, a translation that lost something. For the developer, not
|
|
45
|
+
* the person chatting.
|
|
46
|
+
* @default `console.warn`
|
|
47
|
+
*/
|
|
48
|
+
onWarning?: (message: string) => void;
|
|
25
49
|
}
|
|
26
50
|
/**
|
|
27
51
|
* An `AparteStreamRunner` for an agent served over AG-UI — Agno, LangGraph, Mastra,
|
package/dist/runner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGR,kBAAkB,EAClB,sBAAsB,EACzB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGR,kBAAkB,EAClB,sBAAsB,EACzB,MAAM,cAAc,CAAC;AActB,MAAM,WAAW,iBAAiB;IAC9B,oFAAoF;IACpF,QAAQ,EAAE,MAAM,CAAC;IACjB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACpG,kCAAkC;IAClC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,gEAAgE;IAChE,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,sBAAsB,KAAK,MAAM,CAAC,CAAC;IAC/D,kFAAkF;IAClF,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,oEAAoE;IACpE,OAAO,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACnD;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAkID;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,kBAAkB,CAmY/E"}
|
package/dist/state.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agent's shared state, as AG-UI streams it: `STATE_SNAPSHOT` replaces it whole
|
|
3
|
+
* (any JSON value, `null` and `0` included) and `STATE_DELTA` patches it with an
|
|
4
|
+
* RFC 6902 JSON Patch. The runner keeps the result per thread and sends it back as the
|
|
5
|
+
* next run's `state`, so a stateful agent finds what it left.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* The state after a `STATE_DELTA`. Applied whole or not at all: a patch whose operation
|
|
9
|
+
* fails leaves the state as it was. An operation RFC 6902 does not define is dropped
|
|
10
|
+
* from the patch, the rest applies. Both are told to `warn`; neither fails the run.
|
|
11
|
+
*/
|
|
12
|
+
export declare function applyStateDelta(state: unknown, delta: unknown, warn: (message: string) => void): unknown;
|
|
13
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA2GH;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAkBxG"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type AgUiEvent = {
|
|
2
|
+
type: string;
|
|
3
|
+
} & Record<string, unknown>;
|
|
4
|
+
/**
|
|
5
|
+
* What older AG-UI shapes become before the runner reads them — a middleware, run before
|
|
6
|
+
* anything is stripped, as the protocol requires of a translation:
|
|
7
|
+
*
|
|
8
|
+
* - The retired `THINKING_*` events are always translated into their `REASONING_*`
|
|
9
|
+
* replacements: a producer may still send them whatever it declares. The span's title
|
|
10
|
+
* has no place in the replacement, so the translation says so.
|
|
11
|
+
* - A peer of 0.0.57 or older predates subagents: `SUBAGENT_*` events are dropped and
|
|
12
|
+
* attribution removed, with a warning, rather than read as 1.0 material.
|
|
13
|
+
*
|
|
14
|
+
* `peer` is the configured peer version as numbers; undefined is a 1.0 peer.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createTranslator(peer: readonly number[] | undefined, warn: (message: string) => void): (event: AgUiEvent) => AgUiEvent[];
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=translate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../src/translate.ts"],"names":[],"mappings":"AAAA,KAAK,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAW5D;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,SAAS,EAAE,CA8CxI"}
|
package/dist/verify.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
type AgUiEvent = {
|
|
2
|
+
type: string;
|
|
3
|
+
} & Record<string, unknown>;
|
|
4
|
+
export interface Verifier {
|
|
5
|
+
(event: AgUiEvent): void;
|
|
6
|
+
/** The stream is over. Under a relaxed run framing, what is still open is refused here, not at each RUN_FINISHED. */
|
|
7
|
+
end(): void;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The stream rules of AG-UI 1.0 a consumer enforces before anything is drawn: a run is
|
|
11
|
+
* framed by RUN_STARTED and RUN_FINISHED (or RUN_ERROR, which ends what was open), a
|
|
12
|
+
* message, a tool call, a step or a subagent is opened before it continues and closed
|
|
13
|
+
* before the run finishes, a chunk stream starts with its identity and keeps it, and a
|
|
14
|
+
* known field has its type. What is open is tracked per owner — the run, or each subagent
|
|
15
|
+
* invocation — as the protocol requires: a parent and a subagent may each have a step of
|
|
16
|
+
* the same name open, and one invocation ending closes none of another's.
|
|
17
|
+
*
|
|
18
|
+
* `relaxed` reads the run framing with the older rules — a peer older than 1.0, or a
|
|
19
|
+
* producer named as framing runs its own way (TanStack AI closes each step with a
|
|
20
|
+
* RUN_FINISHED and answers a resume before its RUN_STARTED): the framing is not checked,
|
|
21
|
+
* and what is still open is refused at the end of the stream rather than at each
|
|
22
|
+
* RUN_FINISHED. Every other rule holds.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createVerifier(relaxed: boolean): Verifier;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAEA,KAAK,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAkC5D,MAAM,WAAW,QAAQ;IACrB,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACzB,qHAAqH;IACrH,GAAG,IAAI,IAAI,CAAC;CACf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,CAgLzD"}
|
package/dist/wire.d.ts
CHANGED
|
@@ -81,6 +81,18 @@ export type AgUiEvent = {
|
|
|
81
81
|
content?: unknown;
|
|
82
82
|
metadata?: Record<string, unknown>;
|
|
83
83
|
};
|
|
84
|
+
/** A part of a user message's content, as AG-UI 1.0 describes it — the two aparté sends. */
|
|
85
|
+
export type AgUiInputContent = {
|
|
86
|
+
type: 'text';
|
|
87
|
+
text: string;
|
|
88
|
+
} | {
|
|
89
|
+
type: 'image';
|
|
90
|
+
source: {
|
|
91
|
+
type: 'data' | 'url';
|
|
92
|
+
value: string;
|
|
93
|
+
mimeType?: string;
|
|
94
|
+
};
|
|
95
|
+
};
|
|
84
96
|
/** One message of `RunAgentInput.messages`. */
|
|
85
97
|
export type AgUiMessage = {
|
|
86
98
|
id: string;
|
|
@@ -89,7 +101,7 @@ export type AgUiMessage = {
|
|
|
89
101
|
} | {
|
|
90
102
|
id: string;
|
|
91
103
|
role: 'user';
|
|
92
|
-
content: string;
|
|
104
|
+
content: string | AgUiInputContent[];
|
|
93
105
|
} | {
|
|
94
106
|
id: string;
|
|
95
107
|
role: 'assistant';
|
|
@@ -119,8 +131,9 @@ export interface AgUiResumeItem {
|
|
|
119
131
|
export interface AgUiRunAgentInput {
|
|
120
132
|
threadId: string;
|
|
121
133
|
runId: string;
|
|
134
|
+
protocolVersion?: string;
|
|
122
135
|
parentRunId?: string;
|
|
123
|
-
state:
|
|
136
|
+
state: unknown;
|
|
124
137
|
messages: AgUiMessage[];
|
|
125
138
|
tools: {
|
|
126
139
|
name: string;
|
package/dist/wire.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../src/wire.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../src/wire.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aparte/runner-ag-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"homepage": "https://apartejs.dev/providers/agent/ag-ui/",
|
|
5
5
|
"description": "Render an AG-UI agent in aparté — Agno, LangGraph, Mastra, CrewAI, Pydantic AI, TanStack AI: the agent runs on its server, aparté draws the chat, its tool calls and its approvals.",
|
|
6
6
|
"type": "module",
|
|
@@ -25,15 +25,15 @@
|
|
|
25
25
|
"node": ">=18"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@aparte/core": ">=0.
|
|
28
|
+
"@aparte/core": ">=0.22.0 <1.0.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@ag-ui/core": "^1.0.0",
|
|
32
|
-
"@tanstack/ai": "^0.
|
|
32
|
+
"@tanstack/ai": "^1.0.0",
|
|
33
33
|
"@types/node": "^22.0.0",
|
|
34
34
|
"typescript": "^5.4.0",
|
|
35
35
|
"vite": "^6.0.0",
|
|
36
|
-
"@aparte/core": "0.
|
|
36
|
+
"@aparte/core": "0.22.0"
|
|
37
37
|
},
|
|
38
38
|
"keywords": [
|
|
39
39
|
"ai",
|