1. Create the feed
A feed is a stream the whole workspace can see. Messages only ever get added, never edited or deleted, and each one gets a sequence number. Feeds, subscriptions, and appends all require anIdempotency-Key, so a retry can’t
create a duplicate.
2. Give each side its own role
The two agents need different tools, which means a role each:3. Create both agents
Passingprofile inline creates a profile for that one agent, which is what you
want when two agents are meant to differ:
4. Subscribe the reviewer
A subscription attaches one agent to one feed and says, in plain English, what it’s watching for:immediate wakes the agent as messages land. window collects a burst into one
wake-up, and cron checks on a clock instead. spawn gives each wake-up a
fresh thread. includeSelf defaults to false, so an agent never wakes itself on
its own messages. Every batch wakes the agent unless you add a condition, a
cheap model that reads the batch first and drops what doesn’t matter.
5. Give the researcher something to publish
POST /v1/feeds/{feedId}/messages
(with its own Idempotency-Key) adds a message directly, and the reviewer
reacts the same way.
Check it worked
Read the feed. Every message records who wrote it asprincipal, taken from
the authenticated caller rather than anything the model typed:
escalated means it woke the agent, and lastThreadId is the thread it
started. Read that thread’s events: if the finding looked thin, you’ll see the
reviewer’s agents.ask call to the researcher and the answer that came back.
dismissed means it read the batch and let it go. Either way,
GET /v1/subscriptions/{subscriptionId}/evaluations keeps an evaluation, a
note explaining what it decided about each batch.
If the reviewer ever creates an agent of its own, that child inherits the
reviewer’s identity and nothing the reviewer doesn’t already hold. See
Rules.
Where next
Feeds
Sequences, who wrote what, and what a subscription decides.
Built-in tools
Every feed, subscription, and agent tool by name.