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.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +558 -0
  3. package/bin/va-orchestrate.mjs +153 -0
  4. package/dist/adapter/agent-adapter.d.ts +79 -0
  5. package/dist/adapter/agent-adapter.d.ts.map +1 -0
  6. package/dist/adapter/agent-adapter.js +36 -0
  7. package/dist/adapter/agent-adapter.js.map +1 -0
  8. package/dist/adapter/codex-adapter.d.ts +54 -0
  9. package/dist/adapter/codex-adapter.d.ts.map +1 -0
  10. package/dist/adapter/codex-adapter.js +409 -0
  11. package/dist/adapter/codex-adapter.js.map +1 -0
  12. package/dist/adapter/va-auto-pilot-adapter.d.ts +51 -0
  13. package/dist/adapter/va-auto-pilot-adapter.d.ts.map +1 -0
  14. package/dist/adapter/va-auto-pilot-adapter.js +275 -0
  15. package/dist/adapter/va-auto-pilot-adapter.js.map +1 -0
  16. package/dist/index.d.ts +17 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +15 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/orchestrator/orchestrator.d.ts +101 -0
  21. package/dist/orchestrator/orchestrator.d.ts.map +1 -0
  22. package/dist/orchestrator/orchestrator.js +452 -0
  23. package/dist/orchestrator/orchestrator.js.map +1 -0
  24. package/dist/orchestrator/registry.d.ts +39 -0
  25. package/dist/orchestrator/registry.d.ts.map +1 -0
  26. package/dist/orchestrator/registry.js +62 -0
  27. package/dist/orchestrator/registry.js.map +1 -0
  28. package/dist/orchestrator/scheduler.d.ts +66 -0
  29. package/dist/orchestrator/scheduler.d.ts.map +1 -0
  30. package/dist/orchestrator/scheduler.js +155 -0
  31. package/dist/orchestrator/scheduler.js.map +1 -0
  32. package/dist/test/orchestrator-enqueue.test.d.ts +2 -0
  33. package/dist/test/orchestrator-enqueue.test.d.ts.map +1 -0
  34. package/dist/test/orchestrator-enqueue.test.js +64 -0
  35. package/dist/test/orchestrator-enqueue.test.js.map +1 -0
  36. package/dist/test/orchestrator-lifecycle.test.d.ts +2 -0
  37. package/dist/test/orchestrator-lifecycle.test.d.ts.map +1 -0
  38. package/dist/test/orchestrator-lifecycle.test.js +227 -0
  39. package/dist/test/orchestrator-lifecycle.test.js.map +1 -0
  40. package/dist/test/scheduler.test.d.ts +2 -0
  41. package/dist/test/scheduler.test.d.ts.map +1 -0
  42. package/dist/test/scheduler.test.js +140 -0
  43. package/dist/test/scheduler.test.js.map +1 -0
  44. package/dist/types/index.d.ts +209 -0
  45. package/dist/types/index.d.ts.map +1 -0
  46. package/dist/types/index.js +45 -0
  47. package/dist/types/index.js.map +1 -0
  48. package/dist/utils/logger.d.ts +17 -0
  49. package/dist/utils/logger.d.ts.map +1 -0
  50. package/dist/utils/logger.js +21 -0
  51. package/dist/utils/logger.js.map +1 -0
  52. package/package.json +61 -0
  53. package/schemas/agent-capability.schema.json +99 -0
  54. package/schemas/evidence.schema.json +201 -0
  55. package/schemas/lifecycle.schema.json +80 -0
  56. package/schemas/message.schema.json +181 -0
  57. package/schemas/task-unit.schema.json +137 -0
@@ -0,0 +1,153 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * va-orchestrate — CLI entry point for va-agent-protocol orchestrator.
5
+ *
6
+ * Usage:
7
+ * va-orchestrate dispatch --task <task.json> Dispatch a task from JSON file
8
+ * va-orchestrate status Show active task status
9
+ * va-orchestrate agents List registered agents
10
+ *
11
+ * This is a minimal CLI skeleton for v0.1.
12
+ * The primary interface is the TypeScript API.
13
+ */
14
+
15
+ import { readFileSync } from "node:fs";
16
+ import { resolve } from "node:path";
17
+
18
+ const [, , command, ...rest] = process.argv;
19
+
20
+ function usage() {
21
+ console.log(`va-orchestrate — Universal Agent Task Protocol Orchestrator
22
+
23
+ Usage:
24
+ va-orchestrate dispatch --task <task.json> Dispatch a task
25
+ va-orchestrate status Show running tasks
26
+ va-orchestrate agents List registered agents
27
+ va-orchestrate --help Show this help
28
+
29
+ Protocol: va-agent-protocol v0.1.0`);
30
+ }
31
+
32
+ function parseArgs(args) {
33
+ const opts = {};
34
+ for (let i = 0; i < args.length; i++) {
35
+ if (args[i].startsWith("--") && i + 1 < args.length) {
36
+ opts[args[i].slice(2)] = args[i + 1];
37
+ i++;
38
+ }
39
+ }
40
+ return opts;
41
+ }
42
+
43
+ async function main() {
44
+ if (!command || command === "--help" || command === "-h") {
45
+ usage();
46
+ process.exit(0);
47
+ }
48
+
49
+ // Dynamic import to support ESM build output
50
+ const {
51
+ AgentRegistry,
52
+ Orchestrator,
53
+ VaAutoPilotAdapter,
54
+ } = await import("../dist/index.js");
55
+
56
+ switch (command) {
57
+ case "dispatch": {
58
+ const opts = parseArgs(rest);
59
+ if (!opts.task) {
60
+ console.error("Error: --task <file.json> is required");
61
+ process.exit(1);
62
+ }
63
+
64
+ const taskPath = resolve(opts.task);
65
+ const task = JSON.parse(readFileSync(taskPath, "utf-8"));
66
+
67
+ const registry = new AgentRegistry();
68
+
69
+ // Auto-register va-auto-pilot if in a va-auto-pilot project
70
+ if (opts["project-root"]) {
71
+ const adapter = new VaAutoPilotAdapter({
72
+ projectRoot: resolve(opts["project-root"]),
73
+ });
74
+ registry.register(adapter);
75
+ }
76
+
77
+ const orchestrator = new Orchestrator(registry, {
78
+ onCompleted: (taskId, evidence) => {
79
+ console.log(`\nCompleted: ${taskId}`);
80
+ console.log(JSON.stringify(evidence, null, 2));
81
+ orchestrator.stop();
82
+ },
83
+ onFailed: (taskId, evidence) => {
84
+ console.error(`\nFailed: ${taskId}`);
85
+ console.error(JSON.stringify(evidence, null, 2));
86
+ orchestrator.stop();
87
+ process.exit(1);
88
+ },
89
+ onBlocked: (taskId, reason) => {
90
+ console.log(`\nBlocked: ${taskId} — ${reason}`);
91
+ },
92
+ });
93
+
94
+ const correlationId = await orchestrator.dispatchNow(task);
95
+ if (!correlationId) {
96
+ console.error("Failed to dispatch task. No capable agent found.");
97
+ process.exit(1);
98
+ }
99
+
100
+ console.log(`Dispatched: ${task.id} → correlation: ${correlationId}`);
101
+ console.log("Polling for completion...\n");
102
+ orchestrator.start();
103
+ break;
104
+ }
105
+
106
+ case "agents": {
107
+ const registry = new AgentRegistry();
108
+
109
+ // Register known adapters for discovery
110
+ if (rest.includes("--project-root")) {
111
+ const idx = rest.indexOf("--project-root");
112
+ const adapter = new VaAutoPilotAdapter({
113
+ projectRoot: resolve(rest[idx + 1]),
114
+ });
115
+ registry.register(adapter);
116
+ }
117
+
118
+ const agents = registry.list();
119
+ if (agents.length === 0) {
120
+ console.log("No agents registered. Use --project-root to auto-detect va-auto-pilot.");
121
+ break;
122
+ }
123
+
124
+ for (const agent of agents) {
125
+ const cap = agent.capability;
126
+ console.log(`${cap.agentId}`);
127
+ console.log(` Name: ${cap.name} v${cap.version}`);
128
+ console.log(` Capabilities: ${cap.capabilities.join(", ")}`);
129
+ console.log(` Model: ${cap.modelRequirement ?? "any"}`);
130
+ console.log(` Interface: ${cap.interface.type} — ${cap.interface.command}`);
131
+ console.log(` Concurrency: ${cap.constraints?.maxConcurrent ?? 1}`);
132
+ console.log();
133
+ }
134
+ break;
135
+ }
136
+
137
+ case "status": {
138
+ console.log("Status tracking requires a running orchestrator instance.");
139
+ console.log("Use the TypeScript API for persistent orchestration.");
140
+ break;
141
+ }
142
+
143
+ default:
144
+ console.error(`Unknown command: ${command}`);
145
+ usage();
146
+ process.exit(1);
147
+ }
148
+ }
149
+
150
+ main().catch((err) => {
151
+ console.error(err);
152
+ process.exit(1);
153
+ });
@@ -0,0 +1,79 @@
1
+ /**
2
+ * AgentAdapter — the universal interface that any CLI agent must implement.
3
+ *
4
+ * This is the "USB plug shape". If your agent can implement these methods,
5
+ * the orchestrator can dispatch tasks to it.
6
+ *
7
+ * Design principles:
8
+ * - CLI-first: adapters invoke agents via subprocess, not library import
9
+ * - Evidence-based: completion requires proof, not self-certification
10
+ * - Polling model (v0.1): orchestrator polls for progress. Future versions
11
+ * may add push/streaming via stdio or webhooks.
12
+ */
13
+ import type { AgentCapability, TaskUnit, Evidence, ProgressPayload, TaskState } from "../types/index.js";
14
+ export interface DispatchResult {
15
+ correlationId: string;
16
+ accepted: boolean;
17
+ reason?: string;
18
+ }
19
+ export interface PollResult {
20
+ correlationId: string;
21
+ state: TaskState;
22
+ progress?: ProgressPayload;
23
+ evidence?: Evidence;
24
+ }
25
+ /**
26
+ * Abstract adapter interface. Implement this to wrap any CLI agent.
27
+ */
28
+ export interface AgentAdapter {
29
+ /** Unique identifier for this adapter instance. */
30
+ readonly id: string;
31
+ /** Declare what this agent can do. */
32
+ capabilities(): AgentCapability;
33
+ /**
34
+ * Dispatch a task to this agent.
35
+ * Returns immediately with a correlation ID.
36
+ * The agent begins execution asynchronously.
37
+ */
38
+ dispatch(task: TaskUnit): Promise<DispatchResult>;
39
+ /**
40
+ * Poll the current state of a dispatched task.
41
+ * Returns the latest state + any progress info + evidence if terminal.
42
+ */
43
+ poll(correlationId: string): Promise<PollResult>;
44
+ /**
45
+ * Request cancellation of a running task.
46
+ * Best-effort: agent may not cancel immediately.
47
+ */
48
+ cancel(correlationId: string): Promise<void>;
49
+ /**
50
+ * Notify the agent that a blocked task has been unblocked.
51
+ * Optional — not all agents support external unblock signals.
52
+ * If implemented, the adapter should transition the task so subsequent
53
+ * polls reflect the resumed state.
54
+ */
55
+ unblock?(correlationId: string, resolution?: string): Promise<void>;
56
+ /**
57
+ * Clean up resources. Called when the adapter is being shut down.
58
+ */
59
+ dispose?(): Promise<void>;
60
+ }
61
+ /**
62
+ * Base class with shared utility methods for adapter implementations.
63
+ */
64
+ export declare abstract class BaseAdapter implements AgentAdapter {
65
+ abstract readonly id: string;
66
+ abstract capabilities(): AgentCapability;
67
+ abstract dispatch(task: TaskUnit): Promise<DispatchResult>;
68
+ abstract poll(correlationId: string): Promise<PollResult>;
69
+ abstract cancel(correlationId: string): Promise<void>;
70
+ /** Track active executions: correlationId -> state */
71
+ protected executions: Map<string, {
72
+ taskId: string;
73
+ state: TaskState;
74
+ startedAt: string;
75
+ }>;
76
+ protected setExecution(correlationId: string, taskId: string, state: TaskState): void;
77
+ dispose(): Promise<void>;
78
+ }
79
+ //# sourceMappingURL=agent-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/agent-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,SAAS,EACV,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,sCAAsC;IACtC,YAAY,IAAI,eAAe,CAAC;IAEhC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAElD;;;OAGG;IACH,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAEjD;;;OAGG;IACH,MAAM,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C;;;;;OAKG;IACH,OAAO,CAAC,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpE;;OAEG;IACH,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;GAEG;AACH,8BAAsB,WAAY,YAAW,YAAY;IACvD,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,IAAI,eAAe;IACxC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC;IAC1D,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IACzD,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAErD,sDAAsD;IACtD,SAAS,CAAC,UAAU;gBAER,MAAM;eAAS,SAAS;mBAAa,MAAM;OACnD;IAEJ,SAAS,CAAC,YAAY,CACpB,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,GACf,IAAI;IAaD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/B"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * AgentAdapter — the universal interface that any CLI agent must implement.
3
+ *
4
+ * This is the "USB plug shape". If your agent can implement these methods,
5
+ * the orchestrator can dispatch tasks to it.
6
+ *
7
+ * Design principles:
8
+ * - CLI-first: adapters invoke agents via subprocess, not library import
9
+ * - Evidence-based: completion requires proof, not self-certification
10
+ * - Polling model (v0.1): orchestrator polls for progress. Future versions
11
+ * may add push/streaming via stdio or webhooks.
12
+ */
13
+ /**
14
+ * Base class with shared utility methods for adapter implementations.
15
+ */
16
+ export class BaseAdapter {
17
+ /** Track active executions: correlationId -> state */
18
+ executions = new Map();
19
+ setExecution(correlationId, taskId, state) {
20
+ const existing = this.executions.get(correlationId);
21
+ if (existing) {
22
+ existing.state = state;
23
+ }
24
+ else {
25
+ this.executions.set(correlationId, {
26
+ taskId,
27
+ state,
28
+ startedAt: new Date().toISOString(),
29
+ });
30
+ }
31
+ }
32
+ async dispose() {
33
+ this.executions.clear();
34
+ }
35
+ }
36
+ //# sourceMappingURL=agent-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-adapter.js","sourceRoot":"","sources":["../../src/adapter/agent-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAkEH;;GAEG;AACH,MAAM,OAAgB,WAAW;IAO/B,sDAAsD;IAC5C,UAAU,GAAG,IAAI,GAAG,EAG3B,CAAC;IAEM,YAAY,CACpB,aAAqB,EACrB,MAAc,EACd,KAAgB;QAEhB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACpD,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,EAAE;gBACjC,MAAM;gBACN,KAAK;gBACL,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * CodexAdapter — wraps OpenAI Codex CLI as a protocol-compliant agent.
3
+ *
4
+ * This is a REAL adapter (not simulated). It spawns actual `codex` processes
5
+ * and collects real evidence from their execution.
6
+ *
7
+ * Key design:
8
+ * - `dispatch()` → spawns `codex exec --full-auto` as a child process
9
+ * - `poll()` → checks process exit status, reads stdout/stderr as progress
10
+ * - `cancel()` → sends SIGTERM to the process
11
+ * - Quality gates run after codex completes (typecheck, codex review)
12
+ */
13
+ import type { AgentCapability, TaskUnit } from "../types/index.js";
14
+ import type { Logger } from "../utils/logger.js";
15
+ import type { DispatchResult, PollResult } from "./agent-adapter.js";
16
+ import { BaseAdapter } from "./agent-adapter.js";
17
+ export interface CodexAdapterOptions {
18
+ /** Working directory for codex execution. */
19
+ workingDirectory: string;
20
+ /** Path to the codex binary. Defaults to 'codex'. */
21
+ codexPath?: string;
22
+ /** Model to use. Defaults to codex CLI default. */
23
+ model?: string;
24
+ /** Timeout per task in ms. Defaults to 120000 (2 min). */
25
+ taskTimeoutMs?: number;
26
+ /** Quality gate commands to run after codex completes. Each is a shell command. */
27
+ qualityGates?: string[];
28
+ /** Whether to run `codex review --uncommitted` as a gate. Defaults to true. */
29
+ enableCodexReview?: boolean;
30
+ /** Logger instance. Defaults to console-based logger. */
31
+ logger?: Logger;
32
+ }
33
+ export declare class CodexAdapter extends BaseAdapter {
34
+ readonly id: string;
35
+ private readonly workingDirectory;
36
+ private readonly codexPath;
37
+ private readonly model?;
38
+ private readonly taskTimeoutMs;
39
+ private readonly qualityGates;
40
+ private readonly enableCodexReview;
41
+ private readonly log;
42
+ private codexExecutions;
43
+ constructor(options: CodexAdapterOptions);
44
+ capabilities(): AgentCapability;
45
+ dispatch(task: TaskUnit): Promise<DispatchResult>;
46
+ poll(correlationId: string): Promise<PollResult>;
47
+ cancel(correlationId: string): Promise<void>;
48
+ dispose(): Promise<void>;
49
+ private buildPrompt;
50
+ private runQualityGates;
51
+ private gateNameFromCommand;
52
+ private extractFailureHypothesis;
53
+ }
54
+ //# sourceMappingURL=codex-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/codex-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,OAAO,KAAK,EACV,eAAe,EACf,QAAQ,EAGT,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAIjD,MAAM,WAAW,mBAAmB;IAClC,6CAA6C;IAC7C,gBAAgB,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,+EAA+E;IAC/E,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAeD,qBAAa,YAAa,SAAQ,WAAW;IAC3C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAW;IACxC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAU;IAC5C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,eAAe,CAAqC;gBAEhD,OAAO,EAAE,mBAAmB;IAYxC,YAAY,IAAI,eAAe;IAyBzB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC;IAmEjD,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAyJhD,MAAM,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAanC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAavC,OAAO,CAAC,WAAW;YA0CL,eAAe;IAyF7B,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,wBAAwB;CAgBjC"}