@theaiinc/yggdrasil 0.2.0 → 0.2.3
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 +142 -0
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/orchestration-controller.d.ts +4 -1
- package/dist/src/orchestration-controller.d.ts.map +1 -1
- package/dist/src/orchestration-controller.js +191 -31
- package/dist/src/orchestration-controller.js.map +1 -1
- package/dist/src/types/index.d.ts +78 -1
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/index.js +6 -1
- package/dist/src/types/index.js.map +1 -1
- package/package.json +13 -5
package/README.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# @theaiinc/yggdrasil
|
|
2
|
+
|
|
3
|
+
Distributed runner orchestration controller — receives runner registrations and heartbeats, dispatches tasks, and manages a dynamic pool of Ratatoskr agents.
|
|
4
|
+
|
|
5
|
+
Yggdrasil is the control plane for a fleet of runners. Each runner runs a [Ratatoskr](https://www.npmjs.com/package/@theaiinc/yggdrasil-ratatoskr) daemon that registers, heartbeats, and executes tasks. Yggdrasil tracks which runners are alive, assigns tasks to them, and handles lease expiry, updates, and health monitoring.
|
|
6
|
+
|
|
7
|
+
> **Version note**: `@theaiinc/yggdrasil` and `@theaiinc/yggdrasil-ratatoskr` are always released at the same version number.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @theaiinc/yggdrasil
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { Logger } from '@theaiinc/yggdrasil';
|
|
19
|
+
|
|
20
|
+
const logger = new Logger({ level: 'info', format: 'simple', transports: ['console'] });
|
|
21
|
+
logger.info('Yggdrasil ready');
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Running the controller
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx @theaiinc/yggdrasil
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
By default Yggdrasil listens on port 3000. Configure via environment variables:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
PORT=3100 \
|
|
34
|
+
API_KEYS=my-secret-key \
|
|
35
|
+
LEASE_TTL_MS=60000 \
|
|
36
|
+
npx @theaiinc/yggdrasil
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Architecture
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
┌──────────────┐ HTTP (heartbeat, register, tasks) ┌──────────────┐
|
|
43
|
+
│ Ratatoskr │◄─────────────────────────────────────────►│ Yggdrasil │
|
|
44
|
+
│ (runner) │ POST /runners/register │ (controller)│
|
|
45
|
+
│ │ POST /runners/heartbeat │ │
|
|
46
|
+
│ │ POST /runners/task/:id/patch │ │
|
|
47
|
+
└──────────────┘ └──────────────┘
|
|
48
|
+
│ │
|
|
49
|
+
│ Runs agent tasks │ API surface
|
|
50
|
+
│ (sub-agent LLM loop, │ consumed by
|
|
51
|
+
│ shell, file, web tools) │ orchestration layer
|
|
52
|
+
▼ ▼
|
|
53
|
+
Docker / host api-gateway
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## API Endpoints
|
|
57
|
+
|
|
58
|
+
The controller serves these endpoints (consumed by Ratatoskr and pool orchestrators):
|
|
59
|
+
|
|
60
|
+
| Method | Path | Purpose |
|
|
61
|
+
|--------|------|---------|
|
|
62
|
+
| `GET` | `/health` | Health check |
|
|
63
|
+
| `GET` | `/runners` | List all runners |
|
|
64
|
+
| `POST` | `/runners/register` | Register a new runner |
|
|
65
|
+
| `POST` | `/runners/heartbeat` | Runner heartbeat |
|
|
66
|
+
| `POST` | `/runners/update` | Update runner endpoint |
|
|
67
|
+
| `POST` | `/runners/offline` | Deregister a runner (graceful shutdown) |
|
|
68
|
+
| `GET` | `/runners/:id` | Get runner details |
|
|
69
|
+
| `GET` | `/runners/:id/tasks` | List runner tasks |
|
|
70
|
+
| `POST` | `/runners/:id/tasks` | Dispatch a task to a runner |
|
|
71
|
+
| `PATCH` | `/runners/:id/tasks/:tid` | Update task status |
|
|
72
|
+
| `POST` | `/version-check/:version` | Check version compliance |
|
|
73
|
+
| `POST` | `/runners/:id/request-update` | Request runner update |
|
|
74
|
+
| `GET` | `/admission` | Get admission state (circuit breaker) |
|
|
75
|
+
| `GET` | `/metrics` | Prometheus metrics |
|
|
76
|
+
|
|
77
|
+
## Configuration
|
|
78
|
+
|
|
79
|
+
### Controller environment variables
|
|
80
|
+
|
|
81
|
+
| Variable | Default | Description |
|
|
82
|
+
|----------|---------|-------------|
|
|
83
|
+
| `PORT` | `3000` | HTTP listen port |
|
|
84
|
+
| `API_KEYS` | `''` | Comma-separated API keys for runner auth |
|
|
85
|
+
| `LEASE_TTL_MS` | `60000` | Milliseconds before an unresponsive runner is marked offline |
|
|
86
|
+
| `HEARTBEAT_INTERVAL_MS` | `15000` | Expected heartbeat interval (for lease calculation) |
|
|
87
|
+
| `NODE_ENV` | `development` | Environment name |
|
|
88
|
+
| `LOG_LEVEL` | `info` | Log level (error, warn, info, debug) |
|
|
89
|
+
| `LOG_FORMAT` | `simple` | Log format (json, simple) |
|
|
90
|
+
| `EXPECTED_RUNNER_VERSION` | `''` | Expected runner version string (for version compliance checks) |
|
|
91
|
+
| `METRICS_PREFIX` | `yggdrasil_` | Prefix for Prometheus metric names |
|
|
92
|
+
|
|
93
|
+
### Exported types
|
|
94
|
+
|
|
95
|
+
All wire protocol types are exported for consumers:
|
|
96
|
+
|
|
97
|
+
- `RunnerInfo`, `RunnerTask`, `SystemResources`, `PendingUpdate`
|
|
98
|
+
- `RegisterRunnerPayload`, `HeartbeatPayload`, `HeartbeatResponse`, `RequestUpdatePayload`
|
|
99
|
+
- `LogLevel`, `LoggerConfig`
|
|
100
|
+
|
|
101
|
+
### Exported utilities
|
|
102
|
+
|
|
103
|
+
- `Logger` — Structured logger (JSON or simple format, console transport)
|
|
104
|
+
|
|
105
|
+
## Prometheus Metrics
|
|
106
|
+
|
|
107
|
+
Yggdrasil exposes Prometheus metrics at `GET /metrics`:
|
|
108
|
+
|
|
109
|
+
| Metric | Type | Labels | Description |
|
|
110
|
+
|--------|------|--------|-------------|
|
|
111
|
+
| `yggdrasil_runners_registered` | Gauge | — | Number of registered runners |
|
|
112
|
+
| `yggdrasil_runners_offline` | Gauge | — | Number of offline runners |
|
|
113
|
+
| `yggdrasil_runner_info` | Gauge | `runner_id`, `name`, `version`, `status` | Runner metadata |
|
|
114
|
+
| `yggdrasil_runner_uptime_seconds` | Gauge | `runner_id` | Runner uptime |
|
|
115
|
+
| `yggdrasil_runner_cpu_percent` | Gauge | `runner_id` | CPU usage |
|
|
116
|
+
| `yggdrasil_runner_memory_percent` | Gauge | `runner_id` | Memory usage |
|
|
117
|
+
| `yggdrasil_runner_leases` | Gauge | `runner_id` | Lease expiry timestamp |
|
|
118
|
+
| `yggdrasil_runner_tasks_running` | Gauge | `runner_id` | Running task count |
|
|
119
|
+
| `yggdrasil_tasks_dispatched_total` | Counter | — | Total dispatched tasks |
|
|
120
|
+
| `yggdrasil_tasks_completed_total` | Counter | `status` | Total completed tasks |
|
|
121
|
+
|
|
122
|
+
## Lease Management
|
|
123
|
+
|
|
124
|
+
Each runner registration includes a lease TTL. Yggdrasil expects heartbeats before the lease expires. On timeout:
|
|
125
|
+
|
|
126
|
+
1. The runner is marked `offline`
|
|
127
|
+
2. Its tasks transition to `failed`
|
|
128
|
+
3. A configured `RUNNER_OFFLINE_HOOK` can be triggered (if set)
|
|
129
|
+
4. The runner must re-register to come back online
|
|
130
|
+
|
|
131
|
+
## Self-Update Protocol
|
|
132
|
+
|
|
133
|
+
Yggdrasil supports requesting runner version updates:
|
|
134
|
+
|
|
135
|
+
1. Admin calls `POST /runners/:id/request-update` with a version/command
|
|
136
|
+
2. Yggdrasil stores the pending update on the runner's record
|
|
137
|
+
3. On the next heartbeat, Ratatoskr sees `pendingUpdate` and triggers the update
|
|
138
|
+
4. The update runs after all current tasks complete, then the runner restarts
|
|
139
|
+
|
|
140
|
+
## License
|
|
141
|
+
|
|
142
|
+
MIT — © 2026 The AI Inc
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { Logger } from './services/logger.js';
|
|
2
|
-
export type { LogLevel, LoggerConfig, } from './types/index.js';
|
|
2
|
+
export type { LogLevel, LoggerConfig, SystemResources, PendingUpdate, RunnerTask, RunnerInfo, RegisterRunnerPayload, HeartbeatPayload, HeartbeatResponse, RequestUpdatePayload, } from './types/index.js';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAG9C,YAAY,EACV,QAAQ,EACR,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAG9C,YAAY,EACV,QAAQ,EACR,YAAY,EAGZ,eAAe,EACf,aAAa,EACb,UAAU,EACV,UAAU,EAGV,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestration-controller.d.ts","sourceRoot":"","sources":["../../src/orchestration-controller.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"orchestration-controller.d.ts","sourceRoot":"","sources":["../../src/orchestration-controller.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAGV,UAAU,EAMX,MAAM,kBAAkB,CAAC;AAE1B,QAAA,MAAM,GAAG,6CAAY,CAAC;AAGtB,QAAA,MAAM,OAAO,yBAAgC,CAAC;AA6a9C,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -73,7 +73,51 @@ app.get('/metrics', (_req, res) => {
|
|
|
73
73
|
'# HELP yggdrasil_uptime_seconds Server uptime in seconds',
|
|
74
74
|
'# TYPE yggdrasil_uptime_seconds counter',
|
|
75
75
|
`yggdrasil_uptime_seconds ${process.uptime()}`,
|
|
76
|
+
'# HELP yggdrasil_tasks_running Number of currently running tasks across all runners',
|
|
77
|
+
'# TYPE yggdrasil_tasks_running gauge',
|
|
78
|
+
`yggdrasil_tasks_running ${Array.from(runners.values()).reduce((sum, r) => sum + r.tasks.filter(t => t.status === 'running').length, 0)}`,
|
|
76
79
|
];
|
|
80
|
+
// Expected runner version info (exposing the controller's expectation)
|
|
81
|
+
if (EXPECTED_RUNNER_VERSION) {
|
|
82
|
+
metrics.push(`# HELP yggdrasil_expected_runner_version Expected runner version (always 1) — label carries the expected version`);
|
|
83
|
+
metrics.push(`# TYPE yggdrasil_expected_runner_version info`);
|
|
84
|
+
metrics.push(`yggdrasil_expected_runner_version{version="${EXPECTED_RUNNER_VERSION}"} 1`);
|
|
85
|
+
}
|
|
86
|
+
// Per-runner resource metrics
|
|
87
|
+
for (const [id, runner] of runners.entries()) {
|
|
88
|
+
if (runner.resources && runner.status === 'online') {
|
|
89
|
+
const labels = `runner="${id}",name="${runner.name}"`;
|
|
90
|
+
metrics.push(`# HELP yggdrasil_runner_cpu_percent CPU usage percent per runner`);
|
|
91
|
+
metrics.push(`# TYPE yggdrasil_runner_cpu_percent gauge`);
|
|
92
|
+
metrics.push(`yggdrasil_runner_cpu_percent{${labels}} ${runner.resources.cpu.percent}`);
|
|
93
|
+
metrics.push(`# HELP yggdrasil_runner_memory_percent Memory usage percent per runner`);
|
|
94
|
+
metrics.push(`# TYPE yggdrasil_runner_memory_percent gauge`);
|
|
95
|
+
metrics.push(`yggdrasil_runner_memory_percent{${labels}} ${runner.resources.memory.percent}`);
|
|
96
|
+
metrics.push(`# HELP yggdrasil_runner_memory_used_bytes Memory used bytes per runner`);
|
|
97
|
+
metrics.push(`# TYPE yggdrasil_runner_memory_used_bytes gauge`);
|
|
98
|
+
metrics.push(`yggdrasil_runner_memory_used_bytes{${labels}} ${runner.resources.memory.used}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Per-runner version info (one gauge per runner with version label)
|
|
102
|
+
for (const [id, runner] of runners.entries()) {
|
|
103
|
+
const verLabels = `runner="${id}",name="${runner.name}",version="${runner.version}"`;
|
|
104
|
+
metrics.push(`# HELP yggdrasil_runner_version_info Runner version (always 1) — labels carry version`);
|
|
105
|
+
metrics.push(`# TYPE yggdrasil_runner_version_info gauge`);
|
|
106
|
+
metrics.push(`yggdrasil_runner_version_info{${verLabels}} 1`);
|
|
107
|
+
// Outdated flag: 1 if EXPECTED_RUNNER_VERSION is set and runner version differs
|
|
108
|
+
if (EXPECTED_RUNNER_VERSION && runner.version !== EXPECTED_RUNNER_VERSION) {
|
|
109
|
+
const outdatedLabels = `runner="${id}",name="${runner.name}",current="${runner.version}",expected="${EXPECTED_RUNNER_VERSION}"`;
|
|
110
|
+
metrics.push(`# HELP yggdrasil_runner_outdated Outdated runner flag (1 = version mismatch)`);
|
|
111
|
+
metrics.push(`# TYPE yggdrasil_runner_outdated gauge`);
|
|
112
|
+
metrics.push(`yggdrasil_runner_outdated{${outdatedLabels}} 1`);
|
|
113
|
+
}
|
|
114
|
+
if (runner.pendingUpdate) {
|
|
115
|
+
const updLabels = `runner="${id}",name="${runner.name}",current_version="${runner.version}",target_version="${runner.pendingUpdate.version}"`;
|
|
116
|
+
metrics.push(`# HELP yggdrasil_runner_pending_update Pending update flag per runner (1 = update pending)`);
|
|
117
|
+
metrics.push(`# TYPE yggdrasil_runner_pending_update gauge`);
|
|
118
|
+
metrics.push(`yggdrasil_runner_pending_update{${updLabels}} 1`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
77
121
|
res.set('Content-Type', 'text/plain; charset=utf-8');
|
|
78
122
|
res.send(metrics.join('\n') + '\n');
|
|
79
123
|
});
|
|
@@ -81,6 +125,8 @@ app.get('/metrics', (_req, res) => {
|
|
|
81
125
|
app.post('/runners/register', (req, res) => {
|
|
82
126
|
const body = req.body;
|
|
83
127
|
const runnerId = body.runnerId || nanoid();
|
|
128
|
+
// Upsert: preserve existing tasks when re-registering (lease expiry, reconnect)
|
|
129
|
+
const existing = runners.get(runnerId);
|
|
84
130
|
runners.set(runnerId, {
|
|
85
131
|
runnerId,
|
|
86
132
|
name: body.name || 'unknown',
|
|
@@ -90,9 +136,12 @@ app.post('/runners/register', (req, res) => {
|
|
|
90
136
|
labels: body.labels || {},
|
|
91
137
|
lastHeartbeat: new Date(),
|
|
92
138
|
status: 'online',
|
|
139
|
+
...(body.resources ? { resources: body.resources } : {}),
|
|
140
|
+
// Preserve existing tasks on re-registration
|
|
141
|
+
tasks: existing?.tasks ?? body.tasks ?? [],
|
|
93
142
|
});
|
|
94
|
-
logger.info('Runner registered', { runnerId, name: body.name, endpoint: body.endpoint });
|
|
95
|
-
res.status(201).json({ runnerId, status: 'registered' });
|
|
143
|
+
logger.info('Runner registered', { runnerId, name: body.name, endpoint: body.endpoint, reRegistered: !!existing });
|
|
144
|
+
res.status(201).json({ runnerId, status: existing ? 're-registered' : 'registered' });
|
|
96
145
|
});
|
|
97
146
|
app.post('/runners/heartbeat', (req, res) => {
|
|
98
147
|
const body = req.body;
|
|
@@ -104,8 +153,53 @@ app.post('/runners/heartbeat', (req, res) => {
|
|
|
104
153
|
const runner = runners.get(runnerId);
|
|
105
154
|
runner.lastHeartbeat = new Date();
|
|
106
155
|
runner.status = 'online';
|
|
107
|
-
|
|
108
|
-
|
|
156
|
+
if (body.resources) {
|
|
157
|
+
runner.resources = body.resources;
|
|
158
|
+
}
|
|
159
|
+
if (body.tasks) {
|
|
160
|
+
runner.tasks = body.tasks;
|
|
161
|
+
}
|
|
162
|
+
// If there is a pending update, include it in the response and clear it
|
|
163
|
+
const pendingUpdate = runner.pendingUpdate;
|
|
164
|
+
if (pendingUpdate) {
|
|
165
|
+
delete runner.pendingUpdate;
|
|
166
|
+
}
|
|
167
|
+
logger.debug('Runner heartbeat received', { runnerId, hasPendingUpdate: !!pendingUpdate });
|
|
168
|
+
res.json({ status: 'ok', ...(pendingUpdate ? { pendingUpdate } : {}) });
|
|
169
|
+
});
|
|
170
|
+
/**
|
|
171
|
+
* Request an update for a specific runner.
|
|
172
|
+
* The update is stored and delivered on the next heartbeat response.
|
|
173
|
+
* The runner defers execution until all running tasks complete.
|
|
174
|
+
*/
|
|
175
|
+
app.post('/runners/:runnerId/request-update', (req, res) => {
|
|
176
|
+
const runner = runners.get(req.params.runnerId);
|
|
177
|
+
if (!runner) {
|
|
178
|
+
res.status(404).json({ error: 'Runner not found' });
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const body = req.body;
|
|
182
|
+
if (!body.version) {
|
|
183
|
+
res.status(400).json({ error: 'version is required' });
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
runner.pendingUpdate = {
|
|
187
|
+
version: body.version,
|
|
188
|
+
...(body.command !== undefined ? { command: body.command } : {}),
|
|
189
|
+
...(body.downloadUrl !== undefined ? { downloadUrl: body.downloadUrl } : {}),
|
|
190
|
+
...(body.metadata !== undefined ? { metadata: body.metadata } : {}),
|
|
191
|
+
};
|
|
192
|
+
logger.info('Update requested for runner', {
|
|
193
|
+
runnerId: runner.runnerId,
|
|
194
|
+
version: body.version,
|
|
195
|
+
hasCommand: !!body.command,
|
|
196
|
+
hasDownloadUrl: !!body.downloadUrl,
|
|
197
|
+
});
|
|
198
|
+
res.json({
|
|
199
|
+
status: 'update_requested',
|
|
200
|
+
runnerId: runner.runnerId,
|
|
201
|
+
pendingUpdate: runner.pendingUpdate,
|
|
202
|
+
});
|
|
109
203
|
});
|
|
110
204
|
app.post('/runners/update', (req, res) => {
|
|
111
205
|
const body = req.body;
|
|
@@ -131,6 +225,63 @@ app.post('/runners/offline', (req, res) => {
|
|
|
131
225
|
logger.info('Runner went offline', { runnerId });
|
|
132
226
|
res.json({ status: 'offline' });
|
|
133
227
|
});
|
|
228
|
+
// ─── Task management ────────────────────────────────────────────
|
|
229
|
+
app.post('/runners/:runnerId/tasks', (req, res) => {
|
|
230
|
+
const runner = runners.get(req.params.runnerId);
|
|
231
|
+
if (!runner) {
|
|
232
|
+
res.status(404).json({ error: 'Runner not found' });
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const body = req.body;
|
|
236
|
+
const task = {
|
|
237
|
+
taskId: body.taskId || `task-${nanoid(8)}`,
|
|
238
|
+
type: body.type,
|
|
239
|
+
status: body.status || 'running',
|
|
240
|
+
startedAt: Date.now(),
|
|
241
|
+
...(body.correlationId ? { correlationId: body.correlationId } : {}),
|
|
242
|
+
...(body.metadata ? { metadata: body.metadata } : {}),
|
|
243
|
+
};
|
|
244
|
+
runner.tasks.push(task);
|
|
245
|
+
logger.info('Task created on runner', { runnerId: runner.runnerId, taskId: task.taskId, type: task.type });
|
|
246
|
+
res.status(201).json(task);
|
|
247
|
+
});
|
|
248
|
+
app.patch('/runners/:runnerId/tasks/:taskId', (req, res) => {
|
|
249
|
+
const runner = runners.get(req.params.runnerId);
|
|
250
|
+
if (!runner) {
|
|
251
|
+
res.status(404).json({ error: 'Runner not found' });
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const task = runner.tasks.find(t => t.taskId === req.params.taskId);
|
|
255
|
+
if (!task) {
|
|
256
|
+
res.status(404).json({ error: 'Task not found' });
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
const body = req.body;
|
|
260
|
+
if (body.status) {
|
|
261
|
+
task.status = body.status;
|
|
262
|
+
if (body.status === 'completed' || body.status === 'failed') {
|
|
263
|
+
task.completedAt = Date.now();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (body.metadata) {
|
|
267
|
+
task.metadata = { ...task.metadata, ...body.metadata };
|
|
268
|
+
}
|
|
269
|
+
logger.info('Task updated', { runnerId: runner.runnerId, taskId: task.taskId, status: task.status });
|
|
270
|
+
res.json(task);
|
|
271
|
+
});
|
|
272
|
+
app.get('/runners/:runnerId/tasks', (req, res) => {
|
|
273
|
+
const runner = runners.get(req.params.runnerId);
|
|
274
|
+
if (!runner) {
|
|
275
|
+
res.status(404).json({ error: 'Runner not found' });
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
const { status } = req.query;
|
|
279
|
+
let tasks = runner.tasks;
|
|
280
|
+
if (status) {
|
|
281
|
+
tasks = tasks.filter(t => t.status === status);
|
|
282
|
+
}
|
|
283
|
+
res.json({ runnerId: runner.runnerId, tasks, count: tasks.length });
|
|
284
|
+
});
|
|
134
285
|
// ─── Runner queries ─────────────────────────────────────────────
|
|
135
286
|
app.get('/api/runners', (_req, res) => {
|
|
136
287
|
res.json({
|
|
@@ -143,6 +294,8 @@ app.get('/api/runners', (_req, res) => {
|
|
|
143
294
|
labels: r.labels,
|
|
144
295
|
status: r.status,
|
|
145
296
|
lastHeartbeat: r.lastHeartbeat,
|
|
297
|
+
resources: r.resources,
|
|
298
|
+
tasks: r.tasks,
|
|
146
299
|
})),
|
|
147
300
|
count: runners.size,
|
|
148
301
|
});
|
|
@@ -157,35 +310,42 @@ app.get('/api/runners/:runnerId', (req, res) => {
|
|
|
157
310
|
});
|
|
158
311
|
// ─── Lease-based offline detection ──────────────────────────────
|
|
159
312
|
const LEASE_TTL_MS = parseInt(process.env['LEASE_TTL_MS'] || '60000', 10);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
313
|
+
const EXPECTED_RUNNER_VERSION = process.env['EXPECTED_RUNNER_VERSION'] || '';
|
|
314
|
+
if (typeof process.env.VITEST === 'undefined') {
|
|
315
|
+
setInterval(() => {
|
|
316
|
+
const now = Date.now();
|
|
317
|
+
const stale = [];
|
|
318
|
+
for (const [runnerId, runner] of runners.entries()) {
|
|
319
|
+
if (runner.status === 'offline')
|
|
320
|
+
continue;
|
|
321
|
+
const elapsed = now - runner.lastHeartbeat.getTime();
|
|
322
|
+
if (elapsed > LEASE_TTL_MS) {
|
|
323
|
+
stale.push(runnerId);
|
|
324
|
+
}
|
|
169
325
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
326
|
+
for (const runnerId of stale) {
|
|
327
|
+
const runner = runners.get(runnerId);
|
|
328
|
+
runner.status = 'offline';
|
|
329
|
+
logger.warn('Runner marked offline due to heartbeat timeout', {
|
|
330
|
+
runnerId,
|
|
331
|
+
name: runner.name,
|
|
332
|
+
missedBy: `${Math.round((now - runner.lastHeartbeat.getTime()) / 1000)}s`,
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
}, 10_000);
|
|
336
|
+
}
|
|
181
337
|
// ─── Start server ───────────────────────────────────────────────
|
|
182
338
|
const PORT = parseInt(process.env['PORT'] || '3000', 10);
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
339
|
+
// In test mode (vitest), export app/runners without starting the server
|
|
340
|
+
if (typeof process.env.VITEST === 'undefined') {
|
|
341
|
+
app.listen(PORT, '0.0.0.0', () => {
|
|
342
|
+
logger.info('Orchestration controller started (runner-only mode via Ratatoskr)', {
|
|
343
|
+
port: PORT,
|
|
344
|
+
environment: process.env['NODE_ENV'] || 'development',
|
|
345
|
+
apiKeysConfigured: API_KEYS.length > 0,
|
|
346
|
+
leaseTtlMs: LEASE_TTL_MS,
|
|
347
|
+
});
|
|
189
348
|
});
|
|
190
|
-
}
|
|
349
|
+
}
|
|
350
|
+
export { app, runners };
|
|
191
351
|
//# sourceMappingURL=orchestration-controller.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestration-controller.js","sourceRoot":"","sources":["../../src/orchestration-controller.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"orchestration-controller.js","sourceRoot":"","sources":["../../src/orchestration-controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Runtime types for the Yggdrasil orchestration system.
|
|
3
|
+
*
|
|
4
|
+
* These types define the wire protocol between Yggdrasil (the controller)
|
|
5
|
+
* and Ratatoskr (the runner daemon). They are consumed by both the
|
|
6
|
+
* controller itself and by custom pools (like Oasis yggdrasil-pool.ts)
|
|
7
|
+
* that embed the controller API.
|
|
3
8
|
*/
|
|
4
9
|
export type LogLevel = 'error' | 'warn' | 'info' | 'debug';
|
|
5
10
|
export interface LoggerConfig {
|
|
@@ -7,4 +12,76 @@ export interface LoggerConfig {
|
|
|
7
12
|
format: 'json' | 'simple';
|
|
8
13
|
transports: string[];
|
|
9
14
|
}
|
|
15
|
+
export interface SystemResources {
|
|
16
|
+
cpu: {
|
|
17
|
+
load1: number;
|
|
18
|
+
load5: number;
|
|
19
|
+
load15: number;
|
|
20
|
+
cpus: number;
|
|
21
|
+
percent: number;
|
|
22
|
+
};
|
|
23
|
+
memory: {
|
|
24
|
+
total: number;
|
|
25
|
+
used: number;
|
|
26
|
+
free: number;
|
|
27
|
+
percent: number;
|
|
28
|
+
};
|
|
29
|
+
uptime: number;
|
|
30
|
+
}
|
|
31
|
+
export interface PendingUpdate {
|
|
32
|
+
version: string;
|
|
33
|
+
command?: string;
|
|
34
|
+
downloadUrl?: string;
|
|
35
|
+
metadata?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
export interface RunnerTask {
|
|
38
|
+
taskId: string;
|
|
39
|
+
type: string;
|
|
40
|
+
status: 'running' | 'completed' | 'failed';
|
|
41
|
+
startedAt: number;
|
|
42
|
+
completedAt?: number;
|
|
43
|
+
correlationId?: string;
|
|
44
|
+
metadata?: Record<string, unknown>;
|
|
45
|
+
}
|
|
46
|
+
export interface RunnerInfo {
|
|
47
|
+
runnerId: string;
|
|
48
|
+
name: string;
|
|
49
|
+
endpoint: string;
|
|
50
|
+
version: string;
|
|
51
|
+
capabilities: string[];
|
|
52
|
+
labels: Record<string, string>;
|
|
53
|
+
lastHeartbeat: Date;
|
|
54
|
+
status: 'online' | 'offline';
|
|
55
|
+
resources?: SystemResources;
|
|
56
|
+
tasks: RunnerTask[];
|
|
57
|
+
pendingUpdate?: PendingUpdate;
|
|
58
|
+
}
|
|
59
|
+
export interface RegisterRunnerPayload {
|
|
60
|
+
runnerId?: string;
|
|
61
|
+
name?: string;
|
|
62
|
+
endpoint?: string;
|
|
63
|
+
version?: string;
|
|
64
|
+
capabilities?: string[];
|
|
65
|
+
labels?: Record<string, string>;
|
|
66
|
+
metadata?: Record<string, unknown>;
|
|
67
|
+
resources?: SystemResources;
|
|
68
|
+
tasks?: RunnerTask[];
|
|
69
|
+
}
|
|
70
|
+
export interface HeartbeatPayload {
|
|
71
|
+
runnerId?: string;
|
|
72
|
+
timestamp?: number;
|
|
73
|
+
status?: string;
|
|
74
|
+
resources?: SystemResources;
|
|
75
|
+
tasks?: RunnerTask[];
|
|
76
|
+
}
|
|
77
|
+
export interface HeartbeatResponse {
|
|
78
|
+
status: string;
|
|
79
|
+
pendingUpdate?: PendingUpdate;
|
|
80
|
+
}
|
|
81
|
+
export interface RequestUpdatePayload {
|
|
82
|
+
version: string;
|
|
83
|
+
command?: string;
|
|
84
|
+
downloadUrl?: string;
|
|
85
|
+
metadata?: Record<string, unknown>;
|
|
86
|
+
}
|
|
10
87
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"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"}
|
package/dist/src/types/index.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Runtime types for the Yggdrasil orchestration system.
|
|
3
|
+
*
|
|
4
|
+
* These types define the wire protocol between Yggdrasil (the controller)
|
|
5
|
+
* and Ratatoskr (the runner daemon). They are consumed by both the
|
|
6
|
+
* controller itself and by custom pools (like Oasis yggdrasil-pool.ts)
|
|
7
|
+
* that embed the controller API.
|
|
3
8
|
*/
|
|
4
9
|
export {};
|
|
5
10
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
package/package.json
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theaiinc/yggdrasil",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Distributed runner orchestration —
|
|
3
|
+
"version": "0.2.3",
|
|
4
|
+
"description": "Distributed runner orchestration controller — registration, heartbeat, task dispatch, lease management, and Prometheus metrics for Ratatoskr agents",
|
|
5
5
|
"author": "The AI Inc",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "dist/src/index.js",
|
|
9
|
+
"types": "dist/src/index.d.ts",
|
|
9
10
|
"scripts": {
|
|
10
11
|
"build": "tsc -p ./tsconfig.json",
|
|
11
12
|
"dev": "nodemon --exec \"node --loader ts-node/esm src/orchestration-controller.ts\"",
|
|
12
13
|
"start": "node dist/src/orchestration-controller.js",
|
|
13
|
-
"test": "
|
|
14
|
+
"test": "vitest run",
|
|
14
15
|
"lint": "eslint . --ext .ts",
|
|
15
16
|
"prepublishOnly": "npm run build"
|
|
16
17
|
},
|
|
@@ -32,10 +33,12 @@
|
|
|
32
33
|
"@types/cors": "^2.8.17",
|
|
33
34
|
"@types/express": "^4.17.21",
|
|
34
35
|
"@types/node": "^20.17.24",
|
|
36
|
+
"@types/supertest": "^7.2.0",
|
|
35
37
|
"@typescript-eslint/eslint-plugin": "^8.26.1",
|
|
36
38
|
"@typescript-eslint/parser": "^8.26.1",
|
|
37
39
|
"eslint": "^9.22.0",
|
|
38
40
|
"nodemon": "^3.1.0",
|
|
41
|
+
"supertest": "^7.2.2",
|
|
39
42
|
"ts-node": "^10.9.2",
|
|
40
43
|
"typescript": "^5.3.2",
|
|
41
44
|
"vitest": "^3.2.4"
|
|
@@ -45,9 +48,14 @@
|
|
|
45
48
|
},
|
|
46
49
|
"keywords": [
|
|
47
50
|
"ai",
|
|
51
|
+
"agent",
|
|
48
52
|
"orchestration",
|
|
53
|
+
"runner",
|
|
54
|
+
"yggdrasil",
|
|
49
55
|
"ratatoskr",
|
|
50
|
-
"
|
|
51
|
-
"
|
|
56
|
+
"task-dispatch",
|
|
57
|
+
"lease-management",
|
|
58
|
+
"prometheus",
|
|
59
|
+
"distributed-systems"
|
|
52
60
|
]
|
|
53
61
|
}
|