Skip to main content

Overview

A comms channel is a conversation that lives outside the agent. It can be a markdown file, a queue, a SQLite table, a remote server or an email thread. Every agent or structure given the same channel reads what was said there before it runs and posts what it says after. CommsChannel is the abstract base class. Swarms ships six implementations:
runs/ev_report.md then holds the whole conversation:
For runnable walkthroughs of every channel, see the Comms Channels examples.

Import

All seven names are also exported from swarms.structs. The base class lives in swarms.structs.comms_channel.

Message shape

Every channel stores and returns messages as plain dictionaries, oldest first:
Some channels return more through their own methods. For example, SqliteChannel.fetch_messages() adds id and created_at.

Abstract methods

post()

Append one message.
Parameters:
  • agent_name (str): Who is speaking, such as an agent name or the user name.
  • content (str): The message text.

messages()

Return every message so far, oldest first.
Returns: A list of {"agent_name": ..., "content": ...} dictionaries.

clear()

Remove every message. Optional: the base class raises NotImplementedError, and every built-in channel overrides it.
Raises: NotImplementedError on a subclass that does not override it.
The base class has no close() method. The built-in channels that hold a connection (SqliteChannel, HttpChannel, AgentMailChannel) add one, and QueueChannel.close() means something different: it ends a consumer’s iteration. Agents and structures never call close(), so call it yourself when you are done.

How an Agent uses a channel

Pass the channel as Agent(channel=...). On each run(task):
  1. Read. The agent calls channel.messages() and sends every earlier message to the model as prior turns, under the speaker’s name.
  2. Post the task once. It posts the task under the agent’s user_name (default "Human"), unless that exact message is already in the channel. Several agents sharing a channel and running the same task therefore record it once.
  3. Run. The agent runs as usual.
  4. Post the answer. After a successful run it posts its final answer under its agent_name. A run that raises posts nothing. The answer is the agent’s last message, not the whole transcript that output_type may return.
When you pass messages= yourself, you are managing the transcript, so the agent skips steps 1 and 2. It still posts its answer. Because each run reads the channel first, a channel that already holds a conversation (a file from yesterday, a database row set, an email thread) becomes the context the next run continues from.

How a Conversation uses a channel

Conversation(channel=...) seeds its history from channel.messages() when it is constructed. After that, every add() is also posted to the channel, except messages whose role is System or system and messages with None content.

How multi-agent structures use a channel

Nine structures take a channel argument. Each one posts to the channel through its own conversation: the task once at the start, then each member’s contribution under that member’s name. SwarmRouter(channel=...) forwards the channel to the structure it builds for these swarm_type values: SequentialWorkflow, ConcurrentWorkflow, AgentRearrange, MixtureOfAgents, HierarchicalSwarm, GroupChat, MajorityVoting and PlannerWorkerSwarm. Other swarm types ignore it.
The structure owns the channel. When a structure has a channel, it detaches the channel from each member agent, sets that agent’s channel to None and logs a warning. Without this, every message would be posted twice: once by the structure and once by the agent. The detachment is permanent, so give the channel to the structure, not to its agents.
Agents in SequentialWorkflow and AgentRearrange see what the channel already holds before their run, so you can resume or steer a pipeline by editing its channel between runs. In ConcurrentWorkflow each agent gets only the task; the channel records the answers but does not feed earlier history back to the agents.

Writing your own channel

Subclass CommsChannel and implement post() and messages(). Implement clear() if your medium can delete. Anything that can append and list messages works: Redis, a Slack thread, a Postgres table, a message bus.
Keep these points in mind:
  • Return exact text. An agent decides whether its task is already posted by comparing {"agent_name": user_name, "content": task} with the rows messages() returns. A channel that changes whitespace or encoding posts the task again on every run.
  • Be safe for concurrent posts. ConcurrentWorkflow, MixtureOfAgents and other fan-out structures can call post() from several threads.
  • messages() is called on every run. Keep it cheap, or cache it.

Source Code