Streaming

AgentBackend supports real-time streaming via Server-Sent Events (SSE). Instead of waiting for the full response, you receive tokens as they're generated, plus tool call notifications.

Endpoint

POST /v1/run/stream

Content-Type: application/json

Authorization: Bearer ak_...

Request body is the same as POST /v1/run:

json
{
  "agent_id": "agent_...",
  "message": "Tell me a story"
}

Event Types

EventDescriptionPayload
tokenText token from the agent{"type": "token", "content": "Hello"}
tool_callAgent is calling a tool{"type": "tool_call", "name": "web_search", "arguments": {...}}
tool_resultTool execution result{"type": "tool_result", "name": "web_search", "result": "..."}
doneStream complete{"type": "done", "metadata": {"cost": 0.002, "tokens": 150}}
[DONE]Stream terminatorEnd of stream signal

Raw SSE Example

text
data: {"type": "token", "content": "Hello"}
data: {"type": "token", "content": " world"}
data: {"type": "tool_call", "name": "web_search", "arguments": {"query": "latest news"}}
data: {"type": "tool_result", "name": "web_search", "result": "..."}
data: {"type": "token", "content": "Based on my search..."}
data: {"type": "done", "metadata": {"cost": 0.002, "tokens": 150}}
data: [DONE]

Python SDK

python
from agentbackend import AgentBackend

ab = AgentBackend("ak_your_key")

# Simple streaming
for chunk in ab.agent("agent_id").stream("Tell me a story"):
    print(chunk, end="", flush=True)

# Async streaming
from agentbackend import AsyncAgentBackend

async with AsyncAgentBackend("ak_your_key") as ab:
    async for chunk in ab.agent("agent_id").stream("Tell me a story"):
        print(chunk, end="", flush=True)

JavaScript SDK

javascript
import AgentBackend from 'agentbackend';

const ab = new AgentBackend('ak_your_key');

// Simple streaming
for await (const chunk of ab.agent('agent_id').stream('Tell me a story')) {
  process.stdout.write(chunk);
}

// With event handling
const stream = ab.agent('agent_id').stream('Tell me a story');
for await (const event of stream) {
  if (event.type === 'token') {
    process.stdout.write(event.content);
  } else if (event.type === 'tool_call') {
    console.log('Calling tool:', event.name);
  }
}

JavaScript (fetch)

javascript
const response = await fetch("https://api.agentbackend.ai/v1/run/stream", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer ak_..."
  },
  body: JSON.stringify({
    agent_id: "agent_...",
    message: "Tell me a story"
  })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const text = decoder.decode(value);
  const lines = text.split("\n").filter(line => line.startsWith("data: "));

  for (const line of lines) {
    const data = line.slice(6);
    if (data === "[DONE]") break;

    const event = JSON.parse(data);
    if (event.type === "token") {
      process.stdout.write(event.content);
    }
  }
}

Important Notes

  • The stream uses text/event-stream content type
  • Each event is prefixed with data:
  • The stream terminates with data: [DONE]
  • Use POST (not EventSource) because a request body is needed
  • Tool calls appear mid-stream — the agent pauses token output, calls the tool, then resumes