import { Tool, Middleware, RunAgentInput, AbstractAgent, BaseEvent } from '@ag-ui/client'; import { Observable } from 'rxjs'; /** * A2UI v0.9 inline catalog schema. * Matches the structure defined by the A2UI specification (basic_catalog.json). * Components are keyed by name and use standard JSON Schema to describe * their properties in the flat wire format. */ interface A2UIInlineCatalogSchema { /** Catalog identifier */ catalogId: string; /** Component schemas keyed by component name */ components: Record>; } /** * @deprecated Use A2UIInlineCatalogSchema instead. * Legacy component schema definition with { name, props } format. */ interface A2UIComponentSchema { /** Component name (e.g. "TodoCard", "FlightResult") */ name: string; /** Human-readable description for the AI agent */ description?: string; /** Component props as JSON Schema */ props?: Record; /** Named slots for child components */ slots?: string[]; } /** * Configuration for the A2UI Middleware */ interface A2UIMiddlewareConfig { /** * Component schema — declares which components are available to agents. * When provided, the schema is injected as context into RunAgentInput * so agents know what components they can generate. * * Accepts the v0.9 inline catalog format (preferred) or the legacy * array format for backwards compatibility. */ schema?: A2UIInlineCatalogSchema | A2UIComponentSchema[]; /** * A2UI generation-lifecycle options (OSS-162). A server-side knob applied to * every agent this middleware wraps — Python and TypeScript alike, since the * middleware is the single emitter of the generation lifecycle for all of them. * Values are stamped onto the `a2ui-surface` activity's pre-paint content * (`status: "building" | "retrying" | "failed"`) so the client renderer honors * them. The whole lifecycle rides one stable messageId and is replaced in place * by the painted surface. * * - `debugExposure` — how much retry/error detail the renderer surfaces: * `"hidden"` (no expander), `"collapsed"` (expander present, closed), or * `"verbose"` (expander open). When unset, the client default (`"collapsed"`) * applies. * - `showProgressTokens` — when `true` (default), the building skeleton carries * a throttled live token estimate of the streamed UI spec. Set `false` for a * countless skeleton (the CSS animation is unaffected either way). * - `maxAttempts` — the retry cap shown in the "Retrying… (N/M attempts)" label. * Defaults to the toolkit's `MAX_A2UI_ATTEMPTS`; set it to match the adapter's * recovery cap if you override that. */ recovery?: { debugExposure?: "hidden" | "collapsed" | "verbose"; showProgressTokens?: boolean; maxAttempts?: number; }; /** * Controls whether the middleware injects an A2UI rendering tool into * the agent's tool list. * * - `true` — injects a tool named `"render_a2ui"` (default name). * - `string` — injects the tool with the given custom name. * - `false` / omitted — no tool is injected; the middleware relies on * the agent producing A2UI JSON through its own means and will still * detect and render any valid A2UI JSON in the event stream. */ injectA2UITool?: boolean | string; /** * Tool names the middleware recognizes as A2UI rendering tools. * When the middleware sees a TOOL_CALL_START for any of these names, * it tracks streaming args to progressively extract components/items * and emits a synthetic TOOL_CALL_RESULT at RUN_FINISHED. * * Defaults to `["render_a2ui"]`. */ a2uiToolNames?: string[]; /** * Catalog id used when the middleware creates a surface from a STREAMED * render tool call. * * The streamed `render_a2ui` args no longer carry a catalogId — catalog * choice belongs to the host/factory, not the subagent (the subagent must * not be able to invent a catalog the frontend hasn't registered). Since * the streaming `createSurface` op is emitted before the factory's final * envelope is available, the middleware needs the catalog id up front. * * Set this to the same catalog id the factory's `defaultCatalogId` uses. * When omitted, the middleware falls back to any catalogId present in the * streamed args, then to the v0.9 basic catalog. */ defaultCatalogId?: string; } /** * User action payload sent via forwardedProps.a2uiAction */ interface A2UIUserAction { /** Name of the action being performed */ name?: string; /** ID of the surface the action occurred on */ surfaceId?: string; /** ID of the component within the surface */ sourceComponentId?: string; /** Optional context data for the action */ context?: Record; /** Optional timestamp of the action */ timestamp?: string; } /** * Expected structure of forwardedProps for A2UI actions */ interface A2UIForwardedProps { a2uiAction?: { userAction: A2UIUserAction; }; } /** * A2UI message types (v0.9) */ type A2UIMessageType = "createSurface" | "updateComponents" | "updateDataModel" | "deleteSurface"; /** * A2UI message structure (v0.9) */ interface A2UIMessage { createSurface?: { surfaceId: string; catalogId: string; theme?: Record; attachDataModel?: boolean; }; updateComponents?: { surfaceId: string; components: Array>; }; updateDataModel?: { surfaceId: string; path?: string; value?: unknown; }; deleteSurface?: { surfaceId: string; }; } /** * Tool name for the structured render_a2ui tool */ declare const RENDER_A2UI_TOOL_NAME = "render_a2ui"; /** * Tool name for logging A2UI events (synthetic, used for context) */ declare const LOG_A2UI_EVENT_TOOL_NAME = "log_a2ui_event"; /** * Tool definition for rendering A2UI surfaces. * This tool is injected into the agent's available tools when injectA2UITool is true. * Uses structured parameters (surfaceId, components, data) — the catalog id * is owned by the middleware config, not chosen by the model. */ declare const RENDER_A2UI_TOOL: Tool; /** * Usage guidelines injected as context when injectA2UITool is enabled. * Provides the LLM with protocol instructions and a minimal example * for calling render_a2ui correctly. */ declare const RENDER_A2UI_TOOL_GUIDELINES: (toolName: string) => string; /** * Extract complete items from a partially-streamed JSON object. * Given partial JSON like `{"flights": [{"id":"1",...}, {"id":"2"` and dataKey "flights", * returns an array of all complete objects parsed so far, or null if none found. */ declare function extractCompleteItems(partial: string, dataKey: string): unknown[] | null; /** * Extract a complete JSON object value for a given key from partially-streamed JSON. * Given partial JSON like `{"surfaceId": "s1", "data": {"form": {"name": "Alice"}}, "other":` * and dataKey "data", returns the parsed object `{"form": {"name": "Alice"}}` or null if * the object value is not yet fully closed. * * Only matches the key at the TOP LEVEL — a nested object that happens to * carry the same key (e.g. a component with its own `data` property) is * ignored. This keeps the streaming intercept correct even when component * payloads contain JSON keys that overlap with the render_a2ui arg names. */ declare function extractCompleteObject(partial: string, dataKey: string): Record | null; /** * Extended version of extractCompleteItems that also reports whether the * array has been fully closed in the stream (i.e., the closing `]` has * been received). */ declare function extractCompleteItemsWithStatus(partial: string, dataKey: string): { items: unknown[]; arrayClosed: boolean; } | null; /** * Incrementally extract complete items from the array at `data.` * inside partially-streamed render_a2ui args. * * The render_a2ui args look like: * `{"surfaceId":"s","components":[...],"data":{"items":[{...},{...}` (still streaming) * * We scope the search to the `data` object region first (so a `"items"` token * that appears inside a component's `path` string — e.g. `"path":"/items"` — * is never mistaken for the data array), then reuse the array-item extractor * to return every fully-closed item parsed so far. * * Returns `{ items, arrayClosed }` or null when the data array hasn't started * or no complete item exists yet. */ declare function extractDataArrayItems(partial: string, itemsKey: string): { items: unknown[]; arrayClosed: boolean; } | null; /** * Extract a simple string field value from partial JSON. * Looks for `"key": "value"` and returns the value, or null if incomplete. */ declare function extractStringField(partialJson: string, key: string): string | null; /** * Extract complete A2UI operation objects from the partially-streamed tool call args * for `send_a2ui_json_to_client`. * * The tool call args JSON looks like: `{"a2ui_json": "[{\"surfaceUpdate\":...}, ...]"}` * The `a2ui_json` value is a JSON-encoded string containing an array of operations. * * This function: * 1. Extracts the partial string value of `a2ui_json` from the partial outer JSON * 2. Unescapes JSON escape sequences to recover the inner JSON * 3. Finds complete top-level objects in the inner partial array */ declare function extractCompleteA2UIOperations(partialArgs: string): Array> | null; /** * A2UI JSON Schema * Full specification for A2UI (Agent to UI) messages. * Source: https://github.com/anthropics/A2UI * * This schema is designed to be added to system prompts between the markers: * ---BEGIN A2UI JSON SCHEMA--- * * ---END A2UI JSON SCHEMA--- */ /** * @deprecated Do not use built-in schemas. Component schemas must be passed * explicitly from application code via CopilotRuntime's `a2ui.schema` config. * The middleware injects these as context for agents automatically. */ declare const A2UI_PROMPT = "---BEGIN A2UI JSON SCHEMA---\n\n## A2UI v0.9 Protocol Instructions\n\nA2UI (Agent to UI) is a protocol for rendering rich UI surfaces from agent responses.\nWhen using the send_a2ui_json_to_client tool, you MUST follow these rules:\n\n### CRITICAL: Required Message Sequence\n\nTo render a surface, you MUST send ALL messages in a SINGLE tool call, in this order:\n1. **createSurface** - Create the surface (REQUIRED, only for initial render)\n2. **updateComponents** - Define all UI components (REQUIRED)\n3. **updateDataModel** - Set any data values (OPTIONAL)\n\n**IMPORTANT**:\n- The `createSurface` message is MANDATORY for the first render. Without it, the client has no surface to render into.\n- ALL messages MUST be in the SAME a2ui_json array in ONE tool call.\n- Every message MUST include `\"version\": \"v0.9\"`.\n- The root component MUST have `\"id\": \"root\"`.\n\n### Minimal Working Example\n\nHere is the simplest possible A2UI surface - a button:\n\n```json\n[\n {\n \"version\": \"v0.9\",\n \"createSurface\": {\n \"surfaceId\": \"my-surface\",\n \"catalogId\": \"https://a2ui.org/specification/v0_9/basic_catalog.json\"\n }\n },\n {\n \"version\": \"v0.9\",\n \"updateComponents\": {\n \"surfaceId\": \"my-surface\",\n \"components\": [\n {\n \"id\": \"root\",\n \"component\": \"Button\",\n \"child\": \"btn-text\",\n \"action\": { \"event\": { \"name\": \"button_clicked\" } }\n },\n {\n \"id\": \"btn-text\",\n \"component\": \"Text\",\n \"text\": \"Click Me\"\n }\n ]\n }\n }\n]\n```\n\n### Key Rules\n\n1. **Always include createSurface** for new surfaces - This tells the client to create the surface.\n2. **Use unique surfaceId values** - Each surface must have a unique ID.\n3. **Root component must have id \"root\"** - The root component is always the one with `\"id\": \"root\"`.\n4. **Flat component structure** - Components reference children by ID, not by nesting.\n5. **v0.9 flat format** - Component type is a string: `\"component\": \"Text\"`, not `\"component\": { \"Text\": {...} }`.\n6. **Properties are top-level** - Properties go directly on the component object: `{ \"id\": \"t\", \"component\": \"Text\", \"text\": \"Hello\" }`.\n7. **Children are arrays** - Use `\"children\": [\"child1\", \"child2\"]` not `\"children\": { \"explicitList\": [...] }`.\n8. **Plain data model** - Use `\"value\"` with plain JSON, not typed `contents` arrays.\n9. **Actions use event wrapper** - Button actions use `{ \"event\": { \"name\": \"...\", \"context\": {...} } }` with context as a plain object.\n10. **Production ready** - The UI you generate will be shown to real users. It must be complete, polished, and functional.\n11. **No placeholder images** - NEVER use fake or placeholder image URLs. Only use real, valid image URLs. If unavailable, use an Icon component instead.\n12. **Root must be a layout component** - The root should be Column, Row, Card, or similar. Do NOT use Modal, Button, Text as root.\n13. **Button uses child** - Use `\"child\": \"text-id\"` for the button's label component.\n14. **Button variant** - Use `\"variant\": \"primary\"` instead of `\"primary\": true`.\n15. **Layout uses justify/align** - Use `\"justify\"` (not `\"distribution\"`) and `\"align\"` (not `\"alignment\"`).\n16. **Text variant** - Use `\"variant\"` (not `\"usageHint\"`) for text style: h1, h2, h3, h4, h5, caption, body.\n\n### Updating Surfaces After Initial Render\n\nOnce a surface has been created, you can update it in later turns WITHOUT sending another `createSurface`. Just send updates directly:\n\n**To update UI components** - Send an `updateComponents` with the same surfaceId:\n- To modify a component: send it with the same `id` - it replaces the old definition\n- To add new components: include them in the components array\n\n**To update data values** - Send an `updateDataModel`:\n- Components bound to data paths (using `{ \"path\": \"/some/value\" }`) update automatically\n- Use `\"path\"` to target a specific location, and `\"value\"` for the plain JSON value\n\n**Example: Updating an existing surface**\n\n```json\n[\n {\n \"version\": \"v0.9\",\n \"updateComponents\": {\n \"surfaceId\": \"my-surface\",\n \"components\": [\n {\n \"id\": \"status-text\",\n \"component\": \"Text\",\n \"text\": \"Updated status!\"\n }\n ]\n }\n }\n]\n```\n\nOr update data-bound values:\n\n```json\n[\n {\n \"version\": \"v0.9\",\n \"updateDataModel\": {\n \"surfaceId\": \"my-surface\",\n \"path\": \"/status\",\n \"value\": \"Complete\"\n }\n }\n]\n```\n\n**IMPORTANT**: Do NOT send `createSurface` again for updates to an existing surface.\n\n### Working with Forms and Data Binding\n\nA2UI supports forms where user input is stored in a data model and retrieved when buttons are clicked.\n\n**How it works:**\n1. **TextField binds to a path**: Use `\"text\": { \"path\": \"/form/fieldName\" }` to bind input to the data model\n2. **Initialize the data model**: Send an `updateDataModel` to set initial values\n3. **Button retrieves values**: Use `action.event.context` with path references to include form values when clicked\n4. **Agent receives resolved values**: The context in the action will contain the actual values the user entered\n\n**Form Example:**\n\n```json\n[\n { \"version\": \"v0.9\", \"createSurface\": { \"surfaceId\": \"my-form\", \"catalogId\": \"https://a2ui.org/specification/v0_9/basic_catalog.json\" } },\n {\n \"version\": \"v0.9\",\n \"updateComponents\": {\n \"surfaceId\": \"my-form\",\n \"components\": [\n { \"id\": \"root\", \"component\": \"Card\", \"child\": \"form-col\" },\n { \"id\": \"form-col\", \"component\": \"Column\", \"children\": [\"name-field\", \"submit-btn\"] },\n { \"id\": \"name-field\", \"component\": \"TextField\", \"label\": \"Name\", \"text\": { \"path\": \"/form/name\" } },\n { \"id\": \"submit-btn\", \"component\": \"Button\", \"child\": \"btn-text\", \"action\": { \"event\": { \"name\": \"submit\", \"context\": { \"userName\": { \"path\": \"/form/name\" } } } } },\n { \"id\": \"btn-text\", \"component\": \"Text\", \"text\": \"Submit\" }\n ]\n }\n },\n { \"version\": \"v0.9\", \"updateDataModel\": { \"surfaceId\": \"my-form\", \"value\": { \"form\": { \"name\": \"\" } } } }\n]\n```\n\nWhen the user types \"Alice\" and clicks Submit, you'll receive: `Context: {\"userName\": \"Alice\"}`\n\n### Handling User Interactions\n\nWhen a user interacts with a UI surface you rendered (clicks a button, submits a form, etc.),\nyou will see a `log_a2ui_event` tool call in your conversation history followed by a tool result.\n\nCRITICAL: If the conversation ends with a `log_a2ui_event` tool call followed by its tool result,\nthis means THE USER JUST PERFORMED AN ACTION and you MUST respond to it immediately.\n\nThe `log_a2ui_event` tool call is NOT something you initiated - it is automatically injected into\nthe conversation to represent a real user interaction (like clicking a button) that just happened.\n\nWhen the last messages are a `log_a2ui_event` tool call + result:\n1. The user JUST performed the action described (e.g., clicked a button)\n2. You MUST acknowledge their action and respond appropriately\n3. Look at the action name to understand what they did\n4. Take the appropriate next step based on what that action means in context\n5. Do NOT simply describe what buttons exist - respond to what they clicked!\n\n## JSON Schema Reference\n\nEach message is an object with `\"version\": \"v0.9\"` and exactly ONE operation key.\n\n### Message Types\n\n**createSurface** - Create a new surface:\n```json\n{ \"version\": \"v0.9\", \"createSurface\": { \"surfaceId\": \"my-surface\", \"catalogId\": \"https://a2ui.org/specification/v0_9/basic_catalog.json\" } }\n```\n\n**updateComponents** - Set/update components on a surface:\n```json\n{ \"version\": \"v0.9\", \"updateComponents\": { \"surfaceId\": \"my-surface\", \"components\": [...] } }\n```\n\n**updateDataModel** - Set/update data on a surface (plain JSON):\n```json\n{ \"version\": \"v0.9\", \"updateDataModel\": { \"surfaceId\": \"my-surface\", \"path\": \"/\", \"value\": { \"name\": \"Alice\" } } }\n```\n\n**deleteSurface** - Delete a surface:\n```json\n{ \"version\": \"v0.9\", \"deleteSurface\": { \"surfaceId\": \"my-surface\" } }\n```\n\n### Component Format (v0.9 flat)\n\nEach component is a flat object with `id`, `component` (type name as string), and properties at top level:\n```json\n{ \"id\": \"title\", \"component\": \"Text\", \"text\": \"Hello World\", \"variant\": \"h2\" }\n```\n\n### Component Reference\n\n**Content Components:**\n- **Text**: `{ component: \"Text\", text: \"string\" | { path: \"/data/key\" }, variant?: \"h1\"|\"h2\"|\"h3\"|\"h4\"|\"h5\"|\"caption\"|\"body\" }`\n- **Image**: `{ component: \"Image\", url: \"string\" | { path }, fit?: \"contain\"|\"cover\"|\"fill\", variant?: \"icon\"|\"avatar\"|\"smallFeature\"|\"mediumFeature\"|\"largeFeature\"|\"header\" }`\n- **Icon**: `{ component: \"Icon\", name: \"string\" | { path } }` \u2014 names: accountCircle, add, arrowBack, arrowForward, attachFile, calendarToday, call, camera, check, close, delete, download, edit, event, error, favorite, favoriteOff, folder, help, home, info, locationOn, lock, lockOpen, mail, menu, moreVert, moreHoriz, notificationsOff, notifications, payment, person, phone, photo, print, refresh, search, send, settings, share, shoppingCart, star, starHalf, starOff, upload, visibility, visibilityOff, warning\n- **Video**: `{ component: \"Video\", url: \"string\" | { path } }`\n- **AudioPlayer**: `{ component: \"AudioPlayer\", url: \"string\" | { path }, description?: \"string\" | { path } }`\n- **Divider**: `{ component: \"Divider\", axis?: \"horizontal\"|\"vertical\" }`\n\n**Layout Components:**\n- **Row**: `{ component: \"Row\", children: [\"id1\", \"id2\"] | { componentId, path }, justify?: \"start\"|\"center\"|\"end\"|\"spaceBetween\"|\"spaceAround\"|\"spaceEvenly\", align?: \"start\"|\"center\"|\"end\"|\"stretch\" }`\n- **Column**: `{ component: \"Column\", children: [\"id1\", \"id2\"] | { componentId, path }, justify?: \"start\"|\"center\"|\"end\"|\"spaceBetween\"|\"spaceAround\"|\"spaceEvenly\", align?: \"start\"|\"center\"|\"end\"|\"stretch\" }`\n- **List**: `{ component: \"List\", children: [\"id1\"] | { componentId, path }, direction?: \"vertical\"|\"horizontal\", align?: \"start\"|\"center\"|\"end\"|\"stretch\" }`\n- **Card**: `{ component: \"Card\", child: \"content-id\" }`\n- **Tabs**: `{ component: \"Tabs\", tabItems: [{ title: \"string\" | { path }, child: \"id\" }] }`\n- **Modal**: `{ component: \"Modal\", entryPointChild: \"trigger-id\", contentChild: \"content-id\" }`\n\n**Interactive Components:**\n- **Button**: `{ component: \"Button\", child: \"text-id\", action: { event: { name: \"action_name\", context?: { key: value | { path } } } }, variant?: \"primary\"|\"secondary\"|\"text\" }`\n- **TextField**: `{ component: \"TextField\", label: \"string\" | { path }, text?: \"string\" | { path }, textFieldType?: \"shortText\"|\"longText\"|\"number\"|\"date\"|\"obscured\" }`\n- **CheckBox**: `{ component: \"CheckBox\", label: \"string\" | { path }, checked?: boolean | { path } }`\n- **Slider**: `{ component: \"Slider\", value: number | { path }, minValue?: number, maxValue?: number }`\n- **DateTimeInput**: `{ component: \"DateTimeInput\", value: \"string\" | { path }, enableDate?: boolean, enableTime?: boolean }`\n- **ChoicePicker**: `{ component: \"ChoicePicker\", selections: [\"a\"] | { path }, options: [{ label: \"string\" | { path }, value: \"string\" }], maxAllowedSelections?: number }`\n---END A2UI JSON SCHEMA---"; /** * The container key used to wrap A2UI operations for explicit detection. * Must match the key used by copilotkit.a2ui.render() (Python SDK) * and A2UIMessageRenderer (React). */ declare const A2UI_OPERATIONS_KEY = "a2ui_operations"; /** * Parsed A2UI container result. */ interface A2UIParseResult { operations: Array>; } /** * Try to parse text as an A2UI container. * Returns operations if the text contains a valid { a2ui_operations: [...] } * container, or null otherwise. */ declare function tryParseA2UIOperations(text: string): A2UIParseResult | null; /** * Extract surfaceId from a single A2UI operation (v0.9 keys) */ declare function getOperationSurfaceId(operation: Record): string | undefined; /** * Extract surface IDs from A2UI messages */ declare function extractSurfaceIds(messages: Array<{ [key: string]: unknown; }>): string[]; /** * Activity type for A2UI surface events */ declare const A2UIActivityType = "a2ui-surface"; /** * Context description used to identify the A2UI component schema in RunAgentInput.context. * The LangGraph connector uses this to extract the schema from context and inject it * into the agent's key/value state instead of the system prompt. */ declare const A2UI_SCHEMA_CONTEXT_DESCRIPTION = "A2UI Component Schema \u2014 available components for generating UI surfaces. Use these component names and properties when creating A2UI operations."; /** * A2UI Middleware - Enables AG-UI agents to render A2UI surfaces * and handles bidirectional communication of user actions. */ declare class A2UIMiddleware extends Middleware { private config; constructor(config?: A2UIMiddlewareConfig); /** * Extract the inline catalog (component name → JSON Schema with `required`) * for semantic validation, when one is configured. Returns undefined for the * legacy array form or no schema — validation then degrades to structural-only. */ private getValidationCatalog; /** * Build a pre-paint lifecycle snapshot for the `a2ui-surface` activity (OSS-162). * * The WHOLE generative-UI lifecycle rides ONE stable messageId * (`a2ui-surface-${key}`, key = outer call): `status: "building" | "retrying" | * "failed"` pre-paint, then `a2ui_operations` on paint. Because every state * `replace`s the same messageId, the painted surface supersedes the skeleton in * place — no separate "resolved" signal, and never more than one loader. * * The lifecycle metadata lives on the AG-UI activity-content WRAPPER, never * inside an A2UI envelope (the `a2ui_operations` elements stay strictly * `{ version, }`, per the v0.9 envelope spec). * * `debugExposure` is stamped from server config so the client renderer honors * it; applies to all wrapped agents (Python + TS) since this middleware is the * single emitter. */ private buildLifecycleActivity; /** * Main middleware run method */ run(input: RunAgentInput, next: AbstractAgent): Observable; /** * Inject the A2UI component schema into RunAgentInput.context. * This makes the schema available to agents as a context entry, * similar to how useAgentContext propagates application context. * * If the frontend already provided a schema context entry (via includeSchema), * the server-side schema replaces it. */ private injectSchemaContext; /** * Check forwardedProps for a2uiAction and append synthetic tool call messages */ private processUserAction; /** * Format the user action result message for the agent */ private formatUserActionResult; /** * Inject the A2UI rendering tool + the "injectA2UITool" flag into the input. * Uses the configured name from `injectA2UITool` (string) or defaults to "render_a2ui". * Always replaces the tool if it already exists to ensure the correct parameter schema. */ private injectToolAndFlag; /** * Inject usage guidelines for the render_a2ui tool as a context entry. * Provides the LLM with protocol instructions and a minimal example so it * can produce valid A2UI without agent-specific prompting. */ private injectToolGuidelines; /** * Process the event stream, holding back RUN_FINISHED to process pending A2UI tool calls. * Uses runNextWithState for automatic message tracking. */ private processStream; /** * Find tool calls that don't have a corresponding result (role: "tool") message */ private findPendingToolCalls; /** * Create ACTIVITY_SNAPSHOT events from A2UI operations, grouped by surfaceId. * * @param operations - A2UI operations to emit * @param toolCallId - Unique tool call ID to isolate surfaces between invocations */ private createA2UIActivityEvents; } export { A2UIActivityType, type A2UIComponentSchema, type A2UIForwardedProps, type A2UIInlineCatalogSchema, type A2UIMessage, type A2UIMessageType, A2UIMiddleware, type A2UIMiddlewareConfig, type A2UIParseResult, type A2UIUserAction, A2UI_OPERATIONS_KEY, A2UI_PROMPT, A2UI_SCHEMA_CONTEXT_DESCRIPTION, LOG_A2UI_EVENT_TOOL_NAME, RENDER_A2UI_TOOL, RENDER_A2UI_TOOL_GUIDELINES, RENDER_A2UI_TOOL_NAME, extractCompleteA2UIOperations, extractCompleteItems, extractCompleteItemsWithStatus, extractCompleteObject, extractDataArrayItems, extractStringField, extractSurfaceIds, getOperationSurfaceId, tryParseA2UIOperations };