Conversations
Canonical message history for agent and human chats — Postgres store with stream-backed delivery.
The conversation store provides durable, queryable message history for forums (multi-party chats) and monologues (agent-internal threads). All communication still flows through the global stream for delivery; Postgres holds the canonical transcript.
Data model
actors, participants, conversations, messages.
Forum & monologue
Product roles on the same tables.
Message types
body.parts schema and relations.
Delivery
No inbox — stream fan-out.
Branches
Soft forks per conversation.
HTTP API
Headless chat REST endpoints.
Principles
| Principle | Meaning |
|---|---|
| Everything is conversations | No kind column, no internal table, no visibility flags |
| Forum vs monologue | Product roles — same tables, different participant sets |
| Actor ≠ participant | actors is identity; participants is one stint in one conversation |
| No inbox table | Delivery is immediate via stream append + fan-out |
| Agent = actor instances | An "agent" is composed actor instances, not one monolithic loop |
| Opaque body | messages.body is jsonb; runtime does not interpret content |
Quick start (SDK)
import { createChatClient, conversationEvents } from "@yoke/sdk";
const chat = createChatClient(ctx.conversations);
const room = await chat.createRoom({ title: "support" });
const human = await chat.createActor({ name: "alice" });
const humanP = await chat.addMember(room.id, human.id);
await chat.send(room.id, "Hello!", { authorParticipantId: humanP.id });Merge conversationEvents into your defineEvents() for typed stream payloads.
Stream events
| Event | When |
|---|---|
conversation.created | New conversation row |
conversation.participant.joined | Participant added |
conversation.participant.left | left_at set |
conversation.message.posted | Message inserted |
conversation.branch.created | Soft fork created |
Payloads carry ids only — handlers read full content from Postgres when needed.
Agent integration
Agents use the conversation store alongside the actor mesh:
- Create forum (chat room) via Chat SDK
createAgent→ actor + egress instancejoinConversation→ monologue stint + ingestion + processor per join
See Agents for the full bootstrap flow.
Headless HTTP
For apps without embedded agents, use the control plane REST API on port 8090:
import { createChatHttpClient } from "@yoke/sdk";
const chat = createChatHttpClient({
baseUrl: "http://localhost:8090",
tenantId: "default",
});See HTTP API.