Use polling instead of SSE for environments that can't maintain long-lived HTTP connections.
When to Use Polling
Some environments cannot hold open Server-Sent Events (SSE) connections:
- Convex actions — HTTP requests must complete within a timeout
- Cloudflare Workers — no long-lived inbound connections
- Restricted edge runtimes — firewalls or proxies that drop idle connections
- Serverless functions — Lambda, Cloud Functions with short timeouts
In these cases, set stream: false to switch from SSE to lightweight polling. The SDK automatically polls a status endpoint and only fetches full data when the status changes.
Client-Level Default
Set polling as the default transport for all operations:
1import { inference } from '@inferencesh/sdk';23const client = inference({4 apiKey: 'inf_your_key',5 stream: false, // Use polling instead of SSE6 pollIntervalMs: 2000, // Poll every 2 seconds (default)7});All client.run(), agent.sendMessage(), and AgentChatProvider calls will use polling unless overridden.
Task Polling
Override the transport per-call with stream: false on run():
1const result = await client.run(2 { app: 'infsh/flux', input: { prompt: 'A sunset' } },3 {4 stream: false,5 pollIntervalMs: 3000, // Optional: override interval6 onUpdate: (task) => {7 console.log('Status:', task.status);8 },9 }10);1112console.log('Output:', result.output);How it works:
- Task is created via
POST /apps/run(same as streaming) - SDK polls
GET /tasks/{id}/statuseverypollIntervalMs - When the status changes, it fetches the full task via
GET /tasks/{id} onUpdatefires with the full task data- Promise resolves on completion, rejects on failure/cancellation
Agent Polling
Imperative SDK
1const client = inference({ apiKey: 'inf_your_key' });23const agent = client.agent('my-team/support-agent@latest');45const response = await agent.sendMessage('Hello!', {6 stream: false,7 pollIntervalMs: 2000,8 onMessage: (message) => {9 console.log('Message:', message.content);10 },11 onChat: (chat) => {12 console.log('Chat status:', chat.status);13 },14 onToolCall: (invocation) => {15 console.log('Tool call:', invocation.name);16 },17});How it works:
- Message is sent via
POST /agents/run(same as streaming) - SDK polls
GET /chats/{id}/statuseverypollIntervalMs - When the status changes, it fetches the full chat via
GET /chats/{id} - New and updated messages are dispatched to
onMessage - Client tool invocations (
awaiting_input) are dispatched toonToolCall - Promise resolves when the chat becomes
idle
React Provider
1import { AgentChatProvider, useAgentChat } from '@inferencesh/sdk/agent';23function App() {4 return (5 <AgentChatProvider6 client={client}7 agentConfig={{ agent: 'my-team/support-agent@latest' }}8 stream={false}9 pollIntervalMs={2000}10 >11 <ChatUI />12 </AgentChatProvider>13 );14}The provider uses the same polling mechanism internally. All hooks (useAgentChat, useAgentActions) work identically regardless of transport.
Configuration Reference
| Option | Type | Default | Scope |
|---|---|---|---|
stream | boolean | true | Client, run(), sendMessage(), Provider |
pollIntervalMs | number | 2000 | Client, run(), sendMessage(), Provider |
Precedence: Per-call options override provider props, which override client defaults.
Comparison: Streaming vs Polling
| SSE (default) | Polling | |
|---|---|---|
| Latency | Real-time | Up to pollIntervalMs delay |
| Partial updates | Yes (onPartialUpdate) | No (full fetch only) |
| Connection | Long-lived HTTP | Short-lived requests |
| Edge compatible | No | Yes |
| Bandwidth | Lower (deltas only) | Higher (status checks + full fetches) |
Use SSE when you can. Use polling when you must.