Communication¶
The communication architecture defines how agents exchange information, resolve disagreements, and coordinate through structured meetings. All communication patterns, conflict resolution strategies, and meeting protocols are pluggable and configurable per company, per department, or per interaction type.
Communication Patterns¶
The framework supports multiple communication patterns, configurable per company:
Recommended Default
┌──────────┐ ┌─────────────────┐ ┌──────────┐
│ Agent A │────>│ Message Bus │<────│ Agent B │
└──────────┘ │ (Topics/Queues) │ └──────────┘
└────────┬────────┘
│
┌───────────┼───────────┐
v v v
#engineering #product #all-hands
#code-review #design #incidents
- Agents publish to topics, subscribe to relevant channels
- Async by default, enables parallelism
- Decoupled -- agents do not need to know about each other
- Natural audit trail of all communications
- Best for
- Most scenarios; scales well, production-ready pattern.
- Tasks flow down the hierarchy, results flow up
- Each level can decompose and refine tasks before delegating
- Authority enforcement built into the flow
- Best for
- Structured organizations with clear chains of command.
┌─────────────────────────────────┐
│ Sprint Planning │
│ PM + CTO + Devs + QA + Design │
│ Output: Sprint backlog │
└─────────────────────────────────┘
│
┌────────┴────────┐
│ Daily Standup │
│ Devs + QA │
│ Output: Status │
└─────────────────┘
- Structured multi-agent conversations at defined intervals
- Standup, sprint planning, retrospective, design review, code review
- Best for
- Agile workflows, decision-making, alignment.
Combines all three patterns:
- Message bus for async daily work and notifications
- Hierarchical delegation for task assignment and approvals
- Meetings for cross-team decisions and planning ceremonies
Built-in templates select the communication pattern that fits their archetype (e.g.
event_driven for Solo Builder, Research Lab, and Data Team, hierarchical for Agency,
Enterprise Org, and Consultancy, meeting_based for Product Studio). See the
Company Types table for per-template defaults.
Communication Standards¶
The framework aligns with emerging industry standards:
- A2A Protocol (Agent-to-Agent, Linux Foundation)
- Inter-agent task delegation, capability discovery via Agent Cards, and structured task lifecycle management.
- MCP (Model Context Protocol, Agentic AI Foundation / Linux Foundation)
- Agent-to-tool integration, providing standardized tool discovery and invocation.
Message Format¶
{
"id": "msg-uuid",
"timestamp": "2026-02-27T10:30:00Z",
"sender": "sarah_chen",
"to": "engineering",
"type": "task_update",
"priority": "normal",
"channel": "#backend",
"content": "Completed API endpoint for user authentication. PR ready for review.",
"attachments": [
{"type": "artifact", "ref": "pr-42"}
],
"metadata": {
"task_id": "task-123",
"project_id": null,
"tokens_used": 1200,
"cost_usd": 0.018,
"extra": [["model", "example-medium-001"]]
}
}
All metadata fields are nullable except extra, which is always present (defaults to an empty list). The extra field contains additional key-value pairs for extensibility.
Communication Config¶
Full communication configuration
communication:
default_pattern: "hybrid"
message_bus:
backend: "internal" # internal, redis, rabbitmq, kafka
channels:
- "#all-hands"
- "#engineering"
- "#product"
- "#design"
- "#incidents"
- "#code-review"
- "#watercooler"
meetings:
enabled: true
types:
- name: "daily_standup"
frequency: "per_sprint_day"
participants: ["engineering", "qa"]
duration_tokens: 2000
- name: "sprint_planning"
frequency: "bi_weekly"
participants: ["all"]
duration_tokens: 5000
- name: "code_review"
trigger: "on_pr"
participants: ["author", "reviewers"]
hierarchy:
enforce_chain_of_command: true
allow_skip_level: false # can a junior message the CEO directly?
Loop Prevention¶
Agent communication loops (A delegates to B who delegates back to A) are a critical risk. The framework enforces multiple safeguards:
| Mechanism | Description | Default |
|---|---|---|
| Max delegation depth | Hard limit on chain length (A->B->C->D stops at depth N) | 5 |
| Message rate limit | Max messages per agent pair within a time window | 10 per minute |
| Identical request dedup | Detects and rejects duplicate task delegations within a window | 60s window |
| Circuit breaker | If an agent pair exceeds error/bounce threshold, block further messages until manual reset or cooldown | 3 bounces, 5min cooldown |
| Task ancestry tracking | Every delegated task carries its full delegation chain; agents cannot delegate back to any ancestor in the chain | Always on |
Loop prevention configuration
loop_prevention:
max_delegation_depth: 5
rate_limit:
max_per_pair_per_minute: 10
burst_allowance: 3
dedup_window_seconds: 60
circuit_breaker:
bounce_threshold: 3
cooldown_seconds: 300
Ancestry tracking is always enabled and is not user-configurable.
When a loop is detected, the framework:
- Blocks the looping message
- Notifies the sending agent with the detected loop chain
- Escalates to the sender's manager (or human if at top of hierarchy)
- Logs the loop for analytics and process improvement
Conflict Resolution Protocol¶
When two or more agents disagree on an approach (architecture, implementation,
priority), the framework provides multiple configurable resolution strategies
behind a ConflictResolver protocol. New strategies can be added without
modifying existing ones. The strategy is configurable per company, per
department, or per conflict type.
Default Strategy
The agent with higher authority level decides. Cross-department conflicts (incomparable authority) escalate to the lowest common manager in the hierarchy. The losing agent's reasoning is preserved as a dissent record -- a structured log entry containing the conflict context, both positions, and the resolution. Dissent records feed into organizational learning and can be reviewed during retrospectives.
- Deterministic, zero extra tokens, fast resolution
- Dissent records create institutional memory of alternative approaches
Both agents present arguments (1 round each). A judge -- their shared manager, the CEO, or a configurable arbitrator agent -- evaluates both positions and decides. The judge's reasoning and both arguments are logged as a dissent record.
conflict_resolution:
strategy: "debate"
debate:
judge: "shared_manager" # shared_manager, ceo, designated_agent
- Better decisions -- forces agents to articulate reasoning
- Higher token cost, adds latency proportional to argument length
All genuine conflicts go to the human approval queue with both positions summarized. The agent(s) park the conflicting task and work on other tasks while waiting (see Approval Timeout).
- Safest -- human always makes the call
- Bottleneck at scale, depends on human availability
Recommended for Production
Combines strategies with an intelligent review layer:
- Both agents present arguments (1 round) -- preserving dissent
- A conflict review agent evaluates the result:
- If the resolution is clear (one position is objectively better, or authority applies cleanly) -- resolve automatically, log dissent record
- If the resolution is ambiguous (genuine trade-offs, no clear winner) -- escalate to human queue with both positions + the review agent's analysis
conflict_resolution:
strategy: "hybrid"
hybrid:
review_agent: "conflict_reviewer" # dedicated agent or role
escalate_on_ambiguity: true
- Best balance: most conflicts resolve fast, humans only see genuinely hard calls
- Most complex to implement; review agent itself needs careful prompt design
Meeting Protocol¶
Meetings (Pattern 3 above) follow configurable protocols that determine how
agents interact during structured multi-agent conversations. Different meeting
types naturally suit different protocols. All protocols implement a
MeetingProtocol protocol, making the system extensible -- new protocols can be
registered and selected per meeting type. Cost bounds are enforced by
duration_tokens in the communication config.
The meeting leader calls each participant in turn. A shared transcript grows as each agent responds, seeing all prior contributions. The leader summarizes and extracts action items at the end.
meeting_protocol: "round_robin"
round_robin:
max_turns_per_agent: 2
max_total_turns: 16
leader_summarizes: true
- Simple, natural conversation feel, each agent sees full context
- Token cost grows quadratically; last speaker has more context (ordering bias)
- Best for
- Daily standups, status updates, small groups (3--5 agents).
Each agent independently writes a short position paper (parallel execution, no shared context). A synthesizer agent reads all positions, identifies agreements and conflicts, and produces decisions + action items.
meeting_protocol: "position_papers"
position_papers:
max_tokens_per_position: 300
synthesizer: "meeting_leader" # who synthesizes
- Cheapest -- parallel calls, no quadratic growth, no ordering bias, no groupthink
- Loses back-and-forth dialogue; agents cannot challenge each other's ideas
- Best for
- Brainstorming, architecture proposals, large groups, cost-sensitive meetings.
Meeting split into phases with targeted participation:
- Agenda broadcast -- leader shares agenda and context to all participants
- Input gathering -- each agent submits input independently (parallel)
- Discussion round -- only triggered if conflicts are detected between inputs; relevant agents debate (1 round, capped tokens)
- Decision + action items -- leader synthesizes, creates tasks from action items
meeting_protocol: "structured_phases"
auto_create_tasks: true # action items become tasks (top-level, applies to any protocol)
structured_phases:
skip_discussion_if_no_conflicts: true
max_discussion_tokens: 1000
- Cost-efficient -- parallel input, discussion only when needed
- More complex orchestration; conflict detection between inputs adds implementation complexity
- Best for
- Sprint planning, design reviews, architecture decisions.
Meeting Scheduler¶
The MeetingScheduler is a background service that bridges meeting configuration
and execution. It reads MeetingsConfig and manages two modes of meeting
triggering:
Frequency-Based Scheduling¶
Meetings with a frequency field (e.g. daily, weekly, bi_weekly,
per_sprint_day, monthly) are scheduled as periodic asyncio tasks. The
MeetingFrequency enum maps each value to a sleep interval in seconds. Periodic
tasks survive transient errors -- a single execution failure does not kill the
background loop.
Event-Triggered Meetings¶
Meetings with a trigger field (e.g. on_pr, deploy_complete) are executed
on demand via trigger_event(event_name, context). The scheduler matches all
meeting types whose trigger value equals the event name and executes them in
parallel using asyncio.TaskGroup.
Participant Resolution¶
The ParticipantResolver protocol resolves participant reference strings from
config into concrete agent IDs. The RegistryParticipantResolver implementation
uses the AgentRegistryService with a five-step cascade:
- Context lookup -- if the event context dict has a matching key, use its value.
- Special
"all"-- resolves to all active agents. - Department lookup -- resolves to all agents in the named department.
- Agent name lookup -- resolves to the agent with that name.
- Pass-through -- assumes the entry is a literal agent ID.
Results are deduplicated while preserving insertion order. The first resolved participant is designated as the meeting leader.
When no AgentRegistryService is available (e.g. during auto-wiring without an
explicit registry), the PassthroughParticipantResolver is used as a fallback.
It supports only context lookup and literal pass-through (steps 1 and 5 above),
skipping the registry-dependent steps (2--4).
Meeting API Response Enrichment¶
The meeting REST API enriches every MeetingRecord response with computed
analytics fields. Per-participant metrics are derived from
MeetingMinutes.contributions:
token_usage_by_participant(dict[str, int]): total tokens (input + output) consumed per agent. Empty when no minutes are available.contribution_rank(tuple[str, ...]): agent IDs sorted by total token usage descending. Empty when no minutes are available.
Duration is computed from the meeting timestamps, not from contributions:
meeting_duration_seconds(float | null,>= 0.0): duration computed fromended_at - started_at, clamped to0.0when negative.nullwhen no minutes are available.
These fields are applied to all meeting endpoints (list, detail, trigger).
Auto-Wiring¶
The MeetingOrchestrator and MeetingScheduler are auto-wired at startup
alongside Phase 1 services (no persistence dependency). All three meeting
protocols are registered with default configs. A stub agent_caller returns
empty AgentResponse instances, making the meeting endpoints structurally
available (no 503 on listing) while actual agent invocation requires a
coordinator to be explicitly provided.