Local and simple APIs
Start with plain data or a maintained text transport; add no extra conversation engine.
Choose the actual wire
For a local view or a JSON endpoint already returning canonical messages, use the plain-data example. Keep data and callbacks in your existing React/application store. The external-store example adds guarded commands without a model dependency.
For an endpoint that streams plain UTF-8 text, use the maintained AI SDK TextStreamChatTransport. Install the checked Vercel packages and view peers. This transport does not imply tool, file or structured UI-data support.
Connect a Composer or application input to runtime.controller.send({ text, attachments: [] }); use its guarded stop command and handle rejected commands. The SDK supplies message assembly and cancellation. Supply custom transport request options for authentication and request-body policy rather than hiding them in Ghost.
Upgrade only when needed
Plain text has no tool or artifact schema. Move to current UI-message SSE, AG-UI or full agent state when those contracts solve an actual need. Do not guess a stream format from a successful response or copy a bespoke parser into the view.