# ADR-009: Agent Communication Protocol **Status:** Accepted **Date:** 2025-12-29 **Deciders:** Architecture Team **Related Spikes:** SPIKE-007 --- ## Context Syndarix requires a robust protocol for inter-agent communication. 10+ specialized AI agents must collaborate on software projects, sharing context, delegating tasks, and resolving conflicts. ## Decision Drivers - **Auditability:** All communication must be traceable - **Flexibility:** Support various communication patterns - **Performance:** Low-latency for interactive collaboration - **Reliability:** Messages must not be lost ## Considered Options ### Option 1: Pure Natural Language Agents communicate via free-form text messages. **Pros:** Simple, flexible **Cons:** Difficult to route, parse, and audit ### Option 2: Rigid RPC Protocol Strongly-typed function calls between agents. **Pros:** Predictable, type-safe **Cons:** Loses LLM reasoning flexibility ### Option 3: Structured Envelope + Natural Language Payload (Selected) JSON envelope for routing/auditing with natural language content. **Pros:** Best of both worlds - routeable and auditable while preserving LLM capabilities **Cons:** Slightly more complex ## Decision **Adopt structured message envelopes with natural language payloads**, inspired by Google's A2A protocol concepts. ## Implementation ### Message Schema ```python @dataclass class AgentMessage: id: UUID # Unique message ID type: Literal["request", "response", "broadcast", "notification"] # Routing from_agent: AgentIdentity # Source agent to_agent: AgentIdentity | None # Target (None = broadcast) routing: Literal["direct", "role", "broadcast", "topic"] # Action action: str # e.g., "request_guidance", "task_handoff" priority: Literal["low", "normal", "high", "urgent"] # Context project_id: str conversation_id: str | None # For threading correlation_id: UUID | None # For request/response matching # Content content: str # Natural language message attachments: list[Attachment] # Code snippets, files, etc. # Metadata created_at: datetime expires_at: datetime | None requires_response: bool ``` ### Routing Strategies | Strategy | Syntax | Use Case | |----------|--------|----------| | Direct | `to: "agent-123"` | Specific agent | | Role-based | `to: "@engineers"` | All agents of role | | Broadcast | `to: "@all"` | Project-wide | | Topic-based | `to: "#auth-module"` | Subscribed agents | ### Communication Modes ```python class MessageMode(str, Enum): SYNC = "sync" # Await response (< 30s) ASYNC = "async" # Queue, callback later FIRE_AND_FORGET = "fire" # No response expected STREAM = "stream" # Continuous updates ``` ### Message Bus Implementation ```python class AgentMessageBus: """Redis Streams-based message bus for agent communication.""" async def send(self, message: AgentMessage) -> None: # Persist to PostgreSQL for audit await self.store.save(message) # Publish to Redis for real-time delivery channel = self._get_channel(message) await self.redis.xadd(channel, message.to_dict()) # Publish SSE event for UI visibility await self.event_bus.publish( f"project:{message.project_id}", {"type": "agent_message", "preview": message.content[:100]} ) async def subscribe(self, agent_id: str) -> AsyncIterator[AgentMessage]: """Subscribe to messages for an agent.""" channels = [ f"agent:{agent_id}", # Direct messages f"role:{agent.role}", # Role-based f"project:{agent.project_id}", # Broadcasts ] # ... Redis Streams consumer group logic ``` ### Context Hierarchy 1. **Conversation Context** (short-term): Current thread, last N exchanges 2. **Session Context** (medium-term): Sprint goals, recent decisions 3. **Project Context** (long-term): Architecture, requirements, knowledge base ### Conflict Resolution When agents disagree: 1. **Peer Resolution:** Agents attempt consensus (2 attempts) 2. **Supervisor Escalation:** Product Owner or Architect decides 3. **Human Override:** Client approval if configured ## Consequences ### Positive - Full audit trail of all agent communication - Flexible routing supports various collaboration patterns - Natural language preserves LLM reasoning quality - Real-time UI visibility into agent collaboration ### Negative - Additional complexity vs simple function calls - Message persistence storage requirements ### Mitigation - Archival policy for old messages - Compression for large attachments ## Compliance This decision aligns with: - FR-104: Inter-agent communication - FR-105: Agent activity monitoring - NFR-602: Comprehensive audit logging --- *This ADR establishes the agent communication protocol for Syndarix.*