
memories.create() in it.
Why there is no ingestion call
Conversation turns you report withsend_message() are persisted to conversation history. When the conversation compacts, Synap promotes those raw turns into the long-term ingestion pipeline: the same extraction stages memories.create() runs, producing memories of the same quality.
Compaction happens on any of three triggers:
The token and message thresholds are configurable per Instance. The idle trigger is what makes this complete: a two-turn exchange that never approaches the other thresholds still compacts a few minutes after the user stops, and its turns still become memory.
Because the idle trigger catches whatever the thresholds miss, every conversation reaches long-term memory eventually. Reporting turns with
send_message() is sufficient on its own.The integration
1
Initialize once, at process startup
2
Open one stream for the process
Not one per user, not one per session. Scope travels on each call, not on the stream.See Real-Time Anticipation in a Server for quotas, reconnects, and the health check worth alerting on.
3
Report each turn
assistant_message after the reply. Anticipation runs between turns, so this event is what pre-warms the next one.4
Close on shutdown
Requirements
required
The stream must stay open across turns. This integration suits servers, workers, and voice sessions, not per-request serverless functions, which cannot hold a connection.
required
Stream quotas are per Instance and per client. Opening one per user session exhausts them under real concurrency.
required
Reused across every turn of a conversation.
send_message() does not validate it, but fetch() and every other call do.What still uses REST
The stream is not the entire transport, and it is not meant to be. Two things go over HTTP:initialize(): resolves your client and instance from the API keyfetch()on an anticipation miss: pushed bundles cover what Synap predicted; anything it did not predict is fetched normally
fetch() is one call whether it resolves from the local anticipation cache in about a millisecond or falls through to the network.
When to still call memories.create()
Promotion is automatic but not instant. A turn becomes retrievable when its conversation compacts, which for a quiet conversation means about five minutes. Reach for explicit ingestion in three cases:
use memories.create
A fact the very next turn depends on, or a live demo showing memory forming. Waiting for compaction is not an option.
use memories.create
Promotion ingests conversation turns as conversation content. To set
document_type, mode, custom metadata, or to write at customer or client scope, ingest explicitly.use memories.create
Product docs, support tickets, CRM records, and backfills belong in ingestion, not on the stream.
Framework integrations
Two packages drive the stream for you: Strands Agents viaSynapStreamHook, and the Vercel AI SDK via its model middleware. With any other framework, or none, use the loop above directly. It is plain SDK calls and composes with anything.
How anticipation works
The stream in depth: event types, cache behavior, and failure modes.
Running it in a server
Quotas, reconnects, and the silent failure to alert on.