aiden-runtime 4.1.5 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +265 -847
- package/dist/api/server.js +32 -5
- package/dist/cli/v4/aidenCLI.js +536 -152
- package/dist/cli/v4/callbacks.js +170 -0
- package/dist/cli/v4/chatSession.js +245 -3
- package/dist/cli/v4/commands/_runtimeToggleHelpers.js +94 -0
- package/dist/cli/v4/commands/browserDepth.js +45 -0
- package/dist/cli/v4/commands/cron.js +264 -0
- package/dist/cli/v4/commands/daemon.js +541 -0
- package/dist/cli/v4/commands/daemonStatus.js +253 -0
- package/dist/cli/v4/commands/fanout.js +42 -59
- package/dist/cli/v4/commands/help.js +13 -0
- package/dist/cli/v4/commands/index.js +35 -1
- package/dist/cli/v4/commands/mcp.js +80 -54
- package/dist/cli/v4/commands/plannerGuard.js +53 -0
- package/dist/cli/v4/commands/recovery.js +122 -0
- package/dist/cli/v4/commands/runs.js +223 -0
- package/dist/cli/v4/commands/sandbox.js +48 -0
- package/dist/cli/v4/commands/spawnPause.js +93 -0
- package/dist/cli/v4/commands/suggestions.js +68 -0
- package/dist/cli/v4/commands/tce.js +41 -0
- package/dist/cli/v4/commands/trigger.js +378 -0
- package/dist/cli/v4/commands/update.js +95 -3
- package/dist/cli/v4/daemonAgentBuilder.js +145 -0
- package/dist/cli/v4/defaultSoul.js +1 -1
- package/dist/cli/v4/display/capabilityCard.js +26 -0
- package/dist/cli/v4/display.js +18 -8
- package/dist/cli/v4/replyRenderer.js +31 -23
- package/dist/cli/v4/updateBootPrompt.js +170 -0
- package/dist/core/playwrightBridge.js +129 -0
- package/dist/core/v4/aidenAgent.js +527 -5
- package/dist/core/v4/browserState.js +436 -0
- package/dist/core/v4/checkpoint.js +79 -0
- package/dist/core/v4/daemon/bootstrap.js +651 -0
- package/dist/core/v4/daemon/cleanShutdown.js +154 -0
- package/dist/core/v4/daemon/cron/cronBridge.js +126 -0
- package/dist/core/v4/daemon/cron/cronEmitter.js +173 -0
- package/dist/core/v4/daemon/cron/migration.js +199 -0
- package/dist/core/v4/daemon/cron/misfirePolicy.js +115 -0
- package/dist/core/v4/daemon/daemonConfig.js +90 -0
- package/dist/core/v4/daemon/db/connection.js +106 -0
- package/dist/core/v4/daemon/db/migrations.js +362 -0
- package/dist/core/v4/daemon/db/schema/v1.spec.js +18 -0
- package/dist/core/v4/daemon/dispatcher/agentRunner.js +98 -0
- package/dist/core/v4/daemon/dispatcher/budgetGate.js +127 -0
- package/dist/core/v4/daemon/dispatcher/daemonApproval.js +113 -0
- package/dist/core/v4/daemon/dispatcher/dailyBudgetTracker.js +120 -0
- package/dist/core/v4/daemon/dispatcher/dispatcher.js +389 -0
- package/dist/core/v4/daemon/dispatcher/fireRateLimiter.js +113 -0
- package/dist/core/v4/daemon/dispatcher/index.js +53 -0
- package/dist/core/v4/daemon/dispatcher/promptTemplate.js +95 -0
- package/dist/core/v4/daemon/dispatcher/realAgentRunner.js +356 -0
- package/dist/core/v4/daemon/dispatcher/resolveModel.js +93 -0
- package/dist/core/v4/daemon/dispatcher/sessionId.js +93 -0
- package/dist/core/v4/daemon/drain.js +156 -0
- package/dist/core/v4/daemon/eventLoopLag.js +73 -0
- package/dist/core/v4/daemon/health.js +159 -0
- package/dist/core/v4/daemon/idempotencyStore.js +204 -0
- package/dist/core/v4/daemon/index.js +179 -0
- package/dist/core/v4/daemon/instanceTracker.js +99 -0
- package/dist/core/v4/daemon/resourceRegistry.js +150 -0
- package/dist/core/v4/daemon/restartCode.js +32 -0
- package/dist/core/v4/daemon/restartFailureCounter.js +77 -0
- package/dist/core/v4/daemon/runStore.js +144 -0
- package/dist/core/v4/daemon/runtimeLock.js +167 -0
- package/dist/core/v4/daemon/signals.js +50 -0
- package/dist/core/v4/daemon/supervisor.js +272 -0
- package/dist/core/v4/daemon/triggerBus.js +279 -0
- package/dist/core/v4/daemon/triggers/email/allowlist.js +70 -0
- package/dist/core/v4/daemon/triggers/email/automatedSender.js +78 -0
- package/dist/core/v4/daemon/triggers/email/bodyExtractor.js +0 -0
- package/dist/core/v4/daemon/triggers/email/emailSeenStore.js +99 -0
- package/dist/core/v4/daemon/triggers/email/emailSpec.js +107 -0
- package/dist/core/v4/daemon/triggers/email/imapConnection.js +211 -0
- package/dist/core/v4/daemon/triggers/email/index.js +332 -0
- package/dist/core/v4/daemon/triggers/email/seenUids.js +60 -0
- package/dist/core/v4/daemon/triggers/fileObservationsStore.js +93 -0
- package/dist/core/v4/daemon/triggers/fileWatcher.js +253 -0
- package/dist/core/v4/daemon/triggers/fileWatcherSpec.js +88 -0
- package/dist/core/v4/daemon/triggers/fsIdentity.js +42 -0
- package/dist/core/v4/daemon/triggers/globMatcher.js +100 -0
- package/dist/core/v4/daemon/triggers/reconcile.js +206 -0
- package/dist/core/v4/daemon/triggers/settleStat.js +81 -0
- package/dist/core/v4/daemon/triggers/webhook.js +376 -0
- package/dist/core/v4/daemon/triggers/webhookDeliveriesStore.js +109 -0
- package/dist/core/v4/daemon/triggers/webhookIdempotency.js +72 -0
- package/dist/core/v4/daemon/triggers/webhookRateLimit.js +56 -0
- package/dist/core/v4/daemon/triggers/webhookSpec.js +76 -0
- package/dist/core/v4/daemon/triggers/webhookVerifier.js +128 -0
- package/dist/core/v4/daemon/types.js +15 -0
- package/dist/core/v4/dockerSession.js +461 -0
- package/dist/core/v4/dryRun.js +117 -0
- package/dist/core/v4/failureClassifier.js +779 -0
- package/dist/core/v4/providerFallback.js +35 -2
- package/dist/core/v4/recoveryReport.js +449 -0
- package/dist/core/v4/runtimeToggles.js +214 -0
- package/dist/core/v4/sandboxConfig.js +285 -0
- package/dist/core/v4/sandboxFs.js +316 -0
- package/dist/core/v4/selfimprovement/recoveryStore.js +307 -0
- package/dist/core/v4/selfimprovement/signatureBuilder.js +158 -0
- package/dist/core/v4/subagent/childBuilder.js +391 -0
- package/dist/core/v4/subagent/fanout.js +75 -51
- package/dist/core/v4/subagent/spawnPause.js +191 -0
- package/dist/core/v4/subagent/spawnSubAgent.js +310 -0
- package/dist/core/v4/suggestionCatalog.js +41 -0
- package/dist/core/v4/suggestionEngine.js +210 -0
- package/dist/core/v4/toolRegistry.js +37 -3
- package/dist/core/v4/turnState.js +587 -0
- package/dist/core/v4/update/checkUpdate.js +63 -3
- package/dist/core/v4/update/installMethodDetect.js +115 -0
- package/dist/core/v4/update/registryClient.js +121 -0
- package/dist/core/v4/update/skipState.js +75 -0
- package/dist/core/v4/verifier.js +448 -0
- package/dist/core/version.js +1 -1
- package/dist/moat/plannerGuard.js +29 -0
- package/dist/providers/v4/anthropicAdapter.js +31 -3
- package/dist/providers/v4/chatCompletionsAdapter.js +26 -3
- package/dist/providers/v4/codexResponsesAdapter.js +25 -2
- package/dist/providers/v4/ollamaPromptToolsAdapter.js +57 -2
- package/dist/tools/v4/browser/_observer.js +224 -0
- package/dist/tools/v4/browser/browserBlocker.js +396 -0
- package/dist/tools/v4/browser/browserClick.js +18 -1
- package/dist/tools/v4/browser/browserClose.js +18 -1
- package/dist/tools/v4/browser/browserExtract.js +5 -1
- package/dist/tools/v4/browser/browserFill.js +17 -1
- package/dist/tools/v4/browser/browserGetUrl.js +5 -1
- package/dist/tools/v4/browser/browserNavigate.js +16 -1
- package/dist/tools/v4/browser/browserScreenshot.js +5 -1
- package/dist/tools/v4/browser/browserScroll.js +18 -1
- package/dist/tools/v4/browser/browserType.js +17 -1
- package/dist/tools/v4/browser/captchaCheck.js +5 -1
- package/dist/tools/v4/executeCode.js +1 -0
- package/dist/tools/v4/files/fileCopy.js +56 -2
- package/dist/tools/v4/files/fileDelete.js +38 -1
- package/dist/tools/v4/files/fileList.js +12 -1
- package/dist/tools/v4/files/fileMove.js +59 -2
- package/dist/tools/v4/files/filePatch.js +43 -1
- package/dist/tools/v4/files/fileRead.js +12 -1
- package/dist/tools/v4/files/fileWrite.js +41 -1
- package/dist/tools/v4/index.js +88 -61
- package/dist/tools/v4/memory/memoryAdd.js +14 -0
- package/dist/tools/v4/memory/memoryRemove.js +14 -0
- package/dist/tools/v4/memory/memoryReplace.js +15 -0
- package/dist/tools/v4/memory/sessionSummary.js +12 -0
- package/dist/tools/v4/process/processKill.js +19 -0
- package/dist/tools/v4/process/processList.js +1 -0
- package/dist/tools/v4/process/processLogRead.js +1 -0
- package/dist/tools/v4/process/processSpawn.js +13 -0
- package/dist/tools/v4/process/processWait.js +1 -0
- package/dist/tools/v4/sessions/recallSession.js +1 -0
- package/dist/tools/v4/sessions/sessionList.js +1 -0
- package/dist/tools/v4/sessions/sessionSearch.js +1 -0
- package/dist/tools/v4/skills/lookupToolSchema.js +7 -0
- package/dist/tools/v4/skills/skillManage.js +13 -0
- package/dist/tools/v4/skills/skillView.js +1 -0
- package/dist/tools/v4/skills/skillsList.js +1 -0
- package/dist/tools/v4/subagent/spawnSubAgentTool.js +334 -0
- package/dist/tools/v4/subagent/subagentFanout.js +54 -1
- package/dist/tools/v4/system/aidenSelfUpdate.js +16 -0
- package/dist/tools/v4/system/appClose.js +13 -0
- package/dist/tools/v4/system/appInput.js +13 -0
- package/dist/tools/v4/system/appLaunch.js +13 -0
- package/dist/tools/v4/system/clipboardRead.js +1 -0
- package/dist/tools/v4/system/clipboardWrite.js +14 -0
- package/dist/tools/v4/system/mediaKey.js +12 -0
- package/dist/tools/v4/system/mediaSessions.js +1 -0
- package/dist/tools/v4/system/mediaTransport.js +13 -0
- package/dist/tools/v4/system/naturalEvents.js +1 -0
- package/dist/tools/v4/system/nowPlaying.js +1 -0
- package/dist/tools/v4/system/osProcessList.js +1 -0
- package/dist/tools/v4/system/screenshot.js +1 -0
- package/dist/tools/v4/system/systemInfo.js +1 -0
- package/dist/tools/v4/system/volumeSet.js +17 -0
- package/dist/tools/v4/terminal/shellExec.js +81 -9
- package/dist/tools/v4/web/deepResearch.js +1 -0
- package/dist/tools/v4/web/openUrl.js +1 -0
- package/dist/tools/v4/web/webFetch.js +1 -0
- package/dist/tools/v4/web/webPage.js +1 -0
- package/dist/tools/v4/web/webSearch.js +1 -0
- package/dist/tools/v4/web/youtubeSearch.js +1 -0
- package/package.json +13 -3
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 Shiva Deore (Taracod).
|
|
4
|
+
* Licensed under AGPL-3.0. See LICENSE for details.
|
|
5
|
+
*
|
|
6
|
+
* Aiden — local-first agent.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* cli/v4/commands/daemonStatus.ts — v4.5 Phase 8a.
|
|
10
|
+
*
|
|
11
|
+
* `/daemon status` — read-only slash variant of `aiden daemon
|
|
12
|
+
* status` (the top-level Phase 4b CLI surface). Renders an inline
|
|
13
|
+
* summary inside the REPL without leaving the chat. Points users
|
|
14
|
+
* at `aiden daemon install|start|stop` for any mutation.
|
|
15
|
+
*
|
|
16
|
+
* Q-P8a-3(a) inline format — five lines max when running, two
|
|
17
|
+
* lines when disabled. Reads daemon.db directly so the slash
|
|
18
|
+
* command works regardless of whether the daemon is the same
|
|
19
|
+
* process as the REPL.
|
|
20
|
+
*/
|
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
+
};
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.daemonStatus = void 0;
|
|
26
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
27
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
28
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
29
|
+
const daemon_1 = require("../../../core/v4/daemon");
|
|
30
|
+
const paths_1 = require("../../../core/v4/paths");
|
|
31
|
+
exports.daemonStatus = {
|
|
32
|
+
name: 'daemon',
|
|
33
|
+
description: 'Show v4.5 daemon status (read-only). Use `aiden daemon` for lifecycle.',
|
|
34
|
+
category: 'system',
|
|
35
|
+
icon: '⚙',
|
|
36
|
+
handler: async (ctx) => {
|
|
37
|
+
const sub = (ctx.args[0] ?? 'status').toLowerCase();
|
|
38
|
+
if (sub !== 'status') {
|
|
39
|
+
ctx.display.printError('Usage: /daemon status\n' +
|
|
40
|
+
'For lifecycle commands (install / start / stop / restart / logs), use the top-level CLI:\n' +
|
|
41
|
+
' aiden daemon install\n' +
|
|
42
|
+
' aiden daemon start\n' +
|
|
43
|
+
' aiden daemon stop\n' +
|
|
44
|
+
' aiden daemon status\n' +
|
|
45
|
+
' aiden daemon logs');
|
|
46
|
+
return {};
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const snapshot = readSnapshot();
|
|
50
|
+
printSnapshot(snapshot, ctx);
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
ctx.display.warn(`/daemon status: failed to read state (${e instanceof Error ? e.message : String(e)})`);
|
|
54
|
+
}
|
|
55
|
+
return {};
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
// ── Snapshot collector ─────────────────────────────────────────────────────
|
|
59
|
+
function readSnapshot() {
|
|
60
|
+
const aidenRoot = (0, paths_1.resolveAidenRoot)();
|
|
61
|
+
const dbPath = (0, daemon_1.daemonDbPath)(aidenRoot);
|
|
62
|
+
const lockPath = (0, daemon_1.daemonRuntimeLockPath)(aidenRoot);
|
|
63
|
+
// ── Liveness via the in-process bootstrap handle first, then fall
|
|
64
|
+
// back to the runtime.lock PID check (covers the case where the
|
|
65
|
+
// daemon is another process and we're a REPL inspecting its db).
|
|
66
|
+
let running = false;
|
|
67
|
+
let instanceId = null;
|
|
68
|
+
let port = null;
|
|
69
|
+
let uptimeMs = null;
|
|
70
|
+
const handle = (0, daemon_1.getDaemonHandle)();
|
|
71
|
+
if (handle?.active && handle.instanceId) {
|
|
72
|
+
running = true;
|
|
73
|
+
instanceId = handle.instanceId;
|
|
74
|
+
port = (0, daemon_1.getDaemonConfig)().port;
|
|
75
|
+
if (handle.instanceTracker) {
|
|
76
|
+
// instanceTracker has a `getStartedAt` if exposed; otherwise
|
|
77
|
+
// derive from daemon_instances row below.
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (!running && node_fs_1.default.existsSync(lockPath)) {
|
|
81
|
+
try {
|
|
82
|
+
const lines = node_fs_1.default.readFileSync(lockPath, 'utf-8').split(/\r?\n/);
|
|
83
|
+
// runtime.lock format: [0]=instanceId, [1]=pid, [2]=port (Phase 1).
|
|
84
|
+
const lockedInstance = lines[0] ?? '';
|
|
85
|
+
const lockedPid = Number.parseInt(lines[1] ?? '', 10);
|
|
86
|
+
const lockedPort = Number.parseInt(lines[2] ?? '', 10);
|
|
87
|
+
if (Number.isFinite(lockedPid) && pidAlive(lockedPid)) {
|
|
88
|
+
running = true;
|
|
89
|
+
instanceId = lockedInstance || null;
|
|
90
|
+
if (Number.isFinite(lockedPort))
|
|
91
|
+
port = lockedPort;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch { /* stale or unreadable */ }
|
|
95
|
+
}
|
|
96
|
+
if (!node_fs_1.default.existsSync(dbPath)) {
|
|
97
|
+
return {
|
|
98
|
+
running: false,
|
|
99
|
+
port: null,
|
|
100
|
+
instanceId: null,
|
|
101
|
+
uptimeMs: null,
|
|
102
|
+
triggerCounts: { file: 0, webhook: 0, email: 0, schedule: 0, manual: 0 },
|
|
103
|
+
recentRuns: [],
|
|
104
|
+
bus: { pending: 0, claimed: 0, deadLetter: 0 },
|
|
105
|
+
dailyBudget: null,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
const db = (0, daemon_1.openDaemonDb)(dbPath);
|
|
109
|
+
// Uptime from the instance row when we have an instanceId.
|
|
110
|
+
if (running && instanceId) {
|
|
111
|
+
try {
|
|
112
|
+
const row = db
|
|
113
|
+
.prepare('SELECT started_at, last_heartbeat FROM daemon_instances WHERE instance_id = ?')
|
|
114
|
+
.get(instanceId);
|
|
115
|
+
if (row)
|
|
116
|
+
uptimeMs = Date.now() - row.started_at;
|
|
117
|
+
}
|
|
118
|
+
catch { /* noop */ }
|
|
119
|
+
}
|
|
120
|
+
// Trigger counts by source.
|
|
121
|
+
const triggerCounts = { file: 0, webhook: 0, email: 0, schedule: 0, manual: 0 };
|
|
122
|
+
try {
|
|
123
|
+
const rows = db.prepare(`SELECT source, COUNT(*) AS c FROM triggers WHERE enabled = 1 GROUP BY source`).all();
|
|
124
|
+
for (const r of rows) {
|
|
125
|
+
if (r.source in triggerCounts) {
|
|
126
|
+
triggerCounts[r.source] = r.c;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch { /* triggers table missing — schema v1 not applied */ }
|
|
131
|
+
// Recent runs (last 3).
|
|
132
|
+
const recentRuns = (() => {
|
|
133
|
+
try {
|
|
134
|
+
const rows = db.prepare(`SELECT id, status, finish_reason, started_at, completed_at FROM runs
|
|
135
|
+
ORDER BY id DESC LIMIT 3`).all();
|
|
136
|
+
return rows.map((r) => ({
|
|
137
|
+
id: r.id,
|
|
138
|
+
status: r.status,
|
|
139
|
+
finishReason: r.finish_reason,
|
|
140
|
+
durationMs: r.completed_at !== null ? r.completed_at - r.started_at : null,
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return [];
|
|
145
|
+
}
|
|
146
|
+
})();
|
|
147
|
+
// Bus stats.
|
|
148
|
+
const bus = (() => {
|
|
149
|
+
try {
|
|
150
|
+
const rows = db.prepare(`SELECT status, COUNT(*) AS c FROM trigger_events GROUP BY status`).all();
|
|
151
|
+
const m = {};
|
|
152
|
+
for (const r of rows)
|
|
153
|
+
m[r.status] = r.c;
|
|
154
|
+
return {
|
|
155
|
+
pending: m.pending ?? 0,
|
|
156
|
+
claimed: m.claimed ?? 0,
|
|
157
|
+
deadLetter: m.dead_letter ?? 0,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return { pending: 0, claimed: 0, deadLetter: 0 };
|
|
162
|
+
}
|
|
163
|
+
})();
|
|
164
|
+
// Daily budget (piggybacked on idempotency_keys per Phase 7).
|
|
165
|
+
const dailyBudget = (() => {
|
|
166
|
+
const budgetRaw = process.env.AIDEN_DAEMON_DAILY_BUDGET;
|
|
167
|
+
if (!budgetRaw)
|
|
168
|
+
return null;
|
|
169
|
+
const budget = Number.parseInt(budgetRaw, 10);
|
|
170
|
+
if (!Number.isFinite(budget) || budget <= 0)
|
|
171
|
+
return null;
|
|
172
|
+
try {
|
|
173
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
174
|
+
const row = db.prepare(`SELECT response_json FROM idempotency_keys WHERE scope = ? AND key = ?`).get('daemon_budget', today);
|
|
175
|
+
let used = 0;
|
|
176
|
+
if (row) {
|
|
177
|
+
try {
|
|
178
|
+
const parsed = JSON.parse(row.response_json);
|
|
179
|
+
used = typeof parsed.used === 'number' ? parsed.used : 0;
|
|
180
|
+
}
|
|
181
|
+
catch { /* noop */ }
|
|
182
|
+
}
|
|
183
|
+
return { used, budget, exhausted: used >= budget };
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return { used: 0, budget, exhausted: false };
|
|
187
|
+
}
|
|
188
|
+
})();
|
|
189
|
+
return {
|
|
190
|
+
running,
|
|
191
|
+
port,
|
|
192
|
+
instanceId,
|
|
193
|
+
uptimeMs,
|
|
194
|
+
triggerCounts,
|
|
195
|
+
recentRuns,
|
|
196
|
+
bus,
|
|
197
|
+
dailyBudget,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
// ── Renderer ───────────────────────────────────────────────────────────────
|
|
201
|
+
function printSnapshot(s, ctx) {
|
|
202
|
+
if (!s.running) {
|
|
203
|
+
ctx.display.write('Daemon: disabled.\n');
|
|
204
|
+
ctx.display.write('To enable: `aiden daemon install` (systemd / launchd) or `AIDEN_DAEMON=1` before `aiden`.\n');
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const uptime = s.uptimeMs !== null ? formatUptime(s.uptimeMs) : 'unknown';
|
|
208
|
+
const instanceShort = s.instanceId ? s.instanceId.slice(0, 8) : '?';
|
|
209
|
+
ctx.display.write(`Daemon: running (port ${s.port ?? '?'}, instance ${instanceShort}, uptime ${uptime})\n`);
|
|
210
|
+
const tc = s.triggerCounts;
|
|
211
|
+
ctx.display.write(`Triggers: ${tc.file} file · ${tc.webhook} webhook · ${tc.email} email · ${tc.schedule} schedule\n`);
|
|
212
|
+
if (s.recentRuns.length === 0) {
|
|
213
|
+
ctx.display.write('Recent runs (last 3): (none)\n');
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
const parts = s.recentRuns.map((r) => {
|
|
217
|
+
const dur = r.durationMs !== null ? `(${(r.durationMs / 1000).toFixed(1)}s)` : '';
|
|
218
|
+
return `${r.status}${dur ? ' ' + dur : ''}`;
|
|
219
|
+
});
|
|
220
|
+
ctx.display.write(`Recent runs (last ${s.recentRuns.length}): ${parts.join(' · ')}\n`);
|
|
221
|
+
}
|
|
222
|
+
ctx.display.write(`Bus: ${s.bus.pending} pending · ${s.bus.claimed} claimed · ${s.bus.deadLetter} dead-letter\n`);
|
|
223
|
+
if (s.dailyBudget) {
|
|
224
|
+
const d = s.dailyBudget;
|
|
225
|
+
const exhaustedTag = d.exhausted ? ' EXHAUSTED' : '';
|
|
226
|
+
ctx.display.write(`Daily budget: ${d.used} / ${d.budget} tokens used (UTC ${new Date().toISOString().slice(0, 10)})${exhaustedTag}\n`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
function formatUptime(ms) {
|
|
230
|
+
const s = Math.floor(ms / 1000);
|
|
231
|
+
const days = Math.floor(s / 86400);
|
|
232
|
+
const hours = Math.floor((s % 86400) / 3600);
|
|
233
|
+
const mins = Math.floor((s % 3600) / 60);
|
|
234
|
+
if (days > 0)
|
|
235
|
+
return `${days}d ${hours}h`;
|
|
236
|
+
if (hours > 0)
|
|
237
|
+
return `${hours}h ${mins}m`;
|
|
238
|
+
return `${mins}m ${s % 60}s`;
|
|
239
|
+
}
|
|
240
|
+
function pidAlive(pid) {
|
|
241
|
+
try {
|
|
242
|
+
process.kill(pid, 0);
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
catch (e) {
|
|
246
|
+
// ESRCH = no such process; EPERM = process exists but we lack
|
|
247
|
+
// permission to signal it (still counts as alive).
|
|
248
|
+
return e.code === 'EPERM';
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
// Keep unused-import linter happy.
|
|
252
|
+
void node_os_1.default;
|
|
253
|
+
void node_path_1.default;
|
|
@@ -26,8 +26,6 @@
|
|
|
26
26
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
27
|
exports.parseFanoutArgs = parseFanoutArgs;
|
|
28
28
|
exports.runFanoutCli = runFanoutCli;
|
|
29
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
30
|
-
const fanout_1 = require("../../../core/v4/subagent/fanout");
|
|
31
29
|
function parseFanoutArgs(argv) {
|
|
32
30
|
const args = { positional: [] };
|
|
33
31
|
let i = 0;
|
|
@@ -172,65 +170,50 @@ async function runFanoutCli(argv, opts = {}) {
|
|
|
172
170
|
return 1;
|
|
173
171
|
}
|
|
174
172
|
}
|
|
175
|
-
// ── Dry-run path
|
|
176
|
-
//
|
|
177
|
-
//
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}))
|
|
201
|
-
: undefined,
|
|
202
|
-
n: args.n,
|
|
203
|
-
merge: args.merge,
|
|
204
|
-
providers,
|
|
205
|
-
runChild: async ({ index, prompt, provider }) => {
|
|
206
|
-
return `[dry-run child ${index} via ${provider.providerId}] echo: ${prompt}`;
|
|
207
|
-
},
|
|
208
|
-
aggregatorAdapter: stubAdapter,
|
|
209
|
-
aggregatorModel: { providerId: 'stub-a', modelId: 'fake-model' },
|
|
210
|
-
timeoutMs: args.timeoutMs,
|
|
173
|
+
// ── Dry-run path ─────────────────────────────────────────────
|
|
174
|
+
// v4.6 Phase 2Q — `runFanout` now routes children through
|
|
175
|
+
// `spawnSubAgent`, which needs real `SpawnSubAgentDeps`
|
|
176
|
+
// (toolRegistry, parentProvider, runStore, …). Pre-2Q the dry-run
|
|
177
|
+
// exercised Promise.all + abort + merge dispatch via simple stubs;
|
|
178
|
+
// post-refactor the equivalent coverage now lives in
|
|
179
|
+
// `tests/v4/subagent/fanout.behavioral.test.ts` (Slice 5).
|
|
180
|
+
//
|
|
181
|
+
// Dry-run therefore emits a synthetic snapshot — same observable
|
|
182
|
+
// shape (mode/n/merge/per-child rows) so the runtime smoke can
|
|
183
|
+
// still assert "the CLI subcommand parses + runs to exit 0
|
|
184
|
+
// against the built artifact" without booting a runtime.
|
|
185
|
+
const stubProviders = ['stub-a', 'stub-b'];
|
|
186
|
+
const childRows = [];
|
|
187
|
+
for (let i = 0; i < args.n; i += 1) {
|
|
188
|
+
const providerId = stubProviders[i % stubProviders.length];
|
|
189
|
+
const prompt = args.mode === 'partition'
|
|
190
|
+
? `Task ${i + 1} from CLI: ${args.query}`
|
|
191
|
+
: args.query;
|
|
192
|
+
childRows.push({
|
|
193
|
+
index: i,
|
|
194
|
+
providerId,
|
|
195
|
+
modelId: 'fake-model',
|
|
196
|
+
output: `[dry-run child ${i} via ${providerId}] echo: ${prompt}`,
|
|
197
|
+
elapsedMs: 0,
|
|
211
198
|
});
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
writeOut(`${result.merged ?? '(no merged output)'}\n`);
|
|
199
|
+
}
|
|
200
|
+
writeOut(`fanout dry-run\n`);
|
|
201
|
+
writeOut(` mode: ${args.mode}\n`);
|
|
202
|
+
writeOut(` n: ${args.n}\n`);
|
|
203
|
+
writeOut(` merge: ${args.merge}\n`);
|
|
204
|
+
writeOut(` query: ${args.query}\n`);
|
|
205
|
+
writeOut(` succeeded: ${args.n}/${args.n}\n`);
|
|
206
|
+
writeOut(` totalMs: 0\n`);
|
|
207
|
+
writeOut(` providers: ${childRows.map((r) => r.providerId).join(', ')}\n`);
|
|
208
|
+
writeOut(`\n--- merged ---\n`);
|
|
209
|
+
if (args.merge === 'all') {
|
|
210
|
+
for (const r of childRows) {
|
|
211
|
+
writeOut(`\n[${r.index}] ${r.providerId}:${r.modelId} (${r.elapsedMs}ms)\n`);
|
|
212
|
+
writeOut(`${r.output}\n`);
|
|
229
213
|
}
|
|
230
|
-
return 0;
|
|
231
214
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
return 1;
|
|
215
|
+
else {
|
|
216
|
+
writeOut(`[dry-run aggregator]\n`);
|
|
235
217
|
}
|
|
218
|
+
return 0;
|
|
236
219
|
}
|
|
@@ -58,6 +58,19 @@ exports.SUBSECTION_MAP = {
|
|
|
58
58
|
history: 'System',
|
|
59
59
|
// Phase v4.1.2-update — npm self-update for the running install.
|
|
60
60
|
update: 'System',
|
|
61
|
+
// v4.5 Phase 8a — subsystem live-flip slash commands.
|
|
62
|
+
sandbox: 'System',
|
|
63
|
+
tce: 'System',
|
|
64
|
+
'browser-depth': 'System',
|
|
65
|
+
daemon: 'System',
|
|
66
|
+
// v4.5 Phase 8b — contextual capability suggestions.
|
|
67
|
+
suggestions: 'System',
|
|
68
|
+
// v4.6 Phase 2M — opt-in keyword-based tool narrower.
|
|
69
|
+
'planner-guard': 'System',
|
|
70
|
+
// v4.6 Phase 3A — operator kill-switch for sub-agent spawning.
|
|
71
|
+
'spawn-pause': 'System',
|
|
72
|
+
// v4.6 Phase 3b — self-improvement loop operator surface.
|
|
73
|
+
recovery: 'System',
|
|
61
74
|
// ── Authentication ──
|
|
62
75
|
auth: 'Authentication',
|
|
63
76
|
// ── Help ──
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* and registers each on the global CommandRegistry at boot.
|
|
13
13
|
*/
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.allCommands = exports.update = exports.reloadSoul = exports.history = exports.show = exports.status = exports.voice = exports.channel = exports.setup = exports.cron = exports.doctor = exports.license = exports.auth = exports.plugins = exports.streaming = exports.debugPrompt = exports.identity = exports.providers = exports.quit = exports.clear = exports.verbose = exports.reasoning = exports.reloadMcp = exports.skills = exports.skin = exports.yolo = exports.usage = exports.compress = exports.title = exports.save = exports.personality = exports.model = exports.tools = exports.help = void 0;
|
|
15
|
+
exports.allCommands = exports.recovery = exports.spawnPause = exports.plannerGuard = exports.suggestions = exports.daemonStatus = exports.browserDepth = exports.tce = exports.sandbox = exports.update = exports.reloadSoul = exports.history = exports.show = exports.status = exports.voice = exports.channel = exports.setup = exports.cron = exports.doctor = exports.license = exports.auth = exports.plugins = exports.streaming = exports.debugPrompt = exports.identity = exports.providers = exports.quit = exports.clear = exports.verbose = exports.reasoning = exports.reloadMcp = exports.skills = exports.skin = exports.yolo = exports.usage = exports.compress = exports.title = exports.save = exports.personality = exports.model = exports.tools = exports.help = void 0;
|
|
16
16
|
const help_1 = require("./help");
|
|
17
17
|
Object.defineProperty(exports, "help", { enumerable: true, get: function () { return help_1.help; } });
|
|
18
18
|
const tools_1 = require("./tools");
|
|
@@ -79,6 +79,27 @@ const reloadSoul_1 = require("./reloadSoul");
|
|
|
79
79
|
Object.defineProperty(exports, "reloadSoul", { enumerable: true, get: function () { return reloadSoul_1.reloadSoul; } });
|
|
80
80
|
const update_1 = require("./update");
|
|
81
81
|
Object.defineProperty(exports, "update", { enumerable: true, get: function () { return update_1.update; } });
|
|
82
|
+
// v4.5 Phase 8a — subsystem live-flip slash commands.
|
|
83
|
+
const sandbox_1 = require("./sandbox");
|
|
84
|
+
Object.defineProperty(exports, "sandbox", { enumerable: true, get: function () { return sandbox_1.sandbox; } });
|
|
85
|
+
const tce_1 = require("./tce");
|
|
86
|
+
Object.defineProperty(exports, "tce", { enumerable: true, get: function () { return tce_1.tce; } });
|
|
87
|
+
const browserDepth_1 = require("./browserDepth");
|
|
88
|
+
Object.defineProperty(exports, "browserDepth", { enumerable: true, get: function () { return browserDepth_1.browserDepth; } });
|
|
89
|
+
const daemonStatus_1 = require("./daemonStatus");
|
|
90
|
+
Object.defineProperty(exports, "daemonStatus", { enumerable: true, get: function () { return daemonStatus_1.daemonStatus; } });
|
|
91
|
+
// v4.5 Phase 8b — contextual capability suggestions toggle.
|
|
92
|
+
const suggestions_1 = require("./suggestions");
|
|
93
|
+
Object.defineProperty(exports, "suggestions", { enumerable: true, get: function () { return suggestions_1.suggestions; } });
|
|
94
|
+
// v4.6 Phase 2M — opt-in keyword-based tool narrower (default OFF).
|
|
95
|
+
const plannerGuard_1 = require("./plannerGuard");
|
|
96
|
+
Object.defineProperty(exports, "plannerGuard", { enumerable: true, get: function () { return plannerGuard_1.plannerGuard; } });
|
|
97
|
+
// v4.6 Phase 3A — operator kill-switch for sub-agent spawning.
|
|
98
|
+
const spawnPause_1 = require("./spawnPause");
|
|
99
|
+
Object.defineProperty(exports, "spawnPause", { enumerable: true, get: function () { return spawnPause_1.spawnPause; } });
|
|
100
|
+
// v4.6 Phase 3b — self-improvement loop operator surface.
|
|
101
|
+
const recovery_1 = require("./recovery");
|
|
102
|
+
Object.defineProperty(exports, "recovery", { enumerable: true, get: function () { return recovery_1.recovery; } });
|
|
82
103
|
/** All built-in system commands, in canonical order. */
|
|
83
104
|
exports.allCommands = [
|
|
84
105
|
help_1.help,
|
|
@@ -115,6 +136,19 @@ exports.allCommands = [
|
|
|
115
136
|
// probe + shared executeInstall executor (also wired into
|
|
116
137
|
// aiden_self_update tool for natural-language requests).
|
|
117
138
|
update_1.update,
|
|
139
|
+
// v4.5 Phase 8a — subsystem live-flip slash commands.
|
|
140
|
+
sandbox_1.sandbox,
|
|
141
|
+
tce_1.tce,
|
|
142
|
+
browserDepth_1.browserDepth,
|
|
143
|
+
daemonStatus_1.daemonStatus,
|
|
144
|
+
// v4.5 Phase 8b — contextual suggestions toggle.
|
|
145
|
+
suggestions_1.suggestions,
|
|
146
|
+
// v4.6 Phase 2M — opt-in keyword-based tool narrower (default OFF).
|
|
147
|
+
plannerGuard_1.plannerGuard,
|
|
148
|
+
// v4.6 Phase 3A — operator kill-switch for sub-agent spawning.
|
|
149
|
+
spawnPause_1.spawnPause,
|
|
150
|
+
// v4.6 Phase 3b — self-improvement loop operator surface.
|
|
151
|
+
recovery_1.recovery,
|
|
118
152
|
clear_1.clear,
|
|
119
153
|
quit_1.quit,
|
|
120
154
|
];
|
|
@@ -32,10 +32,15 @@
|
|
|
32
32
|
* tools by default; opting in means the user accepted server-side
|
|
33
33
|
* execution risk at config time.
|
|
34
34
|
*/
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
35
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
39
|
exports.AIDEN_MCP_BUILD = void 0;
|
|
37
40
|
exports.runMcpSubcommand = runMcpSubcommand;
|
|
38
41
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
42
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
43
|
+
const node_crypto_1 = require("node:crypto");
|
|
39
44
|
const paths_1 = require("../../../core/v4/paths");
|
|
40
45
|
const toolRegistry_1 = require("../../../core/v4/toolRegistry");
|
|
41
46
|
const skillLoader_1 = require("../../../core/v4/skillLoader");
|
|
@@ -46,12 +51,26 @@ const processRegistry_1 = require("../../../core/v4/processRegistry");
|
|
|
46
51
|
const config_1 = require("../../../core/v4/config");
|
|
47
52
|
const providerFallback_1 = require("../../../core/v4/providerFallback");
|
|
48
53
|
const chatCompletionsAdapter_1 = require("../../../providers/v4/chatCompletionsAdapter");
|
|
49
|
-
const aidenAgent_1 = require("../../../core/v4/aidenAgent");
|
|
50
54
|
const factory_1 = require("../../../core/v4/logger/factory");
|
|
51
55
|
const index_1 = require("../../../tools/v4/index");
|
|
52
56
|
const envSources_1 = require("../envSources");
|
|
53
57
|
const credentialResolver_1 = require("../../../providers/v4/credentialResolver");
|
|
54
58
|
const runtimeResolver_1 = require("../../../providers/v4/runtimeResolver");
|
|
59
|
+
// v4.6 Phase 2R — MCP-mode subagent_fanout now routes children
|
|
60
|
+
// through the `spawnSubAgent` primitive (same as REPL after 2Q-A).
|
|
61
|
+
// The legacy `runChild` closure + RunChildArgs import are deleted
|
|
62
|
+
// per design doc §12.3 (2R cleanup). MCP needs its own daemon-db
|
|
63
|
+
// connection + instance id so child runs persist under
|
|
64
|
+
// `aiden runs list --include-children` for cross-runtime
|
|
65
|
+
// observability.
|
|
66
|
+
const daemon_1 = require("../../../core/v4/daemon");
|
|
67
|
+
const version_1 = require("../../../core/version");
|
|
68
|
+
// v4.6 Phase 3A — operator kill-switch. Initialised here so
|
|
69
|
+
// MCP-side `subagent_fanout` (and any future MCP-side
|
|
70
|
+
// `spawn_sub_agent` exposure) reads from the same marker file the
|
|
71
|
+
// REPL writes via /spawn-pause. Cross-process coordination is the
|
|
72
|
+
// whole point of the file-marker design.
|
|
73
|
+
const spawnPause_1 = require("../../../core/v4/subagent/spawnPause");
|
|
55
74
|
const stdioServer_1 = require("../../../core/v4/mcp/server/stdioServer");
|
|
56
75
|
Object.defineProperty(exports, "AIDEN_MCP_BUILD", { enumerable: true, get: function () { return stdioServer_1.AIDEN_MCP_BUILD; } });
|
|
57
76
|
const diagnostics_1 = require("../../../core/v4/mcp/server/diagnostics");
|
|
@@ -206,6 +225,43 @@ async function wireSubagentFanout(opts) {
|
|
|
206
225
|
}
|
|
207
226
|
}
|
|
208
227
|
const finalAdapter = wrapped;
|
|
228
|
+
// v4.6 Phase 2R — open a daemon-db connection + seed an MCP
|
|
229
|
+
// instance row so child sub-agent runs (spawned by
|
|
230
|
+
// subagent_fanout below) persist to the same `runs` table the
|
|
231
|
+
// REPL writes to. Operators can then see MCP-side fanout
|
|
232
|
+
// activity under `aiden runs list --include-children`. Same
|
|
233
|
+
// WAL-coexistence model as REPL — connection.ts caches per-path.
|
|
234
|
+
const mcpInstanceId = `mcp-${(0, node_crypto_1.randomUUID)().slice(0, 8)}`;
|
|
235
|
+
const mcpDb = (0, daemon_1.openDaemonDb)((0, daemon_1.daemonDbPath)(opts.paths.root));
|
|
236
|
+
mcpDb.prepare(`INSERT OR IGNORE INTO daemon_instances
|
|
237
|
+
(instance_id, pid, hostname, started_at, last_heartbeat, version)
|
|
238
|
+
VALUES (?, ?, ?, ?, ?, ?)`).run(mcpInstanceId, process.pid, node_os_1.default.hostname(), Date.now(), Date.now(), version_1.VERSION);
|
|
239
|
+
const mcpRunStore = (0, daemon_1.createRunStore)({ db: mcpDb });
|
|
240
|
+
// v4.6 Phase 3b — self-improvement loop singleton against the
|
|
241
|
+
// same daemon.db. MCP-side spawn_sub_agent / subagent_fanout
|
|
242
|
+
// dispatches now record failure occurrences + recoveries into
|
|
243
|
+
// the shared ledger, so operators see MCP failures alongside
|
|
244
|
+
// REPL failures in `aiden /recovery list` from a future REPL
|
|
245
|
+
// session.
|
|
246
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
247
|
+
const { initRecoveryStore } = require('../../../core/v4/selfimprovement/recoveryStore');
|
|
248
|
+
initRecoveryStore({ db: mcpDb });
|
|
249
|
+
// v4.6 Phase 3A — wire the pause singleton against the same
|
|
250
|
+
// `paths.root` the REPL uses. The fanout handler's pause-check
|
|
251
|
+
// reads through `getSpawnPause()`, so initing here makes MCP
|
|
252
|
+
// mode respect the operator's /spawn-pause state without any
|
|
253
|
+
// additional plumbing.
|
|
254
|
+
const mcpPauseState = (0, spawnPause_1.initSpawnPause)({ aidenHome: opts.paths.root });
|
|
255
|
+
if (mcpPauseState.isPaused()) {
|
|
256
|
+
const s = mcpPauseState.status();
|
|
257
|
+
const reasonSuffix = s.reason ? ` (reason: ${s.reason})` : '';
|
|
258
|
+
opts.logger.warn(`MCP boot: subagent_fanout is PAUSED${reasonSuffix}. ` +
|
|
259
|
+
'Operator must run /spawn-pause off in a REPL session to resume.', {
|
|
260
|
+
pausedAt: s.pausedAt ?? null,
|
|
261
|
+
pausedBy: s.pausedBy ?? null,
|
|
262
|
+
durationMs: s.durationMs ?? null,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
209
265
|
opts.registry.register((0, index_1.makeSubagentFanoutTool)({
|
|
210
266
|
logger: opts.logger,
|
|
211
267
|
resolveActiveModel: () => ({ providerId, modelId }),
|
|
@@ -224,70 +280,40 @@ async function wireSubagentFanout(opts) {
|
|
|
224
280
|
}
|
|
225
281
|
return [{ providerId, modelId }];
|
|
226
282
|
},
|
|
227
|
-
|
|
228
|
-
|
|
283
|
+
// v4.6 Phase 2R — `spawnDeps` mirrors the REPL wiring in
|
|
284
|
+
// `cli/v4/aidenCLI.ts` (2Q-A). The MCP-mode parentToolContext
|
|
285
|
+
// is intentionally lean: no approvalEngine (a server has no
|
|
286
|
+
// human at the REPL to prompt — children's mutating tools are
|
|
287
|
+
// gated by AIDEN_SUBAGENT_ALLOW_DESTRUCTIVE in childBuilder),
|
|
288
|
+
// no ssrfProtection/tirithScanner/memoryGuard (MCP's slim
|
|
289
|
+
// runtime never wired them — see header comment §9).
|
|
290
|
+
spawnDeps: {
|
|
291
|
+
toolRegistry: opts.registry,
|
|
292
|
+
parentToolContext: {
|
|
229
293
|
cwd: process.cwd(),
|
|
230
294
|
paths: opts.paths,
|
|
231
295
|
sessions: opts.sessionManager,
|
|
232
296
|
memory: opts.memoryManager,
|
|
233
297
|
skillLoader: opts.skillLoader,
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
process.env.AIDEN_SUBAGENT_ALLOW_DESTRUCTIVE === 'true';
|
|
242
|
-
const childToolNames = [];
|
|
243
|
-
for (const name of opts.registry.list()) {
|
|
244
|
-
const h = opts.registry.get(name);
|
|
245
|
-
if (!h)
|
|
246
|
-
continue;
|
|
247
|
-
if (h.mutates && !allowDestructive)
|
|
248
|
-
continue;
|
|
249
|
-
if (name === 'subagent_fanout')
|
|
250
|
-
continue;
|
|
251
|
-
childToolNames.push(name);
|
|
252
|
-
}
|
|
253
|
-
const childExecutor = opts.registry.buildExecutor(childCtx);
|
|
254
|
-
const childTools = childToolNames
|
|
255
|
-
.map((n) => opts.registry.get(n)?.schema)
|
|
256
|
-
.filter((s) => !!s);
|
|
257
|
-
// Per-child cloned FallbackAdapter — own rate-limit state.
|
|
258
|
-
const childProvider = finalAdapter instanceof providerFallback_1.FallbackAdapter
|
|
259
|
-
? finalAdapter.clone()
|
|
260
|
-
: finalAdapter;
|
|
261
|
-
const child = new aidenAgent_1.AidenAgent({
|
|
262
|
-
provider: childProvider,
|
|
263
|
-
tools: childTools,
|
|
264
|
-
toolExecutor: childExecutor,
|
|
265
|
-
maxTurns: childOpts.maxIterations,
|
|
266
|
-
providerId: childOpts.provider.providerId,
|
|
267
|
-
modelId: childOpts.provider.modelId,
|
|
268
|
-
// No promptBuilder — children get a brief system prompt
|
|
269
|
-
// (same lesson as v4.1-subagent.1: full SOUL.md makes
|
|
270
|
-
// trivial fanouts spend 30s+ on verbose self-introductions).
|
|
271
|
-
});
|
|
272
|
-
if (childOpts.signal.aborted) {
|
|
273
|
-
throw new Error('aborted before dispatch');
|
|
274
|
-
}
|
|
275
|
-
const roleLine = childOpts.role ? `Role: ${childOpts.role}. ` : '';
|
|
276
|
-
const childSystemPrompt = `You are one of N parallel subagents. ${roleLine}` +
|
|
277
|
-
`Answer the user's request concisely. Use available tools when ` +
|
|
278
|
-
`the answer requires real-world information you don't have memorized.`;
|
|
279
|
-
const history = [
|
|
280
|
-
{ role: 'system', content: childSystemPrompt },
|
|
281
|
-
{ role: 'user', content: childOpts.prompt },
|
|
282
|
-
];
|
|
283
|
-
const result = await child.runConversation(history);
|
|
284
|
-
return result.finalContent;
|
|
298
|
+
},
|
|
299
|
+
parentProvider: finalAdapter,
|
|
300
|
+
parentProviderId: providerId,
|
|
301
|
+
parentModelId: modelId,
|
|
302
|
+
runStore: mcpRunStore,
|
|
303
|
+
instanceId: mcpInstanceId,
|
|
304
|
+
logger: opts.logger,
|
|
285
305
|
},
|
|
306
|
+
// No resolveParentRunId / resolveParentSessionId for MCP — the
|
|
307
|
+
// MCP server doesn't run a turn loop with its own `runs` row;
|
|
308
|
+
// each tool invocation arrives discrete from the client. Child
|
|
309
|
+
// rows therefore have NULL spawned_from_run_id, which is the
|
|
310
|
+
// honest representation (no MCP-side parent to link to).
|
|
286
311
|
}));
|
|
287
312
|
opts.logger.info('subagent_fanout: wired (replaces stub) [mcp serve]', {
|
|
288
313
|
providerId,
|
|
289
314
|
modelId,
|
|
290
315
|
fallback: finalAdapter instanceof providerFallback_1.FallbackAdapter ? 'FallbackAdapter' : 'direct',
|
|
316
|
+
instanceId: mcpInstanceId,
|
|
291
317
|
});
|
|
292
318
|
}
|
|
293
319
|
async function runMcpSubcommand(action, opts = {}) {
|