@adhdev/daemon-core 0.9.82-rc.57 → 0.9.82-rc.59
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/dist/index.d.ts +6 -4
- package/dist/index.js +431 -67
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +424 -66
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-active-work.d.ts +48 -0
- package/dist/mesh/mesh-ledger.d.ts +37 -0
- package/dist/mesh/mesh-work-queue.d.ts +12 -0
- package/dist/providers/cli-provider-instance.d.ts +1 -0
- package/package.json +1 -1
- package/src/cli-adapters/provider-cli-runtime.ts +3 -1
- package/src/commands/router.ts +7 -1
- package/src/index.ts +6 -4
- package/src/mesh/mesh-active-work.ts +205 -0
- package/src/mesh/mesh-events.ts +42 -8
- package/src/mesh/mesh-ledger.ts +135 -0
- package/src/mesh/mesh-work-queue.ts +54 -1
- package/src/providers/cli-provider-instance.ts +66 -1
package/dist/index.mjs
CHANGED
|
@@ -1264,6 +1264,7 @@ __export(mesh_ledger_exports, {
|
|
|
1264
1264
|
getSessionRecoveryContext: () => getSessionRecoveryContext,
|
|
1265
1265
|
isIntentionalCleanupStopEntry: () => isIntentionalCleanupStopEntry,
|
|
1266
1266
|
meshLedgerEvents: () => meshLedgerEvents,
|
|
1267
|
+
normalizeMeshWorkerResult: () => normalizeMeshWorkerResult,
|
|
1267
1268
|
readLedgerEntries: () => readLedgerEntries,
|
|
1268
1269
|
readLedgerSlice: () => readLedgerSlice
|
|
1269
1270
|
});
|
|
@@ -1291,6 +1292,86 @@ function getRotatedPath(meshId, index) {
|
|
|
1291
1292
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1292
1293
|
return join6(getLedgerDir(), `${safe}.${index}.jsonl`);
|
|
1293
1294
|
}
|
|
1295
|
+
function readNonEmptyString(value) {
|
|
1296
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
1297
|
+
}
|
|
1298
|
+
function readStringArray(value) {
|
|
1299
|
+
if (!Array.isArray(value)) return [];
|
|
1300
|
+
return value.map((item) => readNonEmptyString(item)).filter(Boolean);
|
|
1301
|
+
}
|
|
1302
|
+
function extractJsonObjectFromSummary(summary) {
|
|
1303
|
+
const text = readNonEmptyString(summary);
|
|
1304
|
+
if (!text) return void 0;
|
|
1305
|
+
const fenced = text.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
1306
|
+
const candidates = [fenced?.[1], text].filter(Boolean);
|
|
1307
|
+
for (const candidate of candidates) {
|
|
1308
|
+
const trimmed = candidate.trim();
|
|
1309
|
+
if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) continue;
|
|
1310
|
+
try {
|
|
1311
|
+
const parsed = JSON.parse(trimmed);
|
|
1312
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
|
|
1313
|
+
} catch {
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
return void 0;
|
|
1317
|
+
}
|
|
1318
|
+
function normalizeValidationResults(value) {
|
|
1319
|
+
if (!Array.isArray(value)) return [];
|
|
1320
|
+
return value.filter((item) => item && typeof item === "object" && !Array.isArray(item)).map((item) => {
|
|
1321
|
+
const status = ["passed", "failed", "skipped", "unknown"].includes(item.status) ? item.status : "unknown";
|
|
1322
|
+
return {
|
|
1323
|
+
...readNonEmptyString(item.command) ? { command: readNonEmptyString(item.command) } : {},
|
|
1324
|
+
status,
|
|
1325
|
+
...Number.isFinite(Number(item.durationMs)) ? { durationMs: Number(item.durationMs) } : {},
|
|
1326
|
+
...readNonEmptyString(item.outputPath) ? { outputPath: readNonEmptyString(item.outputPath) } : {},
|
|
1327
|
+
...readNonEmptyString(item.summary) ? { summary: readNonEmptyString(item.summary) } : {}
|
|
1328
|
+
};
|
|
1329
|
+
});
|
|
1330
|
+
}
|
|
1331
|
+
function normalizeProcessArtifacts(value) {
|
|
1332
|
+
if (!Array.isArray(value)) return [];
|
|
1333
|
+
const kinds = /* @__PURE__ */ new Set(["process", "log", "port", "window", "session", "file", "url", "other"]);
|
|
1334
|
+
return value.filter((item) => item && typeof item === "object" && !Array.isArray(item)).map((item) => ({
|
|
1335
|
+
kind: kinds.has(item.kind) ? item.kind : "other",
|
|
1336
|
+
...readNonEmptyString(item.id) ? { id: readNonEmptyString(item.id) } : {},
|
|
1337
|
+
...readNonEmptyString(item.label) ? { label: readNonEmptyString(item.label) } : {},
|
|
1338
|
+
...readNonEmptyString(item.locator) ? { locator: readNonEmptyString(item.locator) } : {},
|
|
1339
|
+
...Number.isFinite(Number(item.pid)) ? { pid: Number(item.pid) } : {},
|
|
1340
|
+
...Number.isFinite(Number(item.port)) ? { port: Number(item.port) } : {},
|
|
1341
|
+
...readNonEmptyString(item.url) ? { url: readNonEmptyString(item.url) } : {},
|
|
1342
|
+
...readNonEmptyString(item.path) ? { path: readNonEmptyString(item.path) } : {},
|
|
1343
|
+
...readNonEmptyString(item.sessionId) ? { sessionId: readNonEmptyString(item.sessionId) } : {},
|
|
1344
|
+
...typeof item.keepRunning === "boolean" ? { keepRunning: item.keepRunning } : {},
|
|
1345
|
+
...item.metadata && typeof item.metadata === "object" && !Array.isArray(item.metadata) ? { metadata: item.metadata } : {}
|
|
1346
|
+
}));
|
|
1347
|
+
}
|
|
1348
|
+
function normalizeMeshWorkerResult(input, source = "explicit_metadata") {
|
|
1349
|
+
const raw = input && typeof input === "object" ? input : {};
|
|
1350
|
+
const status = ["completed", "failed", "blocked", "partial", "unknown"].includes(String(raw.status)) ? raw.status : "unknown";
|
|
1351
|
+
const gitStatus = raw.gitStatus && typeof raw.gitStatus === "object" && !Array.isArray(raw.gitStatus) ? raw.gitStatus : void 0;
|
|
1352
|
+
return {
|
|
1353
|
+
status,
|
|
1354
|
+
...readNonEmptyString(raw.classification) ? { classification: readNonEmptyString(raw.classification) } : {},
|
|
1355
|
+
changedFiles: readStringArray(raw.changedFiles),
|
|
1356
|
+
validationResults: normalizeValidationResults(raw.validationResults),
|
|
1357
|
+
...gitStatus ? { gitStatus } : {},
|
|
1358
|
+
processArtifacts: normalizeProcessArtifacts(raw.processArtifacts),
|
|
1359
|
+
errors: readStringArray(raw.errors),
|
|
1360
|
+
...readNonEmptyString(raw.nextAction) ? { nextAction: readNonEmptyString(raw.nextAction) } : {},
|
|
1361
|
+
requiresUserAction: raw.requiresUserAction === true,
|
|
1362
|
+
source
|
|
1363
|
+
};
|
|
1364
|
+
}
|
|
1365
|
+
function resolveWorkerResult(opts) {
|
|
1366
|
+
if (opts.workerResult && typeof opts.workerResult === "object") {
|
|
1367
|
+
return normalizeMeshWorkerResult(opts.workerResult, "explicit_metadata");
|
|
1368
|
+
}
|
|
1369
|
+
const parsed = extractJsonObjectFromSummary(opts.finalSummary);
|
|
1370
|
+
if (parsed) {
|
|
1371
|
+
return normalizeMeshWorkerResult(parsed, "final_summary_json");
|
|
1372
|
+
}
|
|
1373
|
+
return normalizeMeshWorkerResult(void 0, "default");
|
|
1374
|
+
}
|
|
1294
1375
|
function buildTaskCompletionEvidence(opts) {
|
|
1295
1376
|
const providerSessionId = opts.providerSessionId?.trim() || void 0;
|
|
1296
1377
|
const providerType = opts.providerType?.trim() || void 0;
|
|
@@ -1307,6 +1388,7 @@ function buildTaskCompletionEvidence(opts) {
|
|
|
1307
1388
|
providerSessionId,
|
|
1308
1389
|
finalSummaryAvailable: typeof opts.finalSummary === "string" && opts.finalSummary.trim().length > 0
|
|
1309
1390
|
},
|
|
1391
|
+
workerResult: resolveWorkerResult(opts),
|
|
1310
1392
|
git: {
|
|
1311
1393
|
status: "deferred",
|
|
1312
1394
|
reason: "ordinary_completion_git_status_not_checked"
|
|
@@ -1601,19 +1683,48 @@ var mesh_work_queue_exports = {};
|
|
|
1601
1683
|
__export(mesh_work_queue_exports, {
|
|
1602
1684
|
ACTIVE_MESH_QUEUE_STATUSES: () => ACTIVE_MESH_QUEUE_STATUSES,
|
|
1603
1685
|
HISTORICAL_MESH_QUEUE_STATUSES: () => HISTORICAL_MESH_QUEUE_STATUSES,
|
|
1686
|
+
MESH_TASK_MODES: () => MESH_TASK_MODES,
|
|
1604
1687
|
cancelTask: () => cancelTask,
|
|
1605
1688
|
claimNextTask: () => claimNextTask,
|
|
1606
1689
|
enqueueTask: () => enqueueTask,
|
|
1607
1690
|
getMeshQueueStats: () => getMeshQueueStats,
|
|
1608
1691
|
getQueue: () => getQueue,
|
|
1692
|
+
normalizeMeshTaskMode: () => normalizeMeshTaskMode,
|
|
1609
1693
|
recordTaskAutoLaunch: () => recordTaskAutoLaunch,
|
|
1610
1694
|
requeueTask: () => requeueTask,
|
|
1611
1695
|
updateSessionTaskStatus: () => updateSessionTaskStatus,
|
|
1612
|
-
updateTaskStatus: () => updateTaskStatus
|
|
1696
|
+
updateTaskStatus: () => updateTaskStatus,
|
|
1697
|
+
validateMeshTaskModeRequest: () => validateMeshTaskModeRequest
|
|
1613
1698
|
});
|
|
1614
1699
|
import { existsSync as existsSync7, writeFileSync as writeFileSync3, readFileSync as readFileSync5, openSync, closeSync, unlinkSync } from "fs";
|
|
1615
1700
|
import { join as join7 } from "path";
|
|
1616
1701
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
1702
|
+
function normalizeMeshTaskMode(value) {
|
|
1703
|
+
if (typeof value !== "string") return void 0;
|
|
1704
|
+
const normalized = value.trim();
|
|
1705
|
+
return MESH_TASK_MODES.includes(normalized) ? normalized : void 0;
|
|
1706
|
+
}
|
|
1707
|
+
function validateMeshTaskModeRequest(mode, message) {
|
|
1708
|
+
const taskMode = normalizeMeshTaskMode(mode);
|
|
1709
|
+
if (!taskMode) {
|
|
1710
|
+
return { valid: true, violations: [] };
|
|
1711
|
+
}
|
|
1712
|
+
if (taskMode !== "live_debug_readonly") {
|
|
1713
|
+
return { valid: true, taskMode, violations: [] };
|
|
1714
|
+
}
|
|
1715
|
+
const violations = LIVE_DEBUG_READONLY_FORBIDDEN.filter((rule) => rule.pattern.test(message || "")).map((rule) => rule.label);
|
|
1716
|
+
return {
|
|
1717
|
+
valid: violations.length === 0,
|
|
1718
|
+
taskMode,
|
|
1719
|
+
violations,
|
|
1720
|
+
allowedOperations: [
|
|
1721
|
+
"process/log/window/port/session inspection",
|
|
1722
|
+
"read-only filesystem listing/reading",
|
|
1723
|
+
"status probes and keep-running handle reporting",
|
|
1724
|
+
"diagnostic summaries without source edits, commits, checkpoints, pushes, deploys, resets, rebases, or destructive cleanups"
|
|
1725
|
+
]
|
|
1726
|
+
};
|
|
1727
|
+
}
|
|
1617
1728
|
function getQueuePath(meshId) {
|
|
1618
1729
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1619
1730
|
return join7(getLedgerDir(), `${safe}.queue.json`);
|
|
@@ -1664,6 +1775,10 @@ function writeQueue(meshId, queue) {
|
|
|
1664
1775
|
}
|
|
1665
1776
|
function enqueueTask(meshId, message, opts) {
|
|
1666
1777
|
requireMeshHostQueueOwner(opts);
|
|
1778
|
+
const modeValidation = validateMeshTaskModeRequest(opts?.taskMode, message);
|
|
1779
|
+
if (!modeValidation.valid) {
|
|
1780
|
+
throw new Error(`live_debug_readonly_guardrail_violation: forbidden operations (${modeValidation.violations.join(", ")})`);
|
|
1781
|
+
}
|
|
1667
1782
|
return withQueueLock(meshId, () => {
|
|
1668
1783
|
const queue = readQueue(meshId);
|
|
1669
1784
|
const entry = {
|
|
@@ -1671,6 +1786,7 @@ function enqueueTask(meshId, message, opts) {
|
|
|
1671
1786
|
meshId,
|
|
1672
1787
|
message,
|
|
1673
1788
|
status: "pending",
|
|
1789
|
+
taskMode: modeValidation.taskMode,
|
|
1674
1790
|
targetNodeId: opts?.targetNodeId,
|
|
1675
1791
|
targetSessionId: opts?.targetSessionId,
|
|
1676
1792
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -1832,7 +1948,7 @@ function getMeshQueueStats(meshId) {
|
|
|
1832
1948
|
}))
|
|
1833
1949
|
};
|
|
1834
1950
|
}
|
|
1835
|
-
var ACTIVE_MESH_QUEUE_STATUSES, HISTORICAL_MESH_QUEUE_STATUSES;
|
|
1951
|
+
var ACTIVE_MESH_QUEUE_STATUSES, HISTORICAL_MESH_QUEUE_STATUSES, MESH_TASK_MODES, LIVE_DEBUG_READONLY_FORBIDDEN;
|
|
1836
1952
|
var init_mesh_work_queue = __esm({
|
|
1837
1953
|
"src/mesh/mesh-work-queue.ts"() {
|
|
1838
1954
|
"use strict";
|
|
@@ -1840,6 +1956,14 @@ var init_mesh_work_queue = __esm({
|
|
|
1840
1956
|
init_mesh_host_ownership();
|
|
1841
1957
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
1842
1958
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
1959
|
+
MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
|
|
1960
|
+
LIVE_DEBUG_READONLY_FORBIDDEN = [
|
|
1961
|
+
{ label: "source_edit", pattern: /\b(edit|modify|patch|apply\s+patch|write\s+(?:to\s+)?(?:file|source)|overwrite|delete\s+file|remove\s+file|create\s+file|touch\s+file)\b/i },
|
|
1962
|
+
{ label: "git_mutation", pattern: /\b(?:git\s+(?:add|commit|push|reset|rebase|clean|checkout|switch|merge|tag|restore|rm|mv)|push\b)/i },
|
|
1963
|
+
{ label: "checkpoint", pattern: /\b(checkpoint|mesh_checkpoint)\b/i },
|
|
1964
|
+
{ label: "deploy_or_version_bump", pattern: /\b(deploy|wrangler\s+deploy|version[-\s]?bump|npm\s+version|release)\b/i },
|
|
1965
|
+
{ label: "destructive_shell", pattern: /\b(rm\s+-rf|mv\s+\S+\s+\S+|truncate\s|tee\s+\S+|sed\s+-i)\b/i }
|
|
1966
|
+
];
|
|
1843
1967
|
}
|
|
1844
1968
|
});
|
|
1845
1969
|
|
|
@@ -2205,6 +2329,9 @@ __export(mesh_events_exports, {
|
|
|
2205
2329
|
});
|
|
2206
2330
|
import { appendFileSync as appendFileSync3, existsSync as existsSync10, readFileSync as readFileSync6, unlinkSync as unlinkSync3 } from "fs";
|
|
2207
2331
|
import { join as join10 } from "path";
|
|
2332
|
+
function readWorkerResultMetadata(event) {
|
|
2333
|
+
return readRecord(event.workerResult) || readRecord(event.meshWorkerResult) || readRecord(event.structuredResult);
|
|
2334
|
+
}
|
|
2208
2335
|
function sweepExpiredRemoteIdleSessions() {
|
|
2209
2336
|
const now = Date.now();
|
|
2210
2337
|
for (const [key, session] of remoteIdleSessions) {
|
|
@@ -2270,20 +2397,28 @@ function clearPendingMeshCoordinatorEvents(meshId) {
|
|
|
2270
2397
|
} catch {
|
|
2271
2398
|
}
|
|
2272
2399
|
}
|
|
2273
|
-
function
|
|
2400
|
+
function readNonEmptyString2(value) {
|
|
2274
2401
|
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
2275
2402
|
}
|
|
2403
|
+
function readRecord(value) {
|
|
2404
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
2405
|
+
}
|
|
2276
2406
|
function resolveEventSessionId(event, fallback) {
|
|
2277
|
-
return
|
|
2407
|
+
return readNonEmptyString2(event.targetSessionId) || readNonEmptyString2(event.sessionId) || readNonEmptyString2(event.instanceId) || readNonEmptyString2(fallback);
|
|
2278
2408
|
}
|
|
2279
2409
|
function isMeshCoordinatorEvent(eventName) {
|
|
2280
2410
|
return typeof eventName === "string" && MESH_COORDINATOR_EVENTS.has(eventName);
|
|
2281
2411
|
}
|
|
2282
2412
|
function formatCompletionMetadata(event) {
|
|
2413
|
+
const completionDiagnostic = event.completionDiagnostic && typeof event.completionDiagnostic === "object" ? event.completionDiagnostic : null;
|
|
2414
|
+
const diagnosticReason = completionDiagnostic ? readNonEmptyString2(completionDiagnostic.blockReason) || "present" : "";
|
|
2415
|
+
const finalAssistantPresent = typeof completionDiagnostic?.finalAssistantPresent === "boolean" ? String(completionDiagnostic.finalAssistantPresent) : "";
|
|
2283
2416
|
const parts = [
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2417
|
+
readNonEmptyString2(event.targetSessionId) ? `session_id=${readNonEmptyString2(event.targetSessionId)}` : "",
|
|
2418
|
+
readNonEmptyString2(event.providerType) ? `provider=${readNonEmptyString2(event.providerType)}` : "",
|
|
2419
|
+
readNonEmptyString2(event.providerSessionId) ? `provider_session_id=${readNonEmptyString2(event.providerSessionId)}` : "",
|
|
2420
|
+
diagnosticReason ? `completion_diagnostic=${diagnosticReason}` : "",
|
|
2421
|
+
finalAssistantPresent ? `final_assistant=${finalAssistantPresent}` : ""
|
|
2287
2422
|
].filter(Boolean);
|
|
2288
2423
|
return parts.length > 0 ? ` (${parts.join("; ")})` : "";
|
|
2289
2424
|
}
|
|
@@ -2325,7 +2460,7 @@ function readEventTimestamp(value) {
|
|
|
2325
2460
|
return null;
|
|
2326
2461
|
}
|
|
2327
2462
|
function buildMeshCompletionFingerprint(args) {
|
|
2328
|
-
const timestampPart = Number.isFinite(args.timestamp) ? String(args.timestamp) :
|
|
2463
|
+
const timestampPart = Number.isFinite(args.timestamp) ? String(args.timestamp) : readNonEmptyString2(args.finalSummary).slice(0, 200);
|
|
2329
2464
|
return [
|
|
2330
2465
|
args.meshId,
|
|
2331
2466
|
args.event,
|
|
@@ -2403,7 +2538,7 @@ function isTerminalSessionStatus(status) {
|
|
|
2403
2538
|
return ["stopped", "failed", "terminated", "exited", "closed"].includes(status);
|
|
2404
2539
|
}
|
|
2405
2540
|
function isIdleSessionState(state) {
|
|
2406
|
-
const status =
|
|
2541
|
+
const status = readNonEmptyString2(state?.status).toLowerCase();
|
|
2407
2542
|
if (isTerminalSessionStatus(status)) return false;
|
|
2408
2543
|
return status === "idle" || state?.activeChat?.status === "waiting_input";
|
|
2409
2544
|
}
|
|
@@ -2412,15 +2547,15 @@ function isDirtyNode(node) {
|
|
|
2412
2547
|
}
|
|
2413
2548
|
function isLaunchableNode(node) {
|
|
2414
2549
|
if (!node || node.status === "disabled" || node.status === "removed") return false;
|
|
2415
|
-
const health =
|
|
2550
|
+
const health = readNonEmptyString2(node.health).toLowerCase();
|
|
2416
2551
|
if (!health) return true;
|
|
2417
2552
|
return health === "online" || health === "unknown";
|
|
2418
2553
|
}
|
|
2419
2554
|
function localAutoLaunchSkipReason(node) {
|
|
2420
|
-
const daemonId =
|
|
2421
|
-
const machineId =
|
|
2555
|
+
const daemonId = readNonEmptyString2(node?.daemonId);
|
|
2556
|
+
const machineId = readNonEmptyString2(node?.machineId);
|
|
2422
2557
|
const appConfig = loadConfig();
|
|
2423
|
-
const localMachineId =
|
|
2558
|
+
const localMachineId = readNonEmptyString2(appConfig.machineId) || readNonEmptyString2(appConfig.registeredMachineId);
|
|
2424
2559
|
const cloudDaemonId = localMachineId ? `daemon_${localMachineId}` : "";
|
|
2425
2560
|
const standaloneDaemonId = localMachineId ? `standalone_${localMachineId}` : "";
|
|
2426
2561
|
const daemonMatchesLocal = !daemonId || daemonId === cloudDaemonId || daemonId === standaloneDaemonId;
|
|
@@ -2443,10 +2578,10 @@ function liveSessionCountForNode(components, meshId, nodeId) {
|
|
|
2443
2578
|
return components.instanceManager.getByCategory("cli").filter((inst) => {
|
|
2444
2579
|
const state = inst.getState();
|
|
2445
2580
|
const settings = state.settings || {};
|
|
2446
|
-
if (
|
|
2447
|
-
const instNodeId =
|
|
2581
|
+
if (readNonEmptyString2(settings.meshNodeFor) !== meshId) return false;
|
|
2582
|
+
const instNodeId = readNonEmptyString2(settings.meshNodeId) || readNonEmptyString2(settings.nodeId);
|
|
2448
2583
|
if (instNodeId !== nodeId) return false;
|
|
2449
|
-
const status =
|
|
2584
|
+
const status = readNonEmptyString2(state.status).toLowerCase();
|
|
2450
2585
|
return !isTerminalSessionStatus(status);
|
|
2451
2586
|
}).length;
|
|
2452
2587
|
}
|
|
@@ -2538,7 +2673,7 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
|
|
|
2538
2673
|
continue;
|
|
2539
2674
|
}
|
|
2540
2675
|
for (const node of candidateNodes) {
|
|
2541
|
-
const nodeId =
|
|
2676
|
+
const nodeId = readNonEmptyString2(node?.id);
|
|
2542
2677
|
if (!nodeId) continue;
|
|
2543
2678
|
const launchKey = `${meshId}:${nodeId}`;
|
|
2544
2679
|
const cooldownUntil = autoLaunchCooldownUntil.get(launchKey) || 0;
|
|
@@ -2597,7 +2732,7 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
|
|
|
2597
2732
|
autoLaunchCooldownUntil.set(launchKey, Date.now() + AUTO_LAUNCH_COOLDOWN_MS);
|
|
2598
2733
|
return false;
|
|
2599
2734
|
}
|
|
2600
|
-
const sessionId =
|
|
2735
|
+
const sessionId = readNonEmptyString2(launchResult.sessionId) || readNonEmptyString2(launchResult.id) || readNonEmptyString2(launchResult.runtimeSessionId);
|
|
2601
2736
|
if (!sessionId) {
|
|
2602
2737
|
markAutoLaunch(meshId, task.id, { status: "failed", reason: "launch_missing_session_id", nodeId, providerType: resolved.providerType });
|
|
2603
2738
|
autoLaunchCooldownUntil.set(launchKey, Date.now() + AUTO_LAUNCH_COOLDOWN_MS);
|
|
@@ -2624,13 +2759,13 @@ async function triggerMeshQueue(components, meshId) {
|
|
|
2624
2759
|
for (const inst of cliInstances) {
|
|
2625
2760
|
const state = inst.getState();
|
|
2626
2761
|
const settings = state.settings || {};
|
|
2627
|
-
const instMeshId =
|
|
2762
|
+
const instMeshId = readNonEmptyString2(settings.meshNodeFor);
|
|
2628
2763
|
if (instMeshId !== meshId) continue;
|
|
2629
|
-
const nodeId =
|
|
2764
|
+
const nodeId = readNonEmptyString2(settings.meshNodeId) || readNonEmptyString2(settings.nodeId);
|
|
2630
2765
|
if (!nodeId) continue;
|
|
2631
2766
|
if (!isIdleSessionState(state)) continue;
|
|
2632
2767
|
const sessionId = state.instanceId;
|
|
2633
|
-
const providerType = state.type ||
|
|
2768
|
+
const providerType = state.type || readNonEmptyString2(settings.providerType);
|
|
2634
2769
|
if (providerType) {
|
|
2635
2770
|
tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType);
|
|
2636
2771
|
}
|
|
@@ -2692,7 +2827,7 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
2692
2827
|
}
|
|
2693
2828
|
function injectMeshSystemMessage(components, args) {
|
|
2694
2829
|
const eventSessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2695
|
-
const eventNodeId =
|
|
2830
|
+
const eventNodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
2696
2831
|
const intentionalCleanupStop = shouldSuppressIntentionalCleanupStop({
|
|
2697
2832
|
event: args.event,
|
|
2698
2833
|
meshId: args.meshId,
|
|
@@ -2713,10 +2848,10 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2713
2848
|
meshId: args.meshId,
|
|
2714
2849
|
event: args.event,
|
|
2715
2850
|
sessionId: eventSessionId,
|
|
2716
|
-
providerType:
|
|
2717
|
-
providerSessionId:
|
|
2851
|
+
providerType: readNonEmptyString2(args.metadataEvent.providerType) || void 0,
|
|
2852
|
+
providerSessionId: readNonEmptyString2(args.metadataEvent.providerSessionId) || void 0,
|
|
2718
2853
|
timestamp: eventTimestamp,
|
|
2719
|
-
finalSummary:
|
|
2854
|
+
finalSummary: readNonEmptyString2(args.metadataEvent.finalSummary) || void 0
|
|
2720
2855
|
});
|
|
2721
2856
|
if (duplicateCompletion) {
|
|
2722
2857
|
LOG.info("MeshEvents", `Suppressed duplicate completion for mesh ${args.meshId} session ${eventSessionId}`);
|
|
@@ -2726,8 +2861,8 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2726
2861
|
let completedTaskForLedger = null;
|
|
2727
2862
|
if (args.event === "agent:generating_completed") {
|
|
2728
2863
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2729
|
-
const nodeId =
|
|
2730
|
-
const providerType =
|
|
2864
|
+
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
2865
|
+
const providerType = readNonEmptyString2(args.metadataEvent.providerType);
|
|
2731
2866
|
if (sessionId) {
|
|
2732
2867
|
const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed", {
|
|
2733
2868
|
occurredAt: eventTimestamp !== null ? new Date(eventTimestamp).toISOString() : void 0
|
|
@@ -2741,8 +2876,11 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2741
2876
|
}
|
|
2742
2877
|
} else if (args.event === "agent:ready") {
|
|
2743
2878
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2744
|
-
const nodeId =
|
|
2745
|
-
const providerType =
|
|
2879
|
+
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
2880
|
+
const providerType = readNonEmptyString2(args.metadataEvent.providerType);
|
|
2881
|
+
const providerSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId) || void 0;
|
|
2882
|
+
const finalSummary = readNonEmptyString2(args.metadataEvent.finalSummary) || void 0;
|
|
2883
|
+
const workerResult = readWorkerResultMetadata(args.metadataEvent);
|
|
2746
2884
|
const completedTask = sessionId ? updateSessionTaskStatus(args.meshId, sessionId, "completed") : null;
|
|
2747
2885
|
if (completedTask) {
|
|
2748
2886
|
completedTaskForLedger = { id: completedTask.id };
|
|
@@ -2757,15 +2895,17 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2757
2895
|
nodeLabel: args.nodeLabel,
|
|
2758
2896
|
taskId: completedTask.id,
|
|
2759
2897
|
completedViaReady: true,
|
|
2760
|
-
providerSessionId
|
|
2761
|
-
finalSummary
|
|
2898
|
+
providerSessionId,
|
|
2899
|
+
finalSummary,
|
|
2900
|
+
workerResult,
|
|
2762
2901
|
evidence: buildTaskCompletionEvidence({
|
|
2763
2902
|
event: "agent:ready",
|
|
2764
2903
|
nodeId,
|
|
2765
2904
|
sessionId,
|
|
2766
2905
|
providerType: providerType || void 0,
|
|
2767
|
-
providerSessionId
|
|
2768
|
-
finalSummary
|
|
2906
|
+
providerSessionId,
|
|
2907
|
+
finalSummary,
|
|
2908
|
+
workerResult
|
|
2769
2909
|
})
|
|
2770
2910
|
}
|
|
2771
2911
|
});
|
|
@@ -2788,13 +2928,13 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2788
2928
|
}
|
|
2789
2929
|
} else if (args.event === "agent:generating_started") {
|
|
2790
2930
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2791
|
-
const nodeId =
|
|
2931
|
+
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
2792
2932
|
if (sessionId && nodeId) {
|
|
2793
2933
|
remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
|
|
2794
2934
|
}
|
|
2795
2935
|
} else if (args.event === "agent:stopped") {
|
|
2796
2936
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2797
|
-
const nodeId =
|
|
2937
|
+
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
2798
2938
|
if (sessionId && nodeId) {
|
|
2799
2939
|
remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
|
|
2800
2940
|
}
|
|
@@ -2805,16 +2945,20 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2805
2945
|
const ledgerKind = EVENT_TO_LEDGER_KIND[args.event];
|
|
2806
2946
|
if (ledgerKind) {
|
|
2807
2947
|
try {
|
|
2808
|
-
const ledgerNodeId =
|
|
2948
|
+
const ledgerNodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId) || void 0;
|
|
2809
2949
|
const ledgerSessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId) || void 0;
|
|
2810
|
-
const ledgerProviderType =
|
|
2950
|
+
const ledgerProviderType = readNonEmptyString2(args.metadataEvent.providerType) || void 0;
|
|
2951
|
+
const providerSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId) || void 0;
|
|
2952
|
+
const finalSummary = readNonEmptyString2(args.metadataEvent.finalSummary) || void 0;
|
|
2953
|
+
const workerResult = readWorkerResultMetadata(args.metadataEvent);
|
|
2811
2954
|
const completionEvidence = ledgerKind === "task_completed" && ledgerNodeId && ledgerSessionId ? buildTaskCompletionEvidence({
|
|
2812
2955
|
event: "agent:generating_completed",
|
|
2813
2956
|
nodeId: ledgerNodeId,
|
|
2814
2957
|
sessionId: ledgerSessionId,
|
|
2815
2958
|
providerType: ledgerProviderType,
|
|
2816
|
-
providerSessionId
|
|
2817
|
-
finalSummary
|
|
2959
|
+
providerSessionId,
|
|
2960
|
+
finalSummary,
|
|
2961
|
+
workerResult
|
|
2818
2962
|
}) : void 0;
|
|
2819
2963
|
appendLedgerEntry(args.meshId, {
|
|
2820
2964
|
kind: ledgerKind,
|
|
@@ -2825,8 +2969,10 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2825
2969
|
event: args.event,
|
|
2826
2970
|
nodeLabel: args.nodeLabel,
|
|
2827
2971
|
taskId: completedTaskForLedger?.id || void 0,
|
|
2828
|
-
providerSessionId
|
|
2829
|
-
finalSummary
|
|
2972
|
+
providerSessionId,
|
|
2973
|
+
finalSummary,
|
|
2974
|
+
workerResult,
|
|
2975
|
+
completionDiagnostic: args.metadataEvent.completionDiagnostic && typeof args.metadataEvent.completionDiagnostic === "object" ? args.metadataEvent.completionDiagnostic : void 0,
|
|
2830
2976
|
evidence: completionEvidence
|
|
2831
2977
|
}
|
|
2832
2978
|
});
|
|
@@ -2841,10 +2987,10 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2841
2987
|
const maxRetries = mesh?.policy?.maxTaskRetries ?? 1;
|
|
2842
2988
|
recoveryContext = getSessionRecoveryContext(args.meshId, {
|
|
2843
2989
|
sessionId: resolveEventSessionId(args.metadataEvent, args.sourceInstanceId) || void 0,
|
|
2844
|
-
nodeId:
|
|
2990
|
+
nodeId: readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId) || void 0,
|
|
2845
2991
|
maxRetries
|
|
2846
2992
|
});
|
|
2847
|
-
recoveryContext.failedProviderType =
|
|
2993
|
+
recoveryContext.failedProviderType = readNonEmptyString2(args.metadataEvent.providerType) || null;
|
|
2848
2994
|
if (recoveryContext.retryRecommended && recoveryContext.consecutiveNodeFailures > 0) {
|
|
2849
2995
|
appendLedgerEntry(args.meshId, {
|
|
2850
2996
|
kind: "recovery_attempted",
|
|
@@ -2900,7 +3046,7 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2900
3046
|
meshId: args.meshId,
|
|
2901
3047
|
nodeLabel: args.nodeLabel,
|
|
2902
3048
|
nodeId: args.nodeId || void 0,
|
|
2903
|
-
workspace:
|
|
3049
|
+
workspace: readNonEmptyString2(args.metadataEvent.workspace),
|
|
2904
3050
|
metadataEvent: {
|
|
2905
3051
|
...args.metadataEvent,
|
|
2906
3052
|
...recoveryContext ? { recoveryContext } : {}
|
|
@@ -2926,14 +3072,14 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2926
3072
|
return { success: true, forwarded: coordinatorInstances.length };
|
|
2927
3073
|
}
|
|
2928
3074
|
function handleMeshForwardEvent(components, payload) {
|
|
2929
|
-
const eventName =
|
|
3075
|
+
const eventName = readNonEmptyString2(payload.event);
|
|
2930
3076
|
if (!isMeshCoordinatorEvent(eventName)) {
|
|
2931
3077
|
return { success: false, error: "unsupported mesh event" };
|
|
2932
3078
|
}
|
|
2933
|
-
const meshId =
|
|
3079
|
+
const meshId = readNonEmptyString2(payload.meshId);
|
|
2934
3080
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
2935
|
-
const nodeId =
|
|
2936
|
-
const workspace =
|
|
3081
|
+
const nodeId = readNonEmptyString2(payload.nodeId);
|
|
3082
|
+
const workspace = readNonEmptyString2(payload.workspace);
|
|
2937
3083
|
const nodeLabel = nodeId ? `Node '${nodeId}'` : workspace ? `Agent at ${workspace}` : "Remote agent";
|
|
2938
3084
|
return injectMeshSystemMessage(components, {
|
|
2939
3085
|
meshId,
|
|
@@ -2941,41 +3087,41 @@ function handleMeshForwardEvent(components, payload) {
|
|
|
2941
3087
|
nodeLabel,
|
|
2942
3088
|
event: eventName,
|
|
2943
3089
|
metadataEvent: {
|
|
2944
|
-
targetSessionId:
|
|
2945
|
-
providerType:
|
|
2946
|
-
providerSessionId:
|
|
2947
|
-
finalSummary:
|
|
3090
|
+
targetSessionId: readNonEmptyString2(payload.targetSessionId) || readNonEmptyString2(payload.sessionId) || readNonEmptyString2(payload.instanceId),
|
|
3091
|
+
providerType: readNonEmptyString2(payload.providerType),
|
|
3092
|
+
providerSessionId: readNonEmptyString2(payload.providerSessionId),
|
|
3093
|
+
finalSummary: readNonEmptyString2(payload.finalSummary) || readNonEmptyString2(payload.summary),
|
|
2948
3094
|
...payload.timestamp !== void 0 ? { timestamp: payload.timestamp } : {},
|
|
2949
3095
|
intentional: payload.intentional === true,
|
|
2950
3096
|
intentionalStop: payload.intentionalStop === true,
|
|
2951
3097
|
operatorCleanup: payload.operatorCleanup === true,
|
|
2952
|
-
reason:
|
|
2953
|
-
stopReason:
|
|
2954
|
-
cleanupReason:
|
|
2955
|
-
source:
|
|
3098
|
+
reason: readNonEmptyString2(payload.reason),
|
|
3099
|
+
stopReason: readNonEmptyString2(payload.stopReason),
|
|
3100
|
+
cleanupReason: readNonEmptyString2(payload.cleanupReason),
|
|
3101
|
+
source: readNonEmptyString2(payload.source)
|
|
2956
3102
|
}
|
|
2957
3103
|
});
|
|
2958
3104
|
}
|
|
2959
3105
|
function setupMeshEventForwarding(components) {
|
|
2960
3106
|
components.instanceManager.onEvent((event) => {
|
|
2961
3107
|
if (!isMeshCoordinatorEvent(event.event)) return;
|
|
2962
|
-
const instanceId =
|
|
3108
|
+
const instanceId = readNonEmptyString2(event.instanceId);
|
|
2963
3109
|
if (!instanceId) return;
|
|
2964
3110
|
const sourceInstance = components.instanceManager.getInstance(instanceId);
|
|
2965
3111
|
if (!sourceInstance || sourceInstance.category !== "cli") return;
|
|
2966
3112
|
const state = sourceInstance.getState();
|
|
2967
|
-
const workspace =
|
|
3113
|
+
const workspace = readNonEmptyString2(state.workspace);
|
|
2968
3114
|
if (!workspace) return;
|
|
2969
3115
|
const settings = state.settings && typeof state.settings === "object" ? state.settings : {};
|
|
2970
|
-
if (
|
|
2971
|
-
const meshIdFromRuntime =
|
|
3116
|
+
if (readNonEmptyString2(settings.meshCoordinatorFor)) return;
|
|
3117
|
+
const meshIdFromRuntime = readNonEmptyString2(settings.meshNodeFor);
|
|
2972
3118
|
const isMeshDelegate = Boolean(meshIdFromRuntime || settings.launchedByCoordinator);
|
|
2973
3119
|
if (!isMeshDelegate) return;
|
|
2974
3120
|
const mesh = meshIdFromRuntime ? getMeshWithCache(components, meshIdFromRuntime) : getMeshByRepo(workspace);
|
|
2975
|
-
const meshId = meshIdFromRuntime ||
|
|
3121
|
+
const meshId = meshIdFromRuntime || readNonEmptyString2(mesh?.id);
|
|
2976
3122
|
if (!meshId) return;
|
|
2977
3123
|
const targetNode = mesh?.nodes?.find((n) => n.workspace === workspace);
|
|
2978
|
-
const runtimeNodeId =
|
|
3124
|
+
const runtimeNodeId = readNonEmptyString2(settings.meshNodeId);
|
|
2979
3125
|
const resolvedNodeId = targetNode?.id || runtimeNodeId;
|
|
2980
3126
|
const nodeLabel = targetNode ? `Node '${targetNode.id}'` : runtimeNodeId ? `Node '${runtimeNodeId}'` : `Agent at ${workspace}`;
|
|
2981
3127
|
injectMeshSystemMessage(components, {
|
|
@@ -3912,7 +4058,9 @@ function resolveCliSpawnPlan(options) {
|
|
|
3912
4058
|
const configuredCommand = typeof runtimeSettings.executablePath === "string" && runtimeSettings.executablePath.trim() ? runtimeSettings.executablePath.trim() : spawnConfig.command;
|
|
3913
4059
|
const binaryPath = findBinary(configuredCommand);
|
|
3914
4060
|
const isWin = os10.platform() === "win32";
|
|
3915
|
-
const allArgs = [...spawnConfig.args, ...extraArgs]
|
|
4061
|
+
const allArgs = [...spawnConfig.args, ...extraArgs].map(
|
|
4062
|
+
(arg) => typeof arg === "string" ? arg.replace(/\{\{workingDir\}\}/g, workingDir) : arg
|
|
4063
|
+
);
|
|
3916
4064
|
let shellCmd;
|
|
3917
4065
|
let shellArgs;
|
|
3918
4066
|
const useShellUnix = !isWin && (!!spawnConfig.shell || !path15.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
@@ -8527,6 +8675,152 @@ function buildMeshLedgerReconciliationEvidence(meshId, replicas) {
|
|
|
8527
8675
|
|
|
8528
8676
|
// src/index.ts
|
|
8529
8677
|
init_mesh_work_queue();
|
|
8678
|
+
|
|
8679
|
+
// src/mesh/mesh-active-work.ts
|
|
8680
|
+
var DIRECT_DISPATCH_VIA = /* @__PURE__ */ new Set(["p2p_direct", "local_direct", "mesh_send_task"]);
|
|
8681
|
+
var TERMINAL_LEDGER_KINDS = /* @__PURE__ */ new Set(["task_completed", "task_failed", "task_stalled"]);
|
|
8682
|
+
function readString2(value) {
|
|
8683
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
8684
|
+
}
|
|
8685
|
+
function summarizeMessage(message) {
|
|
8686
|
+
const oneLine = message.replace(/\s+/g, " ").trim();
|
|
8687
|
+
const title = oneLine.length > 96 ? `${oneLine.slice(0, 93)}...` : oneLine;
|
|
8688
|
+
return { title: title || "(untitled task)", summary: oneLine };
|
|
8689
|
+
}
|
|
8690
|
+
function elapsedSince(value, now) {
|
|
8691
|
+
const started = value ? new Date(value).getTime() : Number.NaN;
|
|
8692
|
+
return Number.isFinite(started) ? Math.max(0, now - started) : 0;
|
|
8693
|
+
}
|
|
8694
|
+
function sessionStatusFromNodes(nodes, nodeId, sessionId) {
|
|
8695
|
+
if (!nodeId || !sessionId || !Array.isArray(nodes)) return void 0;
|
|
8696
|
+
const node = nodes.find((item) => readString2(item?.id) === nodeId || readString2(item?.nodeId) === nodeId || readString2(item?.node_id) === nodeId);
|
|
8697
|
+
if (!node) return void 0;
|
|
8698
|
+
const candidates = [];
|
|
8699
|
+
for (const value of [node.sessions, node.activeSessions, node.active_sessions, node.lastProbe?.sessions, node.last_probe?.sessions, node.lastProbe?.status?.sessions, node.last_probe?.status?.sessions]) {
|
|
8700
|
+
if (Array.isArray(value)) candidates.push(...value);
|
|
8701
|
+
}
|
|
8702
|
+
for (const value of [node.activeSession, node.active_session, node.currentSession, node.current_session, node.runtimeSession, node.runtime_session, node.session]) {
|
|
8703
|
+
if (value && typeof value === "object") candidates.push(value);
|
|
8704
|
+
}
|
|
8705
|
+
const session = candidates.find((item) => {
|
|
8706
|
+
const id = readString2(item?.id) || readString2(item?.sessionId) || readString2(item?.session_id) || readString2(item?.runtimeSessionId) || readString2(item?.instanceId);
|
|
8707
|
+
return id === sessionId;
|
|
8708
|
+
});
|
|
8709
|
+
if (!session) return void 0;
|
|
8710
|
+
const raw = `${readString2(session.status) || ""} ${readString2(session.lifecycle) || ""} ${readString2(session.state) || ""} ${readString2(session.activeChat?.status) || ""}`.toLowerCase();
|
|
8711
|
+
if (raw.includes("approval")) return "awaiting_approval";
|
|
8712
|
+
if (raw.includes("generating") || raw.includes("running") || raw.includes("busy")) return "generating";
|
|
8713
|
+
if (raw.includes("failed") || raw.includes("stopped") || raw.includes("terminated") || raw.includes("exited")) return "failed";
|
|
8714
|
+
if (raw.includes("idle") || raw.includes("waiting_input") || raw.includes("ready")) return "idle";
|
|
8715
|
+
return void 0;
|
|
8716
|
+
}
|
|
8717
|
+
function isDirectDispatch(entry) {
|
|
8718
|
+
if (entry.kind !== "task_dispatched") return false;
|
|
8719
|
+
const payload = entry.payload || {};
|
|
8720
|
+
if (payload.source === "direct") return true;
|
|
8721
|
+
const via = readString2(payload.via);
|
|
8722
|
+
return Boolean(via && DIRECT_DISPATCH_VIA.has(via) && payload.source !== "queue");
|
|
8723
|
+
}
|
|
8724
|
+
function directDispatchTaskId(entry) {
|
|
8725
|
+
return readString2(entry.payload?.taskId) || entry.id;
|
|
8726
|
+
}
|
|
8727
|
+
function terminalMatchesDispatch(terminal, dispatch, taskId) {
|
|
8728
|
+
const terminalTaskId = readString2(terminal.payload?.taskId);
|
|
8729
|
+
if (terminalTaskId && terminalTaskId === taskId) return true;
|
|
8730
|
+
if (terminalTaskId && terminalTaskId !== taskId) return false;
|
|
8731
|
+
if (dispatch.sessionId && terminal.sessionId === dispatch.sessionId) return true;
|
|
8732
|
+
return Boolean(dispatch.nodeId && terminal.nodeId === dispatch.nodeId && !dispatch.sessionId);
|
|
8733
|
+
}
|
|
8734
|
+
function statusFromTerminal(entry) {
|
|
8735
|
+
if (entry.kind === "task_approval_needed") return "awaiting_approval";
|
|
8736
|
+
if (entry.kind === "task_completed") return "idle";
|
|
8737
|
+
return "failed";
|
|
8738
|
+
}
|
|
8739
|
+
function buildMeshActiveWorkSummary(activeWork) {
|
|
8740
|
+
const statusCounts = {
|
|
8741
|
+
pending: 0,
|
|
8742
|
+
assigned: 0,
|
|
8743
|
+
generating: 0,
|
|
8744
|
+
idle: 0,
|
|
8745
|
+
failed: 0,
|
|
8746
|
+
awaiting_approval: 0
|
|
8747
|
+
};
|
|
8748
|
+
const sourceCounts = { queue: 0, direct: 0 };
|
|
8749
|
+
for (const item of activeWork) {
|
|
8750
|
+
sourceCounts[item.source] += 1;
|
|
8751
|
+
statusCounts[item.status] += 1;
|
|
8752
|
+
}
|
|
8753
|
+
return {
|
|
8754
|
+
totalActiveCount: activeWork.length,
|
|
8755
|
+
queueActiveCount: sourceCounts.queue,
|
|
8756
|
+
directActiveCount: sourceCounts.direct,
|
|
8757
|
+
awaitingApprovalCount: statusCounts.awaiting_approval,
|
|
8758
|
+
generatingCount: statusCounts.generating,
|
|
8759
|
+
failedCount: statusCounts.failed,
|
|
8760
|
+
idleCount: statusCounts.idle,
|
|
8761
|
+
sourceCounts,
|
|
8762
|
+
statusCounts
|
|
8763
|
+
};
|
|
8764
|
+
}
|
|
8765
|
+
function buildMeshActiveWork(opts) {
|
|
8766
|
+
const now = opts.now ?? Date.now();
|
|
8767
|
+
const records = [];
|
|
8768
|
+
for (const task of opts.queue || []) {
|
|
8769
|
+
if (task.status !== "pending" && task.status !== "assigned") continue;
|
|
8770
|
+
const { title, summary } = summarizeMessage(task.message || "");
|
|
8771
|
+
records.push({
|
|
8772
|
+
taskId: task.id,
|
|
8773
|
+
source: "queue",
|
|
8774
|
+
status: task.status,
|
|
8775
|
+
nodeId: task.assignedNodeId || task.targetNodeId,
|
|
8776
|
+
sessionId: task.assignedSessionId || task.targetSessionId,
|
|
8777
|
+
taskTitle: title,
|
|
8778
|
+
taskSummary: summary,
|
|
8779
|
+
message: task.message,
|
|
8780
|
+
taskMode: task.taskMode,
|
|
8781
|
+
createdAt: task.createdAt,
|
|
8782
|
+
updatedAt: task.updatedAt,
|
|
8783
|
+
dispatchedAt: task.dispatchTimestamp,
|
|
8784
|
+
elapsedMs: elapsedSince(task.dispatchTimestamp || task.createdAt, now)
|
|
8785
|
+
});
|
|
8786
|
+
}
|
|
8787
|
+
const ledgerEntries = (opts.ledgerEntries || []).slice().sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
8788
|
+
const terminals = ledgerEntries.filter((entry) => TERMINAL_LEDGER_KINDS.has(entry.kind) || entry.kind === "task_approval_needed");
|
|
8789
|
+
for (const dispatch of ledgerEntries.filter(isDirectDispatch)) {
|
|
8790
|
+
const taskId = directDispatchTaskId(dispatch);
|
|
8791
|
+
const terminal = terminals.filter((entry) => new Date(entry.timestamp).getTime() >= new Date(dispatch.timestamp).getTime()).find((entry) => terminalMatchesDispatch(entry, dispatch, taskId));
|
|
8792
|
+
const terminalStatus = terminal ? statusFromTerminal(terminal) : void 0;
|
|
8793
|
+
const liveStatus = sessionStatusFromNodes(opts.nodes, dispatch.nodeId, dispatch.sessionId);
|
|
8794
|
+
const status = terminalStatus || liveStatus || "assigned";
|
|
8795
|
+
const terminalRow = Boolean(terminal && terminal.kind !== "task_approval_needed");
|
|
8796
|
+
if (terminalRow && opts.includeTerminalDirect !== true) continue;
|
|
8797
|
+
const message = readString2(dispatch.payload?.message) || readString2(dispatch.payload?.summary) || "";
|
|
8798
|
+
const { title, summary } = summarizeMessage(message);
|
|
8799
|
+
records.push({
|
|
8800
|
+
taskId,
|
|
8801
|
+
source: "direct",
|
|
8802
|
+
status,
|
|
8803
|
+
nodeId: dispatch.nodeId,
|
|
8804
|
+
sessionId: dispatch.sessionId,
|
|
8805
|
+
providerType: dispatch.providerType || readString2(dispatch.payload?.providerType),
|
|
8806
|
+
taskTitle: readString2(dispatch.payload?.taskTitle) || title,
|
|
8807
|
+
taskSummary: readString2(dispatch.payload?.taskSummary) || summary,
|
|
8808
|
+
message,
|
|
8809
|
+
taskMode: readString2(dispatch.payload?.taskMode),
|
|
8810
|
+
createdAt: dispatch.timestamp,
|
|
8811
|
+
updatedAt: terminal?.timestamp || dispatch.timestamp,
|
|
8812
|
+
dispatchedAt: dispatch.timestamp,
|
|
8813
|
+
elapsedMs: elapsedSince(dispatch.timestamp, now),
|
|
8814
|
+
terminal: terminalRow,
|
|
8815
|
+
terminalKind: terminal?.kind,
|
|
8816
|
+
terminalAt: terminal?.timestamp
|
|
8817
|
+
});
|
|
8818
|
+
}
|
|
8819
|
+
records.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
8820
|
+
return { activeWork: records, summary: buildMeshActiveWorkSummary(records) };
|
|
8821
|
+
}
|
|
8822
|
+
|
|
8823
|
+
// src/index.ts
|
|
8530
8824
|
init_mesh_host_ownership();
|
|
8531
8825
|
init_mesh_events();
|
|
8532
8826
|
|
|
@@ -18526,6 +18820,44 @@ var CliProviderInstance = class {
|
|
|
18526
18820
|
const content = lastVisible ? flattenContent(lastVisible.content).trim() : "";
|
|
18527
18821
|
return role === "assistant" && !!content;
|
|
18528
18822
|
}
|
|
18823
|
+
buildCompletedFinalizationDiagnostic(args) {
|
|
18824
|
+
let parsed = null;
|
|
18825
|
+
let parseError;
|
|
18826
|
+
try {
|
|
18827
|
+
parsed = this.adapter.getScriptParsedStatus();
|
|
18828
|
+
} catch (error) {
|
|
18829
|
+
parseError = error?.message || String(error);
|
|
18830
|
+
}
|
|
18831
|
+
const visibleMessages = (Array.isArray(parsed?.messages) ? parsed.messages : []).filter((message) => isUserFacingChatMessage(message));
|
|
18832
|
+
const lastVisible = visibleMessages[visibleMessages.length - 1];
|
|
18833
|
+
const lastVisibleRole = typeof lastVisible?.role === "string" ? lastVisible.role.trim().toLowerCase() : null;
|
|
18834
|
+
const lastVisibleKind = typeof lastVisible?.kind === "string" ? lastVisible.kind : null;
|
|
18835
|
+
const lastVisibleContentLength = lastVisible ? flattenContent(lastVisible.content).trim().length : 0;
|
|
18836
|
+
return {
|
|
18837
|
+
providerType: this.type,
|
|
18838
|
+
sessionId: this.instanceId,
|
|
18839
|
+
providerSessionId: this.providerSessionId || null,
|
|
18840
|
+
workspace: this.workingDir,
|
|
18841
|
+
blockReason: args.blockReason,
|
|
18842
|
+
emittedAfterFinalizationTimeout: args.emittedAfterFinalizationTimeout,
|
|
18843
|
+
waitedMs: args.waitedMs,
|
|
18844
|
+
maxWaitMs: COMPLETED_FINALIZATION_MAX_WAIT_MS,
|
|
18845
|
+
adapterStatus: typeof args.latestStatus?.status === "string" ? args.latestStatus.status : null,
|
|
18846
|
+
latestVisibleStatus: args.latestVisibleStatus,
|
|
18847
|
+
parsedStatus: typeof parsed?.status === "string" ? parsed.status : parseError ? "parse_error" : "unknown",
|
|
18848
|
+
parseError: parseError || void 0,
|
|
18849
|
+
finalAssistantPresent: this.completionHasFinalAssistantMessage(parsed?.messages),
|
|
18850
|
+
visibleMessageCount: visibleMessages.length,
|
|
18851
|
+
lastVisibleRole,
|
|
18852
|
+
lastVisibleKind,
|
|
18853
|
+
lastVisibleContentLength,
|
|
18854
|
+
pendingStartedAt: this.generatingStartedAt || null,
|
|
18855
|
+
pendingFirstObservedAt: args.pending.firstObservedAt,
|
|
18856
|
+
pendingTimestamp: args.pending.timestamp,
|
|
18857
|
+
pendingDurationSec: args.pending.duration,
|
|
18858
|
+
previousBlockReason: args.pending.loggedBlockReason || null
|
|
18859
|
+
};
|
|
18860
|
+
}
|
|
18529
18861
|
hasAdapterPendingResponse() {
|
|
18530
18862
|
const adapterAny = this.adapter;
|
|
18531
18863
|
if (adapterAny?.isWaitingForResponse === true) return true;
|
|
@@ -18598,7 +18930,23 @@ var CliProviderInstance = class {
|
|
|
18598
18930
|
this.scheduleCompletedDebounceFlush(COMPLETED_FINALIZATION_RETRY_MS);
|
|
18599
18931
|
return;
|
|
18600
18932
|
}
|
|
18601
|
-
|
|
18933
|
+
const completionDiagnostic = this.buildCompletedFinalizationDiagnostic({
|
|
18934
|
+
blockReason,
|
|
18935
|
+
latestStatus,
|
|
18936
|
+
latestVisibleStatus,
|
|
18937
|
+
waitedMs,
|
|
18938
|
+
pending,
|
|
18939
|
+
emittedAfterFinalizationTimeout: true
|
|
18940
|
+
});
|
|
18941
|
+
LOG.warn("CLI", `[${this.type}] emitting completed event after ${waitedMs}ms without finalized assistant turn (${blockReason})`);
|
|
18942
|
+
this.pushEvent({
|
|
18943
|
+
event: "agent:generating_completed",
|
|
18944
|
+
chatTitle: pending.chatTitle,
|
|
18945
|
+
duration: pending.duration,
|
|
18946
|
+
timestamp: pending.timestamp,
|
|
18947
|
+
finalSummary: extractFinalSummaryFromMessages(this.adapter?.getScriptParsedStatus()?.messages),
|
|
18948
|
+
completionDiagnostic
|
|
18949
|
+
});
|
|
18602
18950
|
this.completedDebouncePending = null;
|
|
18603
18951
|
this.completedDebounceTimer = null;
|
|
18604
18952
|
this.generatingStartedAt = 0;
|
|
@@ -24969,6 +25317,9 @@ function reconcileInlineMeshCache(cached, incoming) {
|
|
|
24969
25317
|
const cachedNodes = Array.isArray(cached.nodes) ? cached.nodes : [];
|
|
24970
25318
|
const incomingNodes = Array.isArray(incoming.nodes) ? incoming.nodes : [];
|
|
24971
25319
|
if (!cachedNodes.length || !incomingNodes.length) return { ...cached, ...incoming };
|
|
25320
|
+
const cachedUpdatedAt = Date.parse(readStringValue(cached.updatedAt, cached.updated_at) || "");
|
|
25321
|
+
const incomingUpdatedAt = Date.parse(readStringValue(incoming.updatedAt, incoming.updated_at) || "");
|
|
25322
|
+
const preserveCachedMembership = Number.isFinite(cachedUpdatedAt) && (!Number.isFinite(incomingUpdatedAt) || cachedUpdatedAt > incomingUpdatedAt);
|
|
24972
25323
|
const cachedById = /* @__PURE__ */ new Map();
|
|
24973
25324
|
for (const node of cachedNodes) {
|
|
24974
25325
|
const nodeId = readInlineMeshNodeId(node);
|
|
@@ -24977,12 +25328,13 @@ function reconcileInlineMeshCache(cached, incoming) {
|
|
|
24977
25328
|
const nodes = incomingNodes.map((incomingNode) => {
|
|
24978
25329
|
const nodeId = readInlineMeshNodeId(incomingNode);
|
|
24979
25330
|
const cachedNode = nodeId ? cachedById.get(nodeId) : void 0;
|
|
25331
|
+
if (!cachedNode && preserveCachedMembership) return null;
|
|
24980
25332
|
if (!cachedNode) return incomingNode;
|
|
24981
25333
|
if (hasInlineMeshTransientNodeState(incomingNode)) {
|
|
24982
25334
|
return { ...cachedNode, ...incomingNode };
|
|
24983
25335
|
}
|
|
24984
25336
|
return { ...stripInlineMeshTransientNodeState(cachedNode), ...incomingNode };
|
|
24985
|
-
});
|
|
25337
|
+
}).filter(Boolean);
|
|
24986
25338
|
return {
|
|
24987
25339
|
...cached,
|
|
24988
25340
|
...incoming,
|
|
@@ -36485,6 +36837,8 @@ export {
|
|
|
36485
36837
|
buildChatTailDeliverySignature,
|
|
36486
36838
|
buildCoordinatorSystemPrompt,
|
|
36487
36839
|
buildMachineInfo,
|
|
36840
|
+
buildMeshActiveWork,
|
|
36841
|
+
buildMeshActiveWorkSummary,
|
|
36488
36842
|
buildMeshHostRequiredFailure,
|
|
36489
36843
|
buildMeshLedgerReconciliationEvidence,
|
|
36490
36844
|
buildMeshLedgerReplicaEvidence,
|
|
@@ -36495,6 +36849,7 @@ export {
|
|
|
36495
36849
|
buildSessionModalDeliverySignature,
|
|
36496
36850
|
buildStatusSnapshot,
|
|
36497
36851
|
buildSystemChatMessage,
|
|
36852
|
+
buildTaskCompletionEvidence,
|
|
36498
36853
|
buildTerminalChatMessage,
|
|
36499
36854
|
buildThoughtChatMessage,
|
|
36500
36855
|
buildToolChatMessage,
|
|
@@ -36605,6 +36960,8 @@ export {
|
|
|
36605
36960
|
normalizeInputEnvelope,
|
|
36606
36961
|
normalizeManagedStatus,
|
|
36607
36962
|
normalizeMeshDaemonRole,
|
|
36963
|
+
normalizeMeshTaskMode,
|
|
36964
|
+
normalizeMeshWorkerResult,
|
|
36608
36965
|
normalizeMessageParts,
|
|
36609
36966
|
normalizeRepoIdentity,
|
|
36610
36967
|
normalizeSessionModalFields,
|
|
@@ -36660,6 +37017,7 @@ export {
|
|
|
36660
37017
|
updateSessionTaskStatus,
|
|
36661
37018
|
updateTaskStatus,
|
|
36662
37019
|
upsertSavedProviderSession,
|
|
36663
|
-
validateMeshRefineConfig
|
|
37020
|
+
validateMeshRefineConfig,
|
|
37021
|
+
validateMeshTaskModeRequest
|
|
36664
37022
|
};
|
|
36665
37023
|
//# sourceMappingURL=index.mjs.map
|