Server-Sent Events
Tool execution in ORS utilises Server-Sent Events (SSE) to deliver results. SSE keeps connections alive during long-running tool calls and chunks large responses for reliable delivery.Why SSE for Tool Calls?
Traditional request-response doesn’t work well for tool execution: Problems with standard HTTP:- Bash commands can run for minutes
- LLM calls take 10-30 seconds
- File operations vary in duration
- Connections may time out before the tool finishes
- Keeps connections alive with periodic pings while tools execute
- Chunks large responses (>4KB) into smaller pieces for reliable delivery
- Enables client reconnection via task IDs if the connection drops
- Built into browsers and HTTP libraries
- Simpler than WebSockets (one-way, server → client)
SSE Basics
What is SSE?
Server-Sent Events is a standard for server-to-client streaming over HTTP:- Each event has an
eventtype anddatapayload - Events separated by blank lines
- Connection stays open for multiple events
- Client closes when done
Tool Call SSE Flow
Request
Accept: text/event-stream- Recommended (server returns SSE regardless)X-Session-ID- Session identifier
name: Tool to callinput: Tool parameterstask_id: Optional ID for reconnection/tracing
Response Stream
The server sends events in this sequence:1. Task ID Event
First event identifies the task:2. Chunk Events (if result is large)
For results > 4KB, sent in chunks:3. End Event
Final event with complete result:4. Error Event (if error occurs)
If tool execution fails:Complete Example
Successful tool call:Event Types
task_id
chunk
end
error
{"ok": false, "error": "..."} in an end event.
Handling SSE in Clients
Python (httpx)
Python (ORS SDK)
The Python SDK handles SSE automatically:JavaScript (fetch)
curl
Reconnection
If the SSE connection drops, clients can reconnect using thetask_id:
Save Task ID
Reconnect with Task ID
- Server checks if task is already running
- If still running, stream events from current state
- If completed, immediately send cached result
- If unknown, returns an
errorevent withunknown task_id
Server-Side Considerations
Implementing SSE in Your Server
If implementing an ORS server from scratch:Keep-Alive Pings
The server sends periodic pings (every 10 seconds) to keep the connection alive::) and are ignored by clients.
Error Handling
HTTP-Level Errors
Tool execution fails at server level:- Session doesn’t exist
- Session timed out
- Tool name not recognized
- Server internal error
Tool Logic Errors
Tool executes but returns error:- Tool input validation failed
- Tool logic error (e.g., file not found)
- Expected failure (e.g., incorrect answer)
Performance Considerations
Chunking
Results > 4KB are automatically chunked:- Chunk size: 4KB (4096 bytes)
- Purpose: Prevent memory issues with large outputs
- Client: Reassemble chunks before parsing JSON
Timeouts
SSE streams can run indefinitely:- Connection: Set reasonable timeout on client (e.g., 60s for quick tools, 600s for bash)
- Keep-alive: Server sends pings every 10s to prevent idle timeout
- Session: 15-minute session timeout still applies
Connection Limits
Be mindful of concurrent SSE connections:- Each connection holds server resources
- Limit concurrent tool calls per agent
- Use connection pooling in clients
Debugging SSE
View Raw SSE Stream
Common Issues
Issue: “Connection closed immediately”- Cause: Missing
Accept: text/event-streamheader - Fix: Add header to request
- Cause: Client buffering responses
- Fix: Use streaming API (e.g.,
httpx.stream(), nothttpx.post())
- Cause: Not accumulating chunks before parsing
- Fix: Buffer all chunks until
event: end
Next Steps
Implementing a Client
Build a client that handles SSE responses
Implementing a Server
Implement SSE responses in your server
HTTP API Reference
See complete endpoint documentation
Key Takeaway: SSE keeps connections alive during tool execution and chunks large results for reliable delivery. The protocol is simple: task_id → chunks (optional) → end/error. Clients reassemble chunks and parse the final JSON result.

