@adhdev/daemon-standalone 1.0.56-rc.2 → 1.0.56-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +4085 -823
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/vendor/mcp-server/index.js +238 -197
- package/vendor/mcp-server/index.js.map +1 -1
|
@@ -635,7 +635,7 @@ function withStatusProbeMarker(args = {}) {
|
|
|
635
635
|
}
|
|
636
636
|
|
|
637
637
|
// src/tools/mesh-tools-internal.ts
|
|
638
|
-
var
|
|
638
|
+
var import_daemon_core5 = require("@adhdev/daemon-core");
|
|
639
639
|
|
|
640
640
|
// src/tools/mesh-tool-shared.ts
|
|
641
641
|
function readString(value) {
|
|
@@ -1945,6 +1945,8 @@ var ALL_MESH_TOOLS = [
|
|
|
1945
1945
|
];
|
|
1946
1946
|
|
|
1947
1947
|
// src/tools/mesh-compact.ts
|
|
1948
|
+
var import_daemon_core4 = require("@adhdev/daemon-core");
|
|
1949
|
+
var QUOTA_STALE_AFTER_MS = import_daemon_core4.DEFAULT_QUOTA_ROUTING_POLICY.staleAfterMs;
|
|
1948
1950
|
function buildCompactGitSnapshot(status) {
|
|
1949
1951
|
if (!status || typeof status !== "object" || Array.isArray(status)) return void 0;
|
|
1950
1952
|
const slim = {};
|
|
@@ -1974,19 +1976,58 @@ function summarizeCompactSubmodules(submodules) {
|
|
|
1974
1976
|
};
|
|
1975
1977
|
}
|
|
1976
1978
|
var MESH_COMPACT_PRESERVED_MARKER_FIELDS = ["dataFreshness", "quota", "isLocalWorktree"];
|
|
1977
|
-
function
|
|
1979
|
+
function quotaSnapshotAgeMs(snapshot, now = Date.now()) {
|
|
1980
|
+
const updatedAt = typeof snapshot?.updatedAt === "number" ? snapshot.updatedAt : NaN;
|
|
1981
|
+
if (!Number.isFinite(updatedAt)) return null;
|
|
1982
|
+
return Math.max(0, now - updatedAt);
|
|
1983
|
+
}
|
|
1984
|
+
function isQuotaSnapshotStale(snapshot, now = Date.now()) {
|
|
1985
|
+
const ageMs = quotaSnapshotAgeMs(snapshot, now);
|
|
1986
|
+
return ageMs === null || ageMs >= QUOTA_STALE_AFTER_MS;
|
|
1987
|
+
}
|
|
1988
|
+
function formatQuotaSnapshotAge(snapshot, now) {
|
|
1989
|
+
const ageMs = quotaSnapshotAgeMs(snapshot, now);
|
|
1990
|
+
if (ageMs === null) return "?";
|
|
1991
|
+
return `${Math.round(ageMs / 6e4)}m`;
|
|
1992
|
+
}
|
|
1993
|
+
function annotateQuotaSnapshotFreshness(quota, now = Date.now()) {
|
|
1994
|
+
if (!quota || typeof quota !== "object" || Array.isArray(quota)) return quota;
|
|
1995
|
+
const out = {};
|
|
1996
|
+
for (const [provider, snapshot] of Object.entries(quota)) {
|
|
1997
|
+
if (!snapshot || typeof snapshot !== "object") {
|
|
1998
|
+
out[provider] = snapshot;
|
|
1999
|
+
continue;
|
|
2000
|
+
}
|
|
2001
|
+
const ageMs = quotaSnapshotAgeMs(snapshot, now);
|
|
2002
|
+
out[provider] = {
|
|
2003
|
+
...snapshot,
|
|
2004
|
+
ageMs: ageMs ?? -1,
|
|
2005
|
+
stale: isQuotaSnapshotStale(snapshot, now)
|
|
2006
|
+
};
|
|
2007
|
+
}
|
|
2008
|
+
return out;
|
|
2009
|
+
}
|
|
2010
|
+
function summarizeNodeQuota(quota, now = Date.now()) {
|
|
1978
2011
|
if (!quota || typeof quota !== "object" || Array.isArray(quota)) return void 0;
|
|
1979
2012
|
const out = {};
|
|
1980
2013
|
for (const [provider, snapshot] of Object.entries(quota)) {
|
|
1981
2014
|
if (!snapshot || typeof snapshot !== "object") continue;
|
|
1982
2015
|
const status = typeof snapshot.status === "string" ? snapshot.status : "unknown";
|
|
1983
|
-
|
|
2016
|
+
const lastGood = snapshot.metadata?.lastGoodWindows === true;
|
|
2017
|
+
const pct = (w) => w && Number.isFinite(w.usedPercent) ? `${Math.round(w.usedPercent)}%` : void 0;
|
|
2018
|
+
const weekly = pct(snapshot.weekly);
|
|
2019
|
+
const session = pct(snapshot.session);
|
|
2020
|
+
if (weekly === void 0 && session === void 0) {
|
|
1984
2021
|
const kind = typeof snapshot.metadata?.failureKind === "string" ? snapshot.metadata.failureKind : void 0;
|
|
1985
2022
|
out[provider] = kind ? `${status}:${kind}` : status;
|
|
1986
2023
|
continue;
|
|
1987
2024
|
}
|
|
1988
|
-
const
|
|
1989
|
-
|
|
2025
|
+
const age = formatQuotaSnapshotAge(snapshot, now);
|
|
2026
|
+
const stale = isQuotaSnapshotStale(snapshot, now);
|
|
2027
|
+
let line = `7d ${weekly ?? "\u2014"} \xB7 5h ${session ?? "\u2014"} \xB7 ${age}${stale ? " stale" : ""}`;
|
|
2028
|
+
if (lastGood) line += " \xB7 refreshing";
|
|
2029
|
+
else if (status !== "ok") line += ` \xB7 ${status}`;
|
|
2030
|
+
out[provider] = line;
|
|
1990
2031
|
}
|
|
1991
2032
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
1992
2033
|
}
|
|
@@ -2427,7 +2468,7 @@ function annotateRapidReadChatAdvisory(payload, options) {
|
|
|
2427
2468
|
}
|
|
2428
2469
|
|
|
2429
2470
|
// src/tools/mesh-tools-internal.ts
|
|
2430
|
-
var
|
|
2471
|
+
var import_daemon_core6 = require("@adhdev/daemon-core");
|
|
2431
2472
|
var import_node_crypto = require("crypto");
|
|
2432
2473
|
var SESSION_PROVIDER_METADATA_TTL_MS = 30 * 6e4;
|
|
2433
2474
|
var meshSessionProviderMetadata = /* @__PURE__ */ new Map();
|
|
@@ -2487,7 +2528,7 @@ function buildDirectTaskPayload(message, via, opts) {
|
|
|
2487
2528
|
};
|
|
2488
2529
|
}
|
|
2489
2530
|
function findNode(mesh, nodeId) {
|
|
2490
|
-
const node = mesh.nodes.find((n) => (0,
|
|
2531
|
+
const node = mesh.nodes.find((n) => (0, import_daemon_core5.meshNodeIdMatches)(n, nodeId));
|
|
2491
2532
|
if (!node) throw new Error(`Node '${nodeId}' is not a member of mesh '${mesh.name}'`);
|
|
2492
2533
|
return node;
|
|
2493
2534
|
}
|
|
@@ -2502,13 +2543,13 @@ async function refreshMeshFromDaemon(ctx) {
|
|
|
2502
2543
|
for (const existing of ctx.mesh.nodes) {
|
|
2503
2544
|
const existingId = existing?.id;
|
|
2504
2545
|
if (!existingId) continue;
|
|
2505
|
-
if (merged.some((n) => (0,
|
|
2546
|
+
if (merged.some((n) => (0, import_daemon_core5.meshNodeIdMatches)(n, existingId))) continue;
|
|
2506
2547
|
if (isLocalControlPlaneNode(ctx, existing)) {
|
|
2507
2548
|
settledNodeIds.add(existingId);
|
|
2508
2549
|
continue;
|
|
2509
2550
|
}
|
|
2510
2551
|
const clonedFromNodeId = readString(existing?.clonedFromNodeId) || readString(existing?.cloned_from_node_id);
|
|
2511
|
-
if (clonedFromNodeId && refreshedNodes.some((n) => (0,
|
|
2552
|
+
if (clonedFromNodeId && refreshedNodes.some((n) => (0, import_daemon_core5.meshNodeIdMatches)(n, clonedFromNodeId))) {
|
|
2512
2553
|
settledNodeIds.add(existingId);
|
|
2513
2554
|
continue;
|
|
2514
2555
|
}
|
|
@@ -2537,7 +2578,7 @@ async function resolveNodeFromOwningDaemons(ctx, nodeId) {
|
|
|
2537
2578
|
const candidates = [];
|
|
2538
2579
|
const pushCandidate = (id) => {
|
|
2539
2580
|
if (typeof id !== "string" || !id.trim()) return;
|
|
2540
|
-
if (localDaemonId && (0,
|
|
2581
|
+
if (localDaemonId && (0, import_daemon_core5.daemonIdsEquivalent)(id, localDaemonId)) return;
|
|
2541
2582
|
if (!candidates.includes(id)) candidates.push(id);
|
|
2542
2583
|
};
|
|
2543
2584
|
for (const node of ctx.mesh.nodes) pushCandidate(node?.daemonId);
|
|
@@ -2557,9 +2598,9 @@ async function resolveNodeFromOwningDaemons(ctx, nodeId) {
|
|
|
2557
2598
|
if (result && result.success === false) ownerUnreachable = true;
|
|
2558
2599
|
continue;
|
|
2559
2600
|
}
|
|
2560
|
-
const found = nodes.find((n) => n?.id && (0,
|
|
2601
|
+
const found = nodes.find((n) => n?.id && (0, import_daemon_core5.meshNodeIdMatches)(n, nodeId));
|
|
2561
2602
|
if (!found) continue;
|
|
2562
|
-
const existingIndex = ctx.mesh.nodes.findIndex((n) => (0,
|
|
2603
|
+
const existingIndex = ctx.mesh.nodes.findIndex((n) => (0, import_daemon_core5.meshNodeIdMatches)(n, nodeId));
|
|
2563
2604
|
if (existingIndex >= 0) ctx.mesh.nodes[existingIndex] = found;
|
|
2564
2605
|
else ctx.mesh.nodes.push(found);
|
|
2565
2606
|
return { node: found, ownerUnreachable: false };
|
|
@@ -2567,10 +2608,10 @@ async function resolveNodeFromOwningDaemons(ctx, nodeId) {
|
|
|
2567
2608
|
return { node: null, ownerUnreachable };
|
|
2568
2609
|
}
|
|
2569
2610
|
async function findNodeWithRefresh(ctx, nodeId) {
|
|
2570
|
-
const hit = ctx.mesh.nodes.find((n) => (0,
|
|
2611
|
+
const hit = ctx.mesh.nodes.find((n) => (0, import_daemon_core5.meshNodeIdMatches)(n, nodeId));
|
|
2571
2612
|
if (hit && !hit.isLocalWorktree) return hit;
|
|
2572
2613
|
const { settledNodeIds } = await refreshMeshFromDaemon(ctx);
|
|
2573
|
-
const refreshed = ctx.mesh.nodes.find((n) => (0,
|
|
2614
|
+
const refreshed = ctx.mesh.nodes.find((n) => (0, import_daemon_core5.meshNodeIdMatches)(n, nodeId));
|
|
2574
2615
|
if (refreshed) return refreshed;
|
|
2575
2616
|
if (settledNodeIds.has(nodeId)) {
|
|
2576
2617
|
throw new Error(`Node '${nodeId}' is not a member of mesh '${ctx.mesh.name}'`);
|
|
@@ -2587,10 +2628,10 @@ async function findNodeWithRefresh(ctx, nodeId) {
|
|
|
2587
2628
|
throw new Error(`Node '${nodeId}' is not a member of mesh '${ctx.mesh.name}'`);
|
|
2588
2629
|
}
|
|
2589
2630
|
async function findOptionalNodeWithRefresh(ctx, nodeId) {
|
|
2590
|
-
const hit = ctx.mesh.nodes.find((n) => (0,
|
|
2631
|
+
const hit = ctx.mesh.nodes.find((n) => (0, import_daemon_core5.meshNodeIdMatches)(n, nodeId));
|
|
2591
2632
|
if (hit && !hit.isLocalWorktree) return hit;
|
|
2592
2633
|
const { settledNodeIds } = await refreshMeshFromDaemon(ctx);
|
|
2593
|
-
const refreshed = ctx.mesh.nodes.find((n) => (0,
|
|
2634
|
+
const refreshed = ctx.mesh.nodes.find((n) => (0, import_daemon_core5.meshNodeIdMatches)(n, nodeId));
|
|
2594
2635
|
if (refreshed) return refreshed;
|
|
2595
2636
|
if (settledNodeIds.has(nodeId)) return null;
|
|
2596
2637
|
const owned = await resolveNodeFromOwningDaemons(ctx, nodeId);
|
|
@@ -2599,7 +2640,7 @@ async function findOptionalNodeWithRefresh(ctx, nodeId) {
|
|
|
2599
2640
|
function hasRecentDuplicateDispatch(ctx, args) {
|
|
2600
2641
|
const now = Date.now();
|
|
2601
2642
|
const normalizedMessage = args.message.trim();
|
|
2602
|
-
for (const task of (0,
|
|
2643
|
+
for (const task of (0, import_daemon_core5.getQueue)(ctx.mesh.id)) {
|
|
2603
2644
|
const timestamp = new Date(task.updatedAt || task.createdAt).getTime();
|
|
2604
2645
|
if (!Number.isFinite(timestamp) || now - timestamp > DUPLICATE_DISPATCH_WINDOW_MS) continue;
|
|
2605
2646
|
if (task.targetNodeId && task.targetNodeId !== args.node_id) continue;
|
|
@@ -2609,7 +2650,7 @@ function hasRecentDuplicateDispatch(ctx, args) {
|
|
|
2609
2650
|
return { duplicate: true, entry: task, source: "queue" };
|
|
2610
2651
|
}
|
|
2611
2652
|
}
|
|
2612
|
-
const entries = (0,
|
|
2653
|
+
const entries = (0, import_daemon_core5.readLedgerEntries)(ctx.mesh.id, { tail: 200 });
|
|
2613
2654
|
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
2614
2655
|
const entry = entries[i];
|
|
2615
2656
|
const timestamp = new Date(entry.timestamp).getTime();
|
|
@@ -2626,7 +2667,7 @@ function hasRecentDuplicateDispatch(ctx, args) {
|
|
|
2626
2667
|
}
|
|
2627
2668
|
function buildMissionInactiveWarning(ctx, missionId) {
|
|
2628
2669
|
if (!missionId) return void 0;
|
|
2629
|
-
const mission = (0,
|
|
2670
|
+
const mission = (0, import_daemon_core5.getMeshMission)(ctx.mesh.id, missionId);
|
|
2630
2671
|
if (!mission || mission.status === "active") return void 0;
|
|
2631
2672
|
const hintByStatus = {
|
|
2632
2673
|
paused: `Mission '${missionId}' (${mission.title}) is paused \u2014 a new task was just attached to it anyway. Mission status is never auto-transitioned; if this mission should be active again, call mesh_mission_upsert(mission_id: '${missionId}', status: 'active').`,
|
|
@@ -2640,7 +2681,7 @@ function buildMissionInactiveWarning(ctx, missionId) {
|
|
|
2640
2681
|
};
|
|
2641
2682
|
}
|
|
2642
2683
|
function buildMissingNodeReadChatRecovery(ctx, args) {
|
|
2643
|
-
const entries = (0,
|
|
2684
|
+
const entries = (0, import_daemon_core5.readLedgerEntries)(ctx.mesh.id, { tail: 300 });
|
|
2644
2685
|
const relatedEntries = entries.filter((entry) => entry.nodeId === args.node_id || entry.sessionId === args.session_id);
|
|
2645
2686
|
const completedEntries = relatedEntries.filter((entry) => entry.kind === "task_completed");
|
|
2646
2687
|
const lastDispatch = [...relatedEntries].reverse().find((entry) => entry.kind === "task_dispatched");
|
|
@@ -2764,7 +2805,7 @@ function readFinalAssistantTranscriptEvidence(payload) {
|
|
|
2764
2805
|
}
|
|
2765
2806
|
function findNodeSession(nodes, nodeId, sessionId) {
|
|
2766
2807
|
if (!nodeId || !sessionId) return {};
|
|
2767
|
-
const node = nodes.find((candidate) => (0,
|
|
2808
|
+
const node = nodes.find((candidate) => (0, import_daemon_core5.meshNodeIdMatches)(candidate, nodeId));
|
|
2768
2809
|
if (!node) return {};
|
|
2769
2810
|
const sessions = Array.isArray(node.sessions) ? node.sessions : [];
|
|
2770
2811
|
const session = sessions.find((candidate) => readSessionRecordId(candidate) === sessionId);
|
|
@@ -2833,10 +2874,10 @@ async function reconcileDirectDispatchesFromTranscriptEvidence(ctx, liveNodes, d
|
|
|
2833
2874
|
});
|
|
2834
2875
|
const payload = unwrapCommandPayload(readResult);
|
|
2835
2876
|
if (payload?.success === false) continue;
|
|
2836
|
-
if ((0,
|
|
2877
|
+
if ((0, import_daemon_core5.hasTrailingToolActivityAfterFinalAssistant)(Array.isArray(payload?.messages) ? payload.messages : [])) continue;
|
|
2837
2878
|
const evidence = readFinalAssistantTranscriptEvidence(payload);
|
|
2838
2879
|
if (!evidence.finalSummary) continue;
|
|
2839
|
-
const result = (0,
|
|
2880
|
+
const result = (0, import_daemon_core5.reconcileDirectDispatchCompletionFromTranscript)({
|
|
2840
2881
|
meshId: ctx.mesh.id,
|
|
2841
2882
|
nodeId,
|
|
2842
2883
|
sessionId,
|
|
@@ -3021,7 +3062,7 @@ function extractLaunchPayload(value) {
|
|
|
3021
3062
|
function classifyMeshLaunchFailure(error) {
|
|
3022
3063
|
const message = error instanceof Error ? error.message : String(error || "launch failed");
|
|
3023
3064
|
const lower = message.toLowerCase();
|
|
3024
|
-
const p2pClassification = (0,
|
|
3065
|
+
const p2pClassification = (0, import_daemon_core5.classifyP2pRelayFailure)(error, { command: "launch_cli" });
|
|
3025
3066
|
if (p2pClassification.recoverable) {
|
|
3026
3067
|
return p2pClassification;
|
|
3027
3068
|
}
|
|
@@ -3096,7 +3137,7 @@ function buildRecoverableLaunchFailure(ctx, node, providerType, error) {
|
|
|
3096
3137
|
function recordRecoverableLaunchFailure(ctx, node, providerType, error) {
|
|
3097
3138
|
const failure = buildRecoverableLaunchFailure(ctx, node, providerType, error);
|
|
3098
3139
|
try {
|
|
3099
|
-
(0,
|
|
3140
|
+
(0, import_daemon_core5.appendLedgerEntry)(ctx.mesh.id, {
|
|
3100
3141
|
kind: "recovery_attempted",
|
|
3101
3142
|
nodeId: node.id,
|
|
3102
3143
|
providerType,
|
|
@@ -3110,7 +3151,7 @@ function recordRecoverableLaunchFailure(ctx, node, providerType, error) {
|
|
|
3110
3151
|
return failure;
|
|
3111
3152
|
}
|
|
3112
3153
|
function getLatestActiveLaunchFailure(meshId, nodeId) {
|
|
3113
|
-
const entries = (0,
|
|
3154
|
+
const entries = (0, import_daemon_core5.readLedgerEntries)(meshId, { tail: 200 });
|
|
3114
3155
|
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
3115
3156
|
const entry = entries[i];
|
|
3116
3157
|
if (entry.nodeId !== nodeId) continue;
|
|
@@ -3122,7 +3163,7 @@ function getLatestActiveLaunchFailure(meshId, nodeId) {
|
|
|
3122
3163
|
return null;
|
|
3123
3164
|
}
|
|
3124
3165
|
function buildCoordinatorP2pRelayFailure(error, context) {
|
|
3125
|
-
const payload = (0,
|
|
3166
|
+
const payload = (0, import_daemon_core5.buildP2pRelayFailurePayload)(error, {
|
|
3126
3167
|
command: context.command,
|
|
3127
3168
|
targetDaemonId: context.targetDaemonId
|
|
3128
3169
|
});
|
|
@@ -3305,7 +3346,7 @@ function rememberMeshSessionProviderMetadataFromEvent(event) {
|
|
|
3305
3346
|
});
|
|
3306
3347
|
}
|
|
3307
3348
|
function resolveMeshSessionProviderMetadataFromLedger(ctx, nodeId, runtimeSessionId) {
|
|
3308
|
-
const entries = (0,
|
|
3349
|
+
const entries = (0, import_daemon_core5.readLedgerEntries)(ctx.mesh.id, { tail: 50 });
|
|
3309
3350
|
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
3310
3351
|
const entry = entries[i];
|
|
3311
3352
|
const payload = entry.payload && typeof entry.payload === "object" && !Array.isArray(entry.payload) ? entry.payload : {};
|
|
@@ -3443,12 +3484,12 @@ function readNodeSupportedProviders(policy) {
|
|
|
3443
3484
|
}
|
|
3444
3485
|
function buildNodeCapabilityExposure(node) {
|
|
3445
3486
|
const providers = readNodeSupportedProviders(node.policy);
|
|
3446
|
-
const capabilityTags = (0,
|
|
3487
|
+
const capabilityTags = (0, import_daemon_core5.buildMeshNodeCapabilityTags)(node);
|
|
3447
3488
|
const exposure = { capabilityTags };
|
|
3448
3489
|
if (providers.length) {
|
|
3449
3490
|
const byProvider = {};
|
|
3450
3491
|
for (const provider of providers) {
|
|
3451
|
-
byProvider[provider] = (0,
|
|
3492
|
+
byProvider[provider] = (0, import_daemon_core5.buildMeshNodeCapabilityTags)(node, provider);
|
|
3452
3493
|
}
|
|
3453
3494
|
exposure.capabilityTagsByProvider = byProvider;
|
|
3454
3495
|
}
|
|
@@ -3785,7 +3826,7 @@ function buildMeshForwardPayloadFromPendingEvent(event) {
|
|
|
3785
3826
|
// eventId (idempotency) and unicast routing intact, matching the reconcile-loop
|
|
3786
3827
|
// relay path (buildForwardPayloadFromPending). Spread LAST so the authoritative
|
|
3787
3828
|
// envelope always wins. Empty for a v1 event (version-skew safe).
|
|
3788
|
-
...(0,
|
|
3829
|
+
...(0, import_daemon_core5.serializeV2EnvelopeToWire)(event)
|
|
3789
3830
|
};
|
|
3790
3831
|
}
|
|
3791
3832
|
async function drainCoordinatorPendingEvents(ctx, opts) {
|
|
@@ -3859,11 +3900,11 @@ async function drainCoordinatorPendingEvents(ctx, opts) {
|
|
|
3859
3900
|
}
|
|
3860
3901
|
return surfacedEvents;
|
|
3861
3902
|
}
|
|
3862
|
-
const drainerIdentity = (0,
|
|
3903
|
+
const drainerIdentity = (0, import_daemon_core5.coordinatorIdentityFromEmitFields)({
|
|
3863
3904
|
daemonId: ctx.localDaemonId,
|
|
3864
3905
|
sessionId: ctx.coordinatorSessionId
|
|
3865
3906
|
});
|
|
3866
|
-
const events = (0,
|
|
3907
|
+
const events = (0, import_daemon_core5.drainPendingMeshCoordinatorEvents)(
|
|
3867
3908
|
ctx.mesh.id,
|
|
3868
3909
|
ctx.localDaemonId,
|
|
3869
3910
|
drainerIdentity ? { drainerIdentity } : void 0
|
|
@@ -3872,7 +3913,7 @@ async function drainCoordinatorPendingEvents(ctx, opts) {
|
|
|
3872
3913
|
return events;
|
|
3873
3914
|
}
|
|
3874
3915
|
function isP2pTransportUnavailableError(error) {
|
|
3875
|
-
return (0,
|
|
3916
|
+
return (0, import_daemon_core5.isP2pRelayTransportFailure)(error);
|
|
3876
3917
|
}
|
|
3877
3918
|
function buildRemoveNodeArgs(ctx, nodeId, sessionCleanupMode, force) {
|
|
3878
3919
|
return {
|
|
@@ -3891,7 +3932,7 @@ function classifyReadChatTransportCause(error) {
|
|
|
3891
3932
|
return "saturated";
|
|
3892
3933
|
}
|
|
3893
3934
|
function resolveCachedMeshSessionPreviewFromLedger(ctx, nodeId, sessionId) {
|
|
3894
|
-
const entries = (0,
|
|
3935
|
+
const entries = (0, import_daemon_core5.readLedgerEntries)(ctx.mesh.id, { tail: 200 });
|
|
3895
3936
|
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
3896
3937
|
const entry = entries[i];
|
|
3897
3938
|
const payload = entry.payload && typeof entry.payload === "object" && !Array.isArray(entry.payload) ? entry.payload : {};
|
|
@@ -3900,7 +3941,7 @@ function resolveCachedMeshSessionPreviewFromLedger(ctx, nodeId, sessionId) {
|
|
|
3900
3941
|
const entrySessionId = readString(entry.sessionId) || readString(payload.targetSessionId) || readString(payload.sessionId) || readString(payload.instanceId);
|
|
3901
3942
|
if (entrySessionId !== sessionId) continue;
|
|
3902
3943
|
const metadataEvent = payload.metadataEvent && typeof payload.metadataEvent === "object" && !Array.isArray(payload.metadataEvent) ? payload.metadataEvent : payload;
|
|
3903
|
-
const preview = (0,
|
|
3944
|
+
const preview = (0, import_daemon_core5.resolveMeshSurfacedSessionPreview)(metadataEvent);
|
|
3904
3945
|
if (preview) {
|
|
3905
3946
|
return { ...preview, ledgerKind: entry.kind, timestamp: entry.timestamp };
|
|
3906
3947
|
}
|
|
@@ -3908,7 +3949,7 @@ function resolveCachedMeshSessionPreviewFromLedger(ctx, nodeId, sessionId) {
|
|
|
3908
3949
|
return void 0;
|
|
3909
3950
|
}
|
|
3910
3951
|
function buildMeshReadChatCacheFallback(ctx, args, node, error) {
|
|
3911
|
-
const classification = (0,
|
|
3952
|
+
const classification = (0, import_daemon_core5.classifyP2pRelayFailure)(error, { command: "read_chat", targetDaemonId: node.daemonId });
|
|
3912
3953
|
const cause = classifyReadChatTransportCause(error);
|
|
3913
3954
|
const errorMessage = error instanceof Error ? error.message : String(error ?? "");
|
|
3914
3955
|
const causeNote = cause === "not_connected" ? "the worker daemon is not currently connected over P2P (no live channel)" : "the worker daemon is connected but saturated \u2014 it acknowledged the request but did not return the transcript within the deadline";
|
|
@@ -3989,12 +4030,12 @@ function summarizePendingEventProtocolMetrics(pendingEvents) {
|
|
|
3989
4030
|
};
|
|
3990
4031
|
}
|
|
3991
4032
|
async function meshStatus(ctx, args = {}) {
|
|
3992
|
-
const rateResult = (0,
|
|
4033
|
+
const rateResult = (0, import_daemon_core6.recordMeshToolCall)({ meshId: ctx.mesh.id, tool: "mesh_status" });
|
|
3993
4034
|
const compact = args.verbose === true ? false : args.compact ?? true;
|
|
3994
4035
|
await refreshMeshFromDaemon(ctx);
|
|
3995
4036
|
const { mesh, transport } = ctx;
|
|
3996
|
-
let ledgerSummary = (0,
|
|
3997
|
-
const schedulingRuntime = (0,
|
|
4037
|
+
let ledgerSummary = (0, import_daemon_core6.getLedgerSummary)(mesh.id);
|
|
4038
|
+
const schedulingRuntime = (0, import_daemon_core6.buildMeshSchedulingRuntime)(mesh, (0, import_daemon_core6.getQueue)(mesh.id));
|
|
3998
4039
|
const schedulingByNode = new Map(schedulingRuntime.nodes.map((n) => [n.nodeId, n]));
|
|
3999
4040
|
const results = await Promise.all(mesh.nodes.map(async (node) => {
|
|
4000
4041
|
const entry = {
|
|
@@ -4015,7 +4056,7 @@ async function meshStatus(ctx, args = {}) {
|
|
|
4015
4056
|
const { nodeId: _omit, ...rest } = nodeScheduling;
|
|
4016
4057
|
entry.scheduling = compact ? { load: rest.load, capReached: rest.capReached } : rest;
|
|
4017
4058
|
}
|
|
4018
|
-
const lastQuotaRanking = (0,
|
|
4059
|
+
const lastQuotaRanking = (0, import_daemon_core6.getLastQuotaRanking)(node.id);
|
|
4019
4060
|
if (lastQuotaRanking) {
|
|
4020
4061
|
entry.scheduling = { ...entry.scheduling ?? {}, lastQuotaRanking };
|
|
4021
4062
|
}
|
|
@@ -4066,14 +4107,14 @@ async function meshStatus(ctx, args = {}) {
|
|
|
4066
4107
|
noFallbackReason: failure.noFallbackReason
|
|
4067
4108
|
});
|
|
4068
4109
|
}
|
|
4069
|
-
entry.dataFreshness = (0,
|
|
4110
|
+
entry.dataFreshness = (0, import_daemon_core6.buildMeshNodeProbeFreshness)({
|
|
4070
4111
|
git: entry.git,
|
|
4071
4112
|
liveTruthProbed,
|
|
4072
4113
|
isSelfNode: entry.machine?.sameMachine === true,
|
|
4073
4114
|
daemonId: readNodeDaemonId(node),
|
|
4074
4115
|
node
|
|
4075
4116
|
});
|
|
4076
|
-
const recoveryContext = (0,
|
|
4117
|
+
const recoveryContext = (0, import_daemon_core6.getSessionRecoveryContext)(mesh.id, { nodeId: node.id });
|
|
4077
4118
|
if (recoveryContext.consecutiveNodeFailures > 0) {
|
|
4078
4119
|
entry.recoveryHints = {
|
|
4079
4120
|
consecutiveFailures: recoveryContext.consecutiveNodeFailures,
|
|
@@ -4163,23 +4204,23 @@ async function meshStatus(ctx, args = {}) {
|
|
|
4163
4204
|
}
|
|
4164
4205
|
return entry;
|
|
4165
4206
|
}));
|
|
4166
|
-
let ledgerEntries = (0,
|
|
4167
|
-
let directDispatches = (0,
|
|
4207
|
+
let ledgerEntries = (0, import_daemon_core6.readLedgerEntries)(mesh.id, { tail: 200 });
|
|
4208
|
+
let directDispatches = (0, import_daemon_core6.getActiveDirectDispatches)(mesh.id);
|
|
4168
4209
|
const directReconciliation = await reconcileDirectDispatchesFromTranscriptEvidence(ctx, results, directDispatches, ledgerEntries);
|
|
4169
4210
|
if (directReconciliation.reconciled > 0) {
|
|
4170
|
-
ledgerEntries = (0,
|
|
4171
|
-
directDispatches = (0,
|
|
4172
|
-
ledgerSummary = (0,
|
|
4211
|
+
ledgerEntries = (0, import_daemon_core6.readLedgerEntries)(mesh.id, { tail: 200 });
|
|
4212
|
+
directDispatches = (0, import_daemon_core6.getActiveDirectDispatches)(mesh.id);
|
|
4213
|
+
ledgerSummary = (0, import_daemon_core6.getLedgerSummary)(mesh.id);
|
|
4173
4214
|
}
|
|
4174
|
-
const activeWorkEvidence = (0,
|
|
4215
|
+
const activeWorkEvidence = (0, import_daemon_core6.buildMeshActiveWork)({
|
|
4175
4216
|
meshId: mesh.id,
|
|
4176
|
-
queue: (0,
|
|
4217
|
+
queue: (0, import_daemon_core6.getQueue)(mesh.id),
|
|
4177
4218
|
ledgerEntries,
|
|
4178
4219
|
directDispatches,
|
|
4179
4220
|
nodes: results
|
|
4180
4221
|
});
|
|
4181
4222
|
const pollingGuidance = buildActiveWorkPollingGuidance(activeWorkEvidence.summary);
|
|
4182
|
-
const staleDirectWorkSummary = (0,
|
|
4223
|
+
const staleDirectWorkSummary = (0, import_daemon_core6.buildCompactStaleDirectWorkSummary)(activeWorkEvidence.staleDirectWork, {
|
|
4183
4224
|
note: activeWorkEvidence.staleDirectWorkNote,
|
|
4184
4225
|
detailHint: "Full stale direct entries are omitted from mesh_status by default. Call mesh_status with includeStaleDirectWorkDetails=true or inspect mesh_task_history for ledger detail."
|
|
4185
4226
|
});
|
|
@@ -4224,7 +4265,7 @@ async function meshStatus(ctx, args = {}) {
|
|
|
4224
4265
|
const daemonId = typeof entry?.daemonId === "string" && entry.daemonId ? entry.daemonId : "";
|
|
4225
4266
|
if (!daemonId) continue;
|
|
4226
4267
|
if (entry?.machine && !(daemonId in daemonMachines)) daemonMachines[daemonId] = entry.machine;
|
|
4227
|
-
if (entry?.quota && !(daemonId in daemonQuotas)) daemonQuotas[daemonId] = entry.quota;
|
|
4268
|
+
if (entry?.quota && !(daemonId in daemonQuotas)) daemonQuotas[daemonId] = annotateQuotaSnapshotFreshness(entry.quota);
|
|
4228
4269
|
}
|
|
4229
4270
|
const daemonUpgradeFailures = {};
|
|
4230
4271
|
for (const entry of results) {
|
|
@@ -4443,13 +4484,13 @@ async function meshStatus(ctx, args = {}) {
|
|
|
4443
4484
|
}
|
|
4444
4485
|
if (args.includeUsage === true) {
|
|
4445
4486
|
try {
|
|
4446
|
-
response.usage = (0,
|
|
4487
|
+
response.usage = (0, import_daemon_core6.summarizeMeshUsage)(mesh.id);
|
|
4447
4488
|
} catch {
|
|
4448
4489
|
}
|
|
4449
4490
|
}
|
|
4450
4491
|
try {
|
|
4451
4492
|
if (compact) {
|
|
4452
|
-
const { live, historyFold } = (0,
|
|
4493
|
+
const { live, historyFold } = (0, import_daemon_core6.getMeshStatusMissionsCompact)(mesh.id);
|
|
4453
4494
|
const ranked = [...live].sort((a, b) => String(b.tasks?.lastActivityAt ?? "").localeCompare(String(a.tasks?.lastActivityAt ?? "")));
|
|
4454
4495
|
const kept = [];
|
|
4455
4496
|
const overflow = [];
|
|
@@ -4476,11 +4517,11 @@ async function meshStatus(ctx, args = {}) {
|
|
|
4476
4517
|
}
|
|
4477
4518
|
if (historyFold) response.missionsHistory = historyFold;
|
|
4478
4519
|
} else {
|
|
4479
|
-
const missions = (0,
|
|
4520
|
+
const missions = (0, import_daemon_core6.getMeshStatusMissionSummaries)(mesh.id, { verbose: true });
|
|
4480
4521
|
if (missions.length > 0) {
|
|
4481
4522
|
response.missions = missions.map((mission) => {
|
|
4482
4523
|
try {
|
|
4483
|
-
return { ...mission, stats: (0,
|
|
4524
|
+
return { ...mission, stats: (0, import_daemon_core6.computeMeshMissionStats)(mesh.id, mission.id) };
|
|
4484
4525
|
} catch {
|
|
4485
4526
|
return mission;
|
|
4486
4527
|
}
|
|
@@ -4491,14 +4532,14 @@ async function meshStatus(ctx, args = {}) {
|
|
|
4491
4532
|
}
|
|
4492
4533
|
try {
|
|
4493
4534
|
const pendingEvents = await drainCoordinatorPendingEvents(ctx);
|
|
4494
|
-
const asyncRefineJobs = (0,
|
|
4535
|
+
const asyncRefineJobs = (0, import_daemon_core6.buildMeshAsyncRefineJobs)({
|
|
4495
4536
|
meshId: mesh.id,
|
|
4496
4537
|
ledgerEntries,
|
|
4497
4538
|
pendingEvents
|
|
4498
4539
|
});
|
|
4499
4540
|
if (asyncRefineJobs.length > 0) {
|
|
4500
4541
|
if (compact) {
|
|
4501
|
-
const summary = (0,
|
|
4542
|
+
const summary = (0, import_daemon_core6.summarizeMeshAsyncRefineJobs)(asyncRefineJobs);
|
|
4502
4543
|
if (summary.activeJobs.length > 0) response.asyncRefineJobs = summary.activeJobs;
|
|
4503
4544
|
response.asyncRefineJobsSummary = {
|
|
4504
4545
|
total: summary.total,
|
|
@@ -4509,9 +4550,9 @@ async function meshStatus(ctx, args = {}) {
|
|
|
4509
4550
|
response.asyncRefineJobs = asyncRefineJobs;
|
|
4510
4551
|
}
|
|
4511
4552
|
}
|
|
4512
|
-
const magiActivity = (0,
|
|
4553
|
+
const magiActivity = (0, import_daemon_core6.buildMeshMagiActivity)({ meshId: mesh.id, ledgerEntries });
|
|
4513
4554
|
if (magiActivity.length > 0) {
|
|
4514
|
-
const fold = (0,
|
|
4555
|
+
const fold = (0, import_daemon_core6.summarizeMeshMagiActivity)(magiActivity);
|
|
4515
4556
|
if (compact) {
|
|
4516
4557
|
if (fold.groups.length > 0) response.magiActivity = fold.groups;
|
|
4517
4558
|
response.magiActivitySummary = {
|
|
@@ -4570,12 +4611,12 @@ function normalizeDedupMessage(message) {
|
|
|
4570
4611
|
function findInFlightDuplicate(ctx, message, targetNodeId) {
|
|
4571
4612
|
const fingerprint = normalizeDedupMessage(message);
|
|
4572
4613
|
if (!fingerprint) return null;
|
|
4573
|
-
for (const task of (0,
|
|
4614
|
+
for (const task of (0, import_daemon_core6.getQueue)(ctx.mesh.id)) {
|
|
4574
4615
|
if (task.status !== "pending" && task.status !== "assigned") continue;
|
|
4575
4616
|
if (normalizeDedupMessage(task.message) !== fingerprint) continue;
|
|
4576
4617
|
if (targetNodeId) {
|
|
4577
4618
|
const existingTarget = task.targetNodeId || task.assignedNodeId;
|
|
4578
|
-
if (!existingTarget || !(0,
|
|
4619
|
+
if (!existingTarget || !(0, import_daemon_core6.meshNodeIdMatches)({ id: existingTarget }, targetNodeId)) continue;
|
|
4579
4620
|
}
|
|
4580
4621
|
return { id: task.id, status: task.status, assignedNodeId: task.assignedNodeId, targetNodeId: task.targetNodeId };
|
|
4581
4622
|
}
|
|
@@ -4602,10 +4643,10 @@ function normalizeEnqueueTaskArgs(ctx, args, callerLabel) {
|
|
|
4602
4643
|
}
|
|
4603
4644
|
const taskMode = readString(args.task_mode) || readString(args.taskMode);
|
|
4604
4645
|
const readonly = args.readonly === true || args.read_only === true;
|
|
4605
|
-
const requiredTags = (0,
|
|
4646
|
+
const requiredTags = (0, import_daemon_core6.normalizeMeshCapabilityTags)(Array.isArray(args.requiredTags) ? args.requiredTags : args.required_tags);
|
|
4606
4647
|
const dependsOn = Array.isArray(args.dependsOn) ? args.dependsOn : Array.isArray(args.depends_on) ? args.depends_on : void 0;
|
|
4607
4648
|
const missionId = readString(args.missionId) || readString(args.mission_id) || void 0;
|
|
4608
|
-
if (missionId && !(0,
|
|
4649
|
+
if (missionId && !(0, import_daemon_core6.getMeshMission)(ctx.mesh.id, missionId)) {
|
|
4609
4650
|
return {
|
|
4610
4651
|
ok: false,
|
|
4611
4652
|
code: "mission_not_found",
|
|
@@ -4613,19 +4654,19 @@ function normalizeEnqueueTaskArgs(ctx, args, callerLabel) {
|
|
|
4613
4654
|
extra: { missionId }
|
|
4614
4655
|
};
|
|
4615
4656
|
}
|
|
4616
|
-
const priority = (0,
|
|
4657
|
+
const priority = (0, import_daemon_core6.normalizeMeshTaskPriority)(readString(args.priority)) || void 0;
|
|
4617
4658
|
const model = readString(args.model) || void 0;
|
|
4618
4659
|
const thinkingLevel = readString(args.thinkingLevel) || void 0;
|
|
4619
4660
|
const difficulty = readString(args.difficulty) || void 0;
|
|
4620
4661
|
const notBeforeRaw = args.notBefore !== void 0 ? args.notBefore : args.not_before;
|
|
4621
|
-
const notBefore = (0,
|
|
4662
|
+
const notBefore = (0, import_daemon_core6.resolveNotBefore)(notBeforeRaw);
|
|
4622
4663
|
const maxRetriesRaw = typeof args.maxRetries === "number" ? args.maxRetries : typeof args.max_retries === "number" ? args.max_retries : void 0;
|
|
4623
4664
|
const maxRetries = typeof maxRetriesRaw === "number" && Number.isFinite(maxRetriesRaw) && maxRetriesRaw >= 0 ? Math.floor(maxRetriesRaw) : void 0;
|
|
4624
4665
|
const explicitTargetRaw = readString(args.targetNodeId) || readString(args.target_node_id) || readString(args.targetNode) || readString(args.target_node) || void 0;
|
|
4625
4666
|
const preferWorktree = args.preferWorktree === true || args.prefer_worktree === true;
|
|
4626
4667
|
let targetNodeId;
|
|
4627
4668
|
if (explicitTargetRaw) {
|
|
4628
|
-
const matched = ctx.mesh.nodes.find((n) => (0,
|
|
4669
|
+
const matched = ctx.mesh.nodes.find((n) => (0, import_daemon_core6.meshNodeIdMatches)(n, explicitTargetRaw));
|
|
4629
4670
|
if (!matched) {
|
|
4630
4671
|
return {
|
|
4631
4672
|
ok: false,
|
|
@@ -4668,7 +4709,7 @@ function eagerPushTaskToRemoteNodes(ctx, task, message, targetNodeId, requiredTa
|
|
|
4668
4709
|
const isLocalNode = isLocalControlPlaneNode(ctx, node);
|
|
4669
4710
|
if (isLocalNode || !node.daemonId) continue;
|
|
4670
4711
|
if (targetNodeId && node.id !== targetNodeId) continue;
|
|
4671
|
-
if (!(0,
|
|
4712
|
+
if (!(0, import_daemon_core6.nodeSatisfiesRequiredTags)(requiredTags, (0, import_daemon_core6.buildMeshNodeCapabilityTags)(node))) continue;
|
|
4672
4713
|
dispatchPromises.push(
|
|
4673
4714
|
ipcDispatchToRemoteAgent(ctx, node, {
|
|
4674
4715
|
message,
|
|
@@ -4683,7 +4724,7 @@ function eagerPushTaskToRemoteNodes(ctx, task, message, targetNodeId, requiredTa
|
|
|
4683
4724
|
try {
|
|
4684
4725
|
const providerType = result.providerType;
|
|
4685
4726
|
const descriptor = summarizeTaskMessage(message);
|
|
4686
|
-
(0,
|
|
4727
|
+
(0, import_daemon_core6.appendLedgerEntry)(ctx.mesh.id, {
|
|
4687
4728
|
kind: "task_dispatched",
|
|
4688
4729
|
nodeId: node.id,
|
|
4689
4730
|
sessionId: result.sessionId,
|
|
@@ -4705,7 +4746,7 @@ function eagerPushTaskToRemoteNodes(ctx, task, message, targetNodeId, requiredTa
|
|
|
4705
4746
|
}
|
|
4706
4747
|
}).catch((err) => {
|
|
4707
4748
|
try {
|
|
4708
|
-
(0,
|
|
4749
|
+
(0, import_daemon_core6.appendLedgerEntry)(ctx.mesh.id, {
|
|
4709
4750
|
kind: "p2p_dispatch_failed",
|
|
4710
4751
|
nodeId: node.id,
|
|
4711
4752
|
payload: {
|
|
@@ -4757,7 +4798,7 @@ async function meshEnqueueTask(ctx, args) {
|
|
|
4757
4798
|
});
|
|
4758
4799
|
}
|
|
4759
4800
|
try {
|
|
4760
|
-
const task = (0,
|
|
4801
|
+
const task = (0, import_daemon_core6.enqueueTask)(ctx.mesh.id, message, {
|
|
4761
4802
|
taskMode,
|
|
4762
4803
|
...readonly ? { readonly: true } : {},
|
|
4763
4804
|
requiredTags,
|
|
@@ -4808,9 +4849,9 @@ async function meshEnqueueTask(ctx, args) {
|
|
|
4808
4849
|
{
|
|
4809
4850
|
const queueTrigger = await triggerMeshQueueAndReport(ctx);
|
|
4810
4851
|
const dependencyStatusById = new Map(
|
|
4811
|
-
(0,
|
|
4852
|
+
(0, import_daemon_core6.getQueue)(ctx.mesh.id).map((t) => [t.id, t.status])
|
|
4812
4853
|
);
|
|
4813
|
-
const eagerPushDeferred = !(0,
|
|
4854
|
+
const eagerPushDeferred = !(0, import_daemon_core6.taskDependenciesSatisfied)(task, dependencyStatusById);
|
|
4814
4855
|
const coordinatorDaemonId = resolveCoordinatorDaemonId(ctx);
|
|
4815
4856
|
const dispatchPromises = eagerPushDeferred ? [] : eagerPushTaskToRemoteNodes(ctx, task, message, targetNodeId, requiredTags, coordinatorDaemonId);
|
|
4816
4857
|
Promise.all(dispatchPromises).catch(() => {
|
|
@@ -4864,15 +4905,15 @@ async function meshEnqueueBatch(ctx, args) {
|
|
|
4864
4905
|
error: "mesh_enqueue_batch requires a non-empty `tasks` array."
|
|
4865
4906
|
});
|
|
4866
4907
|
}
|
|
4867
|
-
if (rawTasks.length >
|
|
4908
|
+
if (rawTasks.length > import_daemon_core6.MESH_TASK_GRAPH_MAX_TASKS) {
|
|
4868
4909
|
return JSON.stringify({
|
|
4869
4910
|
success: false,
|
|
4870
4911
|
code: "task_graph_too_large",
|
|
4871
|
-
error: `mesh_enqueue_batch accepts at most ${
|
|
4912
|
+
error: `mesh_enqueue_batch accepts at most ${import_daemon_core6.MESH_TASK_GRAPH_MAX_TASKS} tasks per call (got ${rawTasks.length}). Split the graph, or reconsider whether one batch really needs this many tasks.`
|
|
4872
4913
|
});
|
|
4873
4914
|
}
|
|
4874
4915
|
const batchMissionId = readString(args.missionId) || readString(args.mission_id) || void 0;
|
|
4875
|
-
if (batchMissionId && !(0,
|
|
4916
|
+
if (batchMissionId && !(0, import_daemon_core6.getMeshMission)(ctx.mesh.id, batchMissionId)) {
|
|
4876
4917
|
return JSON.stringify({
|
|
4877
4918
|
success: false,
|
|
4878
4919
|
code: "mission_not_found",
|
|
@@ -4944,7 +4985,7 @@ async function meshEnqueueBatch(ctx, args) {
|
|
|
4944
4985
|
}
|
|
4945
4986
|
let tasks;
|
|
4946
4987
|
try {
|
|
4947
|
-
tasks = (0,
|
|
4988
|
+
tasks = (0, import_daemon_core6.enqueueTaskGraph)(ctx.mesh.id, specs);
|
|
4948
4989
|
} catch (e) {
|
|
4949
4990
|
const message = e?.message || String(e);
|
|
4950
4991
|
const code = BATCH_ENQUEUE_ERROR_CODES.find((c) => message.includes(c));
|
|
@@ -4977,12 +5018,12 @@ async function meshEnqueueBatch(ctx, args) {
|
|
|
4977
5018
|
let eagerPushDeferredCount = 0;
|
|
4978
5019
|
if (ctx.transport instanceof IpcTransport) {
|
|
4979
5020
|
const dependencyStatusById = new Map(
|
|
4980
|
-
(0,
|
|
5021
|
+
(0, import_daemon_core6.getQueue)(ctx.mesh.id).map((t) => [t.id, t.status])
|
|
4981
5022
|
);
|
|
4982
5023
|
const coordinatorDaemonId = resolveCoordinatorDaemonId(ctx);
|
|
4983
5024
|
const dispatchPromises = [];
|
|
4984
5025
|
tasks.forEach((task, i) => {
|
|
4985
|
-
if (!(0,
|
|
5026
|
+
if (!(0, import_daemon_core6.taskDependenciesSatisfied)(task, dependencyStatusById)) {
|
|
4986
5027
|
eagerPushDeferredCount++;
|
|
4987
5028
|
return;
|
|
4988
5029
|
}
|
|
@@ -5025,17 +5066,17 @@ async function meshEnqueueBatch(ctx, args) {
|
|
|
5025
5066
|
});
|
|
5026
5067
|
}
|
|
5027
5068
|
async function meshViewQueue(ctx, args) {
|
|
5028
|
-
const rateResult = (0,
|
|
5069
|
+
const rateResult = (0, import_daemon_core6.recordMeshToolCall)({ meshId: ctx.mesh.id, tool: "mesh_view_queue" });
|
|
5029
5070
|
const compact = args.verbose === true ? false : args.compact ?? true;
|
|
5030
5071
|
try {
|
|
5031
5072
|
await refreshMeshFromDaemon(ctx);
|
|
5032
5073
|
const statusFilter = sanitizeQueueStatusFilter(args.status);
|
|
5033
5074
|
const view = normalizeQueueViewMode(args.view);
|
|
5034
|
-
const rawQueue = (0,
|
|
5075
|
+
const rawQueue = (0, import_daemon_core6.getQueue)(ctx.mesh.id);
|
|
5035
5076
|
const statusById = new Map(rawQueue.map((task) => [task.id, task.status]));
|
|
5036
5077
|
const withDependencies = rawQueue.map((task) => {
|
|
5037
5078
|
if (!Array.isArray(task.dependsOn) || task.dependsOn.length === 0) return task;
|
|
5038
|
-
const depState = (0,
|
|
5079
|
+
const depState = (0, import_daemon_core6.describeTaskDependencyState)(task, statusById);
|
|
5039
5080
|
return { ...task, ...depState };
|
|
5040
5081
|
});
|
|
5041
5082
|
const liveNodes = await collectMeshViewQueueNodesWithLiveSessionsVerified(ctx);
|
|
@@ -5044,16 +5085,16 @@ async function meshViewQueue(ctx, args) {
|
|
|
5044
5085
|
const summary = buildQueueStatusSummary(fullQueue);
|
|
5045
5086
|
const visibleSummary = buildQueueStatusSummary(queue);
|
|
5046
5087
|
const maintenance = buildQueueMaintenanceReport(fullQueue);
|
|
5047
|
-
let ledgerEntries = (0,
|
|
5048
|
-
let directDispatches = (0,
|
|
5088
|
+
let ledgerEntries = (0, import_daemon_core6.readLedgerEntries)(ctx.mesh.id, { tail: 200 });
|
|
5089
|
+
let directDispatches = (0, import_daemon_core6.getActiveDirectDispatches)(ctx.mesh.id);
|
|
5049
5090
|
const directReconciliation = await reconcileDirectDispatchesFromTranscriptEvidence(ctx, liveNodes, directDispatches, ledgerEntries);
|
|
5050
5091
|
if (directReconciliation.reconciled > 0) {
|
|
5051
|
-
ledgerEntries = (0,
|
|
5052
|
-
directDispatches = (0,
|
|
5092
|
+
ledgerEntries = (0, import_daemon_core6.readLedgerEntries)(ctx.mesh.id, { tail: 200 });
|
|
5093
|
+
directDispatches = (0, import_daemon_core6.getActiveDirectDispatches)(ctx.mesh.id);
|
|
5053
5094
|
}
|
|
5054
|
-
(0,
|
|
5055
|
-
directDispatches = (0,
|
|
5056
|
-
const activeWorkEvidence = (0,
|
|
5095
|
+
(0, import_daemon_core6.markStaleDirectDispatches)(ctx.mesh.id);
|
|
5096
|
+
directDispatches = (0, import_daemon_core6.getActiveDirectDispatches)(ctx.mesh.id);
|
|
5097
|
+
const activeWorkEvidence = (0, import_daemon_core6.buildMeshActiveWork)({
|
|
5057
5098
|
meshId: ctx.mesh.id,
|
|
5058
5099
|
queue: fullQueue,
|
|
5059
5100
|
ledgerEntries,
|
|
@@ -5078,7 +5119,7 @@ async function meshViewQueue(ctx, args) {
|
|
|
5078
5119
|
const wantActiveQueueArray = view === "active" || statusFilter?.some((status) => ACTIVE_QUEUE_STATUSES.has(status));
|
|
5079
5120
|
const wantHistoricalQueueArray = !compact && (view === "historical" || requestedHistoricalRows);
|
|
5080
5121
|
const activeWorkResult = compact ? compactActiveWorkRecords(activeWorkEvidence.activeWork) : { records: activeWorkEvidence.activeWork, omitted: 0 };
|
|
5081
|
-
const staleDirectWorkSummary = (0,
|
|
5122
|
+
const staleDirectWorkSummary = (0, import_daemon_core6.buildCompactStaleDirectWorkSummary)(activeWorkEvidence.staleDirectWork, {
|
|
5082
5123
|
note: activeWorkEvidence.staleDirectWorkNote,
|
|
5083
5124
|
detailHint: "Full stale direct entries are omitted from mesh_view_queue in compact mode. Call mesh_view_queue with verbose=true, or inspect mesh_task_history for ledger detail."
|
|
5084
5125
|
});
|
|
@@ -5153,12 +5194,12 @@ async function meshQueueCancel(ctx, args) {
|
|
|
5153
5194
|
try {
|
|
5154
5195
|
const taskId = (args.task_id || args.taskId || "").trim();
|
|
5155
5196
|
if (!taskId) return JSON.stringify({ success: false, error: "task_id required" });
|
|
5156
|
-
const preCancel = (0,
|
|
5197
|
+
const preCancel = (0, import_daemon_core6.getQueue)(ctx.mesh.id).find((t) => t?.id === taskId);
|
|
5157
5198
|
const wasAssigned = preCancel?.status === "assigned";
|
|
5158
5199
|
const assignedSessionId = readString(preCancel?.assignedSessionId) || void 0;
|
|
5159
5200
|
const assignedNodeId = readString(preCancel?.assignedNodeId) || void 0;
|
|
5160
5201
|
const assignedProviderType = readString(preCancel?.assignedProviderType) || void 0;
|
|
5161
|
-
const task = (0,
|
|
5202
|
+
const task = (0, import_daemon_core6.cancelTask)(ctx.mesh.id, taskId, { reason: args.reason });
|
|
5162
5203
|
if (!task) return JSON.stringify({ success: false, error: `Queue task '${taskId}' not found` });
|
|
5163
5204
|
ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
|
|
5164
5205
|
});
|
|
@@ -5188,7 +5229,7 @@ async function meshQueueCancel(ctx, args) {
|
|
|
5188
5229
|
let orphanedPinnedTasks = [];
|
|
5189
5230
|
if (workerStop.attempted && assignedSessionId) {
|
|
5190
5231
|
try {
|
|
5191
|
-
orphanedPinnedTasks = (0,
|
|
5232
|
+
orphanedPinnedTasks = (0, import_daemon_core6.notifyCoordinatorOfOrphanedPins)(ctx.mesh.id, assignedSessionId, {
|
|
5192
5233
|
excludeTaskId: taskId,
|
|
5193
5234
|
cause: `Cancelling task ${taskId}`,
|
|
5194
5235
|
...assignedNodeId ? { nodeId: assignedNodeId } : {},
|
|
@@ -5207,7 +5248,7 @@ async function meshQueueCancel(ctx, args) {
|
|
|
5207
5248
|
// can act without waiting for the event round-trip.
|
|
5208
5249
|
...orphanedPinnedTasks.length > 0 ? {
|
|
5209
5250
|
orphanedPinnedTasks,
|
|
5210
|
-
orphanedPinnedTasksWarning: (0,
|
|
5251
|
+
orphanedPinnedTasksWarning: (0, import_daemon_core6.buildOrphanedPinNotice)(
|
|
5211
5252
|
orphanedPinnedTasks,
|
|
5212
5253
|
assignedSessionId,
|
|
5213
5254
|
`Cancelling task ${taskId}`
|
|
@@ -5262,7 +5303,7 @@ async function meshQueueRequeue(ctx, args) {
|
|
|
5262
5303
|
});
|
|
5263
5304
|
return JSON.stringify({ success: true, task: task2 }, null, 2);
|
|
5264
5305
|
}
|
|
5265
|
-
const task = (0,
|
|
5306
|
+
const task = (0, import_daemon_core6.requeueTask)(ctx.mesh.id, taskId, {
|
|
5266
5307
|
reason: args.reason,
|
|
5267
5308
|
targetNodeId,
|
|
5268
5309
|
targetSessionId,
|
|
@@ -5301,17 +5342,17 @@ async function meshTaskHistory(ctx, args) {
|
|
|
5301
5342
|
const compactCap = requestedTail > 50 ? 20 : 30;
|
|
5302
5343
|
const tail = compact ? Math.min(requestedTail, compactCap) : Math.min(requestedTail, 200);
|
|
5303
5344
|
const kind = typeof args.kind === "string" && args.kind.trim() ? [args.kind.trim()] : void 0;
|
|
5304
|
-
const rawEntries = (0,
|
|
5345
|
+
const rawEntries = (0, import_daemon_core6.readLedgerEntries)(mesh.id, { tail, kind });
|
|
5305
5346
|
const entries = compact ? rawEntries.map((e) => ({
|
|
5306
5347
|
...e,
|
|
5307
5348
|
payload: e.payload ? slimLedgerPayload(e.payload) : e.payload
|
|
5308
5349
|
})) : rawEntries;
|
|
5309
|
-
const summary = (0,
|
|
5350
|
+
const summary = (0, import_daemon_core6.getLedgerSummary)(mesh.id);
|
|
5310
5351
|
let taskStats;
|
|
5311
5352
|
try {
|
|
5312
5353
|
const taskIds = [...new Set(rawEntries.map((e) => typeof e.payload?.taskId === "string" ? e.payload.taskId : "").filter(Boolean))];
|
|
5313
5354
|
if (taskIds.length > 0) {
|
|
5314
|
-
const stats = (0,
|
|
5355
|
+
const stats = (0, import_daemon_core6.computeMeshTaskStats)(mesh.id, { taskIds });
|
|
5315
5356
|
if (stats.length > 0) taskStats = stats;
|
|
5316
5357
|
}
|
|
5317
5358
|
} catch {
|
|
@@ -5333,8 +5374,8 @@ async function meshLedgerQuery(ctx, args) {
|
|
|
5333
5374
|
const node = typeof args.node === "string" && args.node.trim() ? args.node.trim() : void 0;
|
|
5334
5375
|
const requestedTail = typeof args.tail === "number" && args.tail > 0 ? Math.floor(args.tail) : 50;
|
|
5335
5376
|
const tail = Math.min(requestedTail, 500);
|
|
5336
|
-
const entries = (0,
|
|
5337
|
-
const summary = (0,
|
|
5377
|
+
const entries = (0, import_daemon_core6.readLedgerEntries)(mesh.id, { tail, kind, since, node });
|
|
5378
|
+
const summary = (0, import_daemon_core6.getLedgerSummary)(mesh.id);
|
|
5338
5379
|
return JSON.stringify({
|
|
5339
5380
|
meshId: mesh.id,
|
|
5340
5381
|
query: {
|
|
@@ -5367,7 +5408,7 @@ async function meshRecordNote(ctx, args) {
|
|
|
5367
5408
|
const supersedes = typeof args.supersedes === "string" && args.supersedes.trim() ? args.supersedes.trim() : void 0;
|
|
5368
5409
|
const subjectKey = typeof args.subject_key === "string" && args.subject_key.trim() ? args.subject_key.trim() : void 0;
|
|
5369
5410
|
const sourceCoordinator = ctx.coordinatorSessionId || ctx.localDaemonId || ctx.coordinatorHostname || void 0;
|
|
5370
|
-
const entry = (0,
|
|
5411
|
+
const entry = (0, import_daemon_core6.appendLedgerEntry)(mesh.id, {
|
|
5371
5412
|
kind: "coordinator_operating_note",
|
|
5372
5413
|
...sourceCoordinator ? { sessionId: sourceCoordinator } : {},
|
|
5373
5414
|
payload: {
|
|
@@ -5405,7 +5446,7 @@ async function meshForgetNote(ctx, args) {
|
|
|
5405
5446
|
return JSON.stringify({ success: false, error: "note_id or text required" }, null, 2);
|
|
5406
5447
|
}
|
|
5407
5448
|
try {
|
|
5408
|
-
const { tombstone, matched } = (0,
|
|
5449
|
+
const { tombstone, matched } = (0, import_daemon_core6.tombstoneOperatingNote)(mesh.id, {
|
|
5409
5450
|
...noteId ? { noteId } : {},
|
|
5410
5451
|
...text ? { text } : {},
|
|
5411
5452
|
...typeof args.reason === "string" && args.reason.trim() ? { reason: args.reason.trim() } : {}
|
|
@@ -5438,8 +5479,8 @@ async function meshReconcileLedger(ctx, args) {
|
|
|
5438
5479
|
const reconcileNode = async (node) => {
|
|
5439
5480
|
try {
|
|
5440
5481
|
if (isLocalControlPlaneNode(ctx, node) || !node.daemonId) {
|
|
5441
|
-
const slice2 = (0,
|
|
5442
|
-
return (0,
|
|
5482
|
+
const slice2 = (0, import_daemon_core6.readLedgerSliceFromStore)(ctx.mesh.id, queryArgs);
|
|
5483
|
+
return (0, import_daemon_core6.buildMeshLedgerReplicaEvidence)({
|
|
5443
5484
|
nodeId: node.id,
|
|
5444
5485
|
daemonId: node.daemonId,
|
|
5445
5486
|
transport: "local",
|
|
@@ -5456,9 +5497,9 @@ async function meshReconcileLedger(ctx, args) {
|
|
|
5456
5497
|
if (slice?.protocol !== "adhdev.mesh.ledger.slice.v1" || !Array.isArray(slice.entries)) {
|
|
5457
5498
|
throw new Error("remote daemon returned an invalid ledger slice payload");
|
|
5458
5499
|
}
|
|
5459
|
-
const importResult = shouldImport ? (0,
|
|
5500
|
+
const importResult = shouldImport ? (0, import_daemon_core6.appendRemoteLedgerEntries)(ctx.mesh.id, slice.entries) : { accepted: 0, skippedDuplicate: 0, rejectedInvalid: 0, entries: [] };
|
|
5460
5501
|
if (shouldImport && importResult.accepted > 0) {
|
|
5461
|
-
(0,
|
|
5502
|
+
(0, import_daemon_core6.appendLedgerEntry)(ctx.mesh.id, {
|
|
5462
5503
|
kind: "ledger_replicated",
|
|
5463
5504
|
nodeId: node.id,
|
|
5464
5505
|
payload: {
|
|
@@ -5471,7 +5512,7 @@ async function meshReconcileLedger(ctx, args) {
|
|
|
5471
5512
|
}
|
|
5472
5513
|
});
|
|
5473
5514
|
}
|
|
5474
|
-
return (0,
|
|
5515
|
+
return (0, import_daemon_core6.buildMeshLedgerReplicaEvidence)({
|
|
5475
5516
|
nodeId: node.id,
|
|
5476
5517
|
daemonId: node.daemonId,
|
|
5477
5518
|
transport: "p2p_datachannel",
|
|
@@ -5479,7 +5520,7 @@ async function meshReconcileLedger(ctx, args) {
|
|
|
5479
5520
|
importResult
|
|
5480
5521
|
});
|
|
5481
5522
|
} catch (e) {
|
|
5482
|
-
return (0,
|
|
5523
|
+
return (0, import_daemon_core6.buildMeshLedgerReplicaEvidence)({
|
|
5483
5524
|
nodeId: node.id,
|
|
5484
5525
|
daemonId: node.daemonId,
|
|
5485
5526
|
transport: node.daemonId ? "p2p_datachannel" : "local",
|
|
@@ -5494,7 +5535,7 @@ async function meshReconcileLedger(ctx, args) {
|
|
|
5494
5535
|
replicas.push(outcome.value);
|
|
5495
5536
|
} else {
|
|
5496
5537
|
const node = nodes[idx];
|
|
5497
|
-
replicas.push((0,
|
|
5538
|
+
replicas.push((0, import_daemon_core6.buildMeshLedgerReplicaEvidence)({
|
|
5498
5539
|
nodeId: node.id,
|
|
5499
5540
|
daemonId: node.daemonId,
|
|
5500
5541
|
transport: node.daemonId ? "p2p_datachannel" : "local",
|
|
@@ -5503,8 +5544,8 @@ async function meshReconcileLedger(ctx, args) {
|
|
|
5503
5544
|
}));
|
|
5504
5545
|
}
|
|
5505
5546
|
});
|
|
5506
|
-
const evidence = (0,
|
|
5507
|
-
(0,
|
|
5547
|
+
const evidence = (0, import_daemon_core6.buildMeshLedgerReconciliationEvidence)(ctx.mesh.id, replicas);
|
|
5548
|
+
(0, import_daemon_core6.appendLedgerEntry)(ctx.mesh.id, {
|
|
5508
5549
|
kind: "ledger_reconciled",
|
|
5509
5550
|
payload: {
|
|
5510
5551
|
protocol: evidence.protocol,
|
|
@@ -5525,7 +5566,7 @@ async function meshRequeueHeldEvents(ctx, args) {
|
|
|
5525
5566
|
...readString(raw.reason) ? { reason: readString(raw.reason) } : {},
|
|
5526
5567
|
...readString(raw.since) ? { since: readString(raw.since) } : {}
|
|
5527
5568
|
} : void 0;
|
|
5528
|
-
const result = (0,
|
|
5569
|
+
const result = (0, import_daemon_core6.requeueHeldMeshCoordinatorEvents)(mesh.id, filter && Object.keys(filter).length > 0 ? filter : void 0);
|
|
5529
5570
|
const note = result.matched === 0 ? "No recoverable held events matched. Nothing to requeue." : `${result.requeued} held event(s) restored to the pending queue` + (result.dedupSuppressed > 0 ? ` (${result.dedupSuppressed} collapsed onto still-live duplicates)` : "") + (result.alreadyRequeued > 0 ? `; ${result.alreadyRequeued} already recovered by a prior pass` : "") + (result.unrecoverable > 0 ? `; ${result.unrecoverable} had no restorable original event` : "") + ". A coordinator will drain them on its next poll.";
|
|
5530
5571
|
return JSON.stringify({ success: true, ...result, note }, null, 2);
|
|
5531
5572
|
}
|
|
@@ -5543,7 +5584,7 @@ async function meshMissionUpsert(ctx, args) {
|
|
|
5543
5584
|
error: "mission_title_required: single-mission upsert needs a non-empty title. For a bulk status transition pass mission_ids (array) + status instead."
|
|
5544
5585
|
});
|
|
5545
5586
|
}
|
|
5546
|
-
const mission = (0,
|
|
5587
|
+
const mission = (0, import_daemon_core6.upsertMeshMission)(ctx.mesh.id, {
|
|
5547
5588
|
id: readString(args.mission_id) || readString(args.missionId) || void 0,
|
|
5548
5589
|
title,
|
|
5549
5590
|
goal: typeof args.goal === "string" ? args.goal : void 0,
|
|
@@ -5579,9 +5620,9 @@ async function meshMissionUpsertBulk(ctx, missionIds, status) {
|
|
|
5579
5620
|
}
|
|
5580
5621
|
const results = missionIds.map((id) => {
|
|
5581
5622
|
try {
|
|
5582
|
-
const existing = (0,
|
|
5623
|
+
const existing = (0, import_daemon_core6.getMeshMission)(ctx.mesh.id, id);
|
|
5583
5624
|
if (!existing) return { id, ok: false, error: "mission_not_found" };
|
|
5584
|
-
const updated = (0,
|
|
5625
|
+
const updated = (0, import_daemon_core6.upsertMeshMission)(ctx.mesh.id, {
|
|
5585
5626
|
id,
|
|
5586
5627
|
title: existing.title,
|
|
5587
5628
|
status
|
|
@@ -5608,12 +5649,12 @@ async function meshMissionUpsertBulk(ctx, missionIds, status) {
|
|
|
5608
5649
|
async function meshMissionList(ctx, args = {}) {
|
|
5609
5650
|
try {
|
|
5610
5651
|
const rawStatuses = Array.isArray(args.status) ? args.status : typeof args.status === "string" && args.status.trim() ? [args.status] : [];
|
|
5611
|
-
const invalid = rawStatuses.filter((s) => !
|
|
5652
|
+
const invalid = rawStatuses.filter((s) => !import_daemon_core6.MESH_MISSION_STATUSES.includes(s));
|
|
5612
5653
|
if (invalid.length > 0) {
|
|
5613
5654
|
return JSON.stringify({
|
|
5614
5655
|
success: false,
|
|
5615
5656
|
code: "invalid_mission_status",
|
|
5616
|
-
error: `invalid status filter: ${invalid.join(", ")} (valid: ${
|
|
5657
|
+
error: `invalid status filter: ${invalid.join(", ")} (valid: ${import_daemon_core6.MESH_MISSION_STATUSES.join(", ")})`
|
|
5617
5658
|
});
|
|
5618
5659
|
}
|
|
5619
5660
|
const statuses = rawStatuses.length > 0 ? rawStatuses : void 0;
|
|
@@ -5621,7 +5662,7 @@ async function meshMissionList(ctx, args = {}) {
|
|
|
5621
5662
|
const verbose = args.verbose === true;
|
|
5622
5663
|
const withStats = verbose || (args.include_stats ?? args.includeStats) === true;
|
|
5623
5664
|
const limit = typeof args.limit === "number" && Number.isFinite(args.limit) && args.limit > 0 ? Math.floor(args.limit) : void 0;
|
|
5624
|
-
const result = (0,
|
|
5665
|
+
const result = (0, import_daemon_core6.listMeshMissionsForTool)(ctx.mesh.id, {
|
|
5625
5666
|
statuses,
|
|
5626
5667
|
verbose,
|
|
5627
5668
|
includeMagi,
|
|
@@ -5654,7 +5695,7 @@ async function meshReviewInbox(ctx, args = {}) {
|
|
|
5654
5695
|
}
|
|
5655
5696
|
|
|
5656
5697
|
// src/tools/mesh-tools-magi.ts
|
|
5657
|
-
var
|
|
5698
|
+
var import_daemon_core7 = require("@adhdev/daemon-core");
|
|
5658
5699
|
var MAGI_MAX_REPLICAS = 12;
|
|
5659
5700
|
var MAGI_MIN_TARGETS = 2;
|
|
5660
5701
|
var MAGI_CLUSTER_JACCARD = 0.4;
|
|
@@ -6138,19 +6179,19 @@ function buildMagiFanoutPlan(slots, nodes, opts = {}) {
|
|
|
6138
6179
|
slotList.forEach((slot, slotIndex) => {
|
|
6139
6180
|
const provider = slot.provider;
|
|
6140
6181
|
const model = typeof slot.model === "string" && slot.model.trim() ? slot.model.trim() : void 0;
|
|
6141
|
-
const capabilityTags = (0,
|
|
6142
|
-
const requiredTags = (0,
|
|
6182
|
+
const capabilityTags = (0, import_daemon_core6.normalizeMeshCapabilityTags)(slot.capabilityTags);
|
|
6183
|
+
const requiredTags = (0, import_daemon_core6.normalizeMeshCapabilityTags)([`provider=${provider}`, ...capabilityTags]);
|
|
6143
6184
|
const count = replicaCountFor(slot, defaultN, opts.n);
|
|
6144
6185
|
let targetNodeId;
|
|
6145
6186
|
let candidateNodes = [];
|
|
6146
6187
|
if (slot.nodeId) {
|
|
6147
|
-
const node = nodes.find((n) => (0,
|
|
6188
|
+
const node = nodes.find((n) => (0, import_daemon_core6.meshNodeIdMatches)(n, slot.nodeId));
|
|
6148
6189
|
if (node) {
|
|
6149
6190
|
targetNodeId = node.id;
|
|
6150
6191
|
candidateNodes = [node];
|
|
6151
6192
|
}
|
|
6152
6193
|
} else {
|
|
6153
|
-
candidateNodes = nodes.filter((n) => (0,
|
|
6194
|
+
candidateNodes = nodes.filter((n) => (0, import_daemon_core6.nodeSatisfiesRequiredTags)(requiredTags, (0, import_daemon_core6.buildMeshNodeCapabilityTags)(n)));
|
|
6154
6195
|
}
|
|
6155
6196
|
const available = candidateNodes.length > 0;
|
|
6156
6197
|
if (!available) {
|
|
@@ -6164,9 +6205,9 @@ function buildMagiFanoutPlan(slots, nodes, opts = {}) {
|
|
|
6164
6205
|
slotResolutions.push({ slotIndex, provider, nodeId: slot.nodeId, capabilityTags, available: false, gitStale: false, unhealthy: false, excluded: true, reason: "unavailable" });
|
|
6165
6206
|
return;
|
|
6166
6207
|
}
|
|
6167
|
-
const launchableCandidates = candidateNodes.filter((n) => (0,
|
|
6208
|
+
const launchableCandidates = candidateNodes.filter((n) => (0, import_daemon_core6.isMeshNodeHealthLaunchable)(n));
|
|
6168
6209
|
if (launchableCandidates.length === 0) {
|
|
6169
|
-
const health = (0,
|
|
6210
|
+
const health = (0, import_daemon_core6.resolveEffectiveMeshNodeHealth)(candidateNodes[0]);
|
|
6170
6211
|
unhealthySlots.push({
|
|
6171
6212
|
slotIndex,
|
|
6172
6213
|
provider,
|
|
@@ -6231,7 +6272,7 @@ function buildMagiFanoutPlan(slots, nodes, opts = {}) {
|
|
|
6231
6272
|
// Candidate pool was already narrowed to launch-ready nodes above, so an
|
|
6232
6273
|
// included slot is health-launchable by construction.
|
|
6233
6274
|
unhealthy: false,
|
|
6234
|
-
health: (0,
|
|
6275
|
+
health: (0, import_daemon_core6.resolveEffectiveMeshNodeHealth)(candidateNodes[0]),
|
|
6235
6276
|
excluded: false
|
|
6236
6277
|
};
|
|
6237
6278
|
if (gitStale && !includeStale) {
|
|
@@ -6404,13 +6445,13 @@ function collectMagiCandidateTexts(payload) {
|
|
|
6404
6445
|
}
|
|
6405
6446
|
function replicaCompletionIsWeak(meshId, taskId) {
|
|
6406
6447
|
try {
|
|
6407
|
-
const entries = (0,
|
|
6448
|
+
const entries = (0, import_daemon_core6.readLedgerEntries)(meshId, { kind: ["task_completed"], tail: 200 });
|
|
6408
6449
|
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
6409
6450
|
const entry = entries[i];
|
|
6410
6451
|
const payload = entry?.payload && typeof entry.payload === "object" ? entry.payload : void 0;
|
|
6411
6452
|
const entryTaskId = readString(payload?.taskId) || readString(entry?.taskId);
|
|
6412
6453
|
if (!entryTaskId || entryTaskId !== taskId) continue;
|
|
6413
|
-
if ((0,
|
|
6454
|
+
if ((0, import_daemon_core6.isWeakCompletionEvidence)(payload)) return true;
|
|
6414
6455
|
const diag = payload?.completionDiagnostic;
|
|
6415
6456
|
if (diag && typeof diag === "object" && !Array.isArray(diag) && readString(diag.reason) === "short_generating_suppressed") {
|
|
6416
6457
|
return true;
|
|
@@ -6437,9 +6478,9 @@ async function meshMagiKindPanelSet(ctx, args) {
|
|
|
6437
6478
|
const meshId = ctx.mesh.id;
|
|
6438
6479
|
const scope = magiPanelScope(meshId, ctx.mesh.name);
|
|
6439
6480
|
try {
|
|
6440
|
-
const current = (0,
|
|
6481
|
+
const current = (0, import_daemon_core6.getMagiKindPanel)(kind, meshId) ?? [];
|
|
6441
6482
|
if (!write) {
|
|
6442
|
-
const preview = (0,
|
|
6483
|
+
const preview = (0, import_daemon_core6.normalizeMagiSlots)(args.slots, ctx.mesh.nodes.map((n) => n.id));
|
|
6443
6484
|
return JSON.stringify({
|
|
6444
6485
|
success: true,
|
|
6445
6486
|
dryRun: true,
|
|
@@ -6451,7 +6492,7 @@ async function meshMagiKindPanelSet(ctx, args) {
|
|
|
6451
6492
|
note: `Dry-run only \u2014 no file written. This is a WHOLESALE replacement of the kind's slot list for mesh '${meshId}' (machine-local ~/.adhdev/meshes.json); the currentSlots would be fully replaced. Other meshes on this machine are unaffected. Re-run with write=true after explicit user approval.`
|
|
6452
6493
|
}, null, 2);
|
|
6453
6494
|
}
|
|
6454
|
-
const slots = (0,
|
|
6495
|
+
const slots = (0, import_daemon_core6.setMagiKindPanel)(kind, args.slots, meshId);
|
|
6455
6496
|
return JSON.stringify({
|
|
6456
6497
|
success: true,
|
|
6457
6498
|
written: true,
|
|
@@ -6472,9 +6513,9 @@ async function meshMagiKindPanelList(ctx, args = {}) {
|
|
|
6472
6513
|
const only = readString(args.task_kind) || readString(args.kind);
|
|
6473
6514
|
const meshId = ctx.mesh.id;
|
|
6474
6515
|
const scope = magiPanelScope(meshId, ctx.mesh.name);
|
|
6475
|
-
const all = (0,
|
|
6516
|
+
const all = (0, import_daemon_core6.listMagiKindPanels)(meshId);
|
|
6476
6517
|
if (only) {
|
|
6477
|
-
const slots = (0,
|
|
6518
|
+
const slots = (0, import_daemon_core6.getMagiKindPanel)(only, meshId);
|
|
6478
6519
|
if (slots === void 0) {
|
|
6479
6520
|
return JSON.stringify({
|
|
6480
6521
|
success: false,
|
|
@@ -6507,7 +6548,7 @@ async function meshMagiReview(ctx, args) {
|
|
|
6507
6548
|
const referenceSubmoduleKey = resolveMagiReferenceSubmoduleKey(ctx);
|
|
6508
6549
|
const taskKind = normalizeMagiTaskKind(explicitTaskKind);
|
|
6509
6550
|
const panelName = `(kind:${taskKind})`;
|
|
6510
|
-
const slots = (0,
|
|
6551
|
+
const slots = (0, import_daemon_core6.getMagiKindPanel)(taskKind, ctx.mesh.id);
|
|
6511
6552
|
if (!slots || slots.length === 0) {
|
|
6512
6553
|
return JSON.stringify({
|
|
6513
6554
|
success: false,
|
|
@@ -6515,13 +6556,13 @@ async function meshMagiReview(ctx, args) {
|
|
|
6515
6556
|
error: `No panel slots are configured for this task_kind in mesh '${ctx.mesh.id}' settings. Add at least one (machine + provider + model) slot in settings \u2014 task_kind '${taskKind}' has no configured kind-panel.`,
|
|
6516
6557
|
taskKind,
|
|
6517
6558
|
meshId: ctx.mesh.id,
|
|
6518
|
-
configuredKinds: Object.keys((0,
|
|
6559
|
+
configuredKinds: Object.keys((0, import_daemon_core6.listMagiKindPanels)(ctx.mesh.id)),
|
|
6519
6560
|
hint: "Configure this kind in mesh settings (MagiKindPanelEditor), or set it with mesh_magi_kind_panel_set, then retry."
|
|
6520
6561
|
}, null, 2);
|
|
6521
6562
|
}
|
|
6522
6563
|
let planSlots;
|
|
6523
6564
|
try {
|
|
6524
|
-
planSlots = (0,
|
|
6565
|
+
planSlots = (0, import_daemon_core6.normalizeMagiSlots)(slots);
|
|
6525
6566
|
} catch (e) {
|
|
6526
6567
|
return JSON.stringify({
|
|
6527
6568
|
success: false,
|
|
@@ -6577,7 +6618,7 @@ async function meshMagiReview(ctx, args) {
|
|
|
6577
6618
|
const waitTimeoutMs = Math.min(MAGI_MAX_WAIT_MS, Math.max(MAGI_POLL_INTERVAL_MS, Number(args.wait_timeout_ms ?? args.waitTimeoutMs) || MAGI_DEFAULT_WAIT_MS));
|
|
6578
6619
|
const consensusGroupId = `magi_${(0, import_node_crypto.randomUUID)().replace(/-/g, "")}`;
|
|
6579
6620
|
const titleQ = question.length > 80 ? `${question.slice(0, 77)}...` : question;
|
|
6580
|
-
const mission = (0,
|
|
6621
|
+
const mission = (0, import_daemon_core6.upsertMeshMission)(ctx.mesh.id, {
|
|
6581
6622
|
title: `MAGI: ${titleQ}`,
|
|
6582
6623
|
goal: `Cross-verify (read-only) across panel '${panelName}': ${question}${args.target ? `
|
|
6583
6624
|
Target: ${args.target}` : ""}`,
|
|
@@ -6589,7 +6630,7 @@ Target: ${args.target}` : ""}`,
|
|
|
6589
6630
|
const replicaRecords = [];
|
|
6590
6631
|
for (const replica of plan.replicas) {
|
|
6591
6632
|
try {
|
|
6592
|
-
const task = (0,
|
|
6633
|
+
const task = (0, import_daemon_core6.enqueueTask)(ctx.mesh.id, prompt, {
|
|
6593
6634
|
readonly: true,
|
|
6594
6635
|
taskMode: "live_debug_readonly",
|
|
6595
6636
|
// DIFFICULTY-REQUIRED (MAGI decision): a fixed 'freeform' sentinel, NOT an
|
|
@@ -6618,7 +6659,7 @@ Target: ${args.target}` : ""}`,
|
|
|
6618
6659
|
replicaRecords.push({ taskId: task.id, provider: replica.provider, targetNodeId: replica.targetNodeId, requiredTags: replica.requiredTags });
|
|
6619
6660
|
} catch (e) {
|
|
6620
6661
|
try {
|
|
6621
|
-
(0,
|
|
6662
|
+
(0, import_daemon_core6.appendLedgerEntry)(ctx.mesh.id, {
|
|
6622
6663
|
kind: "magi_replica_enqueue_failed",
|
|
6623
6664
|
payload: { consensusGroupId, missionId: mission.id, provider: replica.provider, error: e?.message || String(e) }
|
|
6624
6665
|
});
|
|
@@ -6708,7 +6749,7 @@ Target: ${args.target}` : ""}`,
|
|
|
6708
6749
|
});
|
|
6709
6750
|
closeMagiMissionIfTerminal(ctx, mission.id, collected.terminal);
|
|
6710
6751
|
const cleanupMode = resolveMagiAutoCleanupMode(ctx, args.auto_cleanup ?? args.autoCleanup);
|
|
6711
|
-
const cleanupReplicaTasks = findMagiReplicaTasks((0,
|
|
6752
|
+
const cleanupReplicaTasks = findMagiReplicaTasks((0, import_daemon_core6.getQueue)(ctx.mesh.id), consensusGroupId);
|
|
6712
6753
|
const cleanup = await cleanupMagiAutoLaunchedSessions(ctx, {
|
|
6713
6754
|
replicaTasks: cleanupReplicaTasks,
|
|
6714
6755
|
terminal: collected.terminal,
|
|
@@ -6738,7 +6779,7 @@ async function meshMagiCollect(ctx, args) {
|
|
|
6738
6779
|
await refreshMeshFromDaemon(ctx);
|
|
6739
6780
|
const explicitKind = args.task_kind ?? args.taskKind;
|
|
6740
6781
|
const taskKind = explicitKind !== void 0 ? normalizeMagiTaskKind(explicitKind) : recoverMagiTaskKind(ctx, consensusGroupId);
|
|
6741
|
-
const replicaTasks = findMagiReplicaTasks((0,
|
|
6782
|
+
const replicaTasks = findMagiReplicaTasks((0, import_daemon_core6.getQueue)(ctx.mesh.id), consensusGroupId);
|
|
6742
6783
|
if (replicaTasks.length === 0) {
|
|
6743
6784
|
return JSON.stringify({
|
|
6744
6785
|
success: false,
|
|
@@ -6842,7 +6883,7 @@ function computeMagiCleanupTargets(replicaTasks) {
|
|
|
6842
6883
|
function resolveMagiAutoCleanupMode(ctx, perCallOverride) {
|
|
6843
6884
|
if (perCallOverride === true) return "stop_and_delete";
|
|
6844
6885
|
if (perCallOverride === false) return "preserve";
|
|
6845
|
-
return (0,
|
|
6886
|
+
return (0, import_daemon_core7.resolveMagiSessionCleanupMode)(ctx.mesh?.policy?.magiSessionCleanup);
|
|
6846
6887
|
}
|
|
6847
6888
|
async function cleanupMagiAutoLaunchedSessions(ctx, args) {
|
|
6848
6889
|
if (args.mode === "preserve") return null;
|
|
@@ -6921,7 +6962,7 @@ function classifyStaleReplicas(annotatedTasks, terminal = MAGI_TERMINAL_STATUSES
|
|
|
6921
6962
|
}
|
|
6922
6963
|
function persistMagiDispatched(ctx, args) {
|
|
6923
6964
|
try {
|
|
6924
|
-
(0,
|
|
6965
|
+
(0, import_daemon_core6.appendLedgerEntry)(ctx.mesh.id, {
|
|
6925
6966
|
kind: "magi_dispatched",
|
|
6926
6967
|
payload: {
|
|
6927
6968
|
source: "magi",
|
|
@@ -6941,7 +6982,7 @@ function persistMagiDispatched(ctx, args) {
|
|
|
6941
6982
|
}
|
|
6942
6983
|
function recoverMagiTaskKind(ctx, consensusGroupId) {
|
|
6943
6984
|
try {
|
|
6944
|
-
const entries = (0,
|
|
6985
|
+
const entries = (0, import_daemon_core6.readLedgerEntries)(ctx.mesh.id, { kind: ["magi_dispatched"], tail: 200 });
|
|
6945
6986
|
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
6946
6987
|
const payload = entries[i]?.payload;
|
|
6947
6988
|
if (!payload || typeof payload !== "object") continue;
|
|
@@ -6965,7 +7006,7 @@ function stripRawAnswers(synthesis) {
|
|
|
6965
7006
|
}
|
|
6966
7007
|
function persistMagiSynthesis(ctx, args) {
|
|
6967
7008
|
try {
|
|
6968
|
-
(0,
|
|
7009
|
+
(0, import_daemon_core6.appendLedgerEntry)(ctx.mesh.id, {
|
|
6969
7010
|
kind: "magi_synthesis",
|
|
6970
7011
|
payload: {
|
|
6971
7012
|
source: "magi",
|
|
@@ -6985,9 +7026,9 @@ function closeMagiMissionIfTerminal(ctx, missionId, terminal) {
|
|
|
6985
7026
|
const id = readString(missionId);
|
|
6986
7027
|
if (!id) return;
|
|
6987
7028
|
try {
|
|
6988
|
-
const mission = (0,
|
|
7029
|
+
const mission = (0, import_daemon_core6.getMeshMission)(ctx.mesh.id, id);
|
|
6989
7030
|
if (!mission || mission.status !== "active") return;
|
|
6990
|
-
(0,
|
|
7031
|
+
(0, import_daemon_core6.upsertMeshMission)(ctx.mesh.id, {
|
|
6991
7032
|
id,
|
|
6992
7033
|
title: mission.title,
|
|
6993
7034
|
// Preserve goal: upsert defaults goal to the existing value when omitted.
|
|
@@ -7022,8 +7063,8 @@ async function collectMagiResponses(ctx, args) {
|
|
|
7022
7063
|
const candidates = collectMagiCandidateTexts(payload);
|
|
7023
7064
|
const raw = candidates.find((c) => c.trim().length > 0);
|
|
7024
7065
|
if (!raw) return;
|
|
7025
|
-
if (raw.length >
|
|
7026
|
-
source.rawAnswer = raw.slice(0,
|
|
7066
|
+
if (raw.length > import_daemon_core6.MAGI_RAW_ANSWER_CAP) {
|
|
7067
|
+
source.rawAnswer = raw.slice(0, import_daemon_core6.MAGI_RAW_ANSWER_CAP);
|
|
7027
7068
|
source.rawAnswerTruncated = true;
|
|
7028
7069
|
} else {
|
|
7029
7070
|
source.rawAnswer = raw;
|
|
@@ -7033,7 +7074,7 @@ async function collectMagiResponses(ctx, args) {
|
|
|
7033
7074
|
};
|
|
7034
7075
|
const buildSource = (task) => {
|
|
7035
7076
|
const sourceNodeId = task.assignedNodeId || task.targetNodeId || void 0;
|
|
7036
|
-
const gitRef = extractNodeGitRef(sourceNodeId ? ctx.mesh.nodes.find((n) => (0,
|
|
7077
|
+
const gitRef = extractNodeGitRef(sourceNodeId ? ctx.mesh.nodes.find((n) => (0, import_daemon_core6.meshNodeIdMatches)(n, sourceNodeId)) : void 0);
|
|
7037
7078
|
return {
|
|
7038
7079
|
taskId: task.id,
|
|
7039
7080
|
nodeId: sourceNodeId,
|
|
@@ -7043,7 +7084,7 @@ async function collectMagiResponses(ctx, args) {
|
|
|
7043
7084
|
};
|
|
7044
7085
|
};
|
|
7045
7086
|
const sendKindRetry = async (task, failReason) => {
|
|
7046
|
-
const node = ctx.mesh.nodes.find((n) => (0,
|
|
7087
|
+
const node = ctx.mesh.nodes.find((n) => (0, import_daemon_core6.meshNodeIdMatches)(n, task.assignedNodeId));
|
|
7047
7088
|
if (!node || !task.assignedSessionId) return false;
|
|
7048
7089
|
const why = failReason === "empty_evidence" ? "your previous answer had an empty evidence array" : failReason === "missing_required_fields" ? "your previous answer was missing required fields" : "your previous answer did not parse as the required JSON";
|
|
7049
7090
|
const message = `Your previous MAGI answer could not be accepted (${why}). Respond NOW with ONLY a single JSON object (no prose, no code fence) matching EXACTLY this schema, with non-empty evidence:
|
|
@@ -7069,7 +7110,7 @@ ${magiOutputContractFor(kind)}`;
|
|
|
7069
7110
|
}
|
|
7070
7111
|
});
|
|
7071
7112
|
try {
|
|
7072
|
-
(0,
|
|
7113
|
+
(0, import_daemon_core6.appendLedgerEntry)(ctx.mesh.id, {
|
|
7073
7114
|
kind: "magi_replica_retry",
|
|
7074
7115
|
payload: { taskId: task.id, kind, failReason }
|
|
7075
7116
|
});
|
|
@@ -7081,7 +7122,7 @@ ${magiOutputContractFor(kind)}`;
|
|
|
7081
7122
|
}
|
|
7082
7123
|
};
|
|
7083
7124
|
const nudgeWedgedReplica = async (task) => {
|
|
7084
|
-
const node = ctx.mesh.nodes.find((n) => (0,
|
|
7125
|
+
const node = ctx.mesh.nodes.find((n) => (0, import_daemon_core6.meshNodeIdMatches)(n, task.assignedNodeId));
|
|
7085
7126
|
if (!node || !task.assignedSessionId) return;
|
|
7086
7127
|
try {
|
|
7087
7128
|
const read = await commandForNode(ctx, node, "read_chat", {
|
|
@@ -7103,7 +7144,7 @@ ${magiOutputContractFor(kind)}`;
|
|
|
7103
7144
|
action: "approve"
|
|
7104
7145
|
});
|
|
7105
7146
|
try {
|
|
7106
|
-
(0,
|
|
7147
|
+
(0, import_daemon_core6.appendLedgerEntry)(ctx.mesh.id, {
|
|
7107
7148
|
kind: "magi_replica_auto_approved",
|
|
7108
7149
|
payload: { taskId: task.id, nodeId: task.assignedNodeId, status }
|
|
7109
7150
|
});
|
|
@@ -7147,7 +7188,7 @@ ${magiOutputContractFor(kind)}`;
|
|
|
7147
7188
|
}
|
|
7148
7189
|
let kindResult;
|
|
7149
7190
|
try {
|
|
7150
|
-
const node = ctx.mesh.nodes.find((n) => (0,
|
|
7191
|
+
const node = ctx.mesh.nodes.find((n) => (0, import_daemon_core6.meshNodeIdMatches)(n, task.assignedNodeId));
|
|
7151
7192
|
if (!node) throw new Error("assigned node not in mesh");
|
|
7152
7193
|
const result = await commandForNode(ctx, node, "read_chat", {
|
|
7153
7194
|
sessionId: task.assignedSessionId,
|
|
@@ -7200,7 +7241,7 @@ ${magiOutputContractFor(kind)}`;
|
|
|
7200
7241
|
return false;
|
|
7201
7242
|
};
|
|
7202
7243
|
for (; ; ) {
|
|
7203
|
-
const tasks = annotateQueueStaleness((0,
|
|
7244
|
+
const tasks = annotateQueueStaleness((0, import_daemon_core6.getQueue)(ctx.mesh.id).filter((t) => ids.has(t.id)), ctx.mesh);
|
|
7204
7245
|
const allPresent = tasks.length === ids.size;
|
|
7205
7246
|
const { staleTaskIds: staleTaskIds2, staleReasons: staleReasons2 } = classifyStaleReplicas(tasks, TERMINAL);
|
|
7206
7247
|
const pastDeadline = Date.now() >= deadline;
|
|
@@ -7214,7 +7255,7 @@ ${magiOutputContractFor(kind)}`;
|
|
|
7214
7255
|
if (allPresent && outstanding.length > 0 && outstanding.every((t) => staleTaskIds2.has(t.id))) break;
|
|
7215
7256
|
await sleep(Math.min(MAGI_POLL_INTERVAL_MS, Math.max(0, deadline - Date.now())));
|
|
7216
7257
|
}
|
|
7217
|
-
const finalTasks = annotateQueueStaleness((0,
|
|
7258
|
+
const finalTasks = annotateQueueStaleness((0, import_daemon_core6.getQueue)(ctx.mesh.id).filter((t) => ids.has(t.id)), ctx.mesh);
|
|
7218
7259
|
const { staleTaskIds, staleReasons } = classifyStaleReplicas(finalTasks, TERMINAL);
|
|
7219
7260
|
const presentIds = new Set(finalTasks.map((t) => t.id));
|
|
7220
7261
|
for (const task of finalTasks) {
|
|
@@ -7409,7 +7450,7 @@ async function meshNodeSlotsPropose(ctx, args = {}) {
|
|
|
7409
7450
|
}
|
|
7410
7451
|
|
|
7411
7452
|
// src/tools/mesh-tools-session.ts
|
|
7412
|
-
var
|
|
7453
|
+
var import_daemon_core8 = require("@adhdev/daemon-core");
|
|
7413
7454
|
function computeIdleDispatchAckRisk(sessionWasIdle, dispatchPreRecorded, sessionId) {
|
|
7414
7455
|
if (!sessionWasIdle || dispatchPreRecorded) return {};
|
|
7415
7456
|
return {
|
|
@@ -7423,11 +7464,11 @@ async function meshPruneStaleDirect(ctx, args = {}) {
|
|
|
7423
7464
|
const execute = args.execute === true && args.dry_run !== true;
|
|
7424
7465
|
const includeTerminal = args.include_terminal === true;
|
|
7425
7466
|
const liveNodes = await collectMeshViewQueueNodesWithLiveSessions(ctx);
|
|
7426
|
-
const ledgerEntries = (0,
|
|
7427
|
-
const directDispatches = (0,
|
|
7428
|
-
const result = (0,
|
|
7467
|
+
const ledgerEntries = (0, import_daemon_core6.readLedgerEntries)(ctx.mesh.id, { tail: 500 });
|
|
7468
|
+
const directDispatches = (0, import_daemon_core6.getActiveDirectDispatches)(ctx.mesh.id);
|
|
7469
|
+
const result = (0, import_daemon_core6.pruneStaleDirectDispatches)({
|
|
7429
7470
|
meshId: ctx.mesh.id,
|
|
7430
|
-
queue: (0,
|
|
7471
|
+
queue: (0, import_daemon_core6.getQueue)(ctx.mesh.id),
|
|
7431
7472
|
ledgerEntries,
|
|
7432
7473
|
directDispatches,
|
|
7433
7474
|
nodes: liveNodes,
|
|
@@ -7478,7 +7519,7 @@ async function meshSendTask(ctx, args) {
|
|
|
7478
7519
|
const requestedTaskMode = readString(args.task_mode) || readString(args.taskMode);
|
|
7479
7520
|
const readonly = args.readonly === true || args.read_only === true;
|
|
7480
7521
|
const missionId = readString(args.missionId) || readString(args.mission_id) || void 0;
|
|
7481
|
-
if (missionId && !(0,
|
|
7522
|
+
if (missionId && !(0, import_daemon_core6.getMeshMission)(ctx.mesh.id, missionId)) {
|
|
7482
7523
|
return JSON.stringify({
|
|
7483
7524
|
success: false,
|
|
7484
7525
|
code: "mission_not_found",
|
|
@@ -7496,7 +7537,7 @@ async function meshSendTask(ctx, args) {
|
|
|
7496
7537
|
});
|
|
7497
7538
|
}
|
|
7498
7539
|
const difficulty = difficultyRaw;
|
|
7499
|
-
const modeValidation = (0,
|
|
7540
|
+
const modeValidation = (0, import_daemon_core6.validateMeshTaskModeRequest)(requestedTaskMode, message, readonly);
|
|
7500
7541
|
if (!modeValidation.valid) {
|
|
7501
7542
|
return JSON.stringify({
|
|
7502
7543
|
success: false,
|
|
@@ -7507,7 +7548,7 @@ async function meshSendTask(ctx, args) {
|
|
|
7507
7548
|
// can see what tripped the guard instead of rewording blind.
|
|
7508
7549
|
...modeValidation.violationDetails ? { violationDetails: modeValidation.violationDetails } : {},
|
|
7509
7550
|
allowedOperations: modeValidation.allowedOperations,
|
|
7510
|
-
error: (0,
|
|
7551
|
+
error: (0, import_daemon_core6.buildMeshTaskModeViolationError)(modeValidation)
|
|
7511
7552
|
});
|
|
7512
7553
|
}
|
|
7513
7554
|
const taskMode = modeValidation.taskMode;
|
|
@@ -7611,7 +7652,7 @@ async function meshSendTask(ctx, args) {
|
|
|
7611
7652
|
const dispatchedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7612
7653
|
try {
|
|
7613
7654
|
const providerType = result2.providerType || cached?.providerType;
|
|
7614
|
-
(0,
|
|
7655
|
+
(0, import_daemon_core6.appendLedgerEntry)(ctx.mesh.id, {
|
|
7615
7656
|
kind: "task_dispatched",
|
|
7616
7657
|
nodeId: args.node_id,
|
|
7617
7658
|
sessionId: dispatchedSessionId,
|
|
@@ -7629,7 +7670,7 @@ async function meshSendTask(ctx, args) {
|
|
|
7629
7670
|
...coordinatorDaemonId ? { coordinatorDaemonId } : {}
|
|
7630
7671
|
})
|
|
7631
7672
|
});
|
|
7632
|
-
(0,
|
|
7673
|
+
(0, import_daemon_core6.insertDirectDispatch)(ctx.mesh.id, {
|
|
7633
7674
|
taskId,
|
|
7634
7675
|
nodeId: args.node_id,
|
|
7635
7676
|
sessionId: dispatchedSessionId,
|
|
@@ -7639,7 +7680,7 @@ async function meshSendTask(ctx, args) {
|
|
|
7639
7680
|
via: "p2p_direct",
|
|
7640
7681
|
dispatchedAt
|
|
7641
7682
|
});
|
|
7642
|
-
(0,
|
|
7683
|
+
(0, import_daemon_core6.recordDirectDispatchTask)(ctx.mesh.id, message, {
|
|
7643
7684
|
id: taskId,
|
|
7644
7685
|
...missionId ? { missionId } : {},
|
|
7645
7686
|
assignedNodeId: args.node_id,
|
|
@@ -7744,7 +7785,7 @@ async function meshSendTask(ctx, args) {
|
|
|
7744
7785
|
const { resolveDeliveryDecision } = await import("@adhdev/daemon-core");
|
|
7745
7786
|
const policyResult = resolveDeliveryDecision(sessionStatus, { kind: "task" });
|
|
7746
7787
|
if (policyResult.decision === "queued") {
|
|
7747
|
-
const queuedTask = (0,
|
|
7788
|
+
const queuedTask = (0, import_daemon_core6.enqueueTask)(ctx.mesh.id, message, {
|
|
7748
7789
|
targetNodeId: args.node_id,
|
|
7749
7790
|
targetSessionId: args.session_id,
|
|
7750
7791
|
taskMode,
|
|
@@ -7774,7 +7815,7 @@ async function meshSendTask(ctx, args) {
|
|
|
7774
7815
|
const dispatchedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7775
7816
|
const coordinatorDaemonId = resolveCoordinatorDaemonId(ctx);
|
|
7776
7817
|
try {
|
|
7777
|
-
(0,
|
|
7818
|
+
(0, import_daemon_core6.appendLedgerEntry)(ctx.mesh.id, {
|
|
7778
7819
|
kind: "task_dispatched",
|
|
7779
7820
|
nodeId: args.node_id,
|
|
7780
7821
|
sessionId: args.session_id,
|
|
@@ -7795,7 +7836,7 @@ async function meshSendTask(ctx, args) {
|
|
|
7795
7836
|
});
|
|
7796
7837
|
} catch {
|
|
7797
7838
|
}
|
|
7798
|
-
(0,
|
|
7839
|
+
(0, import_daemon_core6.insertDirectDispatch)(ctx.mesh.id, {
|
|
7799
7840
|
taskId,
|
|
7800
7841
|
nodeId: args.node_id,
|
|
7801
7842
|
sessionId: args.session_id,
|
|
@@ -7808,7 +7849,7 @@ async function meshSendTask(ctx, args) {
|
|
|
7808
7849
|
});
|
|
7809
7850
|
let dispatchPreRecorded = false;
|
|
7810
7851
|
try {
|
|
7811
|
-
dispatchPreRecorded = (0,
|
|
7852
|
+
dispatchPreRecorded = (0, import_daemon_core6.getActiveDirectDispatches)(ctx.mesh.id).some((d) => d.taskId === taskId);
|
|
7812
7853
|
} catch {
|
|
7813
7854
|
}
|
|
7814
7855
|
const dispatchResult = await commandForNode(ctx, node, "agent_command", {
|
|
@@ -7832,7 +7873,7 @@ async function meshSendTask(ctx, args) {
|
|
|
7832
7873
|
const dispatchPayload = unwrapCommandPayload(dispatchResult);
|
|
7833
7874
|
if (dispatchPayload?.success === false || dispatchResult?.success === false) {
|
|
7834
7875
|
try {
|
|
7835
|
-
(0,
|
|
7876
|
+
(0, import_daemon_core6.deleteDirectDispatchesByTaskId)(ctx.mesh.id, [taskId]);
|
|
7836
7877
|
} catch {
|
|
7837
7878
|
}
|
|
7838
7879
|
dispatchPreRecorded = false;
|
|
@@ -7846,7 +7887,7 @@ async function meshSendTask(ctx, args) {
|
|
|
7846
7887
|
});
|
|
7847
7888
|
}
|
|
7848
7889
|
try {
|
|
7849
|
-
(0,
|
|
7890
|
+
(0, import_daemon_core6.recordDirectDispatchTask)(ctx.mesh.id, message, {
|
|
7850
7891
|
id: taskId,
|
|
7851
7892
|
...missionId ? { missionId } : {},
|
|
7852
7893
|
assignedNodeId: args.node_id,
|
|
@@ -7892,7 +7933,7 @@ async function meshSendTask(ctx, args) {
|
|
|
7892
7933
|
...buildMissionInactiveWarning(ctx, missionId) ?? {}
|
|
7893
7934
|
});
|
|
7894
7935
|
}
|
|
7895
|
-
const task = (0,
|
|
7936
|
+
const task = (0, import_daemon_core6.enqueueTask)(ctx.mesh.id, message, {
|
|
7896
7937
|
targetNodeId: args.node_id,
|
|
7897
7938
|
targetSessionId: args.session_id,
|
|
7898
7939
|
taskMode,
|
|
@@ -7902,7 +7943,7 @@ async function meshSendTask(ctx, args) {
|
|
|
7902
7943
|
...ctx.coordinatorSessionId ? { sourceCoordinatorSessionId: ctx.coordinatorSessionId } : {}
|
|
7903
7944
|
});
|
|
7904
7945
|
const queueTrigger = await triggerMeshQueueAndReport(ctx);
|
|
7905
|
-
const pendingEvents = (0,
|
|
7946
|
+
const pendingEvents = (0, import_daemon_core6.drainPendingMeshCoordinatorEvents)(ctx.mesh.id, ctx.localDaemonId);
|
|
7906
7947
|
const result = {
|
|
7907
7948
|
success: true,
|
|
7908
7949
|
source: "queue",
|
|
@@ -7948,7 +7989,7 @@ async function meshReadChat(ctx, args) {
|
|
|
7948
7989
|
tailLimit: args.tail ?? 10
|
|
7949
7990
|
});
|
|
7950
7991
|
} catch (e) {
|
|
7951
|
-
if (isLocalNode || !(0,
|
|
7992
|
+
if (isLocalNode || !(0, import_daemon_core6.isP2pRelayTransportFailure)(e)) throw e;
|
|
7952
7993
|
return buildMeshReadChatCacheFallback(ctx, args, node, e);
|
|
7953
7994
|
}
|
|
7954
7995
|
const payload = annotateRapidReadChatAdvisory(unwrapCommandPayload(result), {
|
|
@@ -8037,7 +8078,7 @@ async function meshSendKeys(ctx, args) {
|
|
|
8037
8078
|
const auditKeys = requestedKeys.slice(0, 64);
|
|
8038
8079
|
const recordAudit = (result2, extra = {}) => {
|
|
8039
8080
|
try {
|
|
8040
|
-
(0,
|
|
8081
|
+
(0, import_daemon_core6.appendLedgerEntry)(ctx.mesh.id, {
|
|
8041
8082
|
kind: "key_injection",
|
|
8042
8083
|
nodeId: args.node_id,
|
|
8043
8084
|
sessionId: args.session_id,
|
|
@@ -8054,7 +8095,7 @@ async function meshSendKeys(ctx, args) {
|
|
|
8054
8095
|
}
|
|
8055
8096
|
};
|
|
8056
8097
|
if (hasDestructive) {
|
|
8057
|
-
const policyAllows = (0,
|
|
8098
|
+
const policyAllows = (0, import_daemon_core6.resolveAllowSendKeysDestructive)(ctx.mesh.policy, node.policy);
|
|
8058
8099
|
if (args.confirm_destructive !== true || !policyAllows) {
|
|
8059
8100
|
recordAudit("refused", { refused: "destructive_gate", policyAllows });
|
|
8060
8101
|
return JSON.stringify({
|
|
@@ -8104,7 +8145,7 @@ async function meshLaunchSession(ctx, args) {
|
|
|
8104
8145
|
supportedProviders: slotProviders
|
|
8105
8146
|
}, null, 2);
|
|
8106
8147
|
}
|
|
8107
|
-
const explicitBlock = (0,
|
|
8148
|
+
const explicitBlock = (0, import_daemon_core8.evaluateProviderQuotaGate)(node, requestedType, ctx.mesh.policy?.quotaRouting ?? null);
|
|
8108
8149
|
if (explicitBlock) {
|
|
8109
8150
|
explicitTypeQuotaWarning = {
|
|
8110
8151
|
quotaWarning: `Provider '${requestedType}' on node '${args.node_id}' is quota-gated (${explicitBlock.reason}; ${explicitBlock.window} window at ${explicitBlock.remainingPercent}% remaining, threshold ${explicitBlock.thresholdPercent}%). Launching anyway because the type was requested explicitly \u2014 the session may fail immediately if the provider rejects on quota.`,
|
|
@@ -8142,7 +8183,7 @@ async function meshLaunchSession(ctx, args) {
|
|
|
8142
8183
|
failed.push(`${providerType}: ${detectedPayload?.error || "not detected"}`);
|
|
8143
8184
|
}
|
|
8144
8185
|
if (detectedCandidates.length) {
|
|
8145
|
-
const ranked = (0,
|
|
8186
|
+
const ranked = (0, import_daemon_core8.rankProvidersByQuotaGate)(node, detectedCandidates, ctx.mesh.policy?.quotaRouting ?? null);
|
|
8146
8187
|
if (ranked.clear.length) {
|
|
8147
8188
|
resolvedProviderType = ranked.clear[0];
|
|
8148
8189
|
} else {
|
|
@@ -8173,14 +8214,14 @@ async function meshLaunchSession(ctx, args) {
|
|
|
8173
8214
|
const coordinatorNode = resolveCoordinatorNode(ctx);
|
|
8174
8215
|
const coordinatorDaemonId = resolveCoordinatorDaemonId(ctx);
|
|
8175
8216
|
const spawnedSessionVisibility = readSpawnedSessionVisibility(ctx.mesh.policy);
|
|
8176
|
-
const delegatedWorkerAutoApprove = (0,
|
|
8217
|
+
const delegatedWorkerAutoApprove = (0, import_daemon_core6.resolveDelegatedWorkerAutoApprove)(ctx.mesh.policy, node.policy);
|
|
8177
8218
|
let requestedAutoApproveMode;
|
|
8178
|
-
const delegatedWorkerDangerousModeAllow = (0,
|
|
8219
|
+
const delegatedWorkerDangerousModeAllow = (0, import_daemon_core6.resolveDelegatedWorkerDangerousModeAllow)(ctx.mesh.policy, node.policy);
|
|
8179
8220
|
if (delegatedWorkerAutoApprove !== false) {
|
|
8180
8221
|
try {
|
|
8181
8222
|
const ws = typeof node.workspace === "string" && node.workspace.trim() ? node.workspace.trim() : "";
|
|
8182
8223
|
if (ws) {
|
|
8183
|
-
const repo = (0,
|
|
8224
|
+
const repo = (0, import_daemon_core6.loadRepoMeshJsonConfig)(ws);
|
|
8184
8225
|
const repoMode = repo.sourceType === "repo_file" ? repo.config?.providerDefaults?.autoApproveModes?.[resolvedProviderType] : void 0;
|
|
8185
8226
|
if (typeof repoMode === "string" && repoMode.trim()) requestedAutoApproveMode = repoMode.trim();
|
|
8186
8227
|
}
|
|
@@ -8277,7 +8318,7 @@ async function meshLaunchSession(ctx, args) {
|
|
|
8277
8318
|
});
|
|
8278
8319
|
}
|
|
8279
8320
|
try {
|
|
8280
|
-
(0,
|
|
8321
|
+
(0, import_daemon_core6.appendLedgerEntry)(ctx.mesh.id, {
|
|
8281
8322
|
kind: "session_launched",
|
|
8282
8323
|
nodeId: args.node_id,
|
|
8283
8324
|
sessionId: runtimeSessionId || void 0,
|
|
@@ -8331,26 +8372,26 @@ async function meshAnswerQuestion(ctx, args) {
|
|
|
8331
8372
|
return JSON.stringify(result, null, 2);
|
|
8332
8373
|
}
|
|
8333
8374
|
async function meshListPendingApprovals(ctx, _args = {}) {
|
|
8334
|
-
(0,
|
|
8375
|
+
(0, import_daemon_core6.recordMeshToolCall)({ meshId: ctx.mesh.id, tool: "mesh_list_pending_approvals" });
|
|
8335
8376
|
await refreshMeshFromDaemon(ctx);
|
|
8336
8377
|
const liveNodes = await collectMeshViewQueueNodesWithLiveSessions(ctx);
|
|
8337
|
-
let ledgerEntries = (0,
|
|
8338
|
-
let directDispatches = (0,
|
|
8378
|
+
let ledgerEntries = (0, import_daemon_core6.readLedgerEntries)(ctx.mesh.id, { tail: 200 });
|
|
8379
|
+
let directDispatches = (0, import_daemon_core6.getActiveDirectDispatches)(ctx.mesh.id);
|
|
8339
8380
|
const directReconciliation = await reconcileDirectDispatchesFromTranscriptEvidence(ctx, liveNodes, directDispatches, ledgerEntries);
|
|
8340
8381
|
if (directReconciliation.reconciled > 0) {
|
|
8341
|
-
ledgerEntries = (0,
|
|
8342
|
-
directDispatches = (0,
|
|
8382
|
+
ledgerEntries = (0, import_daemon_core6.readLedgerEntries)(ctx.mesh.id, { tail: 200 });
|
|
8383
|
+
directDispatches = (0, import_daemon_core6.getActiveDirectDispatches)(ctx.mesh.id);
|
|
8343
8384
|
}
|
|
8344
|
-
(0,
|
|
8345
|
-
directDispatches = (0,
|
|
8346
|
-
const activeWorkEvidence = (0,
|
|
8385
|
+
(0, import_daemon_core6.markStaleDirectDispatches)(ctx.mesh.id);
|
|
8386
|
+
directDispatches = (0, import_daemon_core6.getActiveDirectDispatches)(ctx.mesh.id);
|
|
8387
|
+
const activeWorkEvidence = (0, import_daemon_core6.buildMeshActiveWork)({
|
|
8347
8388
|
meshId: ctx.mesh.id,
|
|
8348
|
-
queue: (0,
|
|
8389
|
+
queue: (0, import_daemon_core6.getQueue)(ctx.mesh.id),
|
|
8349
8390
|
ledgerEntries,
|
|
8350
8391
|
directDispatches,
|
|
8351
8392
|
nodes: liveNodes
|
|
8352
8393
|
});
|
|
8353
|
-
const approvals = (0,
|
|
8394
|
+
const approvals = (0, import_daemon_core6.collectPendingApprovals)(activeWorkEvidence.activeWork);
|
|
8354
8395
|
return JSON.stringify({
|
|
8355
8396
|
count: approvals.length,
|
|
8356
8397
|
approvals,
|
|
@@ -8504,7 +8545,7 @@ async function meshRestartDaemon(ctx, args) {
|
|
|
8504
8545
|
const targetDaemonId = typeof rawTarget.daemonId === "string" && rawTarget.daemonId.trim() ? rawTarget.daemonId.trim() : "unknown";
|
|
8505
8546
|
const targetNpmTag = typeof rawTarget.npmTag === "string" && rawTarget.npmTag.trim() ? rawTarget.npmTag.trim() : typeof payload?.npmTag === "string" && payload.npmTag.trim() ? payload.npmTag.trim() : "unknown";
|
|
8506
8547
|
const trackMismatch = meshAttachedTrack === "unknown" || targetTrack === "unknown" ? null : meshAttachedTrack !== targetTrack;
|
|
8507
|
-
const daemonMismatch = meshAttachedDaemonId === "unknown" || targetDaemonId === "unknown" ? null : !(0,
|
|
8548
|
+
const daemonMismatch = meshAttachedDaemonId === "unknown" || targetDaemonId === "unknown" ? null : !(0, import_daemon_core6.daemonIdsEquivalent)(meshAttachedDaemonId, targetDaemonId);
|
|
8508
8549
|
const routingMismatch = trackMismatch === true || daemonMismatch === true;
|
|
8509
8550
|
return JSON.stringify({
|
|
8510
8551
|
...payload,
|
|
@@ -8558,7 +8599,7 @@ async function meshCheckpoint(ctx, args) {
|
|
|
8558
8599
|
includeUntracked: true
|
|
8559
8600
|
});
|
|
8560
8601
|
try {
|
|
8561
|
-
(0,
|
|
8602
|
+
(0, import_daemon_core6.appendLedgerEntry)(ctx.mesh.id, {
|
|
8562
8603
|
kind: "checkpoint_created",
|
|
8563
8604
|
nodeId: args.node_id,
|
|
8564
8605
|
payload: {
|