Skip to content
MANTYX.IO

Streaming

There are two complementary APIs:

  1. Callback-style — pass onAssistantDelta (or OnAssistantDelta in Go) to a regular runAgent / Send call. The promise/result still resolves with the final text.
  2. Iterator-style — call streamAgent / Session.Stream to get an async iterator (or channel in Go) of every event.
// Callback
await client.runAgent({
systemPrompt: "...",
prompt: "Tell me a story.",
onAssistantDelta: (delta) => process.stdout.write(delta),
});
// Iterator
for await (const event of client.streamAgent({
systemPrompt: "...",
prompt: "Tell me a story.",
})) {
if (event.type === "assistant_delta") process.stdout.write(event.text);
if (event.type === "result") process.stdout.write("\n");
}
# Callback
client.run_agent(
system_prompt="...",
prompt="Tell me a story.",
on_assistant_delta=lambda d: print(d, end="", flush=True),
)
# Iterator
for event in client.stream_agent(system_prompt="...", prompt="Tell me a story."):
if event.type == "assistant_delta":
print(event.text, end="", flush=True)
# Async iterator
async for event in async_client.stream_agent(system_prompt="...", prompt="..."):
...
// Callback
_, _ = client.RunAgent(ctx, mantyx.RunSpec{
SystemPrompt: "...",
Prompt: "Tell me a story.",
OnAssistantDelta: func(s string) { fmt.Print(s) },
})
// Channel
ch, err := client.StreamAgent(ctx, mantyx.RunSpec{
SystemPrompt: "...",
Prompt: "Tell me a story.",
})
if err != nil { log.Fatal(err) }
for ev := range ch {
if ev.Type == "assistant_delta" {
if t, ok := ev.Data["text"].(string); ok {
fmt.Print(t)
}
}
}
EventWhenPayload
assistant_deltaStreaming assistant tokens{ text }
thinking_deltaReasoning models with reasoningLevel > 0 emit chain-of-thought tokens{ text }
assistant_messageFull assistant turn (text + tool calls){ text, toolCalls }
tool_call / tool_resultServer-side tool execution{ toolUseId, name, ... }
local_tool_callThe SDK should run a handler{ toolUseId, name, args, kind?, ... }
local_tool_result_inEcho of the SDK’s result{ toolUseId, output }
resultTerminal{ subtype, text?, error? }
cancelledTerminal (after cancelRun){}

The local_tool_call payload carries a kind discriminator ("local" when omitted, "a2a_local", or "mcp_local") plus extra metadata for the specialised kinds. The SDKs route to the right handler automatically; you only need to care about this if you’re implementing a third-party client. The full event vocabulary is documented in Wire protocol §7.

The SDKs all reconnect automatically via Last-Event-ID + ?lastSeq= if the SSE stream drops.