oneie
Version:
Build apps, websites, and AI agents in English. Zero-interaction setup for AI agents (Claude Code, Cursor, Windsurf). Download to your computer, run in the cloud, deploy to the edge. Open source and free forever.
809 lines (703 loc) • 20.6 kB
Markdown
---
title: Acp
dimension: connections
category: acp.md
tags: agent, ai, architecture, protocol
related_dimensions: events, groups, things
scope: global
created: 2025-11-03
updated: 2025-11-03
version: 1.0.0
ai_context: |
This document is part of the connections dimension in the acp.md category.
Location: one/connections/acp.md
Purpose: Documents acp - agent communication protocol
Related dimensions: events, groups, things
For AI agents: Read this to understand acp.
---
# ACP - Agent Communication Protocol
**Official Specification**: https://agentcommunicationprotocol.dev/
## Overview
The Agent Communication Protocol (ACP) is an open, REST-based protocol for AI agent interoperability. Developed under the Linux Foundation, ACP enables standardized communication between agents across different frameworks and organizations.
## Key Characteristics
### Purpose
- Enable cross-framework agent integration
- Provide REST-based communication standard
- Support all data modalities (text, images, audio, video, binary)
- Enable synchronous and asynchronous agent interactions
- Facilitate agent discovery and capability matching
### Design Principles
1. **REST-Based**: Standard HTTP/HTTPS endpoints
2. **Async-First**: Optimized for long-running tasks
3. **Framework Agnostic**: No mandatory SDK required
4. **Multimodal**: Supports all MimeTypes
5. **Discoverable**: Online and offline agent discovery
## Protocol Architecture
```
┌──────────────────────────────────────────────────────────┐
│ ACP REST Layer │
├──────────────────────────────────────────────────────────┤
│ │
│ POST /agents/{id}/messages - Send message │
│ GET /agents/{id}/messages - Get messages │
│ POST /agents/{id}/tasks - Create task │
│ GET /agents/{id}/tasks/{tid} - Get task status │
│ GET /agents/{id}/capabilities - Get capabilities │
│ GET /agents - Discover agents │
│ │
└──────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│Agent A │ │Agent B │ │Agent C │
│(Python) │ │(TypeScript)│ │(Go) │
└─────────┘ └─────────┘ └─────────┘
```
## Core Features
### 1. Multimodal Communication
Supports all data types via MimeTypes:
```typescript
// Text communication
{
mimeType: "text/plain",
content: "Hello, Agent!"
}
// Image data
{
mimeType: "image/png",
content: "<base64-encoded-image>",
metadata: {
width: 1024,
height: 768
}
}
// Audio data
{
mimeType: "audio/wav",
content: "<base64-encoded-audio>",
metadata: {
duration: 120,
sampleRate: 44100
}
}
// Custom binary format
{
mimeType: "application/octet-stream",
content: "<base64-encoded-binary>",
metadata: {
format: "custom-format-v1"
}
}
```
### 2. Synchronous & Asynchronous Communication
**Synchronous (Request-Response)**:
```typescript
// Quick query with immediate response
POST /agents/agent-b/messages
{
"from": "agent-a",
"message": {
"type": "query",
"content": "What is the capital of France?",
"mimeType": "text/plain"
},
"mode": "sync"
}
// Immediate response
{
"messageId": "msg-123",
"status": "completed",
"response": {
"content": "Paris",
"mimeType": "text/plain"
}
}
```
**Asynchronous (Task-Based)**:
```typescript
// Long-running task
POST /agents/agent-b/tasks
{
"from": "agent-a",
"task": {
"type": "analyze_dataset",
"parameters": {
"datasetUrl": "https://...",
"analysisType": "full"
}
},
"callback": "https://agent-a.example.com/callbacks/task-456"
}
// Immediate task acknowledgment
{
"taskId": "task-456",
"status": "accepted",
"estimatedCompletion": 1800000 // 30 minutes
}
// Later: callback to agent-a when complete
POST https://agent-a.example.com/callbacks/task-456
{
"taskId": "task-456",
"status": "completed",
"result": { /* ... */ }
}
```
### 3. Agent Discovery
**Online Discovery**:
```typescript
// Discover available agents
GET /agents?capability=image_generation
Response:
{
"agents": [
{
"agentId": "img-gen-1",
"endpoint": "https://img-gen-1.example.com",
"capabilities": ["image_generation", "image_editing"],
"status": "online",
"metadata": {
"provider": "DALL-E",
"version": "3.0"
}
},
{
"agentId": "img-gen-2",
"endpoint": "https://img-gen-2.example.com",
"capabilities": ["image_generation"],
"status": "online",
"metadata": {
"provider": "Stable Diffusion",
"version": "2.1"
}
}
]
}
```
**Offline Discovery** (via registry):
```typescript
// Query agent registry
GET /registry/agents?tag=nlp
Response:
{
"agents": [
{
"agentId": "nlp-agent-1",
"endpoint": "https://nlp-1.example.com",
"capabilities": ["text_analysis", "sentiment_analysis"],
"lastSeen": 1704067200000,
"metadata": { /* ... */ }
}
]
}
```
### 4. Streaming Support
Real-time data streaming for long-running tasks:
```typescript
// Request streaming response
POST /agents/agent-b/tasks
{
"from": "agent-a",
"task": {
"type": "generate_content",
"parameters": { "topic": "AI", "length": 5000 }
},
"streaming": true,
"streamEndpoint": "https://agent-a.example.com/streams/stream-789"
}
// Server sends chunks via SSE or WebSocket
POST https://agent-a.example.com/streams/stream-789
{
"chunk": "Artificial Intelligence is...",
"position": 0,
"complete": false
}
POST https://agent-a.example.com/streams/stream-789
{
"chunk": "the simulation of human intelligence...",
"position": 1,
"complete": false
}
POST https://agent-a.example.com/streams/stream-789
{
"chunk": "by machines.",
"position": 2,
"complete": true
}
```
## REST API Specification
### Endpoints
#### POST /agents/{agentId}/messages
Send a message to an agent.
**Request**:
```typescript
{
"from": string, // Sender agent ID
"messageId": string, // Unique message ID
"correlationId"?: string, // For related messages
"message": {
"type": string, // Message type
"content": unknown, // Message payload
"mimeType": string // Content MIME type
},
"mode"?: "sync" | "async", // Default: async
"metadata"?: Record<string, unknown>
}
```
**Response**:
```typescript
{
"messageId": string,
"status": "received" | "processing" | "completed" | "error",
"response"?: unknown, // If mode=sync
"error"?: {
"code": string,
"message": string
}
}
```
#### GET /agents/{agentId}/messages
Get messages for an agent (inbox).
**Response**:
```typescript
{
"messages": Array<{
"messageId": string,
"from": string,
"timestamp": number,
"message": {
"type": string,
"content": unknown,
"mimeType": string
},
"status": string
}>,
"pagination": {
"offset": number,
"limit": number,
"total": number
}
}
```
#### POST /agents/{agentId}/tasks
Create a new task for an agent.
**Request**:
```typescript
{
"from": string,
"taskId"?: string, // Optional client-provided ID
"task": {
"type": string,
"parameters": Record<string, unknown>
},
"callback"?: string, // Callback URL when complete
"streaming"?: boolean, // Enable streaming
"streamEndpoint"?: string, // Stream callback URL
"priority"?: "low" | "medium" | "high" | "critical",
"timeout"?: number, // milliseconds
"metadata"?: Record<string, unknown>
}
```
**Response**:
```typescript
{
"taskId": string,
"status": "accepted" | "rejected",
"estimatedCompletion"?: number,
"error"?: {
"code": string,
"message": string,
"retryable": boolean
}
}
```
#### GET /agents/{agentId}/tasks/{taskId}
Get task status and result.
**Response**:
```typescript
{
"taskId": string,
"status": "pending" | "processing" | "completed" | "failed" | "cancelled",
"progress"?: number, // 0-100
"result"?: unknown, // If completed
"error"?: {
"code": string,
"message": string
},
"createdAt": number,
"updatedAt": number,
"completedAt"?: number
}
```
#### GET /agents/{agentId}/capabilities
Get agent capabilities and metadata.
**Response**:
```typescript
{
"agentId": string,
"capabilities": string[],
"status": "online" | "offline" | "busy",
"metadata": {
"version": string,
"provider": string,
"supportedMimeTypes": string[],
"maxConcurrentTasks": number,
"averageResponseTime": number,
"pricing"?: {
"model": "per_request" | "per_minute" | "subscription",
"rate": number,
"currency": string
}
}
}
```
#### GET /agents
Discover agents by capability.
**Query Parameters**:
- `capability`: Filter by capability
- `status`: Filter by status
- `provider`: Filter by provider
- `offset`: Pagination offset
- `limit`: Pagination limit
**Response**:
```typescript
{
"agents": Array<{
"agentId": string,
"endpoint": string,
"capabilities": string[],
"status": string,
"metadata": Record<string, unknown>
}>,
"pagination": {
"offset": number,
"limit": number,
"total": number
}
}
```
## SDK
```bash
npm install acp-sdk
```
```typescript
import { Agent, Message, Task } from "acp-sdk";
// Create agent
const agent = new Agent({
agentId: "my-agent",
endpoint: "https://my-agent.example.com",
capabilities: ["text_analysis", "summarization"],
});
// Send message
const response = await agent.sendMessage({
to: "agent-b",
message: {
type: "query",
content: "Analyze this text",
mimeType: "text/plain",
},
});
// Create task
const taskId = await agent.createTask({
to: "agent-b",
task: {
type: "analyze_dataset",
parameters: { datasetUrl: "https://..." },
},
callback: "https://my-agent.example.com/callbacks/task-1",
});
```
## Multi-Tenancy & Groups
All entities, connections, and events in this protocol are scoped to a `groupId`:
```typescript
// Every entity
{
groupId: Id<"groups">, // Required for multi-tenancy
type: "agent" | "task",
// ... rest of fields
}
// Every connection
{
groupId: Id<"groups">, // Required for multi-tenancy
fromEntityId: Id<"entities">,
toEntityId: Id<"entities">,
relationshipType: "communicates_via_acp" | "task_assigned_to",
// ... rest of fields
}
// Every event
{
groupId: Id<"groups">, // Required for multi-tenancy
type: "acp_message_sent" | "acp_message_received" | "acp_task_created" | "acp_task_completed",
// ... rest of fields
}
```
## Implementation in Our System
### Integration with Ontology
Map ACP concepts to our 6-dimension ontology:
**Entities**:
- Agent entities with ACP endpoint and capabilities
- Task entities for long-running operations
**Connections**:
- `communicates_via_acp` - Active ACP channel
- `task_assigned_to` - Task delegation
**Events**:
- `acp_message_sent` - Outbound ACP message
- `acp_message_received` - Inbound ACP message
- `acp_task_created` - Task created via ACP
- `acp_task_completed` - Task completed via ACP
- `acp_stream_chunk` - Streaming data chunk
**Tags**:
- ACP capabilities
- Supported MIME types
### Service Implementation
```typescript
// convex/services/agents/acp.ts
export class ACPService extends Effect.Service<ACPService>()("ACPService", {
effect: Effect.gen(function* () {
const db = yield* ConvexDatabase;
return {
// Send ACP message
sendMessage: (request: ACPMessageRequest) =>
Effect.gen(function* () {
const messageId = crypto.randomUUID();
// Log outbound event
yield* Effect.tryPromise(() =>
db.insert("events", {
entityId: request.from,
eventType: "acp_message_sent",
timestamp: Date.now(),
actorType: "agent",
actorId: request.to,
metadata: {
messageId,
messageType: request.message.type,
mimeType: request.message.mimeType,
},
})
);
// Send via REST
const response = yield* Effect.tryPromise(() =>
fetch(`${request.endpoint}/agents/${request.to}/messages`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-ACP-Version": "1.0",
},
body: JSON.stringify({
from: request.from,
messageId,
message: request.message,
mode: request.mode || "async",
}),
})
);
return yield* Effect.promise(() => response.json());
}),
// Create ACP task
createTask: (request: ACPTaskRequest) =>
Effect.gen(function* () {
const taskId = request.taskId || crypto.randomUUID();
// Create task entity
const taskEntityId = yield* Effect.tryPromise(() =>
db.insert("entities", {
type: "task",
name: request.task.type,
properties: {
taskId,
status: "pending",
parameters: request.task.parameters,
},
status: "active",
createdAt: Date.now(),
updatedAt: Date.now(),
})
);
// Create delegation connection
yield* Effect.tryPromise(() =>
db.insert("connections", {
fromEntityId: request.from,
toEntityId: request.to,
relationshipType: "task_assigned_to",
metadata: { taskId, taskEntityId },
createdAt: Date.now(),
})
);
// Log task creation
yield* Effect.tryPromise(() =>
db.insert("events", {
entityId: taskEntityId,
eventType: "acp_task_created",
timestamp: Date.now(),
actorType: "agent",
actorId: request.from,
metadata: {
taskId,
taskType: request.task.type,
},
})
);
// Send via REST
const response = yield* Effect.tryPromise(() =>
fetch(`${request.endpoint}/agents/${request.to}/tasks`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-ACP-Version": "1.0",
},
body: JSON.stringify({
from: request.from,
taskId,
task: request.task,
callback: request.callback,
streaming: request.streaming,
streamEndpoint: request.streamEndpoint,
}),
})
);
const result = yield* Effect.promise(() => response.json());
// Update task entity with response
yield* Effect.tryPromise(() =>
db.patch(taskEntityId, {
properties: {
taskId,
status: result.status,
parameters: request.task.parameters,
estimatedCompletion: result.estimatedCompletion,
},
})
);
return result;
}),
// Discover agents
discoverAgents: (capability?: string) =>
Effect.tryPromise(() =>
db
.query("entities")
.filter(q =>
capability
? q.and(
q.eq(q.field("type"), "agent"),
q.eq(q.field("status"), "active")
)
: q.and(
q.eq(q.field("type"), "agent"),
q.eq(q.field("status"), "active")
)
)
.collect()
.then(agents =>
capability
? agents.filter(a =>
a.properties.capabilities?.includes(capability)
)
: agents
)
),
};
}),
dependencies: [ConvexDatabase.Default],
}) {}
```
### Astro API Routes
```typescript
// src/pages/api/agents/[agentId]/messages.ts
import type { APIRoute } from "astro";
import { ConvexHttpClient } from "convex/browser";
export const POST: APIRoute = async ({ request, params }) => {
const convex = new ConvexHttpClient(import.meta.env.CONVEX_URL);
const body = await request.json();
const result = await convex.mutation(api.agents.receiveMessage, {
agentId: params.agentId,
message: body,
});
return new Response(JSON.stringify(result), {
status: 200,
headers: { "Content-Type": "application/json" },
});
};
```
## Security Considerations
### Authentication
- API keys in headers (`X-API-Key`)
- OAuth 2.0 for agent-to-agent auth
- JWT tokens for session management
### Authorization
- Capability-based access control
- Rate limiting per agent
- IP allowlisting for sensitive agents
### Data Privacy
- TLS 1.3 for all communications
- Optional end-to-end encryption for payloads
- GDPR-compliant data handling
## Best Practices
1. **Use Async Mode for Long Tasks**: Default to async for tasks > 5 seconds
2. **Implement Callbacks**: Always provide callback URLs for async tasks
3. **Handle All MIME Types**: Support multimodal data
4. **Log All Communications**: Store in events table
5. **Implement Retries**: Use exponential backoff for failures
6. **Monitor Performance**: Track response times and success rates
7. **Version Your API**: Use semantic versioning
## Example: Image Generation Pipeline
```typescript
// Discover image generation agents
const agents = await acpService.discoverAgents("image_generation");
// Create task with best agent
const task = await acpService.createTask({
from: "content-creator-agent",
to: agents[0]._id,
endpoint: agents[0].properties.endpoint,
task: {
type: "generate_image",
parameters: {
prompt: "A futuristic cityscape at sunset",
style: "photorealistic",
resolution: "1024x1024",
},
},
callback: `${BASE_URL}/api/callbacks/image-task-123`,
});
// Later: receive callback
// POST /api/callbacks/image-task-123
{
"taskId": "task-123",
"status": "completed",
"result": {
"imageUrl": "https://...",
"mimeType": "image/png",
"metadata": {
"width": 1024,
"height": 1024,
"generationTime": 15000
}
}
}
```
## Roadmap
### Current (Q1 2025)
- [x] Document ACP protocol
- [ ] Implement ACP REST endpoints
- [ ] Add agent discovery service
- [ ] Create message/task handlers
### Next (Q2 2025)
- [ ] Streaming support
- [ ] Multimodal content handling
- [ ] Advanced routing
- [ ] Performance optimization
### Future (Q3 2025)
- [ ] Federation across organizations
- [ ] AI-powered agent matching
- [ ] Real-time monitoring
- [ ] Analytics dashboard
## Resources
- **Official Website**: https://agentcommunicationprotocol.dev/
- **OpenAPI Spec**: (Available on official site)
- **Python SDK**: https://pypi.org/project/acp-sdk/
- **TypeScript SDK**: https://www.npmjs.com/package/acp-sdk
- **Our Implementation**: See `Agent-Communications.md`
## Key Takeaways
1. **REST-Based**: Standard HTTP makes integration easy
2. **Async-First**: Optimized for real-world agent tasks
3. **Multimodal**: Supports all data types via MIME types
4. **Discoverable**: Find agents by capability
5. **Framework Agnostic**: No SDK required, works with any stack
6. **Production-Ready**: Built for enterprise use cases
ACP provides the REST foundation for building scalable, interoperable agent ecosystems.