# Streaming And Actions The renderer processes A2UI messages; it does not own the stream carrying them. AG-UI, HTTP, WebSocket, SSE, local fixtures, and on-device inference can all feed the same engine. ## Message Lifecycle For v0.9, the runtime accepts: 1. `createSurface` to establish a surface and catalog ID; 2. `updateDataModel` to initialize or change bound data; 3. `updateComponents` to add or replace graph components; 4. `deleteSurface` to remove the surface. Messages may arrive incrementally. A surface is renderable after a valid reserved `root` component resolves; until then `A2UISurface` returns `null`. ## Simple Collection Use `A2UIRenderer` when the application already holds one append-oriented message array: ```tsx ``` If the new array retains the exact previous message objects as its prefix, only the appended suffix is applied. Reusing the same array applies nothing. Replacing or reordering earlier objects causes the current collection to be replayed, so prefer immutable append semantics. ## Application-Owned Stream Use an engine when placement and lifecycle are application concerns: ```tsx const engine = createA2UIEngine({ catalogs: [catalog] }); transport.onA2UIMessage((message) => { engine.applyMessage(message); }); ``` Mount one provider around the region that renders surfaces: ```tsx {items.map((item) => item.kind === "surface" ? ( ) : ( ), )} ``` The transport-to-transcript bridge should record surface placement when it observes `createSurface` and remove placement when it observes `deleteSurface`. The engine owns surface content; the transcript owns where it appears. ## Batches And Recovery `applyMessages` validates and commits updates transactionally per affected surface. Use it when one tool result contains an A2UI operation array. One bad surface does not prevent an unrelated valid surface in the same batch from committing. Do not render raw operation JSON as assistant text. Parse the transport payload, pass only message objects to the engine, and expose failures through `onError`. ## Action Round Trip When a presenter dispatches an event action, the engine resolves context from the current surface data model and calls `onAction` with an official `A2UIUserAction`: ```tsx const engine = createA2UIEngine({ catalogs: [catalog], onAction(action) { agent.send({ forwardedProps: { a2ui: { action } } }); }, }); ``` The package does not prescribe the outer payload. The consumer may send an AG-UI action turn, call an API route, execute an application command, or handle the action locally. Do not add a visible fake user message unless that is an intentional product choice. Action-only turns can remain protocol events while the server responds with text, data updates, component updates, or surface deletion. ## Lifetime Call `engine.dispose()` when an application-owned engine will never be used again. Disposal releases upstream reactive state and package subscriptions. Do not dispose an engine merely because one surface was deleted.