va-agent-protocol 0.1.0
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/LICENSE +21 -0
- package/README.md +558 -0
- package/bin/va-orchestrate.mjs +153 -0
- package/dist/adapter/agent-adapter.d.ts +79 -0
- package/dist/adapter/agent-adapter.d.ts.map +1 -0
- package/dist/adapter/agent-adapter.js +36 -0
- package/dist/adapter/agent-adapter.js.map +1 -0
- package/dist/adapter/codex-adapter.d.ts +54 -0
- package/dist/adapter/codex-adapter.d.ts.map +1 -0
- package/dist/adapter/codex-adapter.js +409 -0
- package/dist/adapter/codex-adapter.js.map +1 -0
- package/dist/adapter/va-auto-pilot-adapter.d.ts +51 -0
- package/dist/adapter/va-auto-pilot-adapter.d.ts.map +1 -0
- package/dist/adapter/va-auto-pilot-adapter.js +275 -0
- package/dist/adapter/va-auto-pilot-adapter.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator/orchestrator.d.ts +101 -0
- package/dist/orchestrator/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/orchestrator.js +452 -0
- package/dist/orchestrator/orchestrator.js.map +1 -0
- package/dist/orchestrator/registry.d.ts +39 -0
- package/dist/orchestrator/registry.d.ts.map +1 -0
- package/dist/orchestrator/registry.js +62 -0
- package/dist/orchestrator/registry.js.map +1 -0
- package/dist/orchestrator/scheduler.d.ts +66 -0
- package/dist/orchestrator/scheduler.d.ts.map +1 -0
- package/dist/orchestrator/scheduler.js +155 -0
- package/dist/orchestrator/scheduler.js.map +1 -0
- package/dist/test/orchestrator-enqueue.test.d.ts +2 -0
- package/dist/test/orchestrator-enqueue.test.d.ts.map +1 -0
- package/dist/test/orchestrator-enqueue.test.js +64 -0
- package/dist/test/orchestrator-enqueue.test.js.map +1 -0
- package/dist/test/orchestrator-lifecycle.test.d.ts +2 -0
- package/dist/test/orchestrator-lifecycle.test.d.ts.map +1 -0
- package/dist/test/orchestrator-lifecycle.test.js +227 -0
- package/dist/test/orchestrator-lifecycle.test.js.map +1 -0
- package/dist/test/scheduler.test.d.ts +2 -0
- package/dist/test/scheduler.test.d.ts.map +1 -0
- package/dist/test/scheduler.test.js +140 -0
- package/dist/test/scheduler.test.js.map +1 -0
- package/dist/types/index.d.ts +209 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +45 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/logger.d.ts +17 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +21 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +61 -0
- package/schemas/agent-capability.schema.json +99 -0
- package/schemas/evidence.schema.json +201 -0
- package/schemas/lifecycle.schema.json +80 -0
- package/schemas/message.schema.json +181 -0
- package/schemas/task-unit.schema.json +137 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Vadaski
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
# va-agent-protocol
|
|
2
|
+
|
|
3
|
+
[](https://github.com/Vadaski/va-agent-protocol/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/va-agent-protocol)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://github.com/Vadaski/va-agent-protocol)
|
|
7
|
+
|
|
8
|
+
**The USB interface for AI agents — dispatch, verify, orchestrate.**
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
┌─────────────────────────────────────────┐
|
|
12
|
+
│ Orchestrator │
|
|
13
|
+
│ (dispatch, schedule, monitor, retry) │
|
|
14
|
+
└──────────────────┬──────────────────────┘
|
|
15
|
+
│ ← va-agent-protocol
|
|
16
|
+
┌──────────────────┴──────────────────────┐
|
|
17
|
+
│ ┌───────────┐ ┌──────────┐ ┌─────────┐│
|
|
18
|
+
│ │ Claude │ │ Codex │ │ Your ││
|
|
19
|
+
│ │ Code │ │ │ │ Agent ││
|
|
20
|
+
│ └───────────┘ └──────────┘ └─────────┘│
|
|
21
|
+
│ Any CLI agent │
|
|
22
|
+
└──────────────────────────────────────────┘
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Try it now
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx va-orchestrate agents --project-root .
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Protocol Comparison
|
|
34
|
+
|
|
35
|
+
How does va-agent-protocol relate to MCP and A2A? They are **complementary**, not competing:
|
|
36
|
+
|
|
37
|
+
| Dimension | MCP (Anthropic) | A2A (Google) | va-agent-protocol |
|
|
38
|
+
|-----------|----------------|-------------|-------------------|
|
|
39
|
+
| **Focus** | Tool-level context | Agent discovery + coordination | Long-task execution + evidence verification |
|
|
40
|
+
| **Task type** | Short synchronous tool calls | Discovery + routing | Long tasks + auto-topology + scheduler |
|
|
41
|
+
| **Time model** | Synchronous | Async (push) | Async (polling; v0.2 push) |
|
|
42
|
+
| **Verification** | Return value = result | Weak | CLI gates + model-eval + pitfall |
|
|
43
|
+
| **Orchestration** | None | Basic routing | Topological sort + capability match + concurrency control |
|
|
44
|
+
| **Failure learning** | None | None | Pitfall compounding |
|
|
45
|
+
| **Interop** | — | MCP-compatible | Complements MCP & A2A |
|
|
46
|
+
|
|
47
|
+
> **TL;DR** — MCP connects models to tools. A2A connects agents to agents. va-agent-protocol makes sure the work actually gets done right.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Why
|
|
52
|
+
|
|
53
|
+
AI agents can autonomously write code, review it, and test it. But every agent has its own interface. There's no standard way to:
|
|
54
|
+
|
|
55
|
+
- **Dispatch** a task to an agent with objectives and constraints
|
|
56
|
+
- **Monitor** progress in real-time as the agent works
|
|
57
|
+
- **Collect evidence** that the task was actually completed (not just self-certified)
|
|
58
|
+
- **Retry** with context from previous failures
|
|
59
|
+
- **Compose** multiple agents with different capabilities
|
|
60
|
+
|
|
61
|
+
va-agent-protocol solves this with a **JSON Schema-based contract** — comply with the spec, and your agent plugs into any orchestrator.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Why Frontier Models Need This
|
|
66
|
+
|
|
67
|
+
2026 frontier models (Claude Opus 4, GPT-5, Gemini 2.5 Pro) bring extraordinary capabilities: autonomous multi-step reasoning, million-token context windows, and native tool calling. va-agent-protocol is designed to **amplify these strengths** and **guard against remaining weaknesses**.
|
|
68
|
+
|
|
69
|
+
### Amplifying strengths
|
|
70
|
+
|
|
71
|
+
- **Objective-driven delegation** — Tasks define WHAT to achieve, never HOW. The model's reasoning ability is fully unleashed.
|
|
72
|
+
- **Parallel task scheduling** — The orchestrator dispatches independent tasks concurrently, leaning into frontier models' native parallel tool orchestration.
|
|
73
|
+
- **Long-context awareness** — Task contracts, pitfall guides, and evidence payloads are designed for models that can hold entire projects in context.
|
|
74
|
+
|
|
75
|
+
### Guarding against weaknesses
|
|
76
|
+
|
|
77
|
+
- **Evidence gates prevent hallucination** — Agents cannot self-certify completion. CLI commands and model-evaluation gates produce objective pass/fail signals. "I think it's done" is not the same as "it is done."
|
|
78
|
+
- **Pitfall compounding prevents repeated mistakes** — Structured failure metadata from past attempts is injected into retries as hard constraints. The system gets harder to fool over time.
|
|
79
|
+
- **Model-evaluation gates** — For subjective quality (code style, content tone), AI judges with score thresholds and three-tier decisions (pass / blocked for human / fail+retry).
|
|
80
|
+
|
|
81
|
+
> **One sentence:** Trust the model's reasoning power; use deterministic mechanisms to catch its blind spots.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Design Principles
|
|
86
|
+
|
|
87
|
+
Inherited from [va-auto-pilot](https://github.com/Vadaski/va-auto-pilot):
|
|
88
|
+
|
|
89
|
+
1. **Objective-driven, not step-driven** — Tasks define WHAT to achieve, never HOW
|
|
90
|
+
2. **CLI-first** — Agents are invoked via subprocess, not library import
|
|
91
|
+
3. **Evidence-based completion** — "Prove it's done" with gate results and artifacts, not "trust me"
|
|
92
|
+
4. **Convention over configuration** — Comply with the JSON Schema, you're compatible
|
|
93
|
+
5. **Failure knowledge compounds** — Each retry receives pitfalls from previous failures
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Quick Start
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
npm install va-agent-protocol
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 1. Define a Task
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import type { TaskUnit } from "va-agent-protocol";
|
|
107
|
+
|
|
108
|
+
const task: TaskUnit = {
|
|
109
|
+
id: "TASK-001",
|
|
110
|
+
objective: "Implement user authentication with JWT",
|
|
111
|
+
constraints: [
|
|
112
|
+
"Use bcrypt for password hashing",
|
|
113
|
+
"Tokens expire in 24 hours",
|
|
114
|
+
],
|
|
115
|
+
acceptanceCriteria: [
|
|
116
|
+
"npm run typecheck passes",
|
|
117
|
+
"npm test passes with all auth tests",
|
|
118
|
+
"No CRITICAL findings in code review",
|
|
119
|
+
],
|
|
120
|
+
priority: "P1",
|
|
121
|
+
};
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 2. Implement an Adapter (or use built-in)
|
|
125
|
+
|
|
126
|
+
The adapter is the "USB plug" — it translates between the protocol and your agent's CLI:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import type {
|
|
130
|
+
AgentAdapter,
|
|
131
|
+
AgentCapability,
|
|
132
|
+
DispatchResult,
|
|
133
|
+
PollResult,
|
|
134
|
+
TaskUnit,
|
|
135
|
+
} from "va-agent-protocol";
|
|
136
|
+
import { generateCorrelationId } from "va-agent-protocol";
|
|
137
|
+
|
|
138
|
+
class MyAgentAdapter implements AgentAdapter {
|
|
139
|
+
readonly id = "my-agent";
|
|
140
|
+
|
|
141
|
+
capabilities(): AgentCapability {
|
|
142
|
+
return {
|
|
143
|
+
agentId: this.id,
|
|
144
|
+
name: "My Custom Agent",
|
|
145
|
+
version: "1.0.0",
|
|
146
|
+
capabilities: ["code-generation", "testing"],
|
|
147
|
+
modelRequirement: "frontier",
|
|
148
|
+
interface: {
|
|
149
|
+
type: "cli",
|
|
150
|
+
command: "my-agent-cli",
|
|
151
|
+
},
|
|
152
|
+
constraints: {
|
|
153
|
+
maxConcurrent: 2,
|
|
154
|
+
maxRetries: 3,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async dispatch(task: TaskUnit): Promise<DispatchResult> {
|
|
160
|
+
const correlationId = generateCorrelationId();
|
|
161
|
+
// Spawn your agent process here
|
|
162
|
+
return { correlationId, accepted: true };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async poll(correlationId: string): Promise<PollResult> {
|
|
166
|
+
// Check your agent's state
|
|
167
|
+
return {
|
|
168
|
+
correlationId,
|
|
169
|
+
state: "running",
|
|
170
|
+
progress: {
|
|
171
|
+
taskId: "TASK-001",
|
|
172
|
+
phase: "implementing",
|
|
173
|
+
summary: "Writing authentication middleware...",
|
|
174
|
+
completionEstimate: 0.4,
|
|
175
|
+
logs: [{
|
|
176
|
+
timestamp: new Date().toISOString(),
|
|
177
|
+
level: "info",
|
|
178
|
+
message: "Created src/auth/middleware.ts",
|
|
179
|
+
}],
|
|
180
|
+
data: { linesWritten: 87 },
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async cancel(correlationId: string): Promise<void> {
|
|
186
|
+
// Kill the agent process
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### 3. Orchestrate
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
import {
|
|
195
|
+
AgentRegistry,
|
|
196
|
+
Orchestrator,
|
|
197
|
+
} from "va-agent-protocol";
|
|
198
|
+
|
|
199
|
+
const registry = new AgentRegistry();
|
|
200
|
+
registry.register(new MyAgentAdapter());
|
|
201
|
+
|
|
202
|
+
const orchestrator = new Orchestrator(registry, {
|
|
203
|
+
pollIntervalMs: 3000,
|
|
204
|
+
maxRetries: 3,
|
|
205
|
+
|
|
206
|
+
onProgress: (taskId, progress) => {
|
|
207
|
+
console.log(`${taskId}: ${progress.phase} (${Math.round((progress.completionEstimate ?? 0) * 100)}%)`);
|
|
208
|
+
},
|
|
209
|
+
|
|
210
|
+
onCompleted: (taskId, evidence) => {
|
|
211
|
+
console.log(`${taskId} completed!`);
|
|
212
|
+
for (const gate of evidence.gateResults ?? []) {
|
|
213
|
+
console.log(` ${gate.passed ? "✓" : "✗"} ${gate.gate}`);
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
onFailed: (taskId, evidence) => {
|
|
218
|
+
console.error(`${taskId} failed: ${evidence.failureDetail?.hypothesis}`);
|
|
219
|
+
},
|
|
220
|
+
|
|
221
|
+
onBlocked: (taskId, reason) => {
|
|
222
|
+
console.log(`${taskId} needs human input: ${reason}`);
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
orchestrator.enqueue(task);
|
|
227
|
+
orchestrator.start();
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Protocol Schemas
|
|
233
|
+
|
|
234
|
+
The protocol is defined by 5 JSON Schemas in `schemas/`:
|
|
235
|
+
|
|
236
|
+
| Schema | Purpose |
|
|
237
|
+
|--------|---------|
|
|
238
|
+
| [`task-unit.schema.json`](schemas/task-unit.schema.json) | The universal task contract (objective + constraints + acceptance criteria) |
|
|
239
|
+
| [`agent-capability.schema.json`](schemas/agent-capability.schema.json) | Agent self-description (capabilities, interface, constraints) |
|
|
240
|
+
| [`lifecycle.schema.json`](schemas/lifecycle.schema.json) | Task state machine and valid transitions |
|
|
241
|
+
| [`evidence.schema.json`](schemas/evidence.schema.json) | Completion proof (gate results, artifacts, failure details) |
|
|
242
|
+
| [`message.schema.json`](schemas/message.schema.json) | Communication envelope between orchestrator and agent |
|
|
243
|
+
|
|
244
|
+
### Task Lifecycle
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
pending → running → completed
|
|
248
|
+
↓
|
|
249
|
+
blocked → running (after human input)
|
|
250
|
+
↓
|
|
251
|
+
failed → running (retry with pitfall context)
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Evidence-Based Completion
|
|
255
|
+
|
|
256
|
+
Tasks don't self-certify completion. They must provide **evidence**:
|
|
257
|
+
|
|
258
|
+
```json
|
|
259
|
+
{
|
|
260
|
+
"taskId": "TASK-001",
|
|
261
|
+
"status": "completed",
|
|
262
|
+
"gateResults": [
|
|
263
|
+
{
|
|
264
|
+
"gate": "typecheck",
|
|
265
|
+
"command": "npm run typecheck",
|
|
266
|
+
"exitCode": 0,
|
|
267
|
+
"passed": true,
|
|
268
|
+
"durationMs": 1200
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"gate": "unit-tests",
|
|
272
|
+
"command": "npm test",
|
|
273
|
+
"exitCode": 0,
|
|
274
|
+
"passed": true,
|
|
275
|
+
"output": "42 tests passed, 0 failed"
|
|
276
|
+
}
|
|
277
|
+
],
|
|
278
|
+
"artifacts": [
|
|
279
|
+
{ "type": "commit", "path": "a1b2c3d", "description": "Implement JWT auth" }
|
|
280
|
+
],
|
|
281
|
+
"verification": "All 3 quality gates passed."
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Model-Evaluation Gates
|
|
286
|
+
|
|
287
|
+
Not all quality gates are CLI commands. For subjective or AI-judged evaluations (style consistency, code quality scoring, content review), gates support a `model-evaluation` type:
|
|
288
|
+
|
|
289
|
+
```json
|
|
290
|
+
{
|
|
291
|
+
"gate": "style-consistency",
|
|
292
|
+
"type": "model-evaluation",
|
|
293
|
+
"evaluator": "style-similarity-agent",
|
|
294
|
+
"score": 0.85,
|
|
295
|
+
"threshold": 0.8,
|
|
296
|
+
"softThreshold": 0.65,
|
|
297
|
+
"passed": true,
|
|
298
|
+
"rationale": "Sentence rhythm and vocabulary match. Tone slightly more formal."
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
When `passed: false`, the `severity` field controls the response:
|
|
303
|
+
- `"error"` → hard fail (orchestrator retries)
|
|
304
|
+
- `"warning"` → soft fail (orchestrator may route to `blocked` for human review)
|
|
305
|
+
|
|
306
|
+
The `softThreshold` enables a three-tier decision: below soft = fail+retry, between soft and hard = blocked for human, above hard = pass.
|
|
307
|
+
|
|
308
|
+
### Task Inputs/Outputs
|
|
309
|
+
|
|
310
|
+
Tasks can declare typed inputs and outputs. The orchestrator automatically resolves data references between dependent tasks:
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
const extractSchema: TaskUnit = {
|
|
314
|
+
id: "SCHEMA-001",
|
|
315
|
+
objective: "Extract API schema definitions",
|
|
316
|
+
outputContract: { keys: ["apiSchema"] }, // Declares what this task produces
|
|
317
|
+
// ...
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
const generateClient: TaskUnit = {
|
|
321
|
+
id: "CLIENT-001",
|
|
322
|
+
dependsOn: ["SCHEMA-001"],
|
|
323
|
+
inputs: {
|
|
324
|
+
schema: { fromTask: "SCHEMA-001", outputKey: "apiSchema" }, // Resolved by orchestrator
|
|
325
|
+
language: "typescript", // Static input
|
|
326
|
+
},
|
|
327
|
+
// ...
|
|
328
|
+
};
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Failure → Pitfall → Retry
|
|
332
|
+
|
|
333
|
+
When a task fails, the orchestrator captures structured failure metadata and injects it as `pitfalls` into the retry context:
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
Attempt 1: Agent implements feature → tests fail on edge case
|
|
337
|
+
↓ failureDetail captured
|
|
338
|
+
Attempt 2: Agent receives pitfall context →
|
|
339
|
+
"Previous attempt failed: missing null check for empty array input"
|
|
340
|
+
→ Agent handles edge case → tests pass
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Progress Reporting
|
|
346
|
+
|
|
347
|
+
Agents report progress through `ProgressPayload`:
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
{
|
|
351
|
+
taskId: "TASK-001",
|
|
352
|
+
phase: "implementing", // Current execution phase
|
|
353
|
+
summary: "Writing auth module", // Human-readable status
|
|
354
|
+
completionEstimate: 0.4, // 0.0 → 1.0
|
|
355
|
+
logs: [{ // Structured log entries
|
|
356
|
+
timestamp: "2026-02-24T...",
|
|
357
|
+
level: "info",
|
|
358
|
+
message: "Created src/auth/middleware.ts"
|
|
359
|
+
}],
|
|
360
|
+
data: { // Arbitrary structured data
|
|
361
|
+
linesWritten: 87,
|
|
362
|
+
currentFile: "src/auth/middleware.ts"
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## Multi-Agent Scheduling
|
|
370
|
+
|
|
371
|
+
Register agents with different capabilities. The scheduler matches tasks to the best-fit agent:
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
registry.register(codeAgent); // capabilities: ["code-generation", "testing"]
|
|
375
|
+
registry.register(reviewAgent); // capabilities: ["code-review", "security-audit"]
|
|
376
|
+
|
|
377
|
+
// Scheduler auto-routes:
|
|
378
|
+
// "Implement feature X" → codeAgent (matched "code-generation")
|
|
379
|
+
// "Audit API security" → reviewAgent (matched "security-audit")
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Concurrency limits are respected. If an agent is at max capacity, tasks queue until a slot opens.
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## Task Dependencies
|
|
387
|
+
|
|
388
|
+
Tasks can declare dependencies. The orchestrator dispatches them in topological order:
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
const tasks = [
|
|
392
|
+
{ id: "TASK-001", objective: "Build core module", ... },
|
|
393
|
+
{ id: "TASK-002", objective: "Add tests", dependsOn: ["TASK-001"], ... },
|
|
394
|
+
{ id: "TASK-003", objective: "Write docs", ... }, // No deps, runs in parallel
|
|
395
|
+
];
|
|
396
|
+
|
|
397
|
+
orchestrator.enqueue(...tasks);
|
|
398
|
+
// TASK-001 and TASK-003 dispatch immediately (parallel)
|
|
399
|
+
// TASK-002 waits for TASK-001 to complete
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## Built-in: va-auto-pilot Adapter
|
|
405
|
+
|
|
406
|
+
The first adapter wraps [va-auto-pilot](https://github.com/Vadaski/va-auto-pilot)'s sprint-board CLI:
|
|
407
|
+
|
|
408
|
+
```typescript
|
|
409
|
+
import { VaAutoPilotAdapter, AgentRegistry, Orchestrator } from "va-agent-protocol";
|
|
410
|
+
|
|
411
|
+
const adapter = new VaAutoPilotAdapter({
|
|
412
|
+
projectRoot: "/path/to/your/project",
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
const registry = new AgentRegistry();
|
|
416
|
+
registry.register(adapter);
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## CLI
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
# List registered agents
|
|
425
|
+
npx va-orchestrate agents --project-root ./my-project
|
|
426
|
+
|
|
427
|
+
# Dispatch a task from JSON file
|
|
428
|
+
npx va-orchestrate dispatch --task task.json --project-root ./my-project
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
## Run the Example
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
npm run example
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
This shows multi-agent registration, capability matching, task dependency ordering, real-time progress, quality gate evidence, failure → pitfall → retry, blocked state escalation, and a live terminal dashboard.
|
|
440
|
+
|
|
441
|
+
---
|
|
442
|
+
|
|
443
|
+
## Implementing Your Own Adapter
|
|
444
|
+
|
|
445
|
+
The adapter is the "USB plug" — the only code you write to make your agent protocol-compatible. Implement the `AgentAdapter` interface:
|
|
446
|
+
|
|
447
|
+
```typescript
|
|
448
|
+
import type {
|
|
449
|
+
AgentAdapter,
|
|
450
|
+
AgentCapability,
|
|
451
|
+
DispatchResult,
|
|
452
|
+
PollResult,
|
|
453
|
+
TaskUnit,
|
|
454
|
+
} from "va-agent-protocol";
|
|
455
|
+
import { generateCorrelationId } from "va-agent-protocol";
|
|
456
|
+
|
|
457
|
+
class MyAgentAdapter implements AgentAdapter {
|
|
458
|
+
readonly id = "my-agent";
|
|
459
|
+
|
|
460
|
+
capabilities(): AgentCapability {
|
|
461
|
+
return {
|
|
462
|
+
agentId: this.id,
|
|
463
|
+
name: "My Agent",
|
|
464
|
+
version: "1.0.0",
|
|
465
|
+
capabilities: ["code-generation"],
|
|
466
|
+
interface: { type: "cli", command: "my-agent-cli" },
|
|
467
|
+
constraints: { maxConcurrent: 2 },
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
async dispatch(task: TaskUnit): Promise<DispatchResult> {
|
|
472
|
+
const correlationId = generateCorrelationId();
|
|
473
|
+
return { correlationId, accepted: true };
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
async poll(correlationId: string): Promise<PollResult> {
|
|
477
|
+
return { correlationId, state: "running" };
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
async cancel(correlationId: string): Promise<void> {}
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
See `src/adapter/codex-adapter.ts` for a complete real-world example.
|
|
485
|
+
|
|
486
|
+
---
|
|
487
|
+
|
|
488
|
+
## Architecture
|
|
489
|
+
|
|
490
|
+
```
|
|
491
|
+
va-agent-protocol/
|
|
492
|
+
├── schemas/ # JSON Schema definitions (THE SPEC)
|
|
493
|
+
│ ├── task-unit.schema.json
|
|
494
|
+
│ ├── agent-capability.schema.json
|
|
495
|
+
│ ├── lifecycle.schema.json
|
|
496
|
+
│ ├── evidence.schema.json
|
|
497
|
+
│ └── message.schema.json
|
|
498
|
+
├── src/
|
|
499
|
+
│ ├── types/ # TypeScript types (mirror schemas)
|
|
500
|
+
│ ├── adapter/ # Agent adapter interface + implementations
|
|
501
|
+
│ │ ├── agent-adapter.ts # The "USB plug shape"
|
|
502
|
+
│ │ ├── codex-adapter.ts # OpenAI Codex CLI adapter
|
|
503
|
+
│ │ └── va-auto-pilot-adapter.ts
|
|
504
|
+
│ ├── orchestrator/ # Dispatch loop + scheduling
|
|
505
|
+
│ │ ├── registry.ts # Agent discovery
|
|
506
|
+
│ │ ├── scheduler.ts # Task → agent matching
|
|
507
|
+
│ │ └── orchestrator.ts # Core loop
|
|
508
|
+
│ └── utils/
|
|
509
|
+
│ └── logger.ts # Configurable logger interface
|
|
510
|
+
├── examples/
|
|
511
|
+
│ └── full-lifecycle.ts # Comprehensive demo
|
|
512
|
+
└── bin/
|
|
513
|
+
└── va-orchestrate.mjs # CLI entry point
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
## Roadmap
|
|
519
|
+
|
|
520
|
+
### v0.2
|
|
521
|
+
|
|
522
|
+
- **MCP Server Adapter** — expose va-agent-protocol as an MCP tool server
|
|
523
|
+
- **Persistence** — SQLite-backed orchestrator state with crash recovery
|
|
524
|
+
- **Push-based progress** — Agent-initiated progress via stdio/WebSocket, replacing polling
|
|
525
|
+
- **Sub-orchestration** — Agents can spawn sub-tasks that feed back into the orchestrator
|
|
526
|
+
- **Web Dashboard** — real-time task visualization and monitoring
|
|
527
|
+
- **Extension points** — `metadata` fields on more schema objects, relaxed `additionalProperties`
|
|
528
|
+
|
|
529
|
+
### v0.3
|
|
530
|
+
|
|
531
|
+
- **REST / gRPC adapter** for non-CLI integrations
|
|
532
|
+
- **Governance** — cost guardrails + permission scoping
|
|
533
|
+
- **A2A bridge** — bidirectional agent discovery and task delegation with Google A2A
|
|
534
|
+
|
|
535
|
+
### Future
|
|
536
|
+
|
|
537
|
+
- **Multi-language SDKs** — Python, Go implementations of the protocol
|
|
538
|
+
- **Distributed orchestration** — Multiple orchestrator instances with shared state
|
|
539
|
+
- **Adapter ecosystem** — Claude Code, Cursor, Aider, and other CLI agent adapters
|
|
540
|
+
- **Agentic AI Foundation** contribution
|
|
541
|
+
|
|
542
|
+
---
|
|
543
|
+
|
|
544
|
+
## v0.1 Known Limitations
|
|
545
|
+
|
|
546
|
+
These are deliberate scope constraints for v0.1, not bugs:
|
|
547
|
+
|
|
548
|
+
- **In-memory state only** — Persistence/recovery is planned for v0.2
|
|
549
|
+
- **Polling-based progress** — Agent-initiated push is planned for v0.2+
|
|
550
|
+
- **Strict schemas** — `additionalProperties: false`; v0.2 will introduce extension points
|
|
551
|
+
- **No sub-orchestration** — v0.2+ feature
|
|
552
|
+
- **Single scheduler heuristic** — Capability matching uses keyword inference; production deployments should provide explicit capability tags
|
|
553
|
+
|
|
554
|
+
---
|
|
555
|
+
|
|
556
|
+
## License
|
|
557
|
+
|
|
558
|
+
MIT
|