Skip to content

AI SDK chat, agent, multi-agent

Three Vercel AI SDK apps on one Node server. Every message, tool step and agent turn is a record in a PicoMQ stream. Restart the server and the UI comes back from the streams.

Source: examples/agents/ai-sdk.

node, tsx server/index.tspico :4437browser :3456fetch, SSEOpenAIgpt-4o-minichat.tsstreamTextagent.tsgenerateText, toolsmulti.ts3 agents, hostchat/{id}one ModelMessage per recordagent/run-{id}run_start, step, run_endmulti/{room}/bushost and agent turnsmulti/{room}/agent/{id}memory per agentappendappendappendappend/api/*ai
PageStreamsRecords
/chat.htmlchat/{id}, one per conversationAI SDK ModelMessage JSON
/agent.htmlagent/run-{id}, one per runrun_start, step, run_end
/multi.htmlmulti/{room}/bus, multi/{room}/agent/{ada,remy,quill}bus turns, per-agent memory

All under prefix /examples/agents/ai-sdk. The server uses @picomq/client with protocol pico and a Producer per stream, lingerMs: 10. Each append waits for durable() before the seq is shown in the UI.

Run

bash
cd harness/aio
cp .env.example .env
docker compose up --build
bash
export OPENAI_API_KEY=...
export PICO_ENDPOINT=http://127.0.0.1:4437

cd examples/agents/ai-sdk
npm install
npm run dev

Open http://localhost:3456.

Chat persistence

  • New chat creates chat/{id}. Each user and assistant message is appended as one record.
  • Reply is streamText with gpt-4o-mini, streamed to the browser over SSE, then appended once complete.
  • Context sent to the model is the last 40 messages, AI_SDK_MAX_CONTEXT_MESSAGES.
  • On start the server lists the prefix and opens the newest stream. Recents are built from the first user message of each stream.
  • Restart reads the stream from the beginning and replays it into the UI.

Agent audit trail

run_startpromptstep 1lookupCompanystep 2calculatestep 3textrun_endtext, steps, tokensseq 0seq 4, producer closedone record per onStepFinish
  • generateText with tools lookupCompany and calculate, stopWhen: stepCountIs(10).
  • onStepFinish appends a step record with text, toolCalls, toolResults, finishReason.
  • run_end carries the final text, step count and totalTokens. The producer is closed after it.
  • Continuing a run reuses the stream if it is not closed. Prior run_start and run_end records rebuild the message history.

Multi-agent persistence

round robin, generateText over own memoryhosttopic, follow-upsmulti/{room}/busBusMessage {from, content, turn}Adastaff engineerRemyproduct leadQuillrevieweragent/adamemoryagent/remymemoryagent/quillmemorypostturnuser, assistant, busSeq
  • The host posts a topic to the bus. Every agent memory gets [Host]: topic as a user record with the bus seq.
  • Advance runs generateText for the next agent over its own memory stream, posts the reply to the bus, appends it to its memory as assistant and to the others as user.
  • Each memory record stores busSeq. On reload the server compares it with the bus and appends anything an agent has not seen.
  • Delete removes the bus and the three memory streams.

Environment

VariableDefault
PICO_ENDPOINThttp://127.0.0.1:4437
PORT3456
OPENAI_API_KEYrequired
AI_SDK_MAX_CONTEXT_MESSAGES40
PICO_CHAT_PREFIX/examples/agents/ai-sdk/chat
PICO_AGENT_PREFIX/examples/agents/ai-sdk/agent
PICO_MULTI_PREFIX/examples/agents/ai-sdk/multi