@neotx/core 0.1.0-alpha.14 → 0.1.0-alpha.19
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/README.md +83 -39
- package/dist/index.d.ts +391 -96
- package/dist/index.js +1786 -729
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -5,9 +5,9 @@ Orchestration engine for autonomous developer agents. This is the programmatic A
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @neotx/core
|
|
9
|
-
# or
|
|
10
8
|
pnpm add @neotx/core
|
|
9
|
+
# or
|
|
10
|
+
npm install @neotx/core
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
Requires Node.js >= 22 and the [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) installed and authenticated.
|
|
@@ -15,9 +15,9 @@ Requires Node.js >= 22 and the [Claude Code CLI](https://docs.anthropic.com/en/d
|
|
|
15
15
|
## Quick Start
|
|
16
16
|
|
|
17
17
|
```typescript
|
|
18
|
-
import { AgentRegistry,
|
|
18
|
+
import { AgentRegistry, loadGlobalConfig, Orchestrator } from "@neotx/core";
|
|
19
19
|
|
|
20
|
-
const config = await
|
|
20
|
+
const config = await loadGlobalConfig();
|
|
21
21
|
|
|
22
22
|
const orchestrator = new Orchestrator(config, {
|
|
23
23
|
journalDir: ".neo/journals",
|
|
@@ -34,21 +34,12 @@ for (const agent of registry.list()) {
|
|
|
34
34
|
orchestrator.registerAgent(agent);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
// Register a workflow
|
|
38
|
-
orchestrator.registerWorkflow({
|
|
39
|
-
name: "implement",
|
|
40
|
-
steps: {
|
|
41
|
-
code: { agent: "developer" },
|
|
42
|
-
review: { agent: "reviewer-quality", dependsOn: ["code"] },
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
|
|
46
37
|
// Start the orchestrator
|
|
47
38
|
await orchestrator.start();
|
|
48
39
|
|
|
49
40
|
// Dispatch a task
|
|
50
41
|
const result = await orchestrator.dispatch({
|
|
51
|
-
|
|
42
|
+
agent: "developer",
|
|
52
43
|
repo: "/path/to/repo",
|
|
53
44
|
prompt: "Add rate limiting to the API",
|
|
54
45
|
priority: "high",
|
|
@@ -87,8 +78,6 @@ import { Orchestrator } from "@neotx/core";
|
|
|
87
78
|
const orchestrator = new Orchestrator(config, {
|
|
88
79
|
middleware: [...], // Optional middleware array
|
|
89
80
|
journalDir: ".neo/journals", // Directory for JSONL journals
|
|
90
|
-
builtInWorkflowDir: "...", // Path to built-in workflow YAML files
|
|
91
|
-
customWorkflowDir: "...", // Path to custom workflow YAML files
|
|
92
81
|
});
|
|
93
82
|
```
|
|
94
83
|
|
|
@@ -122,27 +111,17 @@ orchestrator.registerAgent({
|
|
|
122
111
|
sandbox: "writable",
|
|
123
112
|
source: "built-in",
|
|
124
113
|
});
|
|
125
|
-
|
|
126
|
-
// Register a workflow
|
|
127
|
-
orchestrator.registerWorkflow({
|
|
128
|
-
name: "implement",
|
|
129
|
-
steps: {
|
|
130
|
-
code: { agent: "developer" },
|
|
131
|
-
review: { agent: "reviewer-quality", dependsOn: ["code"] },
|
|
132
|
-
},
|
|
133
|
-
});
|
|
134
114
|
```
|
|
135
115
|
|
|
136
116
|
#### Dispatch
|
|
137
117
|
|
|
138
118
|
```typescript
|
|
139
119
|
const result = await orchestrator.dispatch({
|
|
140
|
-
|
|
120
|
+
agent: "developer", // Agent name (required)
|
|
141
121
|
repo: "/path/to/repo", // Repository path (required)
|
|
142
122
|
prompt: "Add feature X", // Task prompt (required)
|
|
143
123
|
runId: "custom-id", // Optional custom run ID
|
|
144
124
|
priority: "high", // "critical" | "high" | "medium" | "low"
|
|
145
|
-
step: "review", // Start from a specific step
|
|
146
125
|
metadata: { ticket: "123" }, // Arbitrary metadata (passed through events)
|
|
147
126
|
});
|
|
148
127
|
```
|
|
@@ -152,10 +131,9 @@ Returns a `TaskResult`:
|
|
|
152
131
|
```typescript
|
|
153
132
|
interface TaskResult {
|
|
154
133
|
runId: string;
|
|
155
|
-
|
|
134
|
+
agent: string;
|
|
156
135
|
repo: string;
|
|
157
136
|
status: "success" | "failure" | "timeout" | "cancelled";
|
|
158
|
-
steps: Record<string, StepResult>;
|
|
159
137
|
branch?: string;
|
|
160
138
|
costUsd: number;
|
|
161
139
|
durationMs: number;
|
|
@@ -179,7 +157,7 @@ const status = orchestrator.status;
|
|
|
179
157
|
// }
|
|
180
158
|
|
|
181
159
|
const sessions = orchestrator.activeSessions;
|
|
182
|
-
// [{ sessionId, runId,
|
|
160
|
+
// [{ sessionId, runId, agent, repo, status, startedAt }]
|
|
183
161
|
```
|
|
184
162
|
|
|
185
163
|
### `AgentRegistry`
|
|
@@ -217,7 +195,7 @@ The orchestrator emits typed events for real-time monitoring:
|
|
|
217
195
|
|
|
218
196
|
```typescript
|
|
219
197
|
orchestrator.on("session:start", (event) => {
|
|
220
|
-
// { type, sessionId, runId,
|
|
198
|
+
// { type, sessionId, runId, agent, repo, metadata, timestamp }
|
|
221
199
|
});
|
|
222
200
|
|
|
223
201
|
orchestrator.on("session:complete", (event) => {
|
|
@@ -293,7 +271,7 @@ const customMiddleware: Middleware = {
|
|
|
293
271
|
match: "Bash", // Optional: only match specific tools
|
|
294
272
|
async handler(event, context) {
|
|
295
273
|
// event: { hookEvent, sessionId, toolName, input, output, message }
|
|
296
|
-
// context: { runId,
|
|
274
|
+
// context: { runId, agent, repo, get, set }
|
|
297
275
|
|
|
298
276
|
const costToday = context.get("costToday");
|
|
299
277
|
|
|
@@ -421,8 +399,6 @@ const journal = new CostJournal({ dir: ".neo/journals" });
|
|
|
421
399
|
await journal.append({
|
|
422
400
|
timestamp: new Date().toISOString(),
|
|
423
401
|
runId: "...",
|
|
424
|
-
workflow: "implement",
|
|
425
|
-
step: "code",
|
|
426
402
|
sessionId: "...",
|
|
427
403
|
agent: "developer",
|
|
428
404
|
costUsd: 0.0842,
|
|
@@ -450,7 +426,7 @@ repos:
|
|
|
450
426
|
defaultBranch: main
|
|
451
427
|
branchPrefix: feat
|
|
452
428
|
pushRemote: origin
|
|
453
|
-
|
|
429
|
+
gitStrategy: branch # or "pr"
|
|
454
430
|
|
|
455
431
|
concurrency:
|
|
456
432
|
maxSessions: 5
|
|
@@ -482,6 +458,19 @@ mcpServers:
|
|
|
482
458
|
headers:
|
|
483
459
|
Authorization: "Bearer ${LINEAR_API_KEY}"
|
|
484
460
|
|
|
461
|
+
supervisor:
|
|
462
|
+
port: 7777
|
|
463
|
+
heartbeatTimeoutMs: 300000
|
|
464
|
+
maxConsecutiveFailures: 3
|
|
465
|
+
maxEventsPerSec: 10
|
|
466
|
+
dailyCapUsd: 50
|
|
467
|
+
consolidationIntervalMs: 300000
|
|
468
|
+
compactionIntervalMs: 3600000
|
|
469
|
+
eventTimeoutMs: 300000
|
|
470
|
+
|
|
471
|
+
memory:
|
|
472
|
+
embeddings: true # Enable local vector embeddings
|
|
473
|
+
|
|
485
474
|
idempotency:
|
|
486
475
|
enabled: true
|
|
487
476
|
key: metadata # or "prompt"
|
|
@@ -511,6 +500,65 @@ await removeRepoFromGlobalConfig("/path/to/repo");
|
|
|
511
500
|
const repos = await listReposFromGlobalConfig();
|
|
512
501
|
```
|
|
513
502
|
|
|
503
|
+
## Supervisor Daemon
|
|
504
|
+
|
|
505
|
+
The supervisor daemon runs as a long-lived process that monitors orchestrator health, processes events, and maintains memory.
|
|
506
|
+
|
|
507
|
+
```typescript
|
|
508
|
+
import { SupervisorDaemon, loadGlobalConfig } from "@neotx/core";
|
|
509
|
+
|
|
510
|
+
const config = await loadGlobalConfig();
|
|
511
|
+
|
|
512
|
+
const daemon = new SupervisorDaemon({
|
|
513
|
+
name: "supervisor",
|
|
514
|
+
config,
|
|
515
|
+
defaultInstructionsPath: "path/to/SUPERVISOR.md",
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
await daemon.start(); // Blocks until stopped
|
|
519
|
+
await daemon.stop();
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
Components:
|
|
523
|
+
- **WebhookServer** — receives events from orchestrator instances
|
|
524
|
+
- **EventQueue** — rate-limited event processing with disk replay
|
|
525
|
+
- **HeartbeatLoop** — periodic health checks and consolidation
|
|
526
|
+
- **ActivityLog** — structured logging of supervisor actions
|
|
527
|
+
|
|
528
|
+
## Memory Store
|
|
529
|
+
|
|
530
|
+
Persistent memory with full-text search (FTS5) and optional vector search (sqlite-vec).
|
|
531
|
+
|
|
532
|
+
```typescript
|
|
533
|
+
import { MemoryStore } from "@neotx/core";
|
|
534
|
+
|
|
535
|
+
const store = new MemoryStore("path/to/memory.sqlite");
|
|
536
|
+
|
|
537
|
+
// Write a memory
|
|
538
|
+
await store.write({
|
|
539
|
+
type: "fact", // "fact" | "procedure" | "episode" | "focus" | "feedback" | "task"
|
|
540
|
+
scope: "/path/to/repo", // or "global"
|
|
541
|
+
content: "CI requires pnpm build before push",
|
|
542
|
+
source: "developer",
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
// Query by type and scope
|
|
546
|
+
const memories = store.query({
|
|
547
|
+
scope: "/path/to/repo",
|
|
548
|
+
types: ["fact", "procedure"],
|
|
549
|
+
limit: 25,
|
|
550
|
+
sortBy: "relevance", // "relevance" | "createdAt" | "accessCount"
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
// Semantic search (uses local embeddings via transformers.js)
|
|
554
|
+
const results = await store.search("CI pipeline", { scope: "/path/to/repo" });
|
|
555
|
+
|
|
556
|
+
// Lifecycle
|
|
557
|
+
store.decay(30, 3); // Remove stale low-access memories
|
|
558
|
+
store.expireEphemeral(); // Remove expired focus entries
|
|
559
|
+
store.close();
|
|
560
|
+
```
|
|
561
|
+
|
|
514
562
|
## Types
|
|
515
563
|
|
|
516
564
|
Key types exported from the package:
|
|
@@ -527,10 +575,6 @@ import type {
|
|
|
527
575
|
AgentConfig,
|
|
528
576
|
AgentDefinition,
|
|
529
577
|
|
|
530
|
-
// Workflows
|
|
531
|
-
WorkflowDefinition,
|
|
532
|
-
WorkflowStepDef,
|
|
533
|
-
|
|
534
578
|
// Dispatch
|
|
535
579
|
DispatchInput,
|
|
536
580
|
TaskResult,
|