@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.js
CHANGED
|
@@ -1269,6 +1269,7 @@ __export(mesh_ledger_exports, {
|
|
|
1269
1269
|
getSessionRecoveryContext: () => getSessionRecoveryContext,
|
|
1270
1270
|
isIntentionalCleanupStopEntry: () => isIntentionalCleanupStopEntry,
|
|
1271
1271
|
meshLedgerEvents: () => meshLedgerEvents,
|
|
1272
|
+
normalizeMeshWorkerResult: () => normalizeMeshWorkerResult,
|
|
1272
1273
|
readLedgerEntries: () => readLedgerEntries,
|
|
1273
1274
|
readLedgerSlice: () => readLedgerSlice
|
|
1274
1275
|
});
|
|
@@ -1292,6 +1293,86 @@ function getRotatedPath(meshId, index) {
|
|
|
1292
1293
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1293
1294
|
return (0, import_path4.join)(getLedgerDir(), `${safe}.${index}.jsonl`);
|
|
1294
1295
|
}
|
|
1296
|
+
function readNonEmptyString(value) {
|
|
1297
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
1298
|
+
}
|
|
1299
|
+
function readStringArray(value) {
|
|
1300
|
+
if (!Array.isArray(value)) return [];
|
|
1301
|
+
return value.map((item) => readNonEmptyString(item)).filter(Boolean);
|
|
1302
|
+
}
|
|
1303
|
+
function extractJsonObjectFromSummary(summary) {
|
|
1304
|
+
const text = readNonEmptyString(summary);
|
|
1305
|
+
if (!text) return void 0;
|
|
1306
|
+
const fenced = text.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
1307
|
+
const candidates = [fenced?.[1], text].filter(Boolean);
|
|
1308
|
+
for (const candidate of candidates) {
|
|
1309
|
+
const trimmed = candidate.trim();
|
|
1310
|
+
if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) continue;
|
|
1311
|
+
try {
|
|
1312
|
+
const parsed = JSON.parse(trimmed);
|
|
1313
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
|
|
1314
|
+
} catch {
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
return void 0;
|
|
1318
|
+
}
|
|
1319
|
+
function normalizeValidationResults(value) {
|
|
1320
|
+
if (!Array.isArray(value)) return [];
|
|
1321
|
+
return value.filter((item) => item && typeof item === "object" && !Array.isArray(item)).map((item) => {
|
|
1322
|
+
const status = ["passed", "failed", "skipped", "unknown"].includes(item.status) ? item.status : "unknown";
|
|
1323
|
+
return {
|
|
1324
|
+
...readNonEmptyString(item.command) ? { command: readNonEmptyString(item.command) } : {},
|
|
1325
|
+
status,
|
|
1326
|
+
...Number.isFinite(Number(item.durationMs)) ? { durationMs: Number(item.durationMs) } : {},
|
|
1327
|
+
...readNonEmptyString(item.outputPath) ? { outputPath: readNonEmptyString(item.outputPath) } : {},
|
|
1328
|
+
...readNonEmptyString(item.summary) ? { summary: readNonEmptyString(item.summary) } : {}
|
|
1329
|
+
};
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
1332
|
+
function normalizeProcessArtifacts(value) {
|
|
1333
|
+
if (!Array.isArray(value)) return [];
|
|
1334
|
+
const kinds = /* @__PURE__ */ new Set(["process", "log", "port", "window", "session", "file", "url", "other"]);
|
|
1335
|
+
return value.filter((item) => item && typeof item === "object" && !Array.isArray(item)).map((item) => ({
|
|
1336
|
+
kind: kinds.has(item.kind) ? item.kind : "other",
|
|
1337
|
+
...readNonEmptyString(item.id) ? { id: readNonEmptyString(item.id) } : {},
|
|
1338
|
+
...readNonEmptyString(item.label) ? { label: readNonEmptyString(item.label) } : {},
|
|
1339
|
+
...readNonEmptyString(item.locator) ? { locator: readNonEmptyString(item.locator) } : {},
|
|
1340
|
+
...Number.isFinite(Number(item.pid)) ? { pid: Number(item.pid) } : {},
|
|
1341
|
+
...Number.isFinite(Number(item.port)) ? { port: Number(item.port) } : {},
|
|
1342
|
+
...readNonEmptyString(item.url) ? { url: readNonEmptyString(item.url) } : {},
|
|
1343
|
+
...readNonEmptyString(item.path) ? { path: readNonEmptyString(item.path) } : {},
|
|
1344
|
+
...readNonEmptyString(item.sessionId) ? { sessionId: readNonEmptyString(item.sessionId) } : {},
|
|
1345
|
+
...typeof item.keepRunning === "boolean" ? { keepRunning: item.keepRunning } : {},
|
|
1346
|
+
...item.metadata && typeof item.metadata === "object" && !Array.isArray(item.metadata) ? { metadata: item.metadata } : {}
|
|
1347
|
+
}));
|
|
1348
|
+
}
|
|
1349
|
+
function normalizeMeshWorkerResult(input, source = "explicit_metadata") {
|
|
1350
|
+
const raw = input && typeof input === "object" ? input : {};
|
|
1351
|
+
const status = ["completed", "failed", "blocked", "partial", "unknown"].includes(String(raw.status)) ? raw.status : "unknown";
|
|
1352
|
+
const gitStatus = raw.gitStatus && typeof raw.gitStatus === "object" && !Array.isArray(raw.gitStatus) ? raw.gitStatus : void 0;
|
|
1353
|
+
return {
|
|
1354
|
+
status,
|
|
1355
|
+
...readNonEmptyString(raw.classification) ? { classification: readNonEmptyString(raw.classification) } : {},
|
|
1356
|
+
changedFiles: readStringArray(raw.changedFiles),
|
|
1357
|
+
validationResults: normalizeValidationResults(raw.validationResults),
|
|
1358
|
+
...gitStatus ? { gitStatus } : {},
|
|
1359
|
+
processArtifacts: normalizeProcessArtifacts(raw.processArtifacts),
|
|
1360
|
+
errors: readStringArray(raw.errors),
|
|
1361
|
+
...readNonEmptyString(raw.nextAction) ? { nextAction: readNonEmptyString(raw.nextAction) } : {},
|
|
1362
|
+
requiresUserAction: raw.requiresUserAction === true,
|
|
1363
|
+
source
|
|
1364
|
+
};
|
|
1365
|
+
}
|
|
1366
|
+
function resolveWorkerResult(opts) {
|
|
1367
|
+
if (opts.workerResult && typeof opts.workerResult === "object") {
|
|
1368
|
+
return normalizeMeshWorkerResult(opts.workerResult, "explicit_metadata");
|
|
1369
|
+
}
|
|
1370
|
+
const parsed = extractJsonObjectFromSummary(opts.finalSummary);
|
|
1371
|
+
if (parsed) {
|
|
1372
|
+
return normalizeMeshWorkerResult(parsed, "final_summary_json");
|
|
1373
|
+
}
|
|
1374
|
+
return normalizeMeshWorkerResult(void 0, "default");
|
|
1375
|
+
}
|
|
1295
1376
|
function buildTaskCompletionEvidence(opts) {
|
|
1296
1377
|
const providerSessionId = opts.providerSessionId?.trim() || void 0;
|
|
1297
1378
|
const providerType = opts.providerType?.trim() || void 0;
|
|
@@ -1308,6 +1389,7 @@ function buildTaskCompletionEvidence(opts) {
|
|
|
1308
1389
|
providerSessionId,
|
|
1309
1390
|
finalSummaryAvailable: typeof opts.finalSummary === "string" && opts.finalSummary.trim().length > 0
|
|
1310
1391
|
},
|
|
1392
|
+
workerResult: resolveWorkerResult(opts),
|
|
1311
1393
|
git: {
|
|
1312
1394
|
status: "deferred",
|
|
1313
1395
|
reason: "ordinary_completion_git_status_not_checked"
|
|
@@ -1606,16 +1688,45 @@ var mesh_work_queue_exports = {};
|
|
|
1606
1688
|
__export(mesh_work_queue_exports, {
|
|
1607
1689
|
ACTIVE_MESH_QUEUE_STATUSES: () => ACTIVE_MESH_QUEUE_STATUSES,
|
|
1608
1690
|
HISTORICAL_MESH_QUEUE_STATUSES: () => HISTORICAL_MESH_QUEUE_STATUSES,
|
|
1691
|
+
MESH_TASK_MODES: () => MESH_TASK_MODES,
|
|
1609
1692
|
cancelTask: () => cancelTask,
|
|
1610
1693
|
claimNextTask: () => claimNextTask,
|
|
1611
1694
|
enqueueTask: () => enqueueTask,
|
|
1612
1695
|
getMeshQueueStats: () => getMeshQueueStats,
|
|
1613
1696
|
getQueue: () => getQueue,
|
|
1697
|
+
normalizeMeshTaskMode: () => normalizeMeshTaskMode,
|
|
1614
1698
|
recordTaskAutoLaunch: () => recordTaskAutoLaunch,
|
|
1615
1699
|
requeueTask: () => requeueTask,
|
|
1616
1700
|
updateSessionTaskStatus: () => updateSessionTaskStatus,
|
|
1617
|
-
updateTaskStatus: () => updateTaskStatus
|
|
1701
|
+
updateTaskStatus: () => updateTaskStatus,
|
|
1702
|
+
validateMeshTaskModeRequest: () => validateMeshTaskModeRequest
|
|
1618
1703
|
});
|
|
1704
|
+
function normalizeMeshTaskMode(value) {
|
|
1705
|
+
if (typeof value !== "string") return void 0;
|
|
1706
|
+
const normalized = value.trim();
|
|
1707
|
+
return MESH_TASK_MODES.includes(normalized) ? normalized : void 0;
|
|
1708
|
+
}
|
|
1709
|
+
function validateMeshTaskModeRequest(mode, message) {
|
|
1710
|
+
const taskMode = normalizeMeshTaskMode(mode);
|
|
1711
|
+
if (!taskMode) {
|
|
1712
|
+
return { valid: true, violations: [] };
|
|
1713
|
+
}
|
|
1714
|
+
if (taskMode !== "live_debug_readonly") {
|
|
1715
|
+
return { valid: true, taskMode, violations: [] };
|
|
1716
|
+
}
|
|
1717
|
+
const violations = LIVE_DEBUG_READONLY_FORBIDDEN.filter((rule) => rule.pattern.test(message || "")).map((rule) => rule.label);
|
|
1718
|
+
return {
|
|
1719
|
+
valid: violations.length === 0,
|
|
1720
|
+
taskMode,
|
|
1721
|
+
violations,
|
|
1722
|
+
allowedOperations: [
|
|
1723
|
+
"process/log/window/port/session inspection",
|
|
1724
|
+
"read-only filesystem listing/reading",
|
|
1725
|
+
"status probes and keep-running handle reporting",
|
|
1726
|
+
"diagnostic summaries without source edits, commits, checkpoints, pushes, deploys, resets, rebases, or destructive cleanups"
|
|
1727
|
+
]
|
|
1728
|
+
};
|
|
1729
|
+
}
|
|
1619
1730
|
function getQueuePath(meshId) {
|
|
1620
1731
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1621
1732
|
return (0, import_path5.join)(getLedgerDir(), `${safe}.queue.json`);
|
|
@@ -1666,6 +1777,10 @@ function writeQueue(meshId, queue) {
|
|
|
1666
1777
|
}
|
|
1667
1778
|
function enqueueTask(meshId, message, opts) {
|
|
1668
1779
|
requireMeshHostQueueOwner(opts);
|
|
1780
|
+
const modeValidation = validateMeshTaskModeRequest(opts?.taskMode, message);
|
|
1781
|
+
if (!modeValidation.valid) {
|
|
1782
|
+
throw new Error(`live_debug_readonly_guardrail_violation: forbidden operations (${modeValidation.violations.join(", ")})`);
|
|
1783
|
+
}
|
|
1669
1784
|
return withQueueLock(meshId, () => {
|
|
1670
1785
|
const queue = readQueue(meshId);
|
|
1671
1786
|
const entry = {
|
|
@@ -1673,6 +1788,7 @@ function enqueueTask(meshId, message, opts) {
|
|
|
1673
1788
|
meshId,
|
|
1674
1789
|
message,
|
|
1675
1790
|
status: "pending",
|
|
1791
|
+
taskMode: modeValidation.taskMode,
|
|
1676
1792
|
targetNodeId: opts?.targetNodeId,
|
|
1677
1793
|
targetSessionId: opts?.targetSessionId,
|
|
1678
1794
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -1834,7 +1950,7 @@ function getMeshQueueStats(meshId) {
|
|
|
1834
1950
|
}))
|
|
1835
1951
|
};
|
|
1836
1952
|
}
|
|
1837
|
-
var import_fs5, import_path5, import_crypto5, ACTIVE_MESH_QUEUE_STATUSES, HISTORICAL_MESH_QUEUE_STATUSES;
|
|
1953
|
+
var import_fs5, import_path5, import_crypto5, ACTIVE_MESH_QUEUE_STATUSES, HISTORICAL_MESH_QUEUE_STATUSES, MESH_TASK_MODES, LIVE_DEBUG_READONLY_FORBIDDEN;
|
|
1838
1954
|
var init_mesh_work_queue = __esm({
|
|
1839
1955
|
"src/mesh/mesh-work-queue.ts"() {
|
|
1840
1956
|
"use strict";
|
|
@@ -1845,6 +1961,14 @@ var init_mesh_work_queue = __esm({
|
|
|
1845
1961
|
init_mesh_host_ownership();
|
|
1846
1962
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
1847
1963
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
1964
|
+
MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
|
|
1965
|
+
LIVE_DEBUG_READONLY_FORBIDDEN = [
|
|
1966
|
+
{ 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 },
|
|
1967
|
+
{ label: "git_mutation", pattern: /\b(?:git\s+(?:add|commit|push|reset|rebase|clean|checkout|switch|merge|tag|restore|rm|mv)|push\b)/i },
|
|
1968
|
+
{ label: "checkpoint", pattern: /\b(checkpoint|mesh_checkpoint)\b/i },
|
|
1969
|
+
{ label: "deploy_or_version_bump", pattern: /\b(deploy|wrangler\s+deploy|version[-\s]?bump|npm\s+version|release)\b/i },
|
|
1970
|
+
{ label: "destructive_shell", pattern: /\b(rm\s+-rf|mv\s+\S+\s+\S+|truncate\s|tee\s+\S+|sed\s+-i)\b/i }
|
|
1971
|
+
];
|
|
1848
1972
|
}
|
|
1849
1973
|
});
|
|
1850
1974
|
|
|
@@ -2209,6 +2333,9 @@ __export(mesh_events_exports, {
|
|
|
2209
2333
|
triggerMeshQueue: () => triggerMeshQueue,
|
|
2210
2334
|
tryAssignQueueTask: () => tryAssignQueueTask
|
|
2211
2335
|
});
|
|
2336
|
+
function readWorkerResultMetadata(event) {
|
|
2337
|
+
return readRecord(event.workerResult) || readRecord(event.meshWorkerResult) || readRecord(event.structuredResult);
|
|
2338
|
+
}
|
|
2212
2339
|
function sweepExpiredRemoteIdleSessions() {
|
|
2213
2340
|
const now = Date.now();
|
|
2214
2341
|
for (const [key, session] of remoteIdleSessions) {
|
|
@@ -2274,20 +2401,28 @@ function clearPendingMeshCoordinatorEvents(meshId) {
|
|
|
2274
2401
|
} catch {
|
|
2275
2402
|
}
|
|
2276
2403
|
}
|
|
2277
|
-
function
|
|
2404
|
+
function readNonEmptyString2(value) {
|
|
2278
2405
|
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
2279
2406
|
}
|
|
2407
|
+
function readRecord(value) {
|
|
2408
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
2409
|
+
}
|
|
2280
2410
|
function resolveEventSessionId(event, fallback) {
|
|
2281
|
-
return
|
|
2411
|
+
return readNonEmptyString2(event.targetSessionId) || readNonEmptyString2(event.sessionId) || readNonEmptyString2(event.instanceId) || readNonEmptyString2(fallback);
|
|
2282
2412
|
}
|
|
2283
2413
|
function isMeshCoordinatorEvent(eventName) {
|
|
2284
2414
|
return typeof eventName === "string" && MESH_COORDINATOR_EVENTS.has(eventName);
|
|
2285
2415
|
}
|
|
2286
2416
|
function formatCompletionMetadata(event) {
|
|
2417
|
+
const completionDiagnostic = event.completionDiagnostic && typeof event.completionDiagnostic === "object" ? event.completionDiagnostic : null;
|
|
2418
|
+
const diagnosticReason = completionDiagnostic ? readNonEmptyString2(completionDiagnostic.blockReason) || "present" : "";
|
|
2419
|
+
const finalAssistantPresent = typeof completionDiagnostic?.finalAssistantPresent === "boolean" ? String(completionDiagnostic.finalAssistantPresent) : "";
|
|
2287
2420
|
const parts = [
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2421
|
+
readNonEmptyString2(event.targetSessionId) ? `session_id=${readNonEmptyString2(event.targetSessionId)}` : "",
|
|
2422
|
+
readNonEmptyString2(event.providerType) ? `provider=${readNonEmptyString2(event.providerType)}` : "",
|
|
2423
|
+
readNonEmptyString2(event.providerSessionId) ? `provider_session_id=${readNonEmptyString2(event.providerSessionId)}` : "",
|
|
2424
|
+
diagnosticReason ? `completion_diagnostic=${diagnosticReason}` : "",
|
|
2425
|
+
finalAssistantPresent ? `final_assistant=${finalAssistantPresent}` : ""
|
|
2291
2426
|
].filter(Boolean);
|
|
2292
2427
|
return parts.length > 0 ? ` (${parts.join("; ")})` : "";
|
|
2293
2428
|
}
|
|
@@ -2329,7 +2464,7 @@ function readEventTimestamp(value) {
|
|
|
2329
2464
|
return null;
|
|
2330
2465
|
}
|
|
2331
2466
|
function buildMeshCompletionFingerprint(args) {
|
|
2332
|
-
const timestampPart = Number.isFinite(args.timestamp) ? String(args.timestamp) :
|
|
2467
|
+
const timestampPart = Number.isFinite(args.timestamp) ? String(args.timestamp) : readNonEmptyString2(args.finalSummary).slice(0, 200);
|
|
2333
2468
|
return [
|
|
2334
2469
|
args.meshId,
|
|
2335
2470
|
args.event,
|
|
@@ -2407,7 +2542,7 @@ function isTerminalSessionStatus(status) {
|
|
|
2407
2542
|
return ["stopped", "failed", "terminated", "exited", "closed"].includes(status);
|
|
2408
2543
|
}
|
|
2409
2544
|
function isIdleSessionState(state) {
|
|
2410
|
-
const status =
|
|
2545
|
+
const status = readNonEmptyString2(state?.status).toLowerCase();
|
|
2411
2546
|
if (isTerminalSessionStatus(status)) return false;
|
|
2412
2547
|
return status === "idle" || state?.activeChat?.status === "waiting_input";
|
|
2413
2548
|
}
|
|
@@ -2416,15 +2551,15 @@ function isDirtyNode(node) {
|
|
|
2416
2551
|
}
|
|
2417
2552
|
function isLaunchableNode(node) {
|
|
2418
2553
|
if (!node || node.status === "disabled" || node.status === "removed") return false;
|
|
2419
|
-
const health =
|
|
2554
|
+
const health = readNonEmptyString2(node.health).toLowerCase();
|
|
2420
2555
|
if (!health) return true;
|
|
2421
2556
|
return health === "online" || health === "unknown";
|
|
2422
2557
|
}
|
|
2423
2558
|
function localAutoLaunchSkipReason(node) {
|
|
2424
|
-
const daemonId =
|
|
2425
|
-
const machineId =
|
|
2559
|
+
const daemonId = readNonEmptyString2(node?.daemonId);
|
|
2560
|
+
const machineId = readNonEmptyString2(node?.machineId);
|
|
2426
2561
|
const appConfig = loadConfig();
|
|
2427
|
-
const localMachineId =
|
|
2562
|
+
const localMachineId = readNonEmptyString2(appConfig.machineId) || readNonEmptyString2(appConfig.registeredMachineId);
|
|
2428
2563
|
const cloudDaemonId = localMachineId ? `daemon_${localMachineId}` : "";
|
|
2429
2564
|
const standaloneDaemonId = localMachineId ? `standalone_${localMachineId}` : "";
|
|
2430
2565
|
const daemonMatchesLocal = !daemonId || daemonId === cloudDaemonId || daemonId === standaloneDaemonId;
|
|
@@ -2447,10 +2582,10 @@ function liveSessionCountForNode(components, meshId, nodeId) {
|
|
|
2447
2582
|
return components.instanceManager.getByCategory("cli").filter((inst) => {
|
|
2448
2583
|
const state = inst.getState();
|
|
2449
2584
|
const settings = state.settings || {};
|
|
2450
|
-
if (
|
|
2451
|
-
const instNodeId =
|
|
2585
|
+
if (readNonEmptyString2(settings.meshNodeFor) !== meshId) return false;
|
|
2586
|
+
const instNodeId = readNonEmptyString2(settings.meshNodeId) || readNonEmptyString2(settings.nodeId);
|
|
2452
2587
|
if (instNodeId !== nodeId) return false;
|
|
2453
|
-
const status =
|
|
2588
|
+
const status = readNonEmptyString2(state.status).toLowerCase();
|
|
2454
2589
|
return !isTerminalSessionStatus(status);
|
|
2455
2590
|
}).length;
|
|
2456
2591
|
}
|
|
@@ -2542,7 +2677,7 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
|
|
|
2542
2677
|
continue;
|
|
2543
2678
|
}
|
|
2544
2679
|
for (const node of candidateNodes) {
|
|
2545
|
-
const nodeId =
|
|
2680
|
+
const nodeId = readNonEmptyString2(node?.id);
|
|
2546
2681
|
if (!nodeId) continue;
|
|
2547
2682
|
const launchKey = `${meshId}:${nodeId}`;
|
|
2548
2683
|
const cooldownUntil = autoLaunchCooldownUntil.get(launchKey) || 0;
|
|
@@ -2601,7 +2736,7 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
|
|
|
2601
2736
|
autoLaunchCooldownUntil.set(launchKey, Date.now() + AUTO_LAUNCH_COOLDOWN_MS);
|
|
2602
2737
|
return false;
|
|
2603
2738
|
}
|
|
2604
|
-
const sessionId =
|
|
2739
|
+
const sessionId = readNonEmptyString2(launchResult.sessionId) || readNonEmptyString2(launchResult.id) || readNonEmptyString2(launchResult.runtimeSessionId);
|
|
2605
2740
|
if (!sessionId) {
|
|
2606
2741
|
markAutoLaunch(meshId, task.id, { status: "failed", reason: "launch_missing_session_id", nodeId, providerType: resolved.providerType });
|
|
2607
2742
|
autoLaunchCooldownUntil.set(launchKey, Date.now() + AUTO_LAUNCH_COOLDOWN_MS);
|
|
@@ -2628,13 +2763,13 @@ async function triggerMeshQueue(components, meshId) {
|
|
|
2628
2763
|
for (const inst of cliInstances) {
|
|
2629
2764
|
const state = inst.getState();
|
|
2630
2765
|
const settings = state.settings || {};
|
|
2631
|
-
const instMeshId =
|
|
2766
|
+
const instMeshId = readNonEmptyString2(settings.meshNodeFor);
|
|
2632
2767
|
if (instMeshId !== meshId) continue;
|
|
2633
|
-
const nodeId =
|
|
2768
|
+
const nodeId = readNonEmptyString2(settings.meshNodeId) || readNonEmptyString2(settings.nodeId);
|
|
2634
2769
|
if (!nodeId) continue;
|
|
2635
2770
|
if (!isIdleSessionState(state)) continue;
|
|
2636
2771
|
const sessionId = state.instanceId;
|
|
2637
|
-
const providerType = state.type ||
|
|
2772
|
+
const providerType = state.type || readNonEmptyString2(settings.providerType);
|
|
2638
2773
|
if (providerType) {
|
|
2639
2774
|
tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType);
|
|
2640
2775
|
}
|
|
@@ -2696,7 +2831,7 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
2696
2831
|
}
|
|
2697
2832
|
function injectMeshSystemMessage(components, args) {
|
|
2698
2833
|
const eventSessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2699
|
-
const eventNodeId =
|
|
2834
|
+
const eventNodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
2700
2835
|
const intentionalCleanupStop = shouldSuppressIntentionalCleanupStop({
|
|
2701
2836
|
event: args.event,
|
|
2702
2837
|
meshId: args.meshId,
|
|
@@ -2717,10 +2852,10 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2717
2852
|
meshId: args.meshId,
|
|
2718
2853
|
event: args.event,
|
|
2719
2854
|
sessionId: eventSessionId,
|
|
2720
|
-
providerType:
|
|
2721
|
-
providerSessionId:
|
|
2855
|
+
providerType: readNonEmptyString2(args.metadataEvent.providerType) || void 0,
|
|
2856
|
+
providerSessionId: readNonEmptyString2(args.metadataEvent.providerSessionId) || void 0,
|
|
2722
2857
|
timestamp: eventTimestamp,
|
|
2723
|
-
finalSummary:
|
|
2858
|
+
finalSummary: readNonEmptyString2(args.metadataEvent.finalSummary) || void 0
|
|
2724
2859
|
});
|
|
2725
2860
|
if (duplicateCompletion) {
|
|
2726
2861
|
LOG.info("MeshEvents", `Suppressed duplicate completion for mesh ${args.meshId} session ${eventSessionId}`);
|
|
@@ -2730,8 +2865,8 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2730
2865
|
let completedTaskForLedger = null;
|
|
2731
2866
|
if (args.event === "agent:generating_completed") {
|
|
2732
2867
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2733
|
-
const nodeId =
|
|
2734
|
-
const providerType =
|
|
2868
|
+
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
2869
|
+
const providerType = readNonEmptyString2(args.metadataEvent.providerType);
|
|
2735
2870
|
if (sessionId) {
|
|
2736
2871
|
const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed", {
|
|
2737
2872
|
occurredAt: eventTimestamp !== null ? new Date(eventTimestamp).toISOString() : void 0
|
|
@@ -2745,8 +2880,11 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2745
2880
|
}
|
|
2746
2881
|
} else if (args.event === "agent:ready") {
|
|
2747
2882
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2748
|
-
const nodeId =
|
|
2749
|
-
const providerType =
|
|
2883
|
+
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
2884
|
+
const providerType = readNonEmptyString2(args.metadataEvent.providerType);
|
|
2885
|
+
const providerSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId) || void 0;
|
|
2886
|
+
const finalSummary = readNonEmptyString2(args.metadataEvent.finalSummary) || void 0;
|
|
2887
|
+
const workerResult = readWorkerResultMetadata(args.metadataEvent);
|
|
2750
2888
|
const completedTask = sessionId ? updateSessionTaskStatus(args.meshId, sessionId, "completed") : null;
|
|
2751
2889
|
if (completedTask) {
|
|
2752
2890
|
completedTaskForLedger = { id: completedTask.id };
|
|
@@ -2761,15 +2899,17 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2761
2899
|
nodeLabel: args.nodeLabel,
|
|
2762
2900
|
taskId: completedTask.id,
|
|
2763
2901
|
completedViaReady: true,
|
|
2764
|
-
providerSessionId
|
|
2765
|
-
finalSummary
|
|
2902
|
+
providerSessionId,
|
|
2903
|
+
finalSummary,
|
|
2904
|
+
workerResult,
|
|
2766
2905
|
evidence: buildTaskCompletionEvidence({
|
|
2767
2906
|
event: "agent:ready",
|
|
2768
2907
|
nodeId,
|
|
2769
2908
|
sessionId,
|
|
2770
2909
|
providerType: providerType || void 0,
|
|
2771
|
-
providerSessionId
|
|
2772
|
-
finalSummary
|
|
2910
|
+
providerSessionId,
|
|
2911
|
+
finalSummary,
|
|
2912
|
+
workerResult
|
|
2773
2913
|
})
|
|
2774
2914
|
}
|
|
2775
2915
|
});
|
|
@@ -2792,13 +2932,13 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2792
2932
|
}
|
|
2793
2933
|
} else if (args.event === "agent:generating_started") {
|
|
2794
2934
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2795
|
-
const nodeId =
|
|
2935
|
+
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
2796
2936
|
if (sessionId && nodeId) {
|
|
2797
2937
|
remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
|
|
2798
2938
|
}
|
|
2799
2939
|
} else if (args.event === "agent:stopped") {
|
|
2800
2940
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2801
|
-
const nodeId =
|
|
2941
|
+
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
2802
2942
|
if (sessionId && nodeId) {
|
|
2803
2943
|
remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
|
|
2804
2944
|
}
|
|
@@ -2809,16 +2949,20 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2809
2949
|
const ledgerKind = EVENT_TO_LEDGER_KIND[args.event];
|
|
2810
2950
|
if (ledgerKind) {
|
|
2811
2951
|
try {
|
|
2812
|
-
const ledgerNodeId =
|
|
2952
|
+
const ledgerNodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId) || void 0;
|
|
2813
2953
|
const ledgerSessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId) || void 0;
|
|
2814
|
-
const ledgerProviderType =
|
|
2954
|
+
const ledgerProviderType = readNonEmptyString2(args.metadataEvent.providerType) || void 0;
|
|
2955
|
+
const providerSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId) || void 0;
|
|
2956
|
+
const finalSummary = readNonEmptyString2(args.metadataEvent.finalSummary) || void 0;
|
|
2957
|
+
const workerResult = readWorkerResultMetadata(args.metadataEvent);
|
|
2815
2958
|
const completionEvidence = ledgerKind === "task_completed" && ledgerNodeId && ledgerSessionId ? buildTaskCompletionEvidence({
|
|
2816
2959
|
event: "agent:generating_completed",
|
|
2817
2960
|
nodeId: ledgerNodeId,
|
|
2818
2961
|
sessionId: ledgerSessionId,
|
|
2819
2962
|
providerType: ledgerProviderType,
|
|
2820
|
-
providerSessionId
|
|
2821
|
-
finalSummary
|
|
2963
|
+
providerSessionId,
|
|
2964
|
+
finalSummary,
|
|
2965
|
+
workerResult
|
|
2822
2966
|
}) : void 0;
|
|
2823
2967
|
appendLedgerEntry(args.meshId, {
|
|
2824
2968
|
kind: ledgerKind,
|
|
@@ -2829,8 +2973,10 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2829
2973
|
event: args.event,
|
|
2830
2974
|
nodeLabel: args.nodeLabel,
|
|
2831
2975
|
taskId: completedTaskForLedger?.id || void 0,
|
|
2832
|
-
providerSessionId
|
|
2833
|
-
finalSummary
|
|
2976
|
+
providerSessionId,
|
|
2977
|
+
finalSummary,
|
|
2978
|
+
workerResult,
|
|
2979
|
+
completionDiagnostic: args.metadataEvent.completionDiagnostic && typeof args.metadataEvent.completionDiagnostic === "object" ? args.metadataEvent.completionDiagnostic : void 0,
|
|
2834
2980
|
evidence: completionEvidence
|
|
2835
2981
|
}
|
|
2836
2982
|
});
|
|
@@ -2845,10 +2991,10 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2845
2991
|
const maxRetries = mesh?.policy?.maxTaskRetries ?? 1;
|
|
2846
2992
|
recoveryContext = getSessionRecoveryContext(args.meshId, {
|
|
2847
2993
|
sessionId: resolveEventSessionId(args.metadataEvent, args.sourceInstanceId) || void 0,
|
|
2848
|
-
nodeId:
|
|
2994
|
+
nodeId: readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId) || void 0,
|
|
2849
2995
|
maxRetries
|
|
2850
2996
|
});
|
|
2851
|
-
recoveryContext.failedProviderType =
|
|
2997
|
+
recoveryContext.failedProviderType = readNonEmptyString2(args.metadataEvent.providerType) || null;
|
|
2852
2998
|
if (recoveryContext.retryRecommended && recoveryContext.consecutiveNodeFailures > 0) {
|
|
2853
2999
|
appendLedgerEntry(args.meshId, {
|
|
2854
3000
|
kind: "recovery_attempted",
|
|
@@ -2904,7 +3050,7 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2904
3050
|
meshId: args.meshId,
|
|
2905
3051
|
nodeLabel: args.nodeLabel,
|
|
2906
3052
|
nodeId: args.nodeId || void 0,
|
|
2907
|
-
workspace:
|
|
3053
|
+
workspace: readNonEmptyString2(args.metadataEvent.workspace),
|
|
2908
3054
|
metadataEvent: {
|
|
2909
3055
|
...args.metadataEvent,
|
|
2910
3056
|
...recoveryContext ? { recoveryContext } : {}
|
|
@@ -2930,14 +3076,14 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2930
3076
|
return { success: true, forwarded: coordinatorInstances.length };
|
|
2931
3077
|
}
|
|
2932
3078
|
function handleMeshForwardEvent(components, payload) {
|
|
2933
|
-
const eventName =
|
|
3079
|
+
const eventName = readNonEmptyString2(payload.event);
|
|
2934
3080
|
if (!isMeshCoordinatorEvent(eventName)) {
|
|
2935
3081
|
return { success: false, error: "unsupported mesh event" };
|
|
2936
3082
|
}
|
|
2937
|
-
const meshId =
|
|
3083
|
+
const meshId = readNonEmptyString2(payload.meshId);
|
|
2938
3084
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
2939
|
-
const nodeId =
|
|
2940
|
-
const workspace =
|
|
3085
|
+
const nodeId = readNonEmptyString2(payload.nodeId);
|
|
3086
|
+
const workspace = readNonEmptyString2(payload.workspace);
|
|
2941
3087
|
const nodeLabel = nodeId ? `Node '${nodeId}'` : workspace ? `Agent at ${workspace}` : "Remote agent";
|
|
2942
3088
|
return injectMeshSystemMessage(components, {
|
|
2943
3089
|
meshId,
|
|
@@ -2945,41 +3091,41 @@ function handleMeshForwardEvent(components, payload) {
|
|
|
2945
3091
|
nodeLabel,
|
|
2946
3092
|
event: eventName,
|
|
2947
3093
|
metadataEvent: {
|
|
2948
|
-
targetSessionId:
|
|
2949
|
-
providerType:
|
|
2950
|
-
providerSessionId:
|
|
2951
|
-
finalSummary:
|
|
3094
|
+
targetSessionId: readNonEmptyString2(payload.targetSessionId) || readNonEmptyString2(payload.sessionId) || readNonEmptyString2(payload.instanceId),
|
|
3095
|
+
providerType: readNonEmptyString2(payload.providerType),
|
|
3096
|
+
providerSessionId: readNonEmptyString2(payload.providerSessionId),
|
|
3097
|
+
finalSummary: readNonEmptyString2(payload.finalSummary) || readNonEmptyString2(payload.summary),
|
|
2952
3098
|
...payload.timestamp !== void 0 ? { timestamp: payload.timestamp } : {},
|
|
2953
3099
|
intentional: payload.intentional === true,
|
|
2954
3100
|
intentionalStop: payload.intentionalStop === true,
|
|
2955
3101
|
operatorCleanup: payload.operatorCleanup === true,
|
|
2956
|
-
reason:
|
|
2957
|
-
stopReason:
|
|
2958
|
-
cleanupReason:
|
|
2959
|
-
source:
|
|
3102
|
+
reason: readNonEmptyString2(payload.reason),
|
|
3103
|
+
stopReason: readNonEmptyString2(payload.stopReason),
|
|
3104
|
+
cleanupReason: readNonEmptyString2(payload.cleanupReason),
|
|
3105
|
+
source: readNonEmptyString2(payload.source)
|
|
2960
3106
|
}
|
|
2961
3107
|
});
|
|
2962
3108
|
}
|
|
2963
3109
|
function setupMeshEventForwarding(components) {
|
|
2964
3110
|
components.instanceManager.onEvent((event) => {
|
|
2965
3111
|
if (!isMeshCoordinatorEvent(event.event)) return;
|
|
2966
|
-
const instanceId =
|
|
3112
|
+
const instanceId = readNonEmptyString2(event.instanceId);
|
|
2967
3113
|
if (!instanceId) return;
|
|
2968
3114
|
const sourceInstance = components.instanceManager.getInstance(instanceId);
|
|
2969
3115
|
if (!sourceInstance || sourceInstance.category !== "cli") return;
|
|
2970
3116
|
const state = sourceInstance.getState();
|
|
2971
|
-
const workspace =
|
|
3117
|
+
const workspace = readNonEmptyString2(state.workspace);
|
|
2972
3118
|
if (!workspace) return;
|
|
2973
3119
|
const settings = state.settings && typeof state.settings === "object" ? state.settings : {};
|
|
2974
|
-
if (
|
|
2975
|
-
const meshIdFromRuntime =
|
|
3120
|
+
if (readNonEmptyString2(settings.meshCoordinatorFor)) return;
|
|
3121
|
+
const meshIdFromRuntime = readNonEmptyString2(settings.meshNodeFor);
|
|
2976
3122
|
const isMeshDelegate = Boolean(meshIdFromRuntime || settings.launchedByCoordinator);
|
|
2977
3123
|
if (!isMeshDelegate) return;
|
|
2978
3124
|
const mesh = meshIdFromRuntime ? getMeshWithCache(components, meshIdFromRuntime) : getMeshByRepo(workspace);
|
|
2979
|
-
const meshId = meshIdFromRuntime ||
|
|
3125
|
+
const meshId = meshIdFromRuntime || readNonEmptyString2(mesh?.id);
|
|
2980
3126
|
if (!meshId) return;
|
|
2981
3127
|
const targetNode = mesh?.nodes?.find((n) => n.workspace === workspace);
|
|
2982
|
-
const runtimeNodeId =
|
|
3128
|
+
const runtimeNodeId = readNonEmptyString2(settings.meshNodeId);
|
|
2983
3129
|
const resolvedNodeId = targetNode?.id || runtimeNodeId;
|
|
2984
3130
|
const nodeLabel = targetNode ? `Node '${targetNode.id}'` : runtimeNodeId ? `Node '${runtimeNodeId}'` : `Agent at ${workspace}`;
|
|
2985
3131
|
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));
|
|
@@ -6170,6 +6318,8 @@ __export(index_exports, {
|
|
|
6170
6318
|
buildChatTailDeliverySignature: () => buildChatTailDeliverySignature,
|
|
6171
6319
|
buildCoordinatorSystemPrompt: () => buildCoordinatorSystemPrompt,
|
|
6172
6320
|
buildMachineInfo: () => buildMachineInfo,
|
|
6321
|
+
buildMeshActiveWork: () => buildMeshActiveWork,
|
|
6322
|
+
buildMeshActiveWorkSummary: () => buildMeshActiveWorkSummary,
|
|
6173
6323
|
buildMeshHostRequiredFailure: () => buildMeshHostRequiredFailure,
|
|
6174
6324
|
buildMeshLedgerReconciliationEvidence: () => buildMeshLedgerReconciliationEvidence,
|
|
6175
6325
|
buildMeshLedgerReplicaEvidence: () => buildMeshLedgerReplicaEvidence,
|
|
@@ -6180,6 +6330,7 @@ __export(index_exports, {
|
|
|
6180
6330
|
buildSessionModalDeliverySignature: () => buildSessionModalDeliverySignature,
|
|
6181
6331
|
buildStatusSnapshot: () => buildStatusSnapshot,
|
|
6182
6332
|
buildSystemChatMessage: () => buildSystemChatMessage,
|
|
6333
|
+
buildTaskCompletionEvidence: () => buildTaskCompletionEvidence,
|
|
6183
6334
|
buildTerminalChatMessage: () => buildTerminalChatMessage,
|
|
6184
6335
|
buildThoughtChatMessage: () => buildThoughtChatMessage,
|
|
6185
6336
|
buildToolChatMessage: () => buildToolChatMessage,
|
|
@@ -6290,6 +6441,8 @@ __export(index_exports, {
|
|
|
6290
6441
|
normalizeInputEnvelope: () => normalizeInputEnvelope,
|
|
6291
6442
|
normalizeManagedStatus: () => normalizeManagedStatus,
|
|
6292
6443
|
normalizeMeshDaemonRole: () => normalizeMeshDaemonRole,
|
|
6444
|
+
normalizeMeshTaskMode: () => normalizeMeshTaskMode,
|
|
6445
|
+
normalizeMeshWorkerResult: () => normalizeMeshWorkerResult,
|
|
6293
6446
|
normalizeMessageParts: () => normalizeMessageParts,
|
|
6294
6447
|
normalizeRepoIdentity: () => normalizeRepoIdentity,
|
|
6295
6448
|
normalizeSessionModalFields: () => normalizeSessionModalFields,
|
|
@@ -6345,7 +6498,8 @@ __export(index_exports, {
|
|
|
6345
6498
|
updateSessionTaskStatus: () => updateSessionTaskStatus,
|
|
6346
6499
|
updateTaskStatus: () => updateTaskStatus,
|
|
6347
6500
|
upsertSavedProviderSession: () => upsertSavedProviderSession,
|
|
6348
|
-
validateMeshRefineConfig: () => validateMeshRefineConfig
|
|
6501
|
+
validateMeshRefineConfig: () => validateMeshRefineConfig,
|
|
6502
|
+
validateMeshTaskModeRequest: () => validateMeshTaskModeRequest
|
|
6349
6503
|
});
|
|
6350
6504
|
module.exports = __toCommonJS(index_exports);
|
|
6351
6505
|
init_repo_mesh_types();
|
|
@@ -8778,6 +8932,152 @@ function buildMeshLedgerReconciliationEvidence(meshId, replicas) {
|
|
|
8778
8932
|
|
|
8779
8933
|
// src/index.ts
|
|
8780
8934
|
init_mesh_work_queue();
|
|
8935
|
+
|
|
8936
|
+
// src/mesh/mesh-active-work.ts
|
|
8937
|
+
var DIRECT_DISPATCH_VIA = /* @__PURE__ */ new Set(["p2p_direct", "local_direct", "mesh_send_task"]);
|
|
8938
|
+
var TERMINAL_LEDGER_KINDS = /* @__PURE__ */ new Set(["task_completed", "task_failed", "task_stalled"]);
|
|
8939
|
+
function readString2(value) {
|
|
8940
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
8941
|
+
}
|
|
8942
|
+
function summarizeMessage(message) {
|
|
8943
|
+
const oneLine = message.replace(/\s+/g, " ").trim();
|
|
8944
|
+
const title = oneLine.length > 96 ? `${oneLine.slice(0, 93)}...` : oneLine;
|
|
8945
|
+
return { title: title || "(untitled task)", summary: oneLine };
|
|
8946
|
+
}
|
|
8947
|
+
function elapsedSince(value, now) {
|
|
8948
|
+
const started = value ? new Date(value).getTime() : Number.NaN;
|
|
8949
|
+
return Number.isFinite(started) ? Math.max(0, now - started) : 0;
|
|
8950
|
+
}
|
|
8951
|
+
function sessionStatusFromNodes(nodes, nodeId, sessionId) {
|
|
8952
|
+
if (!nodeId || !sessionId || !Array.isArray(nodes)) return void 0;
|
|
8953
|
+
const node = nodes.find((item) => readString2(item?.id) === nodeId || readString2(item?.nodeId) === nodeId || readString2(item?.node_id) === nodeId);
|
|
8954
|
+
if (!node) return void 0;
|
|
8955
|
+
const candidates = [];
|
|
8956
|
+
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]) {
|
|
8957
|
+
if (Array.isArray(value)) candidates.push(...value);
|
|
8958
|
+
}
|
|
8959
|
+
for (const value of [node.activeSession, node.active_session, node.currentSession, node.current_session, node.runtimeSession, node.runtime_session, node.session]) {
|
|
8960
|
+
if (value && typeof value === "object") candidates.push(value);
|
|
8961
|
+
}
|
|
8962
|
+
const session = candidates.find((item) => {
|
|
8963
|
+
const id = readString2(item?.id) || readString2(item?.sessionId) || readString2(item?.session_id) || readString2(item?.runtimeSessionId) || readString2(item?.instanceId);
|
|
8964
|
+
return id === sessionId;
|
|
8965
|
+
});
|
|
8966
|
+
if (!session) return void 0;
|
|
8967
|
+
const raw = `${readString2(session.status) || ""} ${readString2(session.lifecycle) || ""} ${readString2(session.state) || ""} ${readString2(session.activeChat?.status) || ""}`.toLowerCase();
|
|
8968
|
+
if (raw.includes("approval")) return "awaiting_approval";
|
|
8969
|
+
if (raw.includes("generating") || raw.includes("running") || raw.includes("busy")) return "generating";
|
|
8970
|
+
if (raw.includes("failed") || raw.includes("stopped") || raw.includes("terminated") || raw.includes("exited")) return "failed";
|
|
8971
|
+
if (raw.includes("idle") || raw.includes("waiting_input") || raw.includes("ready")) return "idle";
|
|
8972
|
+
return void 0;
|
|
8973
|
+
}
|
|
8974
|
+
function isDirectDispatch(entry) {
|
|
8975
|
+
if (entry.kind !== "task_dispatched") return false;
|
|
8976
|
+
const payload = entry.payload || {};
|
|
8977
|
+
if (payload.source === "direct") return true;
|
|
8978
|
+
const via = readString2(payload.via);
|
|
8979
|
+
return Boolean(via && DIRECT_DISPATCH_VIA.has(via) && payload.source !== "queue");
|
|
8980
|
+
}
|
|
8981
|
+
function directDispatchTaskId(entry) {
|
|
8982
|
+
return readString2(entry.payload?.taskId) || entry.id;
|
|
8983
|
+
}
|
|
8984
|
+
function terminalMatchesDispatch(terminal, dispatch, taskId) {
|
|
8985
|
+
const terminalTaskId = readString2(terminal.payload?.taskId);
|
|
8986
|
+
if (terminalTaskId && terminalTaskId === taskId) return true;
|
|
8987
|
+
if (terminalTaskId && terminalTaskId !== taskId) return false;
|
|
8988
|
+
if (dispatch.sessionId && terminal.sessionId === dispatch.sessionId) return true;
|
|
8989
|
+
return Boolean(dispatch.nodeId && terminal.nodeId === dispatch.nodeId && !dispatch.sessionId);
|
|
8990
|
+
}
|
|
8991
|
+
function statusFromTerminal(entry) {
|
|
8992
|
+
if (entry.kind === "task_approval_needed") return "awaiting_approval";
|
|
8993
|
+
if (entry.kind === "task_completed") return "idle";
|
|
8994
|
+
return "failed";
|
|
8995
|
+
}
|
|
8996
|
+
function buildMeshActiveWorkSummary(activeWork) {
|
|
8997
|
+
const statusCounts = {
|
|
8998
|
+
pending: 0,
|
|
8999
|
+
assigned: 0,
|
|
9000
|
+
generating: 0,
|
|
9001
|
+
idle: 0,
|
|
9002
|
+
failed: 0,
|
|
9003
|
+
awaiting_approval: 0
|
|
9004
|
+
};
|
|
9005
|
+
const sourceCounts = { queue: 0, direct: 0 };
|
|
9006
|
+
for (const item of activeWork) {
|
|
9007
|
+
sourceCounts[item.source] += 1;
|
|
9008
|
+
statusCounts[item.status] += 1;
|
|
9009
|
+
}
|
|
9010
|
+
return {
|
|
9011
|
+
totalActiveCount: activeWork.length,
|
|
9012
|
+
queueActiveCount: sourceCounts.queue,
|
|
9013
|
+
directActiveCount: sourceCounts.direct,
|
|
9014
|
+
awaitingApprovalCount: statusCounts.awaiting_approval,
|
|
9015
|
+
generatingCount: statusCounts.generating,
|
|
9016
|
+
failedCount: statusCounts.failed,
|
|
9017
|
+
idleCount: statusCounts.idle,
|
|
9018
|
+
sourceCounts,
|
|
9019
|
+
statusCounts
|
|
9020
|
+
};
|
|
9021
|
+
}
|
|
9022
|
+
function buildMeshActiveWork(opts) {
|
|
9023
|
+
const now = opts.now ?? Date.now();
|
|
9024
|
+
const records = [];
|
|
9025
|
+
for (const task of opts.queue || []) {
|
|
9026
|
+
if (task.status !== "pending" && task.status !== "assigned") continue;
|
|
9027
|
+
const { title, summary } = summarizeMessage(task.message || "");
|
|
9028
|
+
records.push({
|
|
9029
|
+
taskId: task.id,
|
|
9030
|
+
source: "queue",
|
|
9031
|
+
status: task.status,
|
|
9032
|
+
nodeId: task.assignedNodeId || task.targetNodeId,
|
|
9033
|
+
sessionId: task.assignedSessionId || task.targetSessionId,
|
|
9034
|
+
taskTitle: title,
|
|
9035
|
+
taskSummary: summary,
|
|
9036
|
+
message: task.message,
|
|
9037
|
+
taskMode: task.taskMode,
|
|
9038
|
+
createdAt: task.createdAt,
|
|
9039
|
+
updatedAt: task.updatedAt,
|
|
9040
|
+
dispatchedAt: task.dispatchTimestamp,
|
|
9041
|
+
elapsedMs: elapsedSince(task.dispatchTimestamp || task.createdAt, now)
|
|
9042
|
+
});
|
|
9043
|
+
}
|
|
9044
|
+
const ledgerEntries = (opts.ledgerEntries || []).slice().sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
9045
|
+
const terminals = ledgerEntries.filter((entry) => TERMINAL_LEDGER_KINDS.has(entry.kind) || entry.kind === "task_approval_needed");
|
|
9046
|
+
for (const dispatch of ledgerEntries.filter(isDirectDispatch)) {
|
|
9047
|
+
const taskId = directDispatchTaskId(dispatch);
|
|
9048
|
+
const terminal = terminals.filter((entry) => new Date(entry.timestamp).getTime() >= new Date(dispatch.timestamp).getTime()).find((entry) => terminalMatchesDispatch(entry, dispatch, taskId));
|
|
9049
|
+
const terminalStatus = terminal ? statusFromTerminal(terminal) : void 0;
|
|
9050
|
+
const liveStatus = sessionStatusFromNodes(opts.nodes, dispatch.nodeId, dispatch.sessionId);
|
|
9051
|
+
const status = terminalStatus || liveStatus || "assigned";
|
|
9052
|
+
const terminalRow = Boolean(terminal && terminal.kind !== "task_approval_needed");
|
|
9053
|
+
if (terminalRow && opts.includeTerminalDirect !== true) continue;
|
|
9054
|
+
const message = readString2(dispatch.payload?.message) || readString2(dispatch.payload?.summary) || "";
|
|
9055
|
+
const { title, summary } = summarizeMessage(message);
|
|
9056
|
+
records.push({
|
|
9057
|
+
taskId,
|
|
9058
|
+
source: "direct",
|
|
9059
|
+
status,
|
|
9060
|
+
nodeId: dispatch.nodeId,
|
|
9061
|
+
sessionId: dispatch.sessionId,
|
|
9062
|
+
providerType: dispatch.providerType || readString2(dispatch.payload?.providerType),
|
|
9063
|
+
taskTitle: readString2(dispatch.payload?.taskTitle) || title,
|
|
9064
|
+
taskSummary: readString2(dispatch.payload?.taskSummary) || summary,
|
|
9065
|
+
message,
|
|
9066
|
+
taskMode: readString2(dispatch.payload?.taskMode),
|
|
9067
|
+
createdAt: dispatch.timestamp,
|
|
9068
|
+
updatedAt: terminal?.timestamp || dispatch.timestamp,
|
|
9069
|
+
dispatchedAt: dispatch.timestamp,
|
|
9070
|
+
elapsedMs: elapsedSince(dispatch.timestamp, now),
|
|
9071
|
+
terminal: terminalRow,
|
|
9072
|
+
terminalKind: terminal?.kind,
|
|
9073
|
+
terminalAt: terminal?.timestamp
|
|
9074
|
+
});
|
|
9075
|
+
}
|
|
9076
|
+
records.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
9077
|
+
return { activeWork: records, summary: buildMeshActiveWorkSummary(records) };
|
|
9078
|
+
}
|
|
9079
|
+
|
|
9080
|
+
// src/index.ts
|
|
8781
9081
|
init_mesh_host_ownership();
|
|
8782
9082
|
init_mesh_events();
|
|
8783
9083
|
|
|
@@ -18777,6 +19077,44 @@ var CliProviderInstance = class {
|
|
|
18777
19077
|
const content = lastVisible ? flattenContent(lastVisible.content).trim() : "";
|
|
18778
19078
|
return role === "assistant" && !!content;
|
|
18779
19079
|
}
|
|
19080
|
+
buildCompletedFinalizationDiagnostic(args) {
|
|
19081
|
+
let parsed = null;
|
|
19082
|
+
let parseError;
|
|
19083
|
+
try {
|
|
19084
|
+
parsed = this.adapter.getScriptParsedStatus();
|
|
19085
|
+
} catch (error) {
|
|
19086
|
+
parseError = error?.message || String(error);
|
|
19087
|
+
}
|
|
19088
|
+
const visibleMessages = (Array.isArray(parsed?.messages) ? parsed.messages : []).filter((message) => isUserFacingChatMessage(message));
|
|
19089
|
+
const lastVisible = visibleMessages[visibleMessages.length - 1];
|
|
19090
|
+
const lastVisibleRole = typeof lastVisible?.role === "string" ? lastVisible.role.trim().toLowerCase() : null;
|
|
19091
|
+
const lastVisibleKind = typeof lastVisible?.kind === "string" ? lastVisible.kind : null;
|
|
19092
|
+
const lastVisibleContentLength = lastVisible ? flattenContent(lastVisible.content).trim().length : 0;
|
|
19093
|
+
return {
|
|
19094
|
+
providerType: this.type,
|
|
19095
|
+
sessionId: this.instanceId,
|
|
19096
|
+
providerSessionId: this.providerSessionId || null,
|
|
19097
|
+
workspace: this.workingDir,
|
|
19098
|
+
blockReason: args.blockReason,
|
|
19099
|
+
emittedAfterFinalizationTimeout: args.emittedAfterFinalizationTimeout,
|
|
19100
|
+
waitedMs: args.waitedMs,
|
|
19101
|
+
maxWaitMs: COMPLETED_FINALIZATION_MAX_WAIT_MS,
|
|
19102
|
+
adapterStatus: typeof args.latestStatus?.status === "string" ? args.latestStatus.status : null,
|
|
19103
|
+
latestVisibleStatus: args.latestVisibleStatus,
|
|
19104
|
+
parsedStatus: typeof parsed?.status === "string" ? parsed.status : parseError ? "parse_error" : "unknown",
|
|
19105
|
+
parseError: parseError || void 0,
|
|
19106
|
+
finalAssistantPresent: this.completionHasFinalAssistantMessage(parsed?.messages),
|
|
19107
|
+
visibleMessageCount: visibleMessages.length,
|
|
19108
|
+
lastVisibleRole,
|
|
19109
|
+
lastVisibleKind,
|
|
19110
|
+
lastVisibleContentLength,
|
|
19111
|
+
pendingStartedAt: this.generatingStartedAt || null,
|
|
19112
|
+
pendingFirstObservedAt: args.pending.firstObservedAt,
|
|
19113
|
+
pendingTimestamp: args.pending.timestamp,
|
|
19114
|
+
pendingDurationSec: args.pending.duration,
|
|
19115
|
+
previousBlockReason: args.pending.loggedBlockReason || null
|
|
19116
|
+
};
|
|
19117
|
+
}
|
|
18780
19118
|
hasAdapterPendingResponse() {
|
|
18781
19119
|
const adapterAny = this.adapter;
|
|
18782
19120
|
if (adapterAny?.isWaitingForResponse === true) return true;
|
|
@@ -18849,7 +19187,23 @@ var CliProviderInstance = class {
|
|
|
18849
19187
|
this.scheduleCompletedDebounceFlush(COMPLETED_FINALIZATION_RETRY_MS);
|
|
18850
19188
|
return;
|
|
18851
19189
|
}
|
|
18852
|
-
|
|
19190
|
+
const completionDiagnostic = this.buildCompletedFinalizationDiagnostic({
|
|
19191
|
+
blockReason,
|
|
19192
|
+
latestStatus,
|
|
19193
|
+
latestVisibleStatus,
|
|
19194
|
+
waitedMs,
|
|
19195
|
+
pending,
|
|
19196
|
+
emittedAfterFinalizationTimeout: true
|
|
19197
|
+
});
|
|
19198
|
+
LOG.warn("CLI", `[${this.type}] emitting completed event after ${waitedMs}ms without finalized assistant turn (${blockReason})`);
|
|
19199
|
+
this.pushEvent({
|
|
19200
|
+
event: "agent:generating_completed",
|
|
19201
|
+
chatTitle: pending.chatTitle,
|
|
19202
|
+
duration: pending.duration,
|
|
19203
|
+
timestamp: pending.timestamp,
|
|
19204
|
+
finalSummary: extractFinalSummaryFromMessages(this.adapter?.getScriptParsedStatus()?.messages),
|
|
19205
|
+
completionDiagnostic
|
|
19206
|
+
});
|
|
18853
19207
|
this.completedDebouncePending = null;
|
|
18854
19208
|
this.completedDebounceTimer = null;
|
|
18855
19209
|
this.generatingStartedAt = 0;
|
|
@@ -25215,6 +25569,9 @@ function reconcileInlineMeshCache(cached, incoming) {
|
|
|
25215
25569
|
const cachedNodes = Array.isArray(cached.nodes) ? cached.nodes : [];
|
|
25216
25570
|
const incomingNodes = Array.isArray(incoming.nodes) ? incoming.nodes : [];
|
|
25217
25571
|
if (!cachedNodes.length || !incomingNodes.length) return { ...cached, ...incoming };
|
|
25572
|
+
const cachedUpdatedAt = Date.parse(readStringValue(cached.updatedAt, cached.updated_at) || "");
|
|
25573
|
+
const incomingUpdatedAt = Date.parse(readStringValue(incoming.updatedAt, incoming.updated_at) || "");
|
|
25574
|
+
const preserveCachedMembership = Number.isFinite(cachedUpdatedAt) && (!Number.isFinite(incomingUpdatedAt) || cachedUpdatedAt > incomingUpdatedAt);
|
|
25218
25575
|
const cachedById = /* @__PURE__ */ new Map();
|
|
25219
25576
|
for (const node of cachedNodes) {
|
|
25220
25577
|
const nodeId = readInlineMeshNodeId(node);
|
|
@@ -25223,12 +25580,13 @@ function reconcileInlineMeshCache(cached, incoming) {
|
|
|
25223
25580
|
const nodes = incomingNodes.map((incomingNode) => {
|
|
25224
25581
|
const nodeId = readInlineMeshNodeId(incomingNode);
|
|
25225
25582
|
const cachedNode = nodeId ? cachedById.get(nodeId) : void 0;
|
|
25583
|
+
if (!cachedNode && preserveCachedMembership) return null;
|
|
25226
25584
|
if (!cachedNode) return incomingNode;
|
|
25227
25585
|
if (hasInlineMeshTransientNodeState(incomingNode)) {
|
|
25228
25586
|
return { ...cachedNode, ...incomingNode };
|
|
25229
25587
|
}
|
|
25230
25588
|
return { ...stripInlineMeshTransientNodeState(cachedNode), ...incomingNode };
|
|
25231
|
-
});
|
|
25589
|
+
}).filter(Boolean);
|
|
25232
25590
|
return {
|
|
25233
25591
|
...cached,
|
|
25234
25592
|
...incoming,
|
|
@@ -36727,6 +37085,8 @@ async function shutdownDaemonComponents(components) {
|
|
|
36727
37085
|
buildChatTailDeliverySignature,
|
|
36728
37086
|
buildCoordinatorSystemPrompt,
|
|
36729
37087
|
buildMachineInfo,
|
|
37088
|
+
buildMeshActiveWork,
|
|
37089
|
+
buildMeshActiveWorkSummary,
|
|
36730
37090
|
buildMeshHostRequiredFailure,
|
|
36731
37091
|
buildMeshLedgerReconciliationEvidence,
|
|
36732
37092
|
buildMeshLedgerReplicaEvidence,
|
|
@@ -36737,6 +37097,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
36737
37097
|
buildSessionModalDeliverySignature,
|
|
36738
37098
|
buildStatusSnapshot,
|
|
36739
37099
|
buildSystemChatMessage,
|
|
37100
|
+
buildTaskCompletionEvidence,
|
|
36740
37101
|
buildTerminalChatMessage,
|
|
36741
37102
|
buildThoughtChatMessage,
|
|
36742
37103
|
buildToolChatMessage,
|
|
@@ -36847,6 +37208,8 @@ async function shutdownDaemonComponents(components) {
|
|
|
36847
37208
|
normalizeInputEnvelope,
|
|
36848
37209
|
normalizeManagedStatus,
|
|
36849
37210
|
normalizeMeshDaemonRole,
|
|
37211
|
+
normalizeMeshTaskMode,
|
|
37212
|
+
normalizeMeshWorkerResult,
|
|
36850
37213
|
normalizeMessageParts,
|
|
36851
37214
|
normalizeRepoIdentity,
|
|
36852
37215
|
normalizeSessionModalFields,
|
|
@@ -36902,6 +37265,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
36902
37265
|
updateSessionTaskStatus,
|
|
36903
37266
|
updateTaskStatus,
|
|
36904
37267
|
upsertSavedProviderSession,
|
|
36905
|
-
validateMeshRefineConfig
|
|
37268
|
+
validateMeshRefineConfig,
|
|
37269
|
+
validateMeshTaskModeRequest
|
|
36906
37270
|
});
|
|
36907
37271
|
//# sourceMappingURL=index.js.map
|