- Add hanzo-tools-code: code analysis and transformation tools - Add hanzo-tools-net: network and HTTP tools - Add hanzo-tools-plan: planning and task management tools - Add hanzo-tools-test: testing tools - Add hanzo-tools-vcs: version control tools - Add install command for dependency management - Improve CDP bridge server with better error handling - Add ui_tool for computer tools - Add unified tool loading and id_tool - Add HIP documentation (HIP-0300, HIP-0301)
13 KiB
HIP-0301: High-Performance Agent Communication Protocol
Status: Draft Author: Hanzo AI Created: January 2025 Updated: January 2025
Abstract
HIP-0301 defines a high-performance agent-to-agent communication protocol using Cap'n Proto as the wire format, with MCP JSON-RPC as a fallback. This enables sub-millisecond tool invocation between agents while maintaining backward compatibility with existing MCP infrastructure.
Motivation
Current MCP communication has inherent limitations:
- JSON Serialization Overhead: Every tool call requires JSON encode/decode (~100-500μs per call)
- No Zero-Copy: JSON requires full parsing before use; data copied multiple times
- Schema Flexibility = Runtime Errors: JSON's flexibility means errors surface at runtime
- Consensus Latency: Multi-agent consensus requires O(n²) messages; JSON overhead compounds
For AI agent swarms running metastable consensus, the overhead is unacceptable:
- 10 agents × 10 rounds × 100μs = 10ms just for serialization
- Real-world latencies 10-100x higher due to memory allocation
Cap'n Proto solves this with:
- Zero-copy reads: Wire format = memory format (no parsing)
- Incremental reads: Access fields without deserializing entire message
- Type safety: Schema-defined contracts, compile-time verification
- RPC built-in: Native async RPC with promise pipelining
Design
Transport Hierarchy
┌─────────────────────────────────────────────────────────────┐
│ Agent Bus Interface │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │
│ │ Cap'n Proto │ │ MCP JSON-RPC │ │ Unix IPC │ │
│ │ (preferred) │ │ (fallback) │ │ (local) │ │
│ └────────┬────────┘ └────────┬────────┘ └──────┬──────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ Unified Tool Invocation Layer ││
│ │ tool.call(action, params) -> Response ││
│ └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
AgentBus Trait
/// High-performance agent communication bus
#[async_trait]
pub trait AgentBus: Send + Sync {
/// Get bus capabilities
fn capabilities(&self) -> BusCapabilities;
/// Register local agent
async fn register(&self, agent_id: &str, handler: Arc<dyn AgentHandler>) -> Result<()>;
/// Unregister agent
async fn unregister(&self, agent_id: &str) -> Result<()>;
/// Call tool on remote agent (point-to-point)
async fn call(
&self,
from: &str,
to: &str,
tool: &str,
action: &str,
params: &[u8], // Pre-serialized (capnp or json)
) -> Result<Vec<u8>>;
/// Broadcast to all agents
async fn broadcast(
&self,
from: &str,
tool: &str,
action: &str,
params: &[u8],
) -> Result<Vec<(String, Vec<u8>)>>; // (agent_id, response)
/// Run consensus protocol
async fn consensus(
&self,
prompt: &str,
participants: &[&str],
config: ConsensusConfig,
) -> Result<ConsensusState>;
}
#[derive(Clone)]
pub struct BusCapabilities {
pub supports_capnp: bool,
pub supports_mcp: bool,
pub supports_unix_ipc: bool,
pub max_message_size: usize,
pub supports_streaming: bool,
}
pub struct ConsensusConfig {
pub rounds: u32,
pub k: u32, // Peer sample size
pub alpha: f64, // Confidence threshold
pub beta_1: f64, // Phase I threshold
pub beta_2: f64, // Phase II (finality) threshold
pub timeout_ms: u64,
}
Cap'n Proto Schema
@0xb5e7e8d3c9f2a1b4; # Unique file ID
# Core message types for agent communication
struct AgentId {
id @0 :Text;
nodeId @1 :Text; # For distributed deployment
capabilities @2 :List(Text);
}
struct ToolCall {
id @0 :UInt64; # Request ID for correlation
tool @1 :Text; # Tool name (fs, code, plan, etc.)
action @2 :Text; # Action within tool
params @3 :Data; # Serialized params (nested capnp or json)
effect @4 :Effect; # Declared effect level
traceId @5 :Text; # Distributed tracing
}
enum Effect {
pure @0;
deterministic @1;
nondeterministic @2;
}
struct ToolResponse {
id @0 :UInt64; # Matching request ID
ok @1 :Bool;
data @2 :Data; # Serialized result
error @3 :ToolError;
meta @4 :ResponseMeta;
}
struct ToolError {
code @0 :ErrorCode;
message @1 :Text;
details @2 :Data; # JSON or nested capnp
}
enum ErrorCode {
unknownAction @0;
invalidParams @1;
notFound @2;
conflict @3;
permissionDenied @4;
timeout @5;
internalError @6;
}
struct ResponseMeta {
tool @0 :Text;
version @1 :Text;
action @2 :Text;
effect @3 :Effect;
durationNs @4 :UInt64;
traceId @5 :Text;
}
# Consensus protocol messages
struct ConsensusVote {
round @0 :UInt32;
fromAgent @1 :Text;
vote @2 :Text; # Agent's response/vote
confidence @3 :Float64;
luminance @4 :Float64; # Response time weight
signature @5 :Data; # Optional cryptographic signature
}
struct ConsensusState {
round @0 :UInt32;
phase @1 :ConsensusPhase;
votes @2 :List(ConsensusVote);
winner @3 :Text;
synthesis @4 :Text;
finalized @5 :Bool;
confidence @6 :Float64;
}
enum ConsensusPhase {
sampling @0; # Phase I: k-peer sampling
finality @1; # Phase II: threshold aggregation
complete @2;
}
# Agent mesh management
struct AgentRegistration {
agent @0 :AgentId;
endpoint @1 :Text; # capnp://host:port or mcp://host:port
tools @2 :List(Text); # Available tools
publicKey @3 :Data; # For authenticated consensus
}
struct MeshTopology {
agents @0 :List(AgentRegistration);
gossipInterval @1 :UInt32; # ms between topology updates
}
# RPC Interface
interface AgentService {
# Core tool invocation
call @0 (request :ToolCall) -> (response :ToolResponse);
# Streaming for large responses
stream @1 (request :ToolCall) -> (stream :StreamHandle);
# Consensus participation
vote @2 (round :UInt32, prompt :Text, context :Data) -> (vote :ConsensusVote);
# Mesh management
register @3 (registration :AgentRegistration) -> (accepted :Bool);
topology @4 () -> (mesh :MeshTopology);
# Health
ping @5 () -> (pong :Bool, latencyNs :UInt64);
}
interface StreamHandle {
next @0 () -> (chunk :Data, done :Bool);
cancel @1 () -> ();
}
Protocol Negotiation
When agents connect, they negotiate the best available transport:
Agent A Agent B
│ │
│──── HELLO (capabilities) ─────▶│
│ │
│◀─── HELLO_ACK (selected) ──────│
│ │
│ Transport: capnp (preferred) │
│ or: mcp-json (fallback) │
│ or: unix-ipc (local) │
│ │
│══════ Established ═════════════│
Integration with HIP-0300 Tools
All HIP-0300 tools gain an agent action for consensus-based execution:
// fs tool with consensus
fs_tool.call("agent", json!({
"action": "read",
"path": "/etc/hosts",
"consensus": {
"participants": ["claude", "gpt4", "gemini"],
"require_agreement": true
}
}));
// plan tool routes through consensus automatically
plan_tool.call("intent", json!({
"nl": "refactor the authentication module",
"consensus": true // Uses metastable consensus for routing
}));
Metastable Consensus Integration
The plan tool uses metastable consensus for LLM-based intent parsing:
impl PlanTool {
async fn intent_with_consensus(
&self,
nl: &str,
bus: &dyn AgentBus,
) -> Result<IntentIR> {
// Get available LLM agents
let agents = bus.list_agents_with_capability("llm").await?;
// Run consensus
let state = bus.consensus(
&format!("Parse this intent: {}", nl),
&agents,
ConsensusConfig {
rounds: 3,
k: 3,
alpha: 0.6,
beta_1: 0.5,
beta_2: 0.8,
timeout_ms: 30000,
},
).await?;
// Parse winner's response as IntentIR
serde_json::from_str(&state.synthesis)
.map_err(|e| ToolError::internal(format!("Invalid IR: {}", e)))
}
}
Performance Characteristics
| Metric | JSON-RPC (MCP) | Cap'n Proto | Improvement |
|---|---|---|---|
| Serialization | 100-500μs | 0μs (zero-copy) | ∞ |
| Deserialization | 50-200μs | 0μs (zero-copy) | ∞ |
| Message overhead | ~40% | ~5% | 8x smaller |
| Memory allocations | O(n) | O(1) | Constant |
| Type safety | Runtime | Compile-time | Earlier errors |
| Consensus (10 agents, 10 rounds) | ~50-100ms | ~1-5ms | 10-100x |
Backward Compatibility
- MCP Fallback: If Cap'n Proto unavailable, seamlessly falls back to JSON-RPC
- Schema Evolution: Cap'n Proto supports adding fields without breaking
- Hybrid Mesh: Agents using different transports can still communicate via bridge
- Tool API Unchanged: HIP-0300 tool signatures remain identical
Security Considerations
- Authentication: Optional Ed25519 signatures on consensus votes
- Encryption: TLS 1.3 for capnp-rpc, with post-quantum option (ML-KEM)
- Rate Limiting: Per-agent rate limits on consensus participation
- Message Size: Configurable max message size (default 16MB)
Implementation Plan
Phase 1: Schema & Core (Week 1-2)
- Cap'n Proto schema definitions
- Rust capnp code generation
- Python pycapnp bindings
- AgentBus trait implementation
Phase 2: Transport (Week 3-4)
- Cap'n Proto RPC transport (Rust)
- Cap'n Proto RPC transport (Python)
- MCP JSON-RPC fallback
- Protocol negotiation
Phase 3: Consensus Integration (Week 5-6)
- Integrate hanzo-metastable-consensus
- Update plan_tool for consensus routing
- Agent tool with consensus support
- Benchmark and optimize
Phase 4: Production (Week 7-8)
- Documentation
- Migration guide
- Performance benchmarks
- Security audit
References
- Cap'n Proto - Zero-copy serialization
- HIP-0300 - Unified MCP Tools Architecture
- Metastable Consensus - Hanzo consensus protocol
- MCP Specification - Model Context Protocol
Appendix A: Message Size Comparison
Tool Call: fs.read("/etc/hosts")
JSON-RPC (MCP):
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "fs",
"arguments": {
"action": "read",
"path": "/etc/hosts"
}
}
}
Total: 156 bytes
Cap'n Proto:
[8-byte header][tool: 2 bytes][action: 4 bytes][path: 11 bytes][padding: 1 byte]
Total: 26 bytes (6x smaller)
Appendix B: Consensus Latency Analysis
For N agents over R rounds with message size M:
JSON-RPC: T = N × R × (serialize(M) + deserialize(M) + network(M))
≈ N × R × (200μs + 100μs + network)
Cap'n Proto: T = N × R × network(M') where M' ≈ M/6
≈ N × R × network_only
For N=10, R=10, typical network=1ms:
JSON-RPC: 10 × 10 × (300μs + 1ms) = 130ms
Cap'n Proto: 10 × 10 × 1ms = 100ms + 0μs serialization = 100ms
Actual improvement: ~30% in this scenario, but:
- Local agents (no network): 100% improvement (0μs vs 30ms)
- Large messages: Scales linearly better
- High-frequency consensus: Cumulative savings