Skip to main content
A conversation room lets a roster of agents share one chat and reply on their own — you send a message, the room runs the scheduled turns in a deterministic, bounded, restart-safe order and hands you the replies.

Quick Start

Build a team of agents, name the roster, and send one message — the room runs every scheduled turn and returns the replies.
1

Simple room

Three agents share one chat. on_message fans out to the whole roster and returns their replies.
2

Configure caps

Bound the conversation with max_rounds and max_messages so a room can never loop unbounded.
3

Load from YAML / dict

Build the config from a parsed mapping. Either roster: or agents: names the roster.
4

Advanced: drive the planner yourself

If you’re building a wrapper that persists its own transcript, drive plan_next directly instead of using Room.

User Interaction Flow

A real user builds a team and asks the room a question — no manual loop, no reset.
  1. Create Agent objects.
  2. Declare a RoomConfig naming the roster.
  3. Build a Room(cfg, agents=...).
  4. await room.on_message(RoomEvent(speaker="user", content="...")).
  5. The room fans out to round 0, honours any @-mentions for later rounds, and returns the replies.
  6. The next user message reopens a fresh activity automatically.

How a Room Runs

Room.on_message appends your event, drains the planner, runs each scheduled agent, and returns the replies. The planner is pure, so persisting room.transcript and rebuilding the room is enough to resume — replaying a settled transcript returns no next speaker, so there is no double-execution.
The transcript is in-memory only. Room holds no durable state — a wrapper (praisonai-bot) persists room.transcript and handles platform delivery.

Choosing a Configuration Surface

Pick where your room config lives.

Configuration Options

RoomConfig is a dataclass describing the roster and planner caps. RoomConfig methods:
  • build_planner() — constructs RoundRobinRoomPlanner(max_rounds=..., max_messages=...).
  • to_dict() — plain dict for YAML round-tripping or diagnostics.
  • RoomConfig.from_dict(name, data) — builds from a parsed mapping; accepts roster: or agents:. Rejects scalar values (bare string, bytes, mapping) with an actionable ValueError.
RoundRobinRoomPlanner is a dataclass with two hard caps. RoomEvent is a frozen dataclass — immutable, hashable, and safe to persist or replay. For the full Room and RoomConfig API surface, see the auto-generated SDK reference.

Rooms SDK Reference

Every Room and RoomConfig parameter, method, and default.

Turn-Taking Rules

After a human message, every rostered agent speaks once in roster order. This is the “everyone on round 0” default.
A round N+1 admits only the agents that were @-mentioned by an agent during round N, and only agents actually on the roster. Mentions are honoured in roster order (not mention order). An agent speaks at most once per round.
max_rounds and max_messages are hard stops; a room can never loop unbounded.
The plan is a pure function of (roster, transcript). Rebuild a Room from a persisted transcript and plan_next returns the identical next speaker — no double-execution, no lost turn.

Current Activity Semantics

The planner scopes accounting to the slice of the transcript from the last human (non-roster) message onward.
  • A room only starts once a human (non-roster) message has been seen. Before that, plan_next returns None.
  • max_messages is per activity, not lifetime. A settled room reliably restarts on the next human message, no matter how long the historical transcript is.
  • @-mention admission is also scoped to the current activity — stale mentions from a prior settled activity do not leak into a new activity’s later rounds.

Mention Parsing

extract_mentions(text) returns the ordered, de-duplicated list of @name mentions found in text.
  • First-seen order is preserved so addressing is deterministic.
  • Case is preserved; matching against roster ids is case-sensitive.
  • Name grammar: @ followed by [A-Za-z0-9][\w\-.]* — letters, digits, underscore, dash, dot; a name may not start with _, -, or ..
  • Email-safe: a @ glued to a preceding word character does not match, so scanning human text is safe.

Common Patterns

Two overlapping on_message calls do not interleave — each is serialised through an internal asyncio.Lock, so every human message opens exactly one round-0 activity and no agent double-executes for one activity.
An id in roster with no matching agents entry records a passed=True turn so the planner advances instead of looping forever on a missing agent.
Pass render=lambda transcript: ... to control the prompt handed to each agent. The default joins speaker: content lines.
Pass planner=MyPlanner() for a domain-specific policy. The runtime tags each turn with the activity’s current round rather than inventing round-robin admission, so custom planners are never fed misleading round labels.
An agent with nothing to add returns an empty reply, recorded as a turn that advances the planner without adding content.

Best Practices

No clock, no RNG, no I/O. Purity is the whole property that makes a room restart-safe.
When multiple agents are admitted (round 0, or several @-mentions in one round), they speak in roster order, not mention order. Design roster order intentionally.
max_rounds and max_messages are the guardrails against runaway loops. RoomConfig() defaults to 3 rounds and 20 messages per activity.
Room keeps the transcript in memory only. To survive a restart, persist room.transcript in your wrapper and rebuild the room from it — the pure planner resumes the identical schedule.
Message caps are per activity (per human message), by design. A long historical transcript never permanently disables a room.

Make it Live

The core Room is in-memory and I/O-free by design. To run a room over a live platform (Telegram / Slack / Discord / webhook) with a durable transcript and restart-safe schedule, use GatewayRoom from praisonai_bot.bots — it wraps the same core Room, swaps the transcript in and out via BotSessionManager, and plugs in anywhere a single agent is bound today.

Gateway Rooms

Run a rostered room over a live platform with a durable, restart-safe transcript.

Rooms SDK Reference

Full Room and RoomConfig API surface.

Gateway Rooms

Run a room over Telegram / Slack / Discord with a durable transcript.

Bot Gateway

The praisonai-bot wrapper adds durable persistence and platform delivery.

AgentTeam

The in-process, run-to-completion counterpart to a live conversation room.

Gateway Turn Lock

Serialise per-session turns across replicas.