@darkiceinteractive/mcp-conductor 1.1.0 → 3.0.0-beta.1
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 +35 -5
- package/dist/bin/cli.d.ts +20 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +260 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/bridge/http-server.d.ts +65 -1
- package/dist/bridge/http-server.d.ts.map +1 -1
- package/dist/bridge/http-server.js +192 -7
- package/dist/bridge/http-server.js.map +1 -1
- package/dist/bridge/index.d.ts +1 -0
- package/dist/bridge/index.d.ts.map +1 -1
- package/dist/bridge/index.js +1 -0
- package/dist/bridge/index.js.map +1 -1
- package/dist/bridge/pool.d.ts +95 -0
- package/dist/bridge/pool.d.ts.map +1 -0
- package/dist/bridge/pool.js +384 -0
- package/dist/bridge/pool.js.map +1 -0
- package/dist/bridge/session-registry.d.ts +64 -0
- package/dist/bridge/session-registry.d.ts.map +1 -0
- package/dist/bridge/session-registry.js +124 -0
- package/dist/bridge/session-registry.js.map +1 -0
- package/dist/cache/cache.d.ts +43 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +167 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/delta.d.ts +32 -0
- package/dist/cache/delta.d.ts.map +1 -0
- package/dist/cache/delta.js +131 -0
- package/dist/cache/delta.js.map +1 -0
- package/dist/cache/disk.d.ts +65 -0
- package/dist/cache/disk.d.ts.map +1 -0
- package/dist/cache/disk.js +238 -0
- package/dist/cache/disk.js.map +1 -0
- package/dist/cache/index.d.ts +53 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +12 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/key.d.ts +44 -0
- package/dist/cache/key.d.ts.map +1 -0
- package/dist/cache/key.js +83 -0
- package/dist/cache/key.js.map +1 -0
- package/dist/cache/lru.d.ts +57 -0
- package/dist/cache/lru.d.ts.map +1 -0
- package/dist/cache/lru.js +112 -0
- package/dist/cache/lru.js.map +1 -0
- package/dist/cache/policy.d.ts +34 -0
- package/dist/cache/policy.d.ts.map +1 -0
- package/dist/cache/policy.js +95 -0
- package/dist/cache/policy.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +33 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +135 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/export-servers.d.ts +22 -0
- package/dist/cli/commands/export-servers.d.ts.map +1 -0
- package/dist/cli/commands/export-servers.js +45 -0
- package/dist/cli/commands/export-servers.js.map +1 -0
- package/dist/cli/commands/import-servers.d.ts +57 -0
- package/dist/cli/commands/import-servers.d.ts.map +1 -0
- package/dist/cli/commands/import-servers.js +137 -0
- package/dist/cli/commands/import-servers.js.map +1 -0
- package/dist/cli/commands/routing.d.ts +34 -0
- package/dist/cli/commands/routing.d.ts.map +1 -0
- package/dist/cli/commands/routing.js +60 -0
- package/dist/cli/commands/routing.js.map +1 -0
- package/dist/cli/commands/test-server.d.ts +34 -0
- package/dist/cli/commands/test-server.d.ts.map +1 -0
- package/dist/cli/commands/test-server.js +86 -0
- package/dist/cli/commands/test-server.js.map +1 -0
- package/dist/cli/daemon.d.ts +60 -0
- package/dist/cli/daemon.d.ts.map +1 -0
- package/dist/cli/daemon.js +244 -0
- package/dist/cli/daemon.js.map +1 -0
- package/dist/cli/replay.d.ts +16 -0
- package/dist/cli/replay.d.ts.map +1 -0
- package/dist/cli/replay.js +89 -0
- package/dist/cli/replay.js.map +1 -0
- package/dist/cli/wizard/setup.d.ts +12 -0
- package/dist/cli/wizard/setup.d.ts.map +1 -0
- package/dist/cli/wizard/setup.js +71 -0
- package/dist/cli/wizard/setup.js.map +1 -0
- package/dist/config/defaults.d.ts +10 -0
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +14 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/schema.d.ts +34 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/daemon/client.d.ts +97 -0
- package/dist/daemon/client.d.ts.map +1 -0
- package/dist/daemon/client.js +279 -0
- package/dist/daemon/client.js.map +1 -0
- package/dist/daemon/discovery.d.ts +50 -0
- package/dist/daemon/discovery.d.ts.map +1 -0
- package/dist/daemon/discovery.js +104 -0
- package/dist/daemon/discovery.js.map +1 -0
- package/dist/daemon/index.d.ts +16 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +11 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/sandbox-api.d.ts +45 -0
- package/dist/daemon/sandbox-api.d.ts.map +1 -0
- package/dist/daemon/sandbox-api.js +74 -0
- package/dist/daemon/sandbox-api.js.map +1 -0
- package/dist/daemon/server.d.ts +65 -0
- package/dist/daemon/server.d.ts.map +1 -0
- package/dist/daemon/server.js +351 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/daemon/shared-kv.d.ts +81 -0
- package/dist/daemon/shared-kv.d.ts.map +1 -0
- package/dist/daemon/shared-kv.js +215 -0
- package/dist/daemon/shared-kv.js.map +1 -0
- package/dist/daemon/shared-lock.d.ts +71 -0
- package/dist/daemon/shared-lock.d.ts.map +1 -0
- package/dist/daemon/shared-lock.js +119 -0
- package/dist/daemon/shared-lock.js.map +1 -0
- package/dist/hub/mcp-hub.d.ts +23 -0
- package/dist/hub/mcp-hub.d.ts.map +1 -1
- package/dist/hub/mcp-hub.js +34 -1
- package/dist/hub/mcp-hub.js.map +1 -1
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -1
- package/dist/observability/anomaly.d.ts +67 -0
- package/dist/observability/anomaly.d.ts.map +1 -0
- package/dist/observability/anomaly.js +141 -0
- package/dist/observability/anomaly.js.map +1 -0
- package/dist/observability/cost-predictor.d.ts +49 -0
- package/dist/observability/cost-predictor.d.ts.map +1 -0
- package/dist/observability/cost-predictor.js +145 -0
- package/dist/observability/cost-predictor.js.map +1 -0
- package/dist/observability/hot-path.d.ts +49 -0
- package/dist/observability/hot-path.d.ts.map +1 -0
- package/dist/observability/hot-path.js +125 -0
- package/dist/observability/hot-path.js.map +1 -0
- package/dist/observability/index.d.ts +10 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +10 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/replay.d.ts +104 -0
- package/dist/observability/replay.d.ts.map +1 -0
- package/dist/observability/replay.js +239 -0
- package/dist/observability/replay.js.map +1 -0
- package/dist/registry/built-in-recommendations.d.ts +54 -0
- package/dist/registry/built-in-recommendations.d.ts.map +1 -0
- package/dist/registry/built-in-recommendations.js +65 -0
- package/dist/registry/built-in-recommendations.js.map +1 -0
- package/dist/registry/events.d.ts +26 -0
- package/dist/registry/events.d.ts.map +1 -0
- package/dist/registry/events.js +22 -0
- package/dist/registry/events.js.map +1 -0
- package/dist/registry/index.d.ts +159 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +12 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/registry.d.ts +87 -0
- package/dist/registry/registry.d.ts.map +1 -0
- package/dist/registry/registry.js +294 -0
- package/dist/registry/registry.js.map +1 -0
- package/dist/registry/snapshot.d.ts +42 -0
- package/dist/registry/snapshot.d.ts.map +1 -0
- package/dist/registry/snapshot.js +71 -0
- package/dist/registry/snapshot.js.map +1 -0
- package/dist/registry/typegen.d.ts +48 -0
- package/dist/registry/typegen.d.ts.map +1 -0
- package/dist/registry/typegen.js +200 -0
- package/dist/registry/typegen.js.map +1 -0
- package/dist/registry/validator.d.ts +23 -0
- package/dist/registry/validator.d.ts.map +1 -0
- package/dist/registry/validator.js +50 -0
- package/dist/registry/validator.js.map +1 -0
- package/dist/reliability/breaker.d.ts +57 -0
- package/dist/reliability/breaker.d.ts.map +1 -0
- package/dist/reliability/breaker.js +130 -0
- package/dist/reliability/breaker.js.map +1 -0
- package/dist/reliability/errors.d.ts +78 -0
- package/dist/reliability/errors.d.ts.map +1 -0
- package/dist/reliability/errors.js +160 -0
- package/dist/reliability/errors.js.map +1 -0
- package/dist/reliability/gateway.d.ts +88 -0
- package/dist/reliability/gateway.d.ts.map +1 -0
- package/dist/reliability/gateway.js +180 -0
- package/dist/reliability/gateway.js.map +1 -0
- package/dist/reliability/index.d.ts +20 -0
- package/dist/reliability/index.d.ts.map +1 -0
- package/dist/reliability/index.js +16 -0
- package/dist/reliability/index.js.map +1 -0
- package/dist/reliability/profile.d.ts +49 -0
- package/dist/reliability/profile.d.ts.map +1 -0
- package/dist/reliability/profile.js +58 -0
- package/dist/reliability/profile.js.map +1 -0
- package/dist/reliability/retry.d.ts +39 -0
- package/dist/reliability/retry.d.ts.map +1 -0
- package/dist/reliability/retry.js +51 -0
- package/dist/reliability/retry.js.map +1 -0
- package/dist/reliability/timeout.d.ts +34 -0
- package/dist/reliability/timeout.d.ts.map +1 -0
- package/dist/reliability/timeout.js +53 -0
- package/dist/reliability/timeout.js.map +1 -0
- package/dist/runtime/executor.d.ts +12 -0
- package/dist/runtime/executor.d.ts.map +1 -1
- package/dist/runtime/executor.js +148 -16
- package/dist/runtime/executor.js.map +1 -1
- package/dist/runtime/findtool/embed.d.ts +28 -0
- package/dist/runtime/findtool/embed.d.ts.map +1 -0
- package/dist/runtime/findtool/embed.js +85 -0
- package/dist/runtime/findtool/embed.js.map +1 -0
- package/dist/runtime/findtool/index.d.ts +52 -0
- package/dist/runtime/findtool/index.d.ts.map +1 -0
- package/dist/runtime/findtool/index.js +78 -0
- package/dist/runtime/findtool/index.js.map +1 -0
- package/dist/runtime/findtool/vector-index.d.ts +53 -0
- package/dist/runtime/findtool/vector-index.d.ts.map +1 -0
- package/dist/runtime/findtool/vector-index.js +71 -0
- package/dist/runtime/findtool/vector-index.js.map +1 -0
- package/dist/runtime/helpers/budget.d.ts +27 -0
- package/dist/runtime/helpers/budget.d.ts.map +1 -0
- package/dist/runtime/helpers/budget.js +103 -0
- package/dist/runtime/helpers/budget.js.map +1 -0
- package/dist/runtime/helpers/compact.d.ts +32 -0
- package/dist/runtime/helpers/compact.d.ts.map +1 -0
- package/dist/runtime/helpers/compact.js +93 -0
- package/dist/runtime/helpers/compact.js.map +1 -0
- package/dist/runtime/helpers/delta.d.ts +45 -0
- package/dist/runtime/helpers/delta.d.ts.map +1 -0
- package/dist/runtime/helpers/delta.js +116 -0
- package/dist/runtime/helpers/delta.js.map +1 -0
- package/dist/runtime/helpers/index.d.ts +16 -0
- package/dist/runtime/helpers/index.d.ts.map +1 -0
- package/dist/runtime/helpers/index.js +13 -0
- package/dist/runtime/helpers/index.js.map +1 -0
- package/dist/runtime/helpers/summarize.d.ts +24 -0
- package/dist/runtime/helpers/summarize.d.ts.map +1 -0
- package/dist/runtime/helpers/summarize.js +124 -0
- package/dist/runtime/helpers/summarize.js.map +1 -0
- package/dist/runtime/helpers/worker-preload.d.ts +25 -0
- package/dist/runtime/helpers/worker-preload.d.ts.map +1 -0
- package/dist/runtime/helpers/worker-preload.js +223 -0
- package/dist/runtime/helpers/worker-preload.js.map +1 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/pool/index.d.ts +11 -0
- package/dist/runtime/pool/index.d.ts.map +1 -0
- package/dist/runtime/pool/index.js +8 -0
- package/dist/runtime/pool/index.js.map +1 -0
- package/dist/runtime/pool/recycle.d.ts +44 -0
- package/dist/runtime/pool/recycle.d.ts.map +1 -0
- package/dist/runtime/pool/recycle.js +50 -0
- package/dist/runtime/pool/recycle.js.map +1 -0
- package/dist/runtime/pool/worker-pool.d.ts +77 -0
- package/dist/runtime/pool/worker-pool.d.ts.map +1 -0
- package/dist/runtime/pool/worker-pool.js +216 -0
- package/dist/runtime/pool/worker-pool.js.map +1 -0
- package/dist/runtime/pool/worker.d.ts +80 -0
- package/dist/runtime/pool/worker.d.ts.map +1 -0
- package/dist/runtime/pool/worker.js +324 -0
- package/dist/runtime/pool/worker.js.map +1 -0
- package/dist/server/mcp-server.d.ts +6 -0
- package/dist/server/mcp-server.d.ts.map +1 -1
- package/dist/server/mcp-server.js +610 -45
- package/dist/server/mcp-server.js.map +1 -1
- package/dist/server/passthrough-registrar.d.ts +73 -0
- package/dist/server/passthrough-registrar.d.ts.map +1 -0
- package/dist/server/passthrough-registrar.js +110 -0
- package/dist/server/passthrough-registrar.js.map +1 -0
- package/dist/skills/skills-engine.d.ts +9 -1
- package/dist/skills/skills-engine.d.ts.map +1 -1
- package/dist/skills/skills-engine.js +20 -3
- package/dist/skills/skills-engine.js.map +1 -1
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +5 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/orphan-watch.d.ts +34 -0
- package/dist/utils/orphan-watch.d.ts.map +1 -0
- package/dist/utils/orphan-watch.js +54 -0
- package/dist/utils/orphan-watch.js.map +1 -0
- package/dist/utils/redact.d.ts +15 -0
- package/dist/utils/redact.d.ts.map +1 -0
- package/dist/utils/redact.js +48 -0
- package/dist/utils/redact.js.map +1 -0
- package/dist/utils/tokenize.d.ts +55 -0
- package/dist/utils/tokenize.d.ts.map +1 -0
- package/dist/utils/tokenize.js +205 -0
- package/dist/utils/tokenize.js.map +1 -0
- package/dist/version.d.ts +3 -3
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +3 -3
- package/dist/version.js.map +1 -1
- package/package.json +13 -3
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Warm Deno Worker Pool
|
|
3
|
+
*
|
|
4
|
+
* Maintains a fixed pool of pre-warmed Deno workers so that the first
|
|
5
|
+
* execute_code call after startup hits an already-running sandbox.
|
|
6
|
+
*
|
|
7
|
+
* Lifecycle:
|
|
8
|
+
* 1. `new WorkerPool(opts)` — configure
|
|
9
|
+
* 2. `await pool.warmUp()` — spawn `size` workers concurrently
|
|
10
|
+
* 3. `await pool.execute(job)` — pick idle worker, run, release
|
|
11
|
+
* 4. `await pool.shutdown()` — drain in-flight jobs, terminate all workers
|
|
12
|
+
*
|
|
13
|
+
* Recycle policy (see recycle.ts):
|
|
14
|
+
* - After `maxJobsPerWorker` jobs the worker is replaced before termination
|
|
15
|
+
* - After `maxAgeMs` age the worker is replaced after its current job finishes
|
|
16
|
+
* - After any uncaught error the worker is replaced immediately
|
|
17
|
+
*
|
|
18
|
+
* Phase 5 plug-in: pass `preloadHelpers` to `WorkerPoolOptions` and the
|
|
19
|
+
* bootstrap script inside `worker.ts` will `await import()` each path before
|
|
20
|
+
* entering the job loop.
|
|
21
|
+
*
|
|
22
|
+
* @module runtime/pool/worker-pool
|
|
23
|
+
*/
|
|
24
|
+
import { logger } from '../../utils/index.js';
|
|
25
|
+
import { PooledWorker } from './worker.js';
|
|
26
|
+
import { evaluateRecycle } from './recycle.js';
|
|
27
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
28
|
+
// WorkerPool
|
|
29
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
30
|
+
const DEFAULT_SIZE = 4;
|
|
31
|
+
const DEFAULT_MAX_JOBS = 100;
|
|
32
|
+
const DEFAULT_MAX_AGE_MS = 600_000;
|
|
33
|
+
const DEFAULT_ACQUIRE_TIMEOUT_MS = 5_000;
|
|
34
|
+
export class WorkerPool {
|
|
35
|
+
opts;
|
|
36
|
+
workers = [];
|
|
37
|
+
queue = [];
|
|
38
|
+
isShuttingDown = false;
|
|
39
|
+
isWarmedUp = false;
|
|
40
|
+
constructor(options) {
|
|
41
|
+
this.opts = {
|
|
42
|
+
size: options.size ?? DEFAULT_SIZE,
|
|
43
|
+
maxJobsPerWorker: options.maxJobsPerWorker ?? DEFAULT_MAX_JOBS,
|
|
44
|
+
maxAgeMs: options.maxAgeMs ?? DEFAULT_MAX_AGE_MS,
|
|
45
|
+
preloadTypesDir: options.preloadTypesDir,
|
|
46
|
+
preloadHelpers: options.preloadHelpers ?? [],
|
|
47
|
+
maxMemoryMb: options.maxMemoryMb ?? 128,
|
|
48
|
+
bridgeUrl: options.bridgeUrl ?? 'http://127.0.0.1:9847',
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/** Pre-spawn all workers. Must be called before `execute()`. */
|
|
52
|
+
async warmUp() {
|
|
53
|
+
if (this.isWarmedUp)
|
|
54
|
+
return;
|
|
55
|
+
const workerOpts = {
|
|
56
|
+
preloadTypesDir: this.opts.preloadTypesDir,
|
|
57
|
+
preloadHelpers: this.opts.preloadHelpers,
|
|
58
|
+
maxMemoryMb: this.opts.maxMemoryMb,
|
|
59
|
+
bridgeUrl: this.opts.bridgeUrl,
|
|
60
|
+
};
|
|
61
|
+
const spawns = Array.from({ length: this.opts.size }, async () => {
|
|
62
|
+
const w = new PooledWorker(workerOpts);
|
|
63
|
+
await w.start();
|
|
64
|
+
this.workers.push(w);
|
|
65
|
+
});
|
|
66
|
+
await Promise.allSettled(spawns);
|
|
67
|
+
const alive = this.workers.filter((w) => w.currentState !== 'dead').length;
|
|
68
|
+
logger.info('WorkerPool warmed up', { requested: this.opts.size, alive });
|
|
69
|
+
this.isWarmedUp = true;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Execute a job on an idle worker.
|
|
73
|
+
*
|
|
74
|
+
* If no idle worker is available, the job is queued until one becomes
|
|
75
|
+
* free or the acquire timeout elapses.
|
|
76
|
+
*/
|
|
77
|
+
async execute(job, execOpts = {}) {
|
|
78
|
+
if (this.isShuttingDown) {
|
|
79
|
+
throw new Error('WorkerPool is shutting down');
|
|
80
|
+
}
|
|
81
|
+
const fullJob = {
|
|
82
|
+
...job,
|
|
83
|
+
signal: execOpts.signal,
|
|
84
|
+
};
|
|
85
|
+
const worker = this._findIdle();
|
|
86
|
+
if (worker) {
|
|
87
|
+
return this._runOnWorker(worker, fullJob);
|
|
88
|
+
}
|
|
89
|
+
// Queue the job
|
|
90
|
+
const acquireTimeoutMs = execOpts.acquireTimeoutMs ?? DEFAULT_ACQUIRE_TIMEOUT_MS;
|
|
91
|
+
return new Promise((resolve, reject) => {
|
|
92
|
+
const timeoutTimer = setTimeout(() => {
|
|
93
|
+
const idx = this.queue.findIndex((q) => q.job.id === fullJob.id);
|
|
94
|
+
if (idx !== -1)
|
|
95
|
+
this.queue.splice(idx, 1);
|
|
96
|
+
reject(new Error(`WorkerPool: acquire timeout after ${acquireTimeoutMs}ms`));
|
|
97
|
+
}, acquireTimeoutMs);
|
|
98
|
+
if (timeoutTimer.unref)
|
|
99
|
+
timeoutTimer.unref();
|
|
100
|
+
this.queue.push({
|
|
101
|
+
job: fullJob,
|
|
102
|
+
resolve: resolve,
|
|
103
|
+
reject,
|
|
104
|
+
timeoutTimer,
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
size() {
|
|
109
|
+
return this.workers.filter((w) => w.currentState !== 'dead').length;
|
|
110
|
+
}
|
|
111
|
+
busyCount() {
|
|
112
|
+
return this.workers.filter((w) => w.currentState === 'busy').length;
|
|
113
|
+
}
|
|
114
|
+
idleCount() {
|
|
115
|
+
return this.workers.filter((w) => w.currentState === 'idle').length;
|
|
116
|
+
}
|
|
117
|
+
/** Gracefully drain all in-flight jobs then terminate all workers. */
|
|
118
|
+
async shutdown() {
|
|
119
|
+
this.isShuttingDown = true;
|
|
120
|
+
// Reject queued jobs that haven't started
|
|
121
|
+
for (const queued of this.queue) {
|
|
122
|
+
clearTimeout(queued.timeoutTimer);
|
|
123
|
+
queued.reject(new Error('WorkerPool shut down'));
|
|
124
|
+
}
|
|
125
|
+
this.queue.length = 0;
|
|
126
|
+
// Drain busy workers (wait for current jobs to finish, then terminate)
|
|
127
|
+
await Promise.allSettled(this.workers.map((w) => w.shutdown(true)));
|
|
128
|
+
this.workers.length = 0;
|
|
129
|
+
logger.info('WorkerPool: shutdown complete');
|
|
130
|
+
}
|
|
131
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
132
|
+
// Private
|
|
133
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
134
|
+
_findIdle() {
|
|
135
|
+
return this.workers.find((w) => w.isIdle && w.currentState === 'idle');
|
|
136
|
+
}
|
|
137
|
+
async _runOnWorker(worker, job) {
|
|
138
|
+
let result;
|
|
139
|
+
try {
|
|
140
|
+
result = await worker.execute(job);
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
// Worker errored — mark for recycle and propagate
|
|
144
|
+
await this._maybeRecycle(worker);
|
|
145
|
+
throw err;
|
|
146
|
+
}
|
|
147
|
+
// Post-job recycle check (age / job-count triggers)
|
|
148
|
+
await this._maybeRecycle(worker);
|
|
149
|
+
// Drain one queued job onto the (now idle) worker or next available idle
|
|
150
|
+
this._drainQueue();
|
|
151
|
+
if (!result.success && result.error) {
|
|
152
|
+
throw new Error(result.error.message);
|
|
153
|
+
}
|
|
154
|
+
return result.result;
|
|
155
|
+
}
|
|
156
|
+
async _maybeRecycle(worker) {
|
|
157
|
+
const decision = evaluateRecycle({
|
|
158
|
+
id: worker.id,
|
|
159
|
+
state: worker.currentState,
|
|
160
|
+
createdAt: worker.createdAt,
|
|
161
|
+
jobsRun: worker.jobsRun,
|
|
162
|
+
}, { maxJobsPerWorker: this.opts.maxJobsPerWorker, maxAgeMs: this.opts.maxAgeMs });
|
|
163
|
+
if (!decision.shouldRecycle)
|
|
164
|
+
return;
|
|
165
|
+
logger.debug('WorkerPool: recycling worker', { workerId: worker.id, reason: decision.reason });
|
|
166
|
+
// Spawn replacement first to maintain capacity
|
|
167
|
+
const workerOpts = {
|
|
168
|
+
preloadTypesDir: this.opts.preloadTypesDir,
|
|
169
|
+
preloadHelpers: this.opts.preloadHelpers,
|
|
170
|
+
maxMemoryMb: this.opts.maxMemoryMb,
|
|
171
|
+
bridgeUrl: this.opts.bridgeUrl,
|
|
172
|
+
};
|
|
173
|
+
if (!this.isShuttingDown) {
|
|
174
|
+
const replacement = new PooledWorker(workerOpts);
|
|
175
|
+
// Start async — don't block the caller
|
|
176
|
+
replacement.start().then(() => {
|
|
177
|
+
const idx = this.workers.indexOf(worker);
|
|
178
|
+
if (idx !== -1) {
|
|
179
|
+
this.workers.splice(idx, 1, replacement);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
this.workers.push(replacement);
|
|
183
|
+
}
|
|
184
|
+
this._drainQueue();
|
|
185
|
+
logger.debug('WorkerPool: replacement worker ready', { workerId: replacement.id });
|
|
186
|
+
}).catch((err) => {
|
|
187
|
+
logger.error('WorkerPool: replacement spawn failed', { err: String(err) });
|
|
188
|
+
// Remove old dead worker anyway
|
|
189
|
+
this._removeWorker(worker);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
// Terminate old worker (drainFirst=false: it's already idle or dead)
|
|
193
|
+
await worker.shutdown(false);
|
|
194
|
+
if (this.isShuttingDown) {
|
|
195
|
+
this._removeWorker(worker);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
_removeWorker(worker) {
|
|
199
|
+
const idx = this.workers.indexOf(worker);
|
|
200
|
+
if (idx !== -1)
|
|
201
|
+
this.workers.splice(idx, 1);
|
|
202
|
+
}
|
|
203
|
+
_drainQueue() {
|
|
204
|
+
while (this.queue.length > 0) {
|
|
205
|
+
const idle = this._findIdle();
|
|
206
|
+
if (!idle)
|
|
207
|
+
break;
|
|
208
|
+
const queued = this.queue.shift();
|
|
209
|
+
clearTimeout(queued.timeoutTimer);
|
|
210
|
+
this._runOnWorker(idle, queued.job)
|
|
211
|
+
.then((result) => queued.resolve(result))
|
|
212
|
+
.catch((err) => queued.reject(err));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=worker-pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-pool.js","sourceRoot":"","sources":["../../../src/runtime/pool/worker-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAyC/C,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF,MAAM,YAAY,GAAG,CAAC,CAAC;AACvB,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAC7B,MAAM,kBAAkB,GAAG,OAAO,CAAC;AACnC,MAAM,0BAA0B,GAAG,KAAK,CAAC;AAEzC,MAAM,OAAO,UAAU;IACJ,IAAI,CAA8B;IAC3C,OAAO,GAAmB,EAAE,CAAC;IAC7B,KAAK,GAAgB,EAAE,CAAC;IACxB,cAAc,GAAG,KAAK,CAAC;IACvB,UAAU,GAAG,KAAK,CAAC;IAE3B,YAAY,OAA0B;QACpC,IAAI,CAAC,IAAI,GAAG;YACV,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,YAAY;YAClC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,gBAAgB;YAC9D,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,kBAAkB;YAChD,eAAe,EAAE,OAAO,CAAC,eAAe;YACxC,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,EAAE;YAC5C,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,GAAG;YACvC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,uBAAuB;SACxD,CAAC;IACJ,CAAC;IAED,gEAAgE;IAChE,KAAK,CAAC,MAAM;QACV,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO;QAE5B,MAAM,UAAU,GAAkB;YAChC,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,eAAe;YAC1C,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc;YACxC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW;YAClC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS;SAC/B,CAAC;QAEF,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,IAAI,EAAE;YAC/D,MAAM,CAAC,GAAG,IAAI,YAAY,CAAC,UAAU,CAAC,CAAC;YACvC,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAEjC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;QAC3E,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1E,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,OAAO,CACX,GAA8B,EAC9B,WAA+B,EAAE;QAEjC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QAED,MAAM,OAAO,GAAc;YACzB,GAAG,GAAG;YACN,MAAM,EAAE,QAAQ,CAAC,MAAM;SACxB,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAe,CAAC;QAC1D,CAAC;QAED,gBAAgB;QAChB,MAAM,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,IAAI,0BAA0B,CAAC;QACjF,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxC,MAAM,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;gBACnC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC,CAAC;gBACjE,IAAI,GAAG,KAAK,CAAC,CAAC;oBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAC1C,MAAM,CAAC,IAAI,KAAK,CAAC,qCAAqC,gBAAgB,IAAI,CAAC,CAAC,CAAC;YAC/E,CAAC,EAAE,gBAAgB,CAAC,CAAC;YACrB,IAAI,YAAY,CAAC,KAAK;gBAAE,YAAY,CAAC,KAAK,EAAE,CAAC;YAE7C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;gBACd,GAAG,EAAE,OAAO;gBACZ,OAAO,EAAE,OAAoC;gBAC7C,MAAM;gBACN,YAAY;aACb,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IACtE,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IACtE,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IACtE,CAAC;IAED,sEAAsE;IACtE,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAE3B,0CAA0C;QAC1C,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAChC,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YAClC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QAEtB,uEAAuE;QACvE,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpE,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;IAC/C,CAAC;IAED,4EAA4E;IAC5E,UAAU;IACV,4EAA4E;IAEpE,SAAS;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC;IACzE,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,MAAoB,EAAE,GAAc;QAC7D,IAAI,MAAoB,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACrC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,kDAAkD;YAClD,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YACjC,MAAM,GAAG,CAAC;QACZ,CAAC;QAED,oDAAoD;QACpD,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAEjC,yEAAyE;QACzE,IAAI,CAAC,WAAW,EAAE,CAAC;QAEnB,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,MAAoB;QAC9C,MAAM,QAAQ,GAAG,eAAe,CAC9B;YACE,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,KAAK,EAAE,MAAM,CAAC,YAAY;YAC1B,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,EACD,EAAE,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAC/E,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,aAAa;YAAE,OAAO;QAEpC,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAE/F,+CAA+C;QAC/C,MAAM,UAAU,GAAkB;YAChC,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,eAAe;YAC1C,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc;YACxC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW;YAClC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS;SAC/B,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,MAAM,WAAW,GAAG,IAAI,YAAY,CAAC,UAAU,CAAC,CAAC;YACjD,uCAAuC;YACvC,WAAW,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;gBAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBACzC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;oBACf,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;gBAC3C,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACjC,CAAC;gBACD,IAAI,CAAC,WAAW,EAAE,CAAC;gBACnB,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC;YACrF,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACf,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC3E,gCAAgC;gBAChC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC7B,CAAC,CAAC,CAAC;QACL,CAAC;QAED,qEAAqE;QACrE,MAAM,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAE7B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,MAAoB;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC9C,CAAC;IAEO,WAAW;QACjB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAI;gBAAE,MAAM;YAEjB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAG,CAAC;YACnC,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YAElC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC;iBAChC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAsB,CAAC,CAAC;iBACxD,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Individual Deno Worker Lifecycle
|
|
3
|
+
*
|
|
4
|
+
* Manages a single warm Deno worker subprocess. The worker runs a persistent
|
|
5
|
+
* bootstrap script that:
|
|
6
|
+
* 1. Accepts a list of preload helper scripts (Phase 5 plug-in point)
|
|
7
|
+
* 2. Waits for job messages on stdin, executes the code, returns results on stdout
|
|
8
|
+
*
|
|
9
|
+
* Communication protocol (newline-delimited JSON over stdio):
|
|
10
|
+
* host → worker: { id, code, context }
|
|
11
|
+
* worker → host: { id, success, result?, error?, logs }
|
|
12
|
+
*
|
|
13
|
+
* @module runtime/pool/worker
|
|
14
|
+
*/
|
|
15
|
+
export interface WorkerOptions {
|
|
16
|
+
/** Directory containing generated .d.ts files from the registry */
|
|
17
|
+
preloadTypesDir: string;
|
|
18
|
+
/**
|
|
19
|
+
* Additional helper scripts to preload (absolute paths or Deno URLs).
|
|
20
|
+
* Phase 5 (Agent E) plugs compact/summarize/delta helpers in here.
|
|
21
|
+
*/
|
|
22
|
+
preloadHelpers?: string[];
|
|
23
|
+
/** Maximum old-space memory for the Deno process (MB) */
|
|
24
|
+
maxMemoryMb?: number;
|
|
25
|
+
/** Bridge URL the sandbox code uses for MCP calls */
|
|
26
|
+
bridgeUrl?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface WorkerJob {
|
|
29
|
+
/** Unique job identifier for routing responses */
|
|
30
|
+
id: string;
|
|
31
|
+
/** TypeScript source code to execute */
|
|
32
|
+
code: string;
|
|
33
|
+
/** Execution context injected as global variables */
|
|
34
|
+
context: Record<string, unknown>;
|
|
35
|
+
/** Optional AbortSignal to cancel in-flight job */
|
|
36
|
+
signal?: AbortSignal;
|
|
37
|
+
}
|
|
38
|
+
export interface WorkerResult {
|
|
39
|
+
id: string;
|
|
40
|
+
success: boolean;
|
|
41
|
+
result?: unknown;
|
|
42
|
+
error?: {
|
|
43
|
+
message: string;
|
|
44
|
+
stack?: string;
|
|
45
|
+
};
|
|
46
|
+
logs: string[];
|
|
47
|
+
}
|
|
48
|
+
export type WorkerState = 'idle' | 'busy' | 'recycling' | 'dead';
|
|
49
|
+
export declare class PooledWorker {
|
|
50
|
+
private readonly opts;
|
|
51
|
+
readonly id: string;
|
|
52
|
+
private state;
|
|
53
|
+
private proc;
|
|
54
|
+
private bootstrapFile;
|
|
55
|
+
private lineBuffer;
|
|
56
|
+
private pending;
|
|
57
|
+
readonly createdAt: number;
|
|
58
|
+
jobsRun: number;
|
|
59
|
+
constructor(opts: WorkerOptions);
|
|
60
|
+
get currentState(): WorkerState;
|
|
61
|
+
get isIdle(): boolean;
|
|
62
|
+
/** Spawn the Deno subprocess. */
|
|
63
|
+
start(): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Execute a job on this worker.
|
|
66
|
+
* The worker must be idle before calling this.
|
|
67
|
+
*/
|
|
68
|
+
execute(job: WorkerJob): Promise<WorkerResult>;
|
|
69
|
+
/**
|
|
70
|
+
* Gracefully shut down the worker.
|
|
71
|
+
* If `drainFirst` is true, waits for any in-flight job to complete.
|
|
72
|
+
*/
|
|
73
|
+
shutdown(drainFirst?: boolean): Promise<void>;
|
|
74
|
+
private _handleLine;
|
|
75
|
+
private _handleClose;
|
|
76
|
+
private _rejectAll;
|
|
77
|
+
private _terminate;
|
|
78
|
+
private _cleanup;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../../src/runtime/pool/worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAYH,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,eAAe,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,kDAAkD;IAClD,EAAE,EAAE,MAAM,CAAC;IACX,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,mDAAmD;IACnD,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;AA4GjE,qBAAa,YAAY;IAcX,OAAO,CAAC,QAAQ,CAAC,IAAI;IAbjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,IAAI,CAA6B;IACzC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,OAAO,CAGA;IAEf,QAAQ,CAAC,SAAS,SAAc;IAChC,OAAO,SAAK;gBAEiB,IAAI,EAAE,aAAa;IAIhD,IAAI,YAAY,IAAI,WAAW,CAE9B;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,iCAAiC;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA8D5B;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC;IAoD9C;;;OAGG;IACG,QAAQ,CAAC,UAAU,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBhD,OAAO,CAAC,WAAW;IAgBnB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,QAAQ;CAMjB"}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Individual Deno Worker Lifecycle
|
|
3
|
+
*
|
|
4
|
+
* Manages a single warm Deno worker subprocess. The worker runs a persistent
|
|
5
|
+
* bootstrap script that:
|
|
6
|
+
* 1. Accepts a list of preload helper scripts (Phase 5 plug-in point)
|
|
7
|
+
* 2. Waits for job messages on stdin, executes the code, returns results on stdout
|
|
8
|
+
*
|
|
9
|
+
* Communication protocol (newline-delimited JSON over stdio):
|
|
10
|
+
* host → worker: { id, code, context }
|
|
11
|
+
* worker → host: { id, success, result?, error?, logs }
|
|
12
|
+
*
|
|
13
|
+
* @module runtime/pool/worker
|
|
14
|
+
*/
|
|
15
|
+
import { spawn } from 'node:child_process';
|
|
16
|
+
import { writeFileSync, unlinkSync } from 'node:fs';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { tmpdir } from 'node:os';
|
|
19
|
+
import { logger, minimalChildEnv } from '../../utils/index.js';
|
|
20
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
21
|
+
// Bootstrap script written to a temp file once per worker
|
|
22
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
23
|
+
function buildBootstrapScript(opts) {
|
|
24
|
+
const preloads = (opts.preloadHelpers ?? [])
|
|
25
|
+
.map((p) => `await import(${JSON.stringify(p)});`)
|
|
26
|
+
.join('\n');
|
|
27
|
+
return `
|
|
28
|
+
// MCP Conductor — Warm Worker Bootstrap
|
|
29
|
+
// This script runs persistently inside a Deno subprocess.
|
|
30
|
+
// It receives jobs on stdin and returns results on stdout.
|
|
31
|
+
|
|
32
|
+
// Preload Phase-5 helpers when available
|
|
33
|
+
${preloads}
|
|
34
|
+
|
|
35
|
+
const __bridgeUrl = ${JSON.stringify(opts.bridgeUrl ?? 'http://127.0.0.1:9847')};
|
|
36
|
+
const __logs: string[] = [];
|
|
37
|
+
|
|
38
|
+
// Override console.log to capture output
|
|
39
|
+
const __origLog = console.log;
|
|
40
|
+
console.log = (...args: unknown[]) => {
|
|
41
|
+
const msg = args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' ');
|
|
42
|
+
__logs.push(msg);
|
|
43
|
+
__origLog(...args);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// MCPServerClient — mirrors executor.ts sandbox runtime
|
|
47
|
+
class MCPServerClient {
|
|
48
|
+
constructor(public readonly name: string) {}
|
|
49
|
+
async call(tool: string, params: Record<string, unknown> = {}): Promise<unknown> {
|
|
50
|
+
const response = await fetch(\`\${__bridgeUrl}/call\`, {
|
|
51
|
+
method: 'POST',
|
|
52
|
+
headers: { 'Content-Type': 'application/json' },
|
|
53
|
+
body: JSON.stringify({ server: this.name, tool, params }),
|
|
54
|
+
});
|
|
55
|
+
const data = await response.json();
|
|
56
|
+
if (data.error) throw new Error(\`Tool error (\${this.name}.\${tool}): \${data.error.message}\`);
|
|
57
|
+
return data.result;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const __mcpBase = {
|
|
62
|
+
server(name: string) { return new MCPServerClient(name); },
|
|
63
|
+
log(...args: unknown[]) { console.log(...args); },
|
|
64
|
+
};
|
|
65
|
+
const mcp = new Proxy(__mcpBase, {
|
|
66
|
+
get(t, p) {
|
|
67
|
+
if (p in t) return (t as Record<string|symbol, unknown>)[p];
|
|
68
|
+
if (typeof p === 'string') return new MCPServerClient(p);
|
|
69
|
+
return undefined;
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Main job loop — read one JSON line per job
|
|
74
|
+
const decoder = new TextDecoder();
|
|
75
|
+
let buf = '';
|
|
76
|
+
|
|
77
|
+
async function processLine(line: string): Promise<void> {
|
|
78
|
+
let job: { id: string; code: string; context: Record<string, unknown> };
|
|
79
|
+
try {
|
|
80
|
+
job = JSON.parse(line);
|
|
81
|
+
} catch {
|
|
82
|
+
return; // malformed, skip
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
__logs.length = 0; // reset per job
|
|
86
|
+
|
|
87
|
+
let result: unknown;
|
|
88
|
+
let error: { message: string; stack?: string } | undefined;
|
|
89
|
+
let success = true;
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
// Execute user code in an async wrapper with mcp in scope
|
|
93
|
+
const __fn = new Function('mcp', '__ctx', \`return (async () => { \${job.code} })()\`);
|
|
94
|
+
result = await __fn(mcp, job.context ?? {});
|
|
95
|
+
} catch (err: unknown) {
|
|
96
|
+
success = false;
|
|
97
|
+
const e = err as Error;
|
|
98
|
+
error = { message: e.message, stack: e.stack };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const response = JSON.stringify({ id: job.id, success, result, error, logs: [...__logs] });
|
|
102
|
+
__origLog(response); // use original console.log to avoid capture loop
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Read stdin line by line
|
|
106
|
+
for await (const chunk of Deno.stdin.readable) {
|
|
107
|
+
buf += decoder.decode(chunk);
|
|
108
|
+
let nl: number;
|
|
109
|
+
while ((nl = buf.indexOf('\\n')) !== -1) {
|
|
110
|
+
const line = buf.slice(0, nl).trim();
|
|
111
|
+
buf = buf.slice(nl + 1);
|
|
112
|
+
if (line) await processLine(line);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
`;
|
|
116
|
+
}
|
|
117
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
118
|
+
// PooledWorker
|
|
119
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
120
|
+
let workerSeq = 0;
|
|
121
|
+
export class PooledWorker {
|
|
122
|
+
opts;
|
|
123
|
+
id;
|
|
124
|
+
state = 'idle';
|
|
125
|
+
proc = null;
|
|
126
|
+
bootstrapFile = null;
|
|
127
|
+
lineBuffer = '';
|
|
128
|
+
pending = new Map();
|
|
129
|
+
createdAt = Date.now();
|
|
130
|
+
jobsRun = 0;
|
|
131
|
+
constructor(opts) {
|
|
132
|
+
this.opts = opts;
|
|
133
|
+
this.id = `worker-${++workerSeq}-${Date.now()}`;
|
|
134
|
+
}
|
|
135
|
+
get currentState() {
|
|
136
|
+
return this.state;
|
|
137
|
+
}
|
|
138
|
+
get isIdle() {
|
|
139
|
+
return this.state === 'idle';
|
|
140
|
+
}
|
|
141
|
+
/** Spawn the Deno subprocess. */
|
|
142
|
+
async start() {
|
|
143
|
+
const script = buildBootstrapScript(this.opts);
|
|
144
|
+
const tmpPath = join(tmpdir(), `mcp-worker-${this.id}.ts`);
|
|
145
|
+
writeFileSync(tmpPath, script);
|
|
146
|
+
this.bootstrapFile = tmpPath;
|
|
147
|
+
const maxMemMb = this.opts.maxMemoryMb ?? 128;
|
|
148
|
+
const proc = spawn('deno', [
|
|
149
|
+
'run',
|
|
150
|
+
'--allow-net',
|
|
151
|
+
'--allow-read',
|
|
152
|
+
'--no-prompt',
|
|
153
|
+
`--v8-flags=--max-old-space-size=${maxMemMb}`,
|
|
154
|
+
tmpPath,
|
|
155
|
+
], {
|
|
156
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
157
|
+
env: minimalChildEnv({
|
|
158
|
+
DENO_DIR: process.env.DENO_DIR,
|
|
159
|
+
NO_COLOR: '1',
|
|
160
|
+
}),
|
|
161
|
+
});
|
|
162
|
+
this.proc = proc;
|
|
163
|
+
proc.stdout?.on('data', (chunk) => {
|
|
164
|
+
this.lineBuffer += chunk.toString('utf8');
|
|
165
|
+
let nl;
|
|
166
|
+
while ((nl = this.lineBuffer.indexOf('\n')) !== -1) {
|
|
167
|
+
const line = this.lineBuffer.slice(0, nl).trim();
|
|
168
|
+
this.lineBuffer = this.lineBuffer.slice(nl + 1);
|
|
169
|
+
if (line)
|
|
170
|
+
this._handleLine(line);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
proc.stderr?.on('data', (chunk) => {
|
|
174
|
+
const text = chunk.toString('utf8').trim();
|
|
175
|
+
if (text) {
|
|
176
|
+
logger.debug('Worker stderr', { workerId: this.id, text: text.slice(0, 500) });
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
proc.on('close', (code) => {
|
|
180
|
+
this._handleClose(code ?? -1);
|
|
181
|
+
});
|
|
182
|
+
proc.on('error', (err) => {
|
|
183
|
+
logger.error('Worker spawn error', { workerId: this.id, err: err.message });
|
|
184
|
+
this._rejectAll(err);
|
|
185
|
+
this.state = 'dead';
|
|
186
|
+
});
|
|
187
|
+
// Brief pause to allow the Deno runtime to initialise before accepting jobs.
|
|
188
|
+
// This ensures the warm-up cost is paid at pool startup, not at first job.
|
|
189
|
+
await new Promise((resolve) => {
|
|
190
|
+
const t = setTimeout(resolve, 50);
|
|
191
|
+
if (t.unref)
|
|
192
|
+
t.unref();
|
|
193
|
+
});
|
|
194
|
+
logger.debug('Worker started', { workerId: this.id });
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Execute a job on this worker.
|
|
198
|
+
* The worker must be idle before calling this.
|
|
199
|
+
*/
|
|
200
|
+
execute(job) {
|
|
201
|
+
if (this.state !== 'idle') {
|
|
202
|
+
return Promise.reject(new Error(`Worker ${this.id} is not idle (state: ${this.state})`));
|
|
203
|
+
}
|
|
204
|
+
if (!this.proc?.stdin?.writable) {
|
|
205
|
+
return Promise.reject(new Error(`Worker ${this.id} stdin is not writable`));
|
|
206
|
+
}
|
|
207
|
+
this.state = 'busy';
|
|
208
|
+
this.jobsRun++;
|
|
209
|
+
return new Promise((resolve, reject) => {
|
|
210
|
+
// Honour AbortSignal cancellation
|
|
211
|
+
const onAbort = () => {
|
|
212
|
+
this.pending.delete(job.id);
|
|
213
|
+
this.state = 'idle';
|
|
214
|
+
reject(new Error('Job cancelled by AbortSignal'));
|
|
215
|
+
};
|
|
216
|
+
if (job.signal?.aborted) {
|
|
217
|
+
this.state = 'idle';
|
|
218
|
+
this.jobsRun--; // didn't actually run
|
|
219
|
+
onAbort();
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
job.signal?.addEventListener('abort', onAbort, { once: true });
|
|
223
|
+
this.pending.set(job.id, {
|
|
224
|
+
resolve: (result) => {
|
|
225
|
+
job.signal?.removeEventListener('abort', onAbort);
|
|
226
|
+
this.state = 'idle';
|
|
227
|
+
resolve(result);
|
|
228
|
+
},
|
|
229
|
+
reject: (err) => {
|
|
230
|
+
job.signal?.removeEventListener('abort', onAbort);
|
|
231
|
+
this.state = 'idle';
|
|
232
|
+
reject(err);
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
const message = JSON.stringify({ id: job.id, code: job.code, context: job.context });
|
|
236
|
+
try {
|
|
237
|
+
this.proc.stdin.write(message + '\n');
|
|
238
|
+
}
|
|
239
|
+
catch (writeErr) {
|
|
240
|
+
this.pending.delete(job.id);
|
|
241
|
+
this.state = 'idle';
|
|
242
|
+
job.signal?.removeEventListener('abort', onAbort);
|
|
243
|
+
reject(writeErr instanceof Error ? writeErr : new Error(String(writeErr)));
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Gracefully shut down the worker.
|
|
249
|
+
* If `drainFirst` is true, waits for any in-flight job to complete.
|
|
250
|
+
*/
|
|
251
|
+
async shutdown(drainFirst = true) {
|
|
252
|
+
if (this.state === 'dead')
|
|
253
|
+
return;
|
|
254
|
+
if (drainFirst && this.state === 'busy') {
|
|
255
|
+
await new Promise((resolve) => {
|
|
256
|
+
const interval = setInterval(() => {
|
|
257
|
+
if (this.state !== 'busy') {
|
|
258
|
+
clearInterval(interval);
|
|
259
|
+
resolve();
|
|
260
|
+
}
|
|
261
|
+
}, 10);
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
this.state = 'recycling';
|
|
265
|
+
this._terminate();
|
|
266
|
+
}
|
|
267
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
268
|
+
// Private
|
|
269
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
270
|
+
_handleLine(line) {
|
|
271
|
+
let msg;
|
|
272
|
+
try {
|
|
273
|
+
msg = JSON.parse(line);
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
logger.warn('Worker: unparseable response', { workerId: this.id, line: line.slice(0, 200) });
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const pending = this.pending.get(msg.id);
|
|
280
|
+
if (pending) {
|
|
281
|
+
this.pending.delete(msg.id);
|
|
282
|
+
pending.resolve(msg);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
_handleClose(code) {
|
|
286
|
+
this.state = 'dead';
|
|
287
|
+
this._cleanup();
|
|
288
|
+
this._rejectAll(new Error(`Worker ${this.id} exited with code ${code}`));
|
|
289
|
+
logger.debug('Worker exited', { workerId: this.id, code });
|
|
290
|
+
}
|
|
291
|
+
_rejectAll(err) {
|
|
292
|
+
for (const [, handlers] of this.pending) {
|
|
293
|
+
handlers.reject(err);
|
|
294
|
+
}
|
|
295
|
+
this.pending.clear();
|
|
296
|
+
}
|
|
297
|
+
_terminate() {
|
|
298
|
+
try {
|
|
299
|
+
this.proc?.kill('SIGTERM');
|
|
300
|
+
const t = setTimeout(() => {
|
|
301
|
+
try {
|
|
302
|
+
this.proc?.kill('SIGKILL');
|
|
303
|
+
}
|
|
304
|
+
catch { /* already gone */ }
|
|
305
|
+
}, 2000);
|
|
306
|
+
if (t.unref)
|
|
307
|
+
t.unref();
|
|
308
|
+
}
|
|
309
|
+
catch {
|
|
310
|
+
// Already dead
|
|
311
|
+
}
|
|
312
|
+
this._cleanup();
|
|
313
|
+
}
|
|
314
|
+
_cleanup() {
|
|
315
|
+
if (this.bootstrapFile) {
|
|
316
|
+
try {
|
|
317
|
+
unlinkSync(this.bootstrapFile);
|
|
318
|
+
}
|
|
319
|
+
catch { /* ignore */ }
|
|
320
|
+
this.bootstrapFile = null;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../../src/runtime/pool/worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,7 @@ export declare class MCPExecutorServer {
|
|
|
19
19
|
private config;
|
|
20
20
|
private useMockServers;
|
|
21
21
|
private currentMode;
|
|
22
|
+
private registry;
|
|
22
23
|
private mockServers;
|
|
23
24
|
constructor(config: MCPExecutorConfig, options?: {
|
|
24
25
|
useMockServers?: boolean;
|
|
@@ -30,6 +31,11 @@ export declare class MCPExecutorServer {
|
|
|
30
31
|
/**
|
|
31
32
|
* Register all MCP tools
|
|
32
33
|
*/
|
|
34
|
+
/**
|
|
35
|
+
* Record metrics + shape the execute_code tool response. Extracted so the
|
|
36
|
+
* progress/cancel wiring in the handler stays readable.
|
|
37
|
+
*/
|
|
38
|
+
private finaliseExecuteCodeResult;
|
|
33
39
|
private registerTools;
|
|
34
40
|
/**
|
|
35
41
|
* Start the server
|