Room (Proactive Mode)
On this page
The Room section (in the agent’s Automations group) turns an agent from a reactive chatbot into a proactive worker. With the room enabled, the agent runs cycles on its own clock, reacting to events delivered via inbound webhooks rather than waiting for a human to type a message.
What the Room does
Every 30 seconds (TICK_INTERVAL_MS), the Room scheduler wakes up and asks: “For each room with enabled = true, are there any pending events?” If yes, it spawns one supervisor cycle per room. Inside the cycle, the agent sees:
- The room’s prompt, added to the agent’s own prompt as its mandate.
- The pending events as the user-message side of the conversation.
- Three harness tools:
send_message_to_human,mark_events_completed,compact_room_history.
Each cycle creates a new conversation - the conversation id format is room:<instanceId>:<timestamp>, never persistent. Rolling state lives in the activity log instead (see below).
A human reply on the outbound channel triggers an immediate cycle (skipping the 30 s wait) so that the agent is responsive when a human steps in mid-flow.
Configuration
The Room section has three sub-sections: Configuration, Backlog, and Activity Log. Event sources are not a Room sub-section any more - they are their own Webhooks section, a sibling of Room under the agent’s Automation row.
Configuration
- Enabled - master switch.
- Prompt - the room’s mandate. During a room cycle it is appended to the system prompt as a
## Room Mandateblock, after the agent’s seven sections (Identity, Soul, Tooling, Safety, Skills, Memory, User Identity), which all still apply: the mandate adds to the agent’s identity rather than replacing it. It sits in the cacheable prefix with the rest of the system prompt. There is no Datetime section - the date and time are injected into the message context, not the prompt. See Prompt. - Outbound channel -
slack,telegram,whatsapp, ornone. - Outbound target - channel id or user id where
send_message_to_humanwill deliver.
The 30-second tick is a global scheduler interval (TICK_INTERVAL_MS), not a per-room field - it is not configurable from the Room tab.
Event Sources (now the Webhooks section)
Event sources live in the agent’s Webhooks section (?tab=webhooks), alongside Room in the Automations group. The model has not changed; the configuration UI simply relocated. An event source is a connection between an external system and the Room. Each event source has:
-
Webhook URL - auto-generated, formatted as
/webhooks/<webhookToken>. The token IS the secret - anyone who knows the URL can post events. Treat it as a credential; rotate it from the UI when leaked. -
Payload size cap - 64 KB. Oversize payloads receive a
200 OKwith body{ ok: false, error: "payload too large" }(the receiver is always fire-and-forget). -
Backlog cap - 100 pending events per agent, counted across every source. Beyond that, new events are refused at insert time rather than displacing older ones: the insert is conditional on the count, so nothing already queued is lost.
-
Event Definitions - the heart of routing. Matching is evaluated by an LLM (tier
fast) against natural-language prompts you define per event definition - there are no rules, regex, or JSONPath predicates. Each definition has:- Name.
matchingPrompt- a natural-language description of when this definition applies (e.g. “The payload indicates a Stripe invoice has just been paid by a customer”). Definitions are evaluated one at a time and the first match wins; there is no priority to set, so write prompts that do not overlap.interpretationPrompt- a natural-language instruction on how to summarize the matched payload into the user-message side of the room cycle (e.g. “Extract the customer email, amount, and invoice id, and phrase it as a single sentence”).- A target room behavior.
When a webhook fires, the engine sends the payload + each definition’s
matchingPromptto the matcher until one matches, then uses the winning definition’sinterpretationPromptto render the event for the room cycle.
Backlog and Activity Log
- Backlog - pending events waiting to be processed. Status filter:
pending,processing,completed. Each row shows the start of the payload, its status and when it was received, under a search box; clicking a row opens the full payload in a side drawer. - Activity log - a chronological log of every room cycle. Old entries are compacted automatically:
- Daily entries older than 7 days collapse into a weekly summary.
- Weekly entries older than 28 days collapse into a monthly summary.
- Monthly entries are kept for 12 months, then dropped.
Compaction keeps the log readable and the database lean.
Storage retention
The room activity log is auto-compacted on a fixed schedule: daily rows for the last 7 days, then weekly rows after 7d, then monthly rows after 4 weeks. The compaction logic lives in packages/engine/src/room/activity-log.store.ts:49-70 and runs as part of the scheduler’s housekeeping pass - no manual maintenance is required.
Worked example: Stripe invoice paid
Suppose you want the agent to send a Slack DM whenever a customer pays an invoice.
- Create an instance with the right identity for the use case.
- On the Room tab → Configuration, set:
- Enabled: yes
- Prompt: “You watch Stripe invoice events. When an invoice is paid, send a short congratulatory DM to the account owner on Slack.”
- Outbound channel:
slack - Outbound target: the Slack channel id
C012345678
- On the Channels tab, configure Slack and start the channel.
- In Automation → Webhooks, click Add and create an event source:
- Source Name:
Stripe - Open it and, under Event Definitions, click Add:
- Definition Name:
Invoice paid - Matching Prompt: “A Stripe invoice has been paid. The payload includes
event.type = 'invoice.paid'.”
- Definition Name:
- Source Name:
- In Stripe, point a webhook at
https://<your-host>/webhooks/<webhookToken>. Pick theinvoice.paidevent type only (or all if you do not mind extra traffic). - Pay a test invoice. Within ~30 seconds you should see a Slack DM from the bot, and a new entry in the activity log.
For the inbound HTTP contract (size limits, signatures, response codes) see Webhooks (Inbound).
The Automations group
There is no “Triggers” section. The agent’s sidebar has an Automations group whose rows are Hooks, Webhooks, Scheduled and Room, each its own section with its own ?tab= address and each shown to whoever can read it. The three sections this page is about:
- Webhooks - the event sources above (full CRUD: create / edit / delete / event definitions). Needs
agent.room:read. - Scheduled - recurring or one-shot tasks, also created by
scheduleTask. Each row: cron expression, next run, status. Needsagent.task:read. See Scheduled tasks. - Room - this page.
Execution history is not here: scheduled runs and webhook conversations are in the agent’s Monitor section, under the Overview group. A bookmark to ?tab=triggers names nothing and lands on Status.