Packages
nous
0.13.3
0.17.0
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.8
0.15.7
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.17
0.12.16
0.12.15
0.12.14
0.12.13
0.12.12
0.12.11
0.12.9
0.12.7
0.12.6
0.12.5
0.12.3
0.12.2
0.12.0
0.11.3
0.11.0
0.10.1
0.10.0
0.9.0
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.5.0
AI agent framework for Elixir with multi-provider LLM support
Current section
Files
Jump to
Current section
Files
lib/nous/teams/comms.ex
defmodule Nous.Teams.Comms do
@moduledoc """
PubSub topic helpers and communication utilities for multi-agent teams.
Provides consistent topic naming conventions and convenience wrappers
around `Nous.PubSub` for team-scoped messaging.
## Topic Structure
nous:team:<team_id> — team-wide broadcasts
nous:team:<team_id>:context — shared context updates
nous:team:<team_id>:agent:<name> — direct agent messages
## Quick Start
# Subscribe an agent to team + direct topics
Comms.subscribe_team(pubsub, "team_1")
Comms.subscribe_agent(pubsub, "team_1", "alice")
# Broadcast to all agents on a team
Comms.broadcast_team(pubsub, "team_1", {:discovery, %{topic: "bug found"}})
# Send a direct message to one agent
Comms.send_to_agent(pubsub, "team_1", "bob", {:peer_message, "alice", "check this"})
"""
alias Nous.PubSub
@doc """
Build the team-wide broadcast topic.
## Examples
iex> Nous.Teams.Comms.team_topic("team_1")
"nous:team:team_1"
"""
@spec team_topic(String.t()) :: String.t()
def team_topic(team_id), do: "nous:team:#{team_id}"
@doc """
Build the shared context update topic for a team.
## Examples
iex> Nous.Teams.Comms.context_topic("team_1")
"nous:team:team_1:context"
"""
@spec context_topic(String.t()) :: String.t()
def context_topic(team_id), do: "nous:team:#{team_id}:context"
@doc """
Build the direct message topic for a specific agent in a team.
## Examples
iex> Nous.Teams.Comms.agent_topic("team_1", "alice")
"nous:team:team_1:agent:alice"
"""
@spec agent_topic(String.t(), String.t()) :: String.t()
def agent_topic(team_id, agent_name), do: "nous:team:#{team_id}:agent:#{agent_name}"
@doc """
Subscribe the calling process to the team-wide broadcast topic.
## Options
Uses `Nous.PubSub.subscribe/2` — no-op if PubSub is nil or unavailable.
"""
@spec subscribe_team(module() | nil, String.t()) :: :ok | {:error, term()}
def subscribe_team(pubsub, team_id) do
PubSub.subscribe(pubsub, team_topic(team_id))
end
@doc """
Subscribe the calling process to a specific agent's direct message topic.
## Options
Uses `Nous.PubSub.subscribe/2` — no-op if PubSub is nil or unavailable.
"""
@spec subscribe_agent(module() | nil, String.t(), String.t()) :: :ok | {:error, term()}
def subscribe_agent(pubsub, team_id, agent_name) do
PubSub.subscribe(pubsub, agent_topic(team_id, agent_name))
end
@doc """
Broadcast a message to all agents on the team.
## Options
Uses `Nous.PubSub.broadcast/3` — no-op if PubSub is nil or unavailable.
"""
@spec broadcast_team(module() | nil, String.t(), term()) :: :ok | {:error, term()}
def broadcast_team(pubsub, team_id, message) do
PubSub.broadcast(pubsub, team_topic(team_id), message)
end
@doc """
Send a direct message to a specific agent on the team.
## Options
Uses `Nous.PubSub.broadcast/3` on the agent's direct topic — no-op if PubSub
is nil or unavailable.
"""
@spec send_to_agent(module() | nil, String.t(), String.t(), term()) :: :ok | {:error, term()}
def send_to_agent(pubsub, team_id, agent_name, message) do
PubSub.broadcast(pubsub, agent_topic(team_id, agent_name), message)
end
end