Streaming Runs
Run one RubyLLM chat turn and write ordered AG-UI events as server-sent events.
After reading this guide, you will know:
- How to connect a host-owned chat, parsed input, scope, and store.
- How a RubyLLM turn becomes ordered AG-UI events.
- What each terminal outcome means.
Run a Complete Example
The repository includes a scripted chat that emits an approval pause, resumes the tool call, and prints the server-sent events. Run it from the repository root; it does not need a provider key.
bundle exec rake example
In an application, parse the request first, then pass the host-selected chat, parsed input, authenticated scope, and run store to RubyLLM::AgUI::Run. Call stream(to:) with an IO-like stream. The host builds the chat and authorizes access to the thread; the gem reserves the run identity before provider work.
Event Order
The mapper turns RubyLLM callbacks into AG-UI events. The emitter assigns each event a sequence, persists run state, closes open text or tool events, and writes one JSON event per data: line through the SSE writer.
An assistant message opens on its first non-empty chunk and closes before a tool call, phase change, or terminal event. A tool call starts when its id and name are known, emits the arguments as received, and ends before the call runs. One run ends with one terminal result.
Outcomes
- A completed chat ends with
RUN_FINISHEDand asuccessoutcome. - A
requires_approvalpause ends withRUN_FINISHEDand aninterruptoutcome. Chat#cancelends withRUN_FINISHEDand acancelledoutcome.- A failure ends with
RUN_ERRORand a sanitized message and code. - A pause the protocol cannot express is an error, never a success.
The run record reaches a terminal state before the terminal event is written. If the connection closes in the middle, the record remains available for a later reconnect.
Next Steps
- Validating Input - parse untrusted request data.
- Approval and Resume - answer an interrupt on a new run.
- Reconnects and Run Identity - serve a completed run again.