- Tool Execution Streaming: For monitoring long-running tool tasks.
- Agent Session Streaming: For receiving real-time chat responses from agents.
Tool Execution Streaming
This section shows you how to connect to a tool’s event stream. This assumes you have already started a tool execution as shown in the Executing Your First Tool guide.Start a Tool Execution
First, execute a tool as you normally would. The initial Copy the
202 Accepted response will contain a stream_url. This is the endpoint we’ll use to receive live events.Response
stream_url for the next step.Connect to the Event Stream
Now, you can connect to the
stream_url using any SSE-compatible client. The connection will remain open, and the server will push events as they happen.In the JavaScript
EventSource example, we pass the API key as a query parameter. Our server is configured to accept the API key from either the X-API-KEY header or a query parameter named api_key for SSE connections, as EventSource does not support custom headers.Tool Execution Events
As the tool executes, you will receive a series of JSON objects. Each object contains an
Used for general progress updates or structured data changes.
Used for streaming content (e.g., text generation, partial image downloads).
Sent when an interactive tool pauses execution to wait for user input.
The final event of a successful execution. The data contains the direct outputs of the tool.
Indicates that an error occurred during execution.Reassembly Logic (Client-Side):
event_type and a data payload. Here are the detailed event types and their structures:tool_update
Used for general progress updates or structured data changes.tool_partial_update
Used for streaming content (e.g., text generation, partial image downloads).tool_input_required
Sent when an interactive tool pauses execution to wait for user input.tool_end
The final event of a successful execution. The data contains the direct outputs of the tool.For compatibility reasons or depending on the execution method, this event may sometimes appear as
final_result. It should be treated the same way as tool_end.error
Indicates that an error occurred during execution.Handling Large Events (Chunking)
For events that exceed the size limit (e.g., large base64 encoded images or long text), the API uses a “chunking” mechanism. These events are split into multiple parts with the_delta_sse suffix added to the original event name.For example, if a tool_update event is too large, you will receive a series of tool_update_delta_sse events.Structure of a chunked event:- Detect if the event name ends with
_delta_sse. - Store the
chunk_datain a buffer, ordered bychunk_index. - When
is_last_chunkistrue, concatenate allchunk_datafragments. - Parse the concatenated string as JSON.
- Process the resulting object as if it were the
original_event_type.
Example Event Stream
Integrating Tool Events in Chat UI
When building a custom chat interface, you often need to combine the permanent conversation history (text) with transient real-time updates (events). This ensures your UI is both responsive during execution and accurate when reloading history.The Dual-Stream Strategy
- Text Stream (
response_chunk): Contains the “source of truth” for the conversation. It includes delimiters that mark where a tool was called and what the final result was. - Event Stream (
tool_update,tool_partial_update): Contains real-time status updates, logs, and progress indicators that should be displayed while the tool is running.
Implementation Logic
To build a rich UI like the one in Ubik, follow this pattern:- Detect Start: When you parse
<<TOOL_STEP_START/tool_name:exec_id>>in the text stream, create a Tool Container in your UI. Mark it as “Loading” or “Running”. - Live Updates: Listen for SSE events. If you receive a
tool_updateortool_partial_updatewheretool_execution_idmatchesexec_id, update the content of your Tool Container (e.g., show “Searching web…”, update a progress bar, or stream logs). - Detect End: When you parse
<<TOOL_STEP_RESULT_START>>…<<TOOL_STEP_RESULT_END>>in the text stream, you have the final, permanent output. You can now replace the “Loading” state in your Tool Container with the final static result.
Tool-Specific Event Streams
Each tool may emit different data structures in itstool_update and tool_partial_update events depending on its function (e.g., a web search tool might stream “Searching URL…” updates, while a code execution tool streams console logs).
To build a robust UI, you will need to analyze the specific event stream for the tools you intend to support.
Note: Detailed guides documenting the specific event structures for each native tool will be available in the future. For now, we recommend inspecting the events returned by the tools during development.For a list of available tools and their capabilities, please refer to the Native Tools guide.
Agent Session Streaming
Agent Sessions provide a different set of events tailored for conversational interfaces. When you send a message with"stream": true, the server will stream the agent’s thought process and response chunks.
Agent Session Events
Unlike tool executions, agent session events are often used to render a chat interface in real-time. For a complete list of event types and their structure, please refer to the Agent Session Events Guide.Dedicated Stream Endpoint
WhilePOST /agent-sessions/{id}/messages supports direct streaming, UBIK also provides a dedicated endpoint for subscribing to session events. This is useful for:
- Reconnection: Resuming a stream if the connection drops (past events are replayed).
- Browser Compatibility: Using
EventSourcewhich requires a GET request and URL-based auth.
GET /agent-sessions/{session_id}/stream
Authentication with JWT
Since the standardEventSource API in browsers cannot send custom headers (like X-API-KEY), this endpoint accepts a token query parameter. You should generate a short-lived JWT using /auth/token and pass it here.
For details on generating tokens, see the Authentication & Security Guide.

