Skip to main content
The typical pattern is a stream per agent run. Each invocation gets its own stream (s2://my-basin/agents/{run-id}) containing an ordered log of everything that happened — tool calls, LLM responses, state changes. Streams can be created automatically on first append or read, to simplify setup.

Architecture

Chat / LLM token streaming

The agent (or your backend) appends tokens to a stream as they’re generated. The client opens a read session and renders them as they arrive. If the client disconnects and reconnects, it can easily resume from the last sequence number it processed by starting a new read session from that position.
There’s a ready-made integration for doing this with the Vercel AI SDK: @s2-dev/resumable-stream.

Agent logs and debugging

Actions the agent takes — tool invocations, API calls, intermediate reasoning — can be appended as structured records using headers. This gives you an audit trail for each run. Read the stream later to debug failures, or tail it live to watch an agent work. See the agent session example for a working implementation with the Vercel AI SDK.

State and context storage

A stream can serve as an append-only log of state changes for an agent session. Instead of overwriting state in a database, append each change as a record. Replay the stream to reconstruct state at any point — essentially event sourcing at the session level.

Multi-agent coordination

When multiple agents need to communicate, S2 streams provide natural coordination primitives. Use a shared stream as a message bus between agents, with per-agent streams for private memory. The ordered log guarantees all agents see events in the same order. See the dinner party example for a multi-agent implementation with the Vercel AI SDK.

Getting started

If you’re already building with the Vercel AI SDK, see the page on how we integrate. For custom setups, this flow can be modeled directly from the CLI:
# Create a basin with auto-stream creation
s2 create-basin agent-runs --create-stream-on-append

# Agent appends (from your backend)
echo "tool_call: search('weather in SF')" \
    | s2 append s2://agent-runs/session-abc

# Client reads (from your frontend, using the token you issued)
s2 read -s0 s2://agent-runs/session-abc
In production, you would likely want to build around these same methods via our SDKs — in particular, via the Producer API, which handles batching and pipelining automatically.