Skip to Content
Polyant is open source under AGPL-3.0 — star us on GitHub.
Admin PanelRoom (Proactive Mode)

Tab: Room (Proactive Mode)

The Room turns an instance from a reactive chatbot into a proactive worker. With the room enabled, the assistant 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 assistant sees:

  • The room’s prompt (separate from the instance’s identity prompt).
  • 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 assistant is responsive when a human steps in mid-flow.

Configuration

The Room tab has three sub-sections: Configuration, Backlog, and Activity Log. Event sources are not a Room sub-section any more — they moved to the new top-level Triggers tab (see Tab: Triggers below).

Configuration

  • Enabled — master switch.
  • Prompt — the room-specific system prompt. This replaces the instance’s identity prompt during a room cycle, but the other seven sections (Soul, Tooling, Safety, Skills, Memory, User Identity, Datetime) still apply.
  • Outbound channelslack, telegram, whatsapp, or none.
  • Outbound target — channel id or user id where send_message_to_human will 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 (moved to Triggers → Webhooks)

Event sources now live under the instance’s Triggers tab → Webhooks subtab. 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 OK with body { ok: false, error: "payload too large" } (the receiver is always fire-and-forget).

  • Backlog cap — 100 pending events per source. Beyond that, oldest events are dropped.

  • 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 and priority (lower priority fires first).
    • 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”). Evaluated sequentially in priority order; first match wins.
    • 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 matchingPrompt to the matcher until one matches, then uses the winning definition’s interpretationPrompt to 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 event source, definition matched, payload (collapsed), and timestamps.
  • 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 assistant to send a Slack DM whenever a customer pays an invoice.

  1. Create an instance with the right identity for the use case.
  2. 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
  3. On the Channels tab, configure Slack and start the channel.
  4. On the Room tab → Event Sources, click New event source:
    • Name: Stripe
    • Optional secret: any string; mirror it on Stripe’s webhook config.
    • Add an event definition:
      • Name: Invoice paid
      • Priority: 1
      • Description: “A Stripe invoice has been paid. The payload includes event.type = 'invoice.paid'.”
  5. In Stripe, point a webhook at https://<your-host>/webhooks/<webhookToken>. Pick the invoice.paid event type only (or all if you do not mind extra traffic).
  6. 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).

Tab: Triggers

Triggers is a separate top-level instance tab — a sibling of Room, not a subtab inside it. It groups three subtabs:

  • Webhooks — the event sources from above (full CRUD: create / edit / delete / event definitions).
  • Scheduled — recurring or one-shot tasks created by scheduleTask. Each row: cron expression, next run, status.
  • Runs — execution history of all triggers (webhook + scheduled + room ticks).

Use the Triggers tab to configure trigger sources and to debug why an event did or did not fire.

Last updated on