@bluefly/openstandardagents 0.2.8 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +1 -1
- package/.github/AGENTS.md +245 -0
- package/.github/agents/github-issue-triage.ossa.yaml +99 -0
- package/.github/agents/github-pr-triage.ossa.yaml +137 -0
- package/.github/workflows/issue-sync-to-gitlab.yml +138 -0
- package/.github/workflows/pr-triage-to-gitlab.yml +164 -0
- package/.version.json +1 -1
- package/.wiki-config.json +1 -1
- package/CHANGELOG.md +33 -0
- package/CONTRIBUTING.md +102 -3
- package/README.md +17 -10
- package/dist/services/release-automation/schemas/release.schema.js +1 -1
- package/dist/services/release-automation/webhook.service.js +3 -3
- package/dist/services/release-automation/webhook.service.js.map +1 -1
- package/dist/services/runtime/claude/claude-adapter.d.ts +1 -1
- package/dist/services/runtime/claude/claude-adapter.d.ts.map +1 -1
- package/dist/services/runtime/claude/claude-adapter.js +1 -1
- package/dist/services/runtime/claude/claude-adapter.js.map +1 -1
- package/dist/spec/v0.2.9/a2a-protocol.md +1337 -0
- package/dist/spec/v0.2.9/agent.md +1946 -0
- package/dist/spec/v0.2.9/capabilities/index.yaml +25 -0
- package/dist/spec/v0.2.9/capabilities/memory.yaml +251 -0
- package/dist/spec/v0.2.9/capability-schema.md +576 -0
- package/dist/spec/v0.2.9/compliance-profiles.md +533 -0
- package/dist/spec/v0.2.9/conformance-testing.md +1527 -0
- package/dist/spec/v0.2.9/gitlab-duo-integration.md +621 -0
- package/dist/spec/v0.2.9/ossa-0.2.9.schema.json +3699 -0
- package/dist/spec/v0.2.9/runtime-semantics.md +464 -0
- package/dist/spec/v0.2.9/security-model.md +1245 -0
- package/dist/spec/v0.2.9/semantic-conventions.md +347 -0
- package/dist/spec/v0.2.9/types.ts +522 -0
- package/dist/types/policy.d.ts +377 -0
- package/dist/types/policy.d.ts.map +1 -0
- package/dist/types/policy.js +84 -0
- package/dist/types/policy.js.map +1 -0
- package/dist/utils/version.js +1 -1
- package/docs/specs/policy-dsl.md +925 -0
- package/examples/adk-integration/code-review-workflow.yml +1 -1
- package/examples/adk-integration/customer-support.yml +1 -1
- package/examples/adk-integration/data-pipeline.yml +1 -1
- package/examples/advanced/reasoning-agent.yaml +136 -0
- package/examples/advanced/workflows/hybrid-model-strategy.yaml +1 -1
- package/examples/agent-manifests/critics/critic-agent.yaml +1 -1
- package/examples/agent-manifests/governors/governor-agent.yaml +1 -1
- package/examples/agent-manifests/integrators/integrator-agent.yaml +1 -1
- package/examples/agent-manifests/judges/judge-agent.yaml +1 -1
- package/examples/agent-manifests/monitors/monitor-agent.yaml +1 -1
- package/examples/agent-manifests/orchestrators/orchestrator-agent.yaml +1 -1
- package/examples/agent-manifests/sample-compliant-agent.yaml +1 -1
- package/examples/agent-manifests/workers/worker-agent.yaml +1 -1
- package/examples/agents-md/code-agent.ossa.json +100 -0
- package/examples/agents-md/monorepo-agent.ossa.yaml +180 -0
- package/examples/anthropic/claude-assistant.ossa.json +1 -1
- package/examples/autogen/multi-agent.ossa.json +1 -1
- package/examples/claude-code/code-reviewer.ossa.yaml +1 -1
- package/examples/claude-code/ossa-validator.ossa.yaml +2 -2
- package/examples/common_npm/agent-router.ossa.yaml +1 -1
- package/examples/common_npm/agent-router.v0.2.2.ossa.yaml +1 -1
- package/examples/crewai/research-team.ossa.json +1 -1
- package/examples/cursor/code-review-agent.ossa.json +1 -1
- package/examples/drupal/gitlab-ml-recommender.ossa.yaml +1 -1
- package/examples/drupal/gitlab-ml-recommender.v0.2.2.ossa.yaml +1 -1
- package/examples/extensions/agents-md-v1.yml +175 -0
- package/examples/extensions/drupal-v1.yml +1 -1
- package/examples/extensions/kagent-v1.yml +1 -1
- package/examples/getting-started/hello-world-complete.ossa.yaml +1 -1
- package/examples/integration-patterns/agent-to-agent-orchestration.ossa.yaml +4 -4
- package/examples/kagent/compliance-validator.ossa.yaml +1 -1
- package/examples/kagent/cost-optimizer.ossa.yaml +1 -1
- package/examples/kagent/documentation-agent.ossa.yaml +1 -1
- package/examples/kagent/k8s-troubleshooter-v1.ossa.yaml +1 -1
- package/examples/kagent/k8s-troubleshooter-v1.v0.2.2.ossa.yaml +1 -1
- package/examples/kagent/k8s-troubleshooter.ossa.yaml +1 -1
- package/examples/kagent/security-scanner.ossa.yaml +1 -1
- package/examples/langchain/chain-agent.ossa.json +1 -1
- package/examples/langflow/workflow-agent.ossa.json +1 -1
- package/examples/langgraph/state-machine-agent.ossa.json +1 -1
- package/examples/llamaindex/rag-agent.ossa.json +1 -1
- package/examples/migration-guides/from-langchain-to-ossa.yaml +4 -4
- package/examples/multi-agent/conditional-router.ossa.yaml +1 -1
- package/examples/multi-agent/parallel-execution.ossa.yaml +1 -1
- package/examples/multi-agent/sequential-pipeline.ossa.yaml +1 -1
- package/examples/openai/basic-agent.ossa.yaml +1 -1
- package/examples/openai/multi-tool-agent.ossa.json +1 -1
- package/examples/openai/swarm-agent.ossa.json +1 -1
- package/examples/production/document-analyzer-openai.yml +1 -1
- package/examples/quickstart/support-agent.ossa.yaml +1 -1
- package/examples/templates/ossa-compliance.yaml +1 -1
- package/examples/vercel/edge-agent.ossa.json +1 -1
- package/llms.txt +1 -1
- package/package.json +5 -3
- package/scripts/README.md +25 -0
- package/scripts/compliance-audit.ts +796 -0
- package/scripts/generate-agents-catalog.ts +2 -1
- package/scripts/generate-api-docs.ts +2 -1
- package/scripts/generate-examples-docs.ts +2 -1
- package/scripts/generate-llms-ctx.sh +2 -2
- package/spec/v0.2.9/a2a-protocol.md +1337 -0
- package/spec/v0.2.9/agent.md +1946 -0
- package/spec/v0.2.9/capabilities/index.yaml +25 -0
- package/spec/v0.2.9/capabilities/memory.yaml +251 -0
- package/spec/v0.2.9/capability-schema.md +576 -0
- package/spec/v0.2.9/compliance-profiles.md +533 -0
- package/spec/v0.2.9/conformance-testing.md +1527 -0
- package/spec/v0.2.9/gitlab-duo-integration.md +621 -0
- package/spec/v0.2.9/ossa-0.2.9.schema.json +3699 -0
- package/spec/v0.2.9/runtime-semantics.md +464 -0
- package/spec/v0.2.9/security-model.md +1245 -0
- package/spec/v0.2.9/semantic-conventions.md +347 -0
- package/spec/v0.2.9/types.ts +522 -0
- package/test-results/junit.xml +184 -146
- package/.github/workflows/pr-comment.yml +0 -33
|
@@ -0,0 +1,1337 @@
|
|
|
1
|
+
# OSSA Agent-to-Agent (A2A) Protocol Specification
|
|
2
|
+
|
|
3
|
+
**Version**: 0.2.9
|
|
4
|
+
**Status**: Draft
|
|
5
|
+
**Last Updated**: 2025-12-04
|
|
6
|
+
|
|
7
|
+
This document defines the Agent-to-Agent (A2A) Protocol for multi-agent communication in OSSA-compliant systems. The A2A protocol enables agents to discover, authenticate, and communicate with each other using standardized message formats and routing patterns.
|
|
8
|
+
|
|
9
|
+
## 1. Overview
|
|
10
|
+
|
|
11
|
+
The A2A Protocol provides:
|
|
12
|
+
- **Discovery**: Agents advertise capabilities via AgentCard
|
|
13
|
+
- **Authentication**: mTLS, JWT bearer tokens, and OIDC
|
|
14
|
+
- **Routing**: Direct, broadcast, topic-based, and request/response patterns
|
|
15
|
+
- **Task Lifecycle**: Standard states for collaborative work
|
|
16
|
+
- **Streaming**: Support for long-running tasks with progress updates
|
|
17
|
+
- **Push Notifications**: Real-time event delivery
|
|
18
|
+
|
|
19
|
+
### Design Principles
|
|
20
|
+
|
|
21
|
+
1. **Interoperability**: Works across different OSSA runtime implementations
|
|
22
|
+
2. **Security**: Authentication and encryption by default
|
|
23
|
+
3. **Scalability**: Supports peer-to-peer and hub-spoke topologies
|
|
24
|
+
4. **Observability**: Full W3C trace context propagation
|
|
25
|
+
5. **Simplicity**: Minimal protocol overhead
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 2. Message Envelope Format
|
|
30
|
+
|
|
31
|
+
All A2A messages MUST use the following envelope structure:
|
|
32
|
+
|
|
33
|
+
```yaml
|
|
34
|
+
# Message Envelope (v0.2.9)
|
|
35
|
+
version: "ossa/a2a/v0.2.9"
|
|
36
|
+
id: "msg_2kj3h4k2j3h4k" # Unique message ID (UUID v7 recommended)
|
|
37
|
+
timestamp: "2025-12-04T19:30:00.000Z" # ISO 8601 timestamp
|
|
38
|
+
from: "agent://team-a/code-reviewer" # Sender agent URI
|
|
39
|
+
to: "agent://team-b/code-analyzer" # Recipient agent URI (or topic)
|
|
40
|
+
correlation_id: "req_abc123" # Groups related messages
|
|
41
|
+
reply_to: "agent://team-a/code-reviewer" # Optional: where to send response
|
|
42
|
+
ttl: 300 # Time-to-live in seconds
|
|
43
|
+
priority: "normal" # normal | high | urgent
|
|
44
|
+
type: "request" # request | response | event | command
|
|
45
|
+
payload:
|
|
46
|
+
# Application-specific payload (see sections below)
|
|
47
|
+
action: "analyze_code"
|
|
48
|
+
data:
|
|
49
|
+
repository: "https://github.com/org/repo"
|
|
50
|
+
commit_sha: "abc123"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Envelope Fields
|
|
54
|
+
|
|
55
|
+
| Field | Type | Required | Description |
|
|
56
|
+
|-------|------|----------|-------------|
|
|
57
|
+
| `version` | string | Yes | Protocol version (MUST be `ossa/a2a/v0.2.9`) |
|
|
58
|
+
| `id` | string | Yes | Unique message identifier (UUID) |
|
|
59
|
+
| `timestamp` | ISO8601 | Yes | Message creation time |
|
|
60
|
+
| `from` | URI | Yes | Sender agent URI |
|
|
61
|
+
| `to` | URI | Yes | Recipient agent URI or topic |
|
|
62
|
+
| `correlation_id` | string | No | Groups request/response pairs |
|
|
63
|
+
| `reply_to` | URI | No | Where to send responses |
|
|
64
|
+
| `ttl` | integer | No | Time-to-live in seconds (default: 300) |
|
|
65
|
+
| `priority` | enum | No | Message priority (default: normal) |
|
|
66
|
+
| `type` | enum | Yes | Message type (request/response/event/command) |
|
|
67
|
+
| `payload` | object | Yes | Application-specific message content |
|
|
68
|
+
|
|
69
|
+
### Message Types
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
type MessageType =
|
|
73
|
+
| 'request' // Expects a response
|
|
74
|
+
| 'response' // Reply to a request
|
|
75
|
+
| 'event' // Fire-and-forget notification
|
|
76
|
+
| 'command'; // Imperative action (no response expected)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 3. Discovery Mechanism
|
|
82
|
+
|
|
83
|
+
Agents discover each other through three methods:
|
|
84
|
+
|
|
85
|
+
### 3.1 Registry-Based Discovery
|
|
86
|
+
|
|
87
|
+
Agents register with a central registry (e.g., Consul, etcd, OSSA Registry).
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
# Register agent
|
|
91
|
+
POST /registry/agents
|
|
92
|
+
Content-Type: application/json
|
|
93
|
+
|
|
94
|
+
{
|
|
95
|
+
"agent_card": {
|
|
96
|
+
"uri": "agent://team-a/code-reviewer",
|
|
97
|
+
"name": "Code Review Agent",
|
|
98
|
+
"version": "1.2.3",
|
|
99
|
+
"capabilities": [
|
|
100
|
+
"code_analysis",
|
|
101
|
+
"security_scanning",
|
|
102
|
+
"style_checking"
|
|
103
|
+
],
|
|
104
|
+
"endpoints": {
|
|
105
|
+
"http": "https://agents.example.com/code-reviewer",
|
|
106
|
+
"grpc": "grpc://agents.example.com:50051/code-reviewer"
|
|
107
|
+
},
|
|
108
|
+
"transport": ["http", "grpc"],
|
|
109
|
+
"authentication": ["mtls", "bearer"],
|
|
110
|
+
"ossa_version": "0.2.9",
|
|
111
|
+
"metadata": {
|
|
112
|
+
"team": "engineering",
|
|
113
|
+
"environment": "production",
|
|
114
|
+
"region": "us-west-2"
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"ttl": 60 # Re-register every 60 seconds (heartbeat)
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Query registry:
|
|
122
|
+
|
|
123
|
+
```yaml
|
|
124
|
+
# Find agents by capability
|
|
125
|
+
GET /registry/agents?capability=code_analysis
|
|
126
|
+
|
|
127
|
+
# Response
|
|
128
|
+
{
|
|
129
|
+
"agents": [
|
|
130
|
+
{
|
|
131
|
+
"uri": "agent://team-a/code-reviewer",
|
|
132
|
+
"capabilities": ["code_analysis", "security_scanning"],
|
|
133
|
+
"endpoints": {
|
|
134
|
+
"http": "https://agents.example.com/code-reviewer"
|
|
135
|
+
},
|
|
136
|
+
"last_heartbeat": "2025-12-04T19:30:00.000Z",
|
|
137
|
+
"status": "healthy"
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 3.2 Broadcast Discovery (DNS-SD)
|
|
144
|
+
|
|
145
|
+
Agents broadcast presence via DNS Service Discovery (RFC 6763).
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# Publish agent via Avahi/Bonjour
|
|
149
|
+
dns-sd -R "Code Reviewer" _ossa-agent._tcp local 8080 \
|
|
150
|
+
uri=agent://team-a/code-reviewer \
|
|
151
|
+
version=0.2.9 \
|
|
152
|
+
capabilities=code_analysis,security_scanning
|
|
153
|
+
|
|
154
|
+
# Discover agents
|
|
155
|
+
dns-sd -B _ossa-agent._tcp local
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**AgentCard via DNS TXT Record**:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
_ossa-agent._tcp.local.
|
|
162
|
+
PTR code-reviewer.ossa-agent._tcp.local.
|
|
163
|
+
|
|
164
|
+
code-reviewer._ossa-agent._tcp.local.
|
|
165
|
+
SRV 0 0 8080 agent-host.local.
|
|
166
|
+
TXT "uri=agent://team-a/code-reviewer"
|
|
167
|
+
TXT "version=0.2.9"
|
|
168
|
+
TXT "capabilities=code_analysis,security_scanning"
|
|
169
|
+
TXT "transport=http,grpc"
|
|
170
|
+
TXT "auth=mtls"
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 3.3 Multicast Discovery (mDNS)
|
|
174
|
+
|
|
175
|
+
Agents use multicast DNS for local network discovery.
|
|
176
|
+
|
|
177
|
+
```yaml
|
|
178
|
+
# mDNS announcement packet
|
|
179
|
+
type: PTR
|
|
180
|
+
name: _ossa-agent._tcp.local
|
|
181
|
+
data: code-reviewer._ossa-agent._tcp.local
|
|
182
|
+
|
|
183
|
+
type: SRV
|
|
184
|
+
name: code-reviewer._ossa-agent._tcp.local
|
|
185
|
+
priority: 0
|
|
186
|
+
weight: 0
|
|
187
|
+
port: 8080
|
|
188
|
+
target: agent-host.local
|
|
189
|
+
|
|
190
|
+
type: TXT
|
|
191
|
+
name: code-reviewer._ossa-agent._tcp.local
|
|
192
|
+
data:
|
|
193
|
+
- "uri=agent://team-a/code-reviewer"
|
|
194
|
+
- "capabilities=code_analysis"
|
|
195
|
+
- "ossa_version=0.2.9"
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## 4. AgentCard Schema
|
|
201
|
+
|
|
202
|
+
The AgentCard is a self-describing document that advertises agent capabilities.
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
interface AgentCard {
|
|
206
|
+
// Identity
|
|
207
|
+
uri: string; // Unique agent URI
|
|
208
|
+
name: string; // Human-readable name
|
|
209
|
+
version: string; // Semantic version
|
|
210
|
+
ossa_version: string; // OSSA spec version
|
|
211
|
+
|
|
212
|
+
// Capabilities
|
|
213
|
+
capabilities: string[]; // Advertised capabilities
|
|
214
|
+
tools?: ToolDescriptor[]; // Available tools
|
|
215
|
+
role?: string; // Agent role/specialty
|
|
216
|
+
|
|
217
|
+
// Connectivity
|
|
218
|
+
endpoints: {
|
|
219
|
+
http?: string; // HTTP/REST endpoint
|
|
220
|
+
grpc?: string; // gRPC endpoint
|
|
221
|
+
websocket?: string; // WebSocket endpoint
|
|
222
|
+
};
|
|
223
|
+
transport: Transport[]; // Supported transports
|
|
224
|
+
|
|
225
|
+
// Security
|
|
226
|
+
authentication: AuthMethod[]; // Supported auth methods
|
|
227
|
+
encryption: EncryptionSpec; // Encryption requirements
|
|
228
|
+
|
|
229
|
+
// Metadata
|
|
230
|
+
metadata?: {
|
|
231
|
+
team?: string;
|
|
232
|
+
environment?: string;
|
|
233
|
+
region?: string;
|
|
234
|
+
[key: string]: unknown;
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
// Health
|
|
238
|
+
status?: 'healthy' | 'degraded' | 'unavailable';
|
|
239
|
+
last_heartbeat?: string; // ISO 8601 timestamp
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
type Transport = 'http' | 'grpc' | 'websocket' | 'mqtt';
|
|
243
|
+
type AuthMethod = 'mtls' | 'bearer' | 'oidc' | 'api_key';
|
|
244
|
+
|
|
245
|
+
interface ToolDescriptor {
|
|
246
|
+
name: string;
|
|
247
|
+
description: string;
|
|
248
|
+
input_schema: JSONSchema;
|
|
249
|
+
output_schema?: JSONSchema;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
interface EncryptionSpec {
|
|
253
|
+
tls_required: boolean;
|
|
254
|
+
min_tls_version: '1.2' | '1.3';
|
|
255
|
+
cipher_suites?: string[];
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### AgentCard Example
|
|
260
|
+
|
|
261
|
+
```yaml
|
|
262
|
+
uri: "agent://team-a/code-reviewer"
|
|
263
|
+
name: "Code Review Agent"
|
|
264
|
+
version: "1.2.3"
|
|
265
|
+
ossa_version: "0.2.9"
|
|
266
|
+
|
|
267
|
+
capabilities:
|
|
268
|
+
- code_analysis
|
|
269
|
+
- security_scanning
|
|
270
|
+
- style_checking
|
|
271
|
+
|
|
272
|
+
tools:
|
|
273
|
+
- name: analyze_code
|
|
274
|
+
description: "Perform static code analysis"
|
|
275
|
+
input_schema:
|
|
276
|
+
type: object
|
|
277
|
+
required: [repository, commit_sha]
|
|
278
|
+
properties:
|
|
279
|
+
repository:
|
|
280
|
+
type: string
|
|
281
|
+
format: uri
|
|
282
|
+
commit_sha:
|
|
283
|
+
type: string
|
|
284
|
+
pattern: "^[0-9a-f]{40}$"
|
|
285
|
+
|
|
286
|
+
- name: check_security
|
|
287
|
+
description: "Scan code for security vulnerabilities"
|
|
288
|
+
input_schema:
|
|
289
|
+
type: object
|
|
290
|
+
required: [code]
|
|
291
|
+
properties:
|
|
292
|
+
code:
|
|
293
|
+
type: string
|
|
294
|
+
|
|
295
|
+
endpoints:
|
|
296
|
+
http: "https://agents.example.com/code-reviewer"
|
|
297
|
+
grpc: "grpc://agents.example.com:50051/code-reviewer"
|
|
298
|
+
|
|
299
|
+
transport:
|
|
300
|
+
- http
|
|
301
|
+
- grpc
|
|
302
|
+
|
|
303
|
+
authentication:
|
|
304
|
+
- mtls
|
|
305
|
+
- bearer
|
|
306
|
+
|
|
307
|
+
encryption:
|
|
308
|
+
tls_required: true
|
|
309
|
+
min_tls_version: "1.3"
|
|
310
|
+
cipher_suites:
|
|
311
|
+
- "TLS_AES_256_GCM_SHA384"
|
|
312
|
+
- "TLS_CHACHA20_POLY1305_SHA256"
|
|
313
|
+
|
|
314
|
+
metadata:
|
|
315
|
+
team: "engineering"
|
|
316
|
+
environment: "production"
|
|
317
|
+
region: "us-west-2"
|
|
318
|
+
cost_per_request: "$0.05"
|
|
319
|
+
|
|
320
|
+
status: "healthy"
|
|
321
|
+
last_heartbeat: "2025-12-04T19:30:00.000Z"
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## 5. Authentication Methods
|
|
327
|
+
|
|
328
|
+
### 5.1 Mutual TLS (mTLS)
|
|
329
|
+
|
|
330
|
+
**Recommended for production**. Both client and server authenticate via X.509 certificates.
|
|
331
|
+
|
|
332
|
+
```yaml
|
|
333
|
+
# Agent manifest with mTLS
|
|
334
|
+
apiVersion: ossa/v0.2.9
|
|
335
|
+
kind: Agent
|
|
336
|
+
metadata:
|
|
337
|
+
name: secure-agent
|
|
338
|
+
spec:
|
|
339
|
+
security:
|
|
340
|
+
authentication:
|
|
341
|
+
type: mtls
|
|
342
|
+
certificate:
|
|
343
|
+
path: /etc/ossa/certs/agent.crt
|
|
344
|
+
key_path: /etc/ossa/certs/agent.key
|
|
345
|
+
ca_bundle: /etc/ossa/certs/ca.crt
|
|
346
|
+
verify_client: true
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**Certificate Requirements**:
|
|
350
|
+
- Subject Alternative Name (SAN) MUST include agent URI
|
|
351
|
+
- Common Name (CN) SHOULD be agent name
|
|
352
|
+
- Certificates MUST be valid (not expired)
|
|
353
|
+
- Issuer MUST be trusted CA
|
|
354
|
+
|
|
355
|
+
**Example Certificate**:
|
|
356
|
+
|
|
357
|
+
```
|
|
358
|
+
Subject: CN=code-reviewer, O=Acme Corp
|
|
359
|
+
SAN:
|
|
360
|
+
- URI:agent://team-a/code-reviewer
|
|
361
|
+
- DNS:code-reviewer.agents.example.com
|
|
362
|
+
Issuer: CN=OSSA CA, O=Acme Corp
|
|
363
|
+
Validity: 2025-01-01 to 2026-01-01
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### 5.2 Bearer Token (JWT)
|
|
367
|
+
|
|
368
|
+
Agents authenticate using JWT bearer tokens.
|
|
369
|
+
|
|
370
|
+
```yaml
|
|
371
|
+
# Agent manifest with JWT
|
|
372
|
+
apiVersion: ossa/v0.2.9
|
|
373
|
+
kind: Agent
|
|
374
|
+
metadata:
|
|
375
|
+
name: api-agent
|
|
376
|
+
spec:
|
|
377
|
+
security:
|
|
378
|
+
authentication:
|
|
379
|
+
type: bearer
|
|
380
|
+
token_source:
|
|
381
|
+
type: file
|
|
382
|
+
path: /run/secrets/agent-token
|
|
383
|
+
issuer: "https://auth.example.com"
|
|
384
|
+
audience: "ossa-agents"
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
**JWT Claims**:
|
|
388
|
+
|
|
389
|
+
```json
|
|
390
|
+
{
|
|
391
|
+
"iss": "https://auth.example.com",
|
|
392
|
+
"sub": "agent://team-a/code-reviewer",
|
|
393
|
+
"aud": "ossa-agents",
|
|
394
|
+
"exp": 1735939800,
|
|
395
|
+
"iat": 1735936200,
|
|
396
|
+
"capabilities": ["code_analysis", "security_scanning"]
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
**HTTP Request with Bearer Token**:
|
|
401
|
+
|
|
402
|
+
```http
|
|
403
|
+
POST /agents/code-analyzer/tasks HTTP/1.1
|
|
404
|
+
Host: agents.example.com
|
|
405
|
+
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
406
|
+
Content-Type: application/json
|
|
407
|
+
|
|
408
|
+
{
|
|
409
|
+
"version": "ossa/a2a/v0.2.9",
|
|
410
|
+
"from": "agent://team-a/code-reviewer",
|
|
411
|
+
"to": "agent://team-b/code-analyzer",
|
|
412
|
+
"payload": {...}
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### 5.3 OpenID Connect (OIDC)
|
|
417
|
+
|
|
418
|
+
Agents use OIDC for federated authentication.
|
|
419
|
+
|
|
420
|
+
```yaml
|
|
421
|
+
# Agent manifest with OIDC
|
|
422
|
+
apiVersion: ossa/v0.2.9
|
|
423
|
+
kind: Agent
|
|
424
|
+
metadata:
|
|
425
|
+
name: oidc-agent
|
|
426
|
+
spec:
|
|
427
|
+
security:
|
|
428
|
+
authentication:
|
|
429
|
+
type: oidc
|
|
430
|
+
provider: "https://accounts.google.com"
|
|
431
|
+
client_id: "abc123.apps.googleusercontent.com"
|
|
432
|
+
client_secret:
|
|
433
|
+
secret_ref:
|
|
434
|
+
name: oidc-credentials
|
|
435
|
+
key: client_secret
|
|
436
|
+
scopes:
|
|
437
|
+
- openid
|
|
438
|
+
- profile
|
|
439
|
+
- ossa.agent
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
**OIDC Flow**:
|
|
443
|
+
|
|
444
|
+
1. Agent requests token from provider
|
|
445
|
+
2. Provider returns ID token + access token
|
|
446
|
+
3. Agent includes access token in `Authorization` header
|
|
447
|
+
4. Recipient validates token with provider's public keys
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## 6. Routing Patterns
|
|
452
|
+
|
|
453
|
+
### 6.1 Direct Routing (Point-to-Point)
|
|
454
|
+
|
|
455
|
+
Agent A sends message directly to Agent B.
|
|
456
|
+
|
|
457
|
+
```yaml
|
|
458
|
+
version: "ossa/a2a/v0.2.9"
|
|
459
|
+
id: "msg_abc123"
|
|
460
|
+
timestamp: "2025-12-04T19:30:00.000Z"
|
|
461
|
+
from: "agent://team-a/code-reviewer"
|
|
462
|
+
to: "agent://team-b/code-analyzer" # Direct recipient
|
|
463
|
+
type: "request"
|
|
464
|
+
correlation_id: "req_xyz789"
|
|
465
|
+
payload:
|
|
466
|
+
action: "analyze_code"
|
|
467
|
+
data:
|
|
468
|
+
repository: "https://github.com/org/repo"
|
|
469
|
+
commit_sha: "abc123"
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
**Use Case**: Task delegation, peer-to-peer collaboration
|
|
473
|
+
|
|
474
|
+
### 6.2 Broadcast Routing (Fan-Out)
|
|
475
|
+
|
|
476
|
+
Agent A sends message to all agents in a group.
|
|
477
|
+
|
|
478
|
+
```yaml
|
|
479
|
+
version: "ossa/a2a/v0.2.9"
|
|
480
|
+
id: "msg_broadcast_001"
|
|
481
|
+
timestamp: "2025-12-04T19:30:00.000Z"
|
|
482
|
+
from: "agent://orchestrator/main"
|
|
483
|
+
to: "broadcast://team-a/*" # All agents in team-a
|
|
484
|
+
type: "event"
|
|
485
|
+
payload:
|
|
486
|
+
event: "deployment_started"
|
|
487
|
+
data:
|
|
488
|
+
version: "v1.2.3"
|
|
489
|
+
environment: "production"
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
**Use Case**: Notifications, system-wide announcements
|
|
493
|
+
|
|
494
|
+
### 6.3 Topic-Based Routing (Pub/Sub)
|
|
495
|
+
|
|
496
|
+
Agents subscribe to topics and receive matching messages.
|
|
497
|
+
|
|
498
|
+
```yaml
|
|
499
|
+
# Publisher
|
|
500
|
+
version: "ossa/a2a/v0.2.9"
|
|
501
|
+
id: "msg_topic_001"
|
|
502
|
+
timestamp: "2025-12-04T19:30:00.000Z"
|
|
503
|
+
from: "agent://team-a/code-reviewer"
|
|
504
|
+
to: "topic://code-reviews" # Topic name
|
|
505
|
+
type: "event"
|
|
506
|
+
payload:
|
|
507
|
+
event: "review_completed"
|
|
508
|
+
data:
|
|
509
|
+
pull_request: "https://github.com/org/repo/pull/42"
|
|
510
|
+
status: "approved"
|
|
511
|
+
reviewer: "agent://team-a/code-reviewer"
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
**Subscription Example**:
|
|
515
|
+
|
|
516
|
+
```yaml
|
|
517
|
+
# Agent subscribes to topic
|
|
518
|
+
apiVersion: ossa/v0.2.9
|
|
519
|
+
kind: Agent
|
|
520
|
+
metadata:
|
|
521
|
+
name: notification-agent
|
|
522
|
+
spec:
|
|
523
|
+
messaging:
|
|
524
|
+
subscriptions:
|
|
525
|
+
- topic: "topic://code-reviews"
|
|
526
|
+
handler: on_code_review
|
|
527
|
+
- topic: "topic://deployments"
|
|
528
|
+
handler: on_deployment
|
|
529
|
+
filter:
|
|
530
|
+
environment: production
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
**Use Case**: Event-driven architectures, logging/monitoring
|
|
534
|
+
|
|
535
|
+
### 6.4 Request/Response Pattern
|
|
536
|
+
|
|
537
|
+
Agent A sends request, Agent B responds with correlation.
|
|
538
|
+
|
|
539
|
+
```yaml
|
|
540
|
+
# Request
|
|
541
|
+
version: "ossa/a2a/v0.2.9"
|
|
542
|
+
id: "msg_req_001"
|
|
543
|
+
timestamp: "2025-12-04T19:30:00.000Z"
|
|
544
|
+
from: "agent://team-a/requester"
|
|
545
|
+
to: "agent://team-b/responder"
|
|
546
|
+
type: "request"
|
|
547
|
+
correlation_id: "conv_abc123"
|
|
548
|
+
reply_to: "agent://team-a/requester"
|
|
549
|
+
ttl: 30
|
|
550
|
+
payload:
|
|
551
|
+
action: "get_analysis"
|
|
552
|
+
params:
|
|
553
|
+
file: "src/main.ts"
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
# Response
|
|
557
|
+
version: "ossa/a2a/v0.2.9"
|
|
558
|
+
id: "msg_resp_001"
|
|
559
|
+
timestamp: "2025-12-04T19:30:15.000Z"
|
|
560
|
+
from: "agent://team-b/responder"
|
|
561
|
+
to: "agent://team-a/requester"
|
|
562
|
+
type: "response"
|
|
563
|
+
correlation_id: "conv_abc123" # Same as request
|
|
564
|
+
payload:
|
|
565
|
+
status: "success"
|
|
566
|
+
result:
|
|
567
|
+
issues: []
|
|
568
|
+
quality_score: 95
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
**Use Case**: Synchronous operations, queries
|
|
572
|
+
|
|
573
|
+
---
|
|
574
|
+
|
|
575
|
+
## 7. Task Lifecycle
|
|
576
|
+
|
|
577
|
+
When agents collaborate on tasks, they follow a standard lifecycle:
|
|
578
|
+
|
|
579
|
+
```
|
|
580
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
581
|
+
│ TASK LIFECYCLE │
|
|
582
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
583
|
+
│ │
|
|
584
|
+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
585
|
+
│ │SUBMITTED │──▶│ ACCEPTED │──▶│ WORKING │──▶│COMPLETED │ │
|
|
586
|
+
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
587
|
+
│ │ │ │ │ │
|
|
588
|
+
│ │ │ │ │ │
|
|
589
|
+
│ │ ▼ ▼ │ │
|
|
590
|
+
│ │ ┌──────────┐ ┌──────────┐ │ │
|
|
591
|
+
│ └────────▶│ REJECTED │ │ FAILED │◀───────┘ │
|
|
592
|
+
│ └──────────┘ └──────────┘ │
|
|
593
|
+
│ │ │
|
|
594
|
+
│ ▼ │
|
|
595
|
+
│ ┌──────────┐ │
|
|
596
|
+
│ │CANCELLED │ │
|
|
597
|
+
│ └──────────┘ │
|
|
598
|
+
│ │
|
|
599
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
### Task States
|
|
603
|
+
|
|
604
|
+
```typescript
|
|
605
|
+
type TaskState =
|
|
606
|
+
| 'submitted' // Task sent to agent
|
|
607
|
+
| 'accepted' // Agent acknowledged task
|
|
608
|
+
| 'rejected' // Agent declined task
|
|
609
|
+
| 'working' // Agent processing task
|
|
610
|
+
| 'completed' // Task finished successfully
|
|
611
|
+
| 'failed' // Task failed with error
|
|
612
|
+
| 'cancelled'; // Task cancelled by requester
|
|
613
|
+
|
|
614
|
+
interface TaskStatus {
|
|
615
|
+
task_id: string;
|
|
616
|
+
state: TaskState;
|
|
617
|
+
progress?: number; // 0-100
|
|
618
|
+
message?: string; // Human-readable status
|
|
619
|
+
error?: TaskError;
|
|
620
|
+
started_at?: string; // ISO 8601
|
|
621
|
+
completed_at?: string; // ISO 8601
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
interface TaskError {
|
|
625
|
+
code: string;
|
|
626
|
+
message: string;
|
|
627
|
+
details?: unknown;
|
|
628
|
+
recoverable: boolean;
|
|
629
|
+
}
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
### Task Submission
|
|
633
|
+
|
|
634
|
+
```yaml
|
|
635
|
+
# Submit task
|
|
636
|
+
version: "ossa/a2a/v0.2.9"
|
|
637
|
+
id: "msg_task_submit_001"
|
|
638
|
+
timestamp: "2025-12-04T19:30:00.000Z"
|
|
639
|
+
from: "agent://team-a/orchestrator"
|
|
640
|
+
to: "agent://team-b/worker"
|
|
641
|
+
type: "request"
|
|
642
|
+
correlation_id: "task_xyz789"
|
|
643
|
+
reply_to: "agent://team-a/orchestrator"
|
|
644
|
+
payload:
|
|
645
|
+
action: "execute_task"
|
|
646
|
+
task_id: "task_xyz789"
|
|
647
|
+
input:
|
|
648
|
+
operation: "analyze_codebase"
|
|
649
|
+
parameters:
|
|
650
|
+
repository: "https://github.com/org/repo"
|
|
651
|
+
branch: "main"
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
### Task Acceptance
|
|
655
|
+
|
|
656
|
+
```yaml
|
|
657
|
+
# Accept task
|
|
658
|
+
version: "ossa/a2a/v0.2.9"
|
|
659
|
+
id: "msg_task_accept_001"
|
|
660
|
+
timestamp: "2025-12-04T19:30:01.000Z"
|
|
661
|
+
from: "agent://team-b/worker"
|
|
662
|
+
to: "agent://team-a/orchestrator"
|
|
663
|
+
type: "response"
|
|
664
|
+
correlation_id: "task_xyz789"
|
|
665
|
+
payload:
|
|
666
|
+
status: "accepted"
|
|
667
|
+
task_id: "task_xyz789"
|
|
668
|
+
estimated_duration_seconds: 120
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
### Task Progress Updates (Streaming)
|
|
672
|
+
|
|
673
|
+
```yaml
|
|
674
|
+
# Progress update
|
|
675
|
+
version: "ossa/a2a/v0.2.9"
|
|
676
|
+
id: "msg_task_progress_001"
|
|
677
|
+
timestamp: "2025-12-04T19:30:30.000Z"
|
|
678
|
+
from: "agent://team-b/worker"
|
|
679
|
+
to: "agent://team-a/orchestrator"
|
|
680
|
+
type: "event"
|
|
681
|
+
correlation_id: "task_xyz789"
|
|
682
|
+
payload:
|
|
683
|
+
event: "task_progress"
|
|
684
|
+
task_id: "task_xyz789"
|
|
685
|
+
state: "working"
|
|
686
|
+
progress: 50
|
|
687
|
+
message: "Analyzed 150/300 files"
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
### Task Completion
|
|
691
|
+
|
|
692
|
+
```yaml
|
|
693
|
+
# Success
|
|
694
|
+
version: "ossa/a2a/v0.2.9"
|
|
695
|
+
id: "msg_task_complete_001"
|
|
696
|
+
timestamp: "2025-12-04T19:32:00.000Z"
|
|
697
|
+
from: "agent://team-b/worker"
|
|
698
|
+
to: "agent://team-a/orchestrator"
|
|
699
|
+
type: "response"
|
|
700
|
+
correlation_id: "task_xyz789"
|
|
701
|
+
payload:
|
|
702
|
+
status: "completed"
|
|
703
|
+
task_id: "task_xyz789"
|
|
704
|
+
result:
|
|
705
|
+
files_analyzed: 300
|
|
706
|
+
issues_found: 12
|
|
707
|
+
quality_score: 87
|
|
708
|
+
|
|
709
|
+
---
|
|
710
|
+
# Failure
|
|
711
|
+
version: "ossa/a2a/v0.2.9"
|
|
712
|
+
id: "msg_task_fail_001"
|
|
713
|
+
timestamp: "2025-12-04T19:31:30.000Z"
|
|
714
|
+
from: "agent://team-b/worker"
|
|
715
|
+
to: "agent://team-a/orchestrator"
|
|
716
|
+
type: "response"
|
|
717
|
+
correlation_id: "task_xyz789"
|
|
718
|
+
payload:
|
|
719
|
+
status: "failed"
|
|
720
|
+
task_id: "task_xyz789"
|
|
721
|
+
error:
|
|
722
|
+
code: "REPOSITORY_UNREACHABLE"
|
|
723
|
+
message: "Failed to clone repository"
|
|
724
|
+
details:
|
|
725
|
+
url: "https://github.com/org/repo"
|
|
726
|
+
http_status: 404
|
|
727
|
+
recoverable: true
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
### Task Cancellation
|
|
731
|
+
|
|
732
|
+
```yaml
|
|
733
|
+
# Cancel request
|
|
734
|
+
version: "ossa/a2a/v0.2.9"
|
|
735
|
+
id: "msg_task_cancel_001"
|
|
736
|
+
timestamp: "2025-12-04T19:31:00.000Z"
|
|
737
|
+
from: "agent://team-a/orchestrator"
|
|
738
|
+
to: "agent://team-b/worker"
|
|
739
|
+
type: "command"
|
|
740
|
+
correlation_id: "task_xyz789"
|
|
741
|
+
payload:
|
|
742
|
+
action: "cancel_task"
|
|
743
|
+
task_id: "task_xyz789"
|
|
744
|
+
reason: "User requested cancellation"
|
|
745
|
+
|
|
746
|
+
---
|
|
747
|
+
# Cancel acknowledgment
|
|
748
|
+
version: "ossa/a2a/v0.2.9"
|
|
749
|
+
id: "msg_task_cancelled_001"
|
|
750
|
+
timestamp: "2025-12-04T19:31:01.000Z"
|
|
751
|
+
from: "agent://team-b/worker"
|
|
752
|
+
to: "agent://team-a/orchestrator"
|
|
753
|
+
type: "response"
|
|
754
|
+
correlation_id: "task_xyz789"
|
|
755
|
+
payload:
|
|
756
|
+
status: "cancelled"
|
|
757
|
+
task_id: "task_xyz789"
|
|
758
|
+
partial_result:
|
|
759
|
+
files_analyzed: 75
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
---
|
|
763
|
+
|
|
764
|
+
## 8. Error Handling
|
|
765
|
+
|
|
766
|
+
### A2A Error Codes
|
|
767
|
+
|
|
768
|
+
```typescript
|
|
769
|
+
type A2AErrorCode =
|
|
770
|
+
// Addressing Errors
|
|
771
|
+
| 'AGENT_NOT_FOUND' // Recipient agent not found
|
|
772
|
+
| 'AGENT_UNREACHABLE' // Cannot connect to agent
|
|
773
|
+
| 'TOPIC_NOT_FOUND' // Topic doesn't exist
|
|
774
|
+
|
|
775
|
+
// Authentication Errors
|
|
776
|
+
| 'AUTH_REQUIRED' // Authentication required
|
|
777
|
+
| 'AUTH_FAILED' // Authentication failed
|
|
778
|
+
| 'AUTH_EXPIRED' // Credentials expired
|
|
779
|
+
| 'INSUFFICIENT_PERMISSIONS' // Lacks required permissions
|
|
780
|
+
|
|
781
|
+
// Message Errors
|
|
782
|
+
| 'INVALID_MESSAGE' // Malformed message
|
|
783
|
+
| 'MESSAGE_EXPIRED' // TTL exceeded
|
|
784
|
+
| 'MESSAGE_TOO_LARGE' // Payload exceeds limit
|
|
785
|
+
|
|
786
|
+
// Task Errors
|
|
787
|
+
| 'TASK_REJECTED' // Agent rejected task
|
|
788
|
+
| 'TASK_TIMEOUT' // Task execution timeout
|
|
789
|
+
| 'TASK_CANCELLED' // Task cancelled by requester
|
|
790
|
+
|
|
791
|
+
// Protocol Errors
|
|
792
|
+
| 'UNSUPPORTED_VERSION' // Protocol version not supported
|
|
793
|
+
| 'UNSUPPORTED_TRANSPORT' // Transport not supported
|
|
794
|
+
| 'RATE_LIMITED'; // Too many requests
|
|
795
|
+
|
|
796
|
+
interface A2AError {
|
|
797
|
+
code: A2AErrorCode;
|
|
798
|
+
message: string;
|
|
799
|
+
details?: Record<string, unknown>;
|
|
800
|
+
timestamp: string;
|
|
801
|
+
retry_after_seconds?: number;
|
|
802
|
+
}
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
### Error Response
|
|
806
|
+
|
|
807
|
+
```yaml
|
|
808
|
+
version: "ossa/a2a/v0.2.9"
|
|
809
|
+
id: "msg_error_001"
|
|
810
|
+
timestamp: "2025-12-04T19:30:00.000Z"
|
|
811
|
+
from: "agent://team-b/worker"
|
|
812
|
+
to: "agent://team-a/orchestrator"
|
|
813
|
+
type: "response"
|
|
814
|
+
correlation_id: "task_xyz789"
|
|
815
|
+
payload:
|
|
816
|
+
status: "error"
|
|
817
|
+
error:
|
|
818
|
+
code: "AGENT_UNREACHABLE"
|
|
819
|
+
message: "Cannot connect to code-analyzer agent"
|
|
820
|
+
details:
|
|
821
|
+
target_agent: "agent://team-c/code-analyzer"
|
|
822
|
+
endpoint: "https://agents.example.com/code-analyzer"
|
|
823
|
+
network_error: "Connection timeout after 30s"
|
|
824
|
+
timestamp: "2025-12-04T19:30:00.000Z"
|
|
825
|
+
retry_after_seconds: 60
|
|
826
|
+
```
|
|
827
|
+
|
|
828
|
+
### Retry Strategy
|
|
829
|
+
|
|
830
|
+
```yaml
|
|
831
|
+
# Agent manifest with retry policy
|
|
832
|
+
apiVersion: ossa/v0.2.9
|
|
833
|
+
kind: Agent
|
|
834
|
+
metadata:
|
|
835
|
+
name: resilient-agent
|
|
836
|
+
spec:
|
|
837
|
+
messaging:
|
|
838
|
+
retry:
|
|
839
|
+
max_attempts: 3
|
|
840
|
+
backoff: exponential
|
|
841
|
+
initial_delay_ms: 1000
|
|
842
|
+
max_delay_ms: 30000
|
|
843
|
+
retryable_errors:
|
|
844
|
+
- AGENT_UNREACHABLE
|
|
845
|
+
- MESSAGE_TIMEOUT
|
|
846
|
+
- RATE_LIMITED
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
---
|
|
850
|
+
|
|
851
|
+
## 9. Streaming Support
|
|
852
|
+
|
|
853
|
+
For long-running tasks, agents can stream progress updates.
|
|
854
|
+
|
|
855
|
+
### Server-Sent Events (SSE)
|
|
856
|
+
|
|
857
|
+
```http
|
|
858
|
+
GET /agents/worker/tasks/task_xyz789/stream HTTP/1.1
|
|
859
|
+
Host: agents.example.com
|
|
860
|
+
Accept: text/event-stream
|
|
861
|
+
|
|
862
|
+
HTTP/1.1 200 OK
|
|
863
|
+
Content-Type: text/event-stream
|
|
864
|
+
Cache-Control: no-cache
|
|
865
|
+
|
|
866
|
+
event: progress
|
|
867
|
+
data: {"progress": 25, "message": "Analyzing files..."}
|
|
868
|
+
|
|
869
|
+
event: progress
|
|
870
|
+
data: {"progress": 50, "message": "Running security scan..."}
|
|
871
|
+
|
|
872
|
+
event: progress
|
|
873
|
+
data: {"progress": 75, "message": "Generating report..."}
|
|
874
|
+
|
|
875
|
+
event: completed
|
|
876
|
+
data: {"status": "success", "result": {...}}
|
|
877
|
+
```
|
|
878
|
+
|
|
879
|
+
### WebSocket Streaming
|
|
880
|
+
|
|
881
|
+
```yaml
|
|
882
|
+
# Connect to task stream
|
|
883
|
+
ws://agents.example.com/agents/worker/tasks/task_xyz789/stream
|
|
884
|
+
|
|
885
|
+
# Messages from agent
|
|
886
|
+
{
|
|
887
|
+
"type": "progress",
|
|
888
|
+
"task_id": "task_xyz789",
|
|
889
|
+
"progress": 33,
|
|
890
|
+
"message": "Processing batch 1/3"
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
{
|
|
894
|
+
"type": "progress",
|
|
895
|
+
"task_id": "task_xyz789",
|
|
896
|
+
"progress": 66,
|
|
897
|
+
"message": "Processing batch 2/3"
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
{
|
|
901
|
+
"type": "completed",
|
|
902
|
+
"task_id": "task_xyz789",
|
|
903
|
+
"status": "success",
|
|
904
|
+
"result": {...}
|
|
905
|
+
}
|
|
906
|
+
```
|
|
907
|
+
|
|
908
|
+
### gRPC Streaming
|
|
909
|
+
|
|
910
|
+
```protobuf
|
|
911
|
+
service AgentService {
|
|
912
|
+
rpc ExecuteTask(TaskRequest) returns (stream TaskUpdate);
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
message TaskUpdate {
|
|
916
|
+
string task_id = 1;
|
|
917
|
+
TaskState state = 2;
|
|
918
|
+
int32 progress = 3;
|
|
919
|
+
string message = 4;
|
|
920
|
+
google.protobuf.Struct result = 5;
|
|
921
|
+
}
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
---
|
|
925
|
+
|
|
926
|
+
## 10. Push Notifications
|
|
927
|
+
|
|
928
|
+
Agents can register webhooks to receive push notifications.
|
|
929
|
+
|
|
930
|
+
### Webhook Registration
|
|
931
|
+
|
|
932
|
+
```yaml
|
|
933
|
+
# Register webhook
|
|
934
|
+
POST /agents/code-reviewer/webhooks
|
|
935
|
+
Content-Type: application/json
|
|
936
|
+
|
|
937
|
+
{
|
|
938
|
+
"url": "https://my-app.example.com/webhooks/agent-events",
|
|
939
|
+
"events": [
|
|
940
|
+
"task.completed",
|
|
941
|
+
"task.failed",
|
|
942
|
+
"agent.status_changed"
|
|
943
|
+
],
|
|
944
|
+
"authentication": {
|
|
945
|
+
"type": "bearer",
|
|
946
|
+
"token": "secret_webhook_token_xyz"
|
|
947
|
+
},
|
|
948
|
+
"retry_policy": {
|
|
949
|
+
"max_attempts": 5,
|
|
950
|
+
"backoff": "exponential"
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
```
|
|
954
|
+
|
|
955
|
+
### Webhook Delivery
|
|
956
|
+
|
|
957
|
+
```http
|
|
958
|
+
POST /webhooks/agent-events HTTP/1.1
|
|
959
|
+
Host: my-app.example.com
|
|
960
|
+
Content-Type: application/json
|
|
961
|
+
X-OSSA-Event: task.completed
|
|
962
|
+
X-OSSA-Signature: sha256=abc123...
|
|
963
|
+
X-OSSA-Delivery: delivery_001
|
|
964
|
+
|
|
965
|
+
{
|
|
966
|
+
"version": "ossa/a2a/v0.2.9",
|
|
967
|
+
"id": "event_webhook_001",
|
|
968
|
+
"timestamp": "2025-12-04T19:32:00.000Z",
|
|
969
|
+
"from": "agent://team-b/worker",
|
|
970
|
+
"event": "task.completed",
|
|
971
|
+
"payload": {
|
|
972
|
+
"task_id": "task_xyz789",
|
|
973
|
+
"status": "completed",
|
|
974
|
+
"result": {...}
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
**Webhook Verification**:
|
|
980
|
+
|
|
981
|
+
```python
|
|
982
|
+
import hmac
|
|
983
|
+
import hashlib
|
|
984
|
+
|
|
985
|
+
def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
|
|
986
|
+
expected = "sha256=" + hmac.new(
|
|
987
|
+
secret.encode(),
|
|
988
|
+
payload,
|
|
989
|
+
hashlib.sha256
|
|
990
|
+
).hexdigest()
|
|
991
|
+
return hmac.compare_digest(expected, signature)
|
|
992
|
+
```
|
|
993
|
+
|
|
994
|
+
---
|
|
995
|
+
|
|
996
|
+
## 11. Transport Bindings
|
|
997
|
+
|
|
998
|
+
### 11.1 HTTP/REST Binding
|
|
999
|
+
|
|
1000
|
+
```http
|
|
1001
|
+
POST /agents/{agent_name}/messages HTTP/1.1
|
|
1002
|
+
Host: agents.example.com
|
|
1003
|
+
Content-Type: application/json
|
|
1004
|
+
Authorization: Bearer {token}
|
|
1005
|
+
|
|
1006
|
+
{
|
|
1007
|
+
"version": "ossa/a2a/v0.2.9",
|
|
1008
|
+
"id": "msg_abc123",
|
|
1009
|
+
"from": "agent://sender",
|
|
1010
|
+
"to": "agent://receiver",
|
|
1011
|
+
"type": "request",
|
|
1012
|
+
"payload": {...}
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
---
|
|
1016
|
+
HTTP/1.1 202 Accepted
|
|
1017
|
+
Content-Type: application/json
|
|
1018
|
+
|
|
1019
|
+
{
|
|
1020
|
+
"message_id": "msg_abc123",
|
|
1021
|
+
"status": "accepted",
|
|
1022
|
+
"timestamp": "2025-12-04T19:30:00.000Z"
|
|
1023
|
+
}
|
|
1024
|
+
```
|
|
1025
|
+
|
|
1026
|
+
### 11.2 gRPC Binding
|
|
1027
|
+
|
|
1028
|
+
```protobuf
|
|
1029
|
+
service AgentMessaging {
|
|
1030
|
+
rpc SendMessage(A2AMessage) returns (MessageAck);
|
|
1031
|
+
rpc StreamMessages(StreamRequest) returns (stream A2AMessage);
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
message A2AMessage {
|
|
1035
|
+
string version = 1;
|
|
1036
|
+
string id = 2;
|
|
1037
|
+
google.protobuf.Timestamp timestamp = 3;
|
|
1038
|
+
string from = 4;
|
|
1039
|
+
string to = 5;
|
|
1040
|
+
string correlation_id = 6;
|
|
1041
|
+
MessageType type = 7;
|
|
1042
|
+
google.protobuf.Struct payload = 8;
|
|
1043
|
+
}
|
|
1044
|
+
```
|
|
1045
|
+
|
|
1046
|
+
### 11.3 MQTT Binding
|
|
1047
|
+
|
|
1048
|
+
```yaml
|
|
1049
|
+
# Publish to agent topic
|
|
1050
|
+
Topic: ossa/agents/code-reviewer/messages
|
|
1051
|
+
QoS: 1
|
|
1052
|
+
Retain: false
|
|
1053
|
+
|
|
1054
|
+
Payload:
|
|
1055
|
+
version: "ossa/a2a/v0.2.9"
|
|
1056
|
+
id: "msg_mqtt_001"
|
|
1057
|
+
from: "agent://sender"
|
|
1058
|
+
to: "agent://code-reviewer"
|
|
1059
|
+
type: "request"
|
|
1060
|
+
payload: {...}
|
|
1061
|
+
```
|
|
1062
|
+
|
|
1063
|
+
---
|
|
1064
|
+
|
|
1065
|
+
## 12. Observability
|
|
1066
|
+
|
|
1067
|
+
### W3C Trace Context Propagation
|
|
1068
|
+
|
|
1069
|
+
All A2A messages MUST propagate W3C trace context.
|
|
1070
|
+
|
|
1071
|
+
```yaml
|
|
1072
|
+
version: "ossa/a2a/v0.2.9"
|
|
1073
|
+
id: "msg_abc123"
|
|
1074
|
+
timestamp: "2025-12-04T19:30:00.000Z"
|
|
1075
|
+
from: "agent://team-a/orchestrator"
|
|
1076
|
+
to: "agent://team-b/worker"
|
|
1077
|
+
type: "request"
|
|
1078
|
+
trace_context:
|
|
1079
|
+
traceparent: "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"
|
|
1080
|
+
tracestate: "vendor=value"
|
|
1081
|
+
payload:
|
|
1082
|
+
action: "execute_task"
|
|
1083
|
+
```
|
|
1084
|
+
|
|
1085
|
+
**HTTP Headers**:
|
|
1086
|
+
|
|
1087
|
+
```http
|
|
1088
|
+
POST /agents/worker/messages HTTP/1.1
|
|
1089
|
+
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
|
|
1090
|
+
tracestate: vendor=value
|
|
1091
|
+
```
|
|
1092
|
+
|
|
1093
|
+
### OpenTelemetry Spans
|
|
1094
|
+
|
|
1095
|
+
```typescript
|
|
1096
|
+
// Sender creates span
|
|
1097
|
+
const span = tracer.startSpan('a2a.send_message', {
|
|
1098
|
+
attributes: {
|
|
1099
|
+
'a2a.message_id': 'msg_abc123',
|
|
1100
|
+
'a2a.from': 'agent://team-a/orchestrator',
|
|
1101
|
+
'a2a.to': 'agent://team-b/worker',
|
|
1102
|
+
'a2a.type': 'request',
|
|
1103
|
+
'a2a.correlation_id': 'task_xyz789'
|
|
1104
|
+
}
|
|
1105
|
+
});
|
|
1106
|
+
|
|
1107
|
+
// Receiver continues trace
|
|
1108
|
+
const receiverSpan = tracer.startSpan('a2a.receive_message', {
|
|
1109
|
+
parent: extractedContext,
|
|
1110
|
+
attributes: {
|
|
1111
|
+
'a2a.message_id': 'msg_abc123',
|
|
1112
|
+
'a2a.processing_time_ms': 1234
|
|
1113
|
+
}
|
|
1114
|
+
});
|
|
1115
|
+
```
|
|
1116
|
+
|
|
1117
|
+
---
|
|
1118
|
+
|
|
1119
|
+
## 13. Security Considerations
|
|
1120
|
+
|
|
1121
|
+
### Message Signing
|
|
1122
|
+
|
|
1123
|
+
Messages SHOULD be signed to prevent tampering.
|
|
1124
|
+
|
|
1125
|
+
```yaml
|
|
1126
|
+
version: "ossa/a2a/v0.2.9"
|
|
1127
|
+
id: "msg_signed_001"
|
|
1128
|
+
timestamp: "2025-12-04T19:30:00.000Z"
|
|
1129
|
+
from: "agent://team-a/sender"
|
|
1130
|
+
to: "agent://team-b/receiver"
|
|
1131
|
+
type: "request"
|
|
1132
|
+
payload: {...}
|
|
1133
|
+
signature:
|
|
1134
|
+
algorithm: "RS256"
|
|
1135
|
+
keyid: "key_abc123"
|
|
1136
|
+
value: "base64_signature_here..."
|
|
1137
|
+
```
|
|
1138
|
+
|
|
1139
|
+
### Message Encryption
|
|
1140
|
+
|
|
1141
|
+
Sensitive payloads SHOULD be encrypted.
|
|
1142
|
+
|
|
1143
|
+
```yaml
|
|
1144
|
+
version: "ossa/a2a/v0.2.9"
|
|
1145
|
+
id: "msg_encrypted_001"
|
|
1146
|
+
timestamp: "2025-12-04T19:30:00.000Z"
|
|
1147
|
+
from: "agent://team-a/sender"
|
|
1148
|
+
to: "agent://team-b/receiver"
|
|
1149
|
+
type: "request"
|
|
1150
|
+
payload_encrypted: true
|
|
1151
|
+
encryption:
|
|
1152
|
+
algorithm: "AES-256-GCM"
|
|
1153
|
+
key_id: "key_xyz789"
|
|
1154
|
+
nonce: "base64_nonce..."
|
|
1155
|
+
payload: "base64_encrypted_payload..."
|
|
1156
|
+
```
|
|
1157
|
+
|
|
1158
|
+
### Rate Limiting
|
|
1159
|
+
|
|
1160
|
+
```yaml
|
|
1161
|
+
# Agent manifest with rate limiting
|
|
1162
|
+
apiVersion: ossa/v0.2.9
|
|
1163
|
+
kind: Agent
|
|
1164
|
+
metadata:
|
|
1165
|
+
name: rate-limited-agent
|
|
1166
|
+
spec:
|
|
1167
|
+
messaging:
|
|
1168
|
+
rate_limits:
|
|
1169
|
+
- type: per_sender
|
|
1170
|
+
requests_per_minute: 60
|
|
1171
|
+
- type: global
|
|
1172
|
+
requests_per_minute: 1000
|
|
1173
|
+
- type: per_topic
|
|
1174
|
+
topic: "topic://high-priority"
|
|
1175
|
+
requests_per_minute: 10
|
|
1176
|
+
```
|
|
1177
|
+
|
|
1178
|
+
---
|
|
1179
|
+
|
|
1180
|
+
## 14. Compliance Requirements
|
|
1181
|
+
|
|
1182
|
+
### MUST Requirements
|
|
1183
|
+
|
|
1184
|
+
1. Messages MUST include `version`, `id`, `timestamp`, `from`, `to`, `type`, `payload`
|
|
1185
|
+
2. Agent URIs MUST follow format: `agent://{namespace}/{name}`
|
|
1186
|
+
3. Timestamps MUST be ISO 8601 format with timezone
|
|
1187
|
+
4. Message IDs MUST be globally unique (UUID recommended)
|
|
1188
|
+
5. Correlation IDs MUST match across request/response pairs
|
|
1189
|
+
6. TTL MUST be honored; expired messages MUST be dropped
|
|
1190
|
+
7. Authentication MUST be enforced in production environments
|
|
1191
|
+
8. TLS 1.3+ MUST be used for HTTP/gRPC transports
|
|
1192
|
+
|
|
1193
|
+
### SHOULD Requirements
|
|
1194
|
+
|
|
1195
|
+
1. Agents SHOULD publish AgentCard on startup
|
|
1196
|
+
2. Agents SHOULD implement at least one discovery method
|
|
1197
|
+
3. Agents SHOULD propagate W3C trace context
|
|
1198
|
+
4. Agents SHOULD sign messages in untrusted networks
|
|
1199
|
+
5. Agents SHOULD implement exponential backoff for retries
|
|
1200
|
+
6. Agents SHOULD emit OpenTelemetry spans for all messages
|
|
1201
|
+
|
|
1202
|
+
### MAY Requirements
|
|
1203
|
+
|
|
1204
|
+
1. Agents MAY support multiple transports
|
|
1205
|
+
2. Agents MAY implement custom routing logic
|
|
1206
|
+
3. Agents MAY encrypt message payloads
|
|
1207
|
+
4. Agents MAY implement priority queuing
|
|
1208
|
+
|
|
1209
|
+
---
|
|
1210
|
+
|
|
1211
|
+
## 15. Examples
|
|
1212
|
+
|
|
1213
|
+
### Example 1: Code Review Workflow
|
|
1214
|
+
|
|
1215
|
+
```yaml
|
|
1216
|
+
# 1. Developer agent requests code review
|
|
1217
|
+
version: "ossa/a2a/v0.2.9"
|
|
1218
|
+
id: "msg_001"
|
|
1219
|
+
timestamp: "2025-12-04T19:30:00.000Z"
|
|
1220
|
+
from: "agent://dev/alice-assistant"
|
|
1221
|
+
to: "agent://code-review/reviewer"
|
|
1222
|
+
type: "request"
|
|
1223
|
+
correlation_id: "review_pr_42"
|
|
1224
|
+
reply_to: "agent://dev/alice-assistant"
|
|
1225
|
+
payload:
|
|
1226
|
+
action: "review_code"
|
|
1227
|
+
pull_request: "https://github.com/org/repo/pull/42"
|
|
1228
|
+
focus_areas: ["security", "performance"]
|
|
1229
|
+
|
|
1230
|
+
---
|
|
1231
|
+
# 2. Reviewer accepts task
|
|
1232
|
+
version: "ossa/a2a/v0.2.9"
|
|
1233
|
+
id: "msg_002"
|
|
1234
|
+
timestamp: "2025-12-04T19:30:01.000Z"
|
|
1235
|
+
from: "agent://code-review/reviewer"
|
|
1236
|
+
to: "agent://dev/alice-assistant"
|
|
1237
|
+
type: "response"
|
|
1238
|
+
correlation_id: "review_pr_42"
|
|
1239
|
+
payload:
|
|
1240
|
+
status: "accepted"
|
|
1241
|
+
estimated_duration_seconds: 180
|
|
1242
|
+
|
|
1243
|
+
---
|
|
1244
|
+
# 3. Reviewer sends progress
|
|
1245
|
+
version: "ossa/a2a/v0.2.9"
|
|
1246
|
+
id: "msg_003"
|
|
1247
|
+
timestamp: "2025-12-04T19:31:00.000Z"
|
|
1248
|
+
from: "agent://code-review/reviewer"
|
|
1249
|
+
to: "agent://dev/alice-assistant"
|
|
1250
|
+
type: "event"
|
|
1251
|
+
correlation_id: "review_pr_42"
|
|
1252
|
+
payload:
|
|
1253
|
+
event: "progress"
|
|
1254
|
+
progress: 50
|
|
1255
|
+
message: "Completed security scan, running performance tests"
|
|
1256
|
+
|
|
1257
|
+
---
|
|
1258
|
+
# 4. Reviewer completes review
|
|
1259
|
+
version: "ossa/a2a/v0.2.9"
|
|
1260
|
+
id: "msg_004"
|
|
1261
|
+
timestamp: "2025-12-04T19:33:00.000Z"
|
|
1262
|
+
from: "agent://code-review/reviewer"
|
|
1263
|
+
to: "agent://dev/alice-assistant"
|
|
1264
|
+
type: "response"
|
|
1265
|
+
correlation_id: "review_pr_42"
|
|
1266
|
+
payload:
|
|
1267
|
+
status: "completed"
|
|
1268
|
+
result:
|
|
1269
|
+
overall_score: 85
|
|
1270
|
+
security_issues: 2
|
|
1271
|
+
performance_concerns: 1
|
|
1272
|
+
recommendation: "approve_with_changes"
|
|
1273
|
+
comments:
|
|
1274
|
+
- line: 42
|
|
1275
|
+
message: "Consider using parameterized query to prevent SQL injection"
|
|
1276
|
+
```
|
|
1277
|
+
|
|
1278
|
+
### Example 2: Multi-Agent Orchestration
|
|
1279
|
+
|
|
1280
|
+
```yaml
|
|
1281
|
+
# Orchestrator broadcasts task to worker pool
|
|
1282
|
+
version: "ossa/a2a/v0.2.9"
|
|
1283
|
+
id: "msg_orchestrator_001"
|
|
1284
|
+
timestamp: "2025-12-04T19:30:00.000Z"
|
|
1285
|
+
from: "agent://orchestrator/main"
|
|
1286
|
+
to: "broadcast://workers/*"
|
|
1287
|
+
type: "request"
|
|
1288
|
+
correlation_id: "batch_job_123"
|
|
1289
|
+
reply_to: "agent://orchestrator/main"
|
|
1290
|
+
payload:
|
|
1291
|
+
action: "claim_task"
|
|
1292
|
+
task_pool: "image_processing"
|
|
1293
|
+
max_workers: 5
|
|
1294
|
+
|
|
1295
|
+
---
|
|
1296
|
+
# Worker claims task
|
|
1297
|
+
version: "ossa/a2a/v0.2.9"
|
|
1298
|
+
id: "msg_worker_001"
|
|
1299
|
+
timestamp: "2025-12-04T19:30:01.000Z"
|
|
1300
|
+
from: "agent://workers/worker-01"
|
|
1301
|
+
to: "agent://orchestrator/main"
|
|
1302
|
+
type: "response"
|
|
1303
|
+
correlation_id: "batch_job_123"
|
|
1304
|
+
payload:
|
|
1305
|
+
status: "claimed"
|
|
1306
|
+
worker_id: "worker-01"
|
|
1307
|
+
capacity: 10
|
|
1308
|
+
|
|
1309
|
+
---
|
|
1310
|
+
# Orchestrator assigns task
|
|
1311
|
+
version: "ossa/a2a/v0.2.9"
|
|
1312
|
+
id: "msg_orchestrator_002"
|
|
1313
|
+
timestamp: "2025-12-04T19:30:02.000Z"
|
|
1314
|
+
from: "agent://orchestrator/main"
|
|
1315
|
+
to: "agent://workers/worker-01"
|
|
1316
|
+
type: "request"
|
|
1317
|
+
correlation_id: "task_img_001"
|
|
1318
|
+
payload:
|
|
1319
|
+
action: "process_images"
|
|
1320
|
+
images:
|
|
1321
|
+
- "s3://bucket/img1.jpg"
|
|
1322
|
+
- "s3://bucket/img2.jpg"
|
|
1323
|
+
operations: ["resize", "optimize", "watermark"]
|
|
1324
|
+
```
|
|
1325
|
+
|
|
1326
|
+
---
|
|
1327
|
+
|
|
1328
|
+
## References
|
|
1329
|
+
|
|
1330
|
+
- [OSSA Schema v0.2.9](./ossa-0.2.9.schema.json)
|
|
1331
|
+
- [Runtime Semantics](./runtime-semantics.md)
|
|
1332
|
+
- [Semantic Conventions](./semantic-conventions.md)
|
|
1333
|
+
- [Google A2A Protocol (2024)](https://github.com/google/a2a-protocol)
|
|
1334
|
+
- [W3C Trace Context](https://www.w3.org/TR/trace-context/)
|
|
1335
|
+
- [CloudEvents Specification](https://cloudevents.io/)
|
|
1336
|
+
- [OpenTelemetry Specification](https://opentelemetry.io/docs/specs/)
|
|
1337
|
+
- [RFC 6763: DNS-Based Service Discovery](https://tools.ietf.org/html/rfc6763)
|