@adhdev/daemon-core 0.9.82-rc.256 → 0.9.82-rc.258
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/boot/daemon-lifecycle.d.ts +3 -0
- package/dist/index.js +287 -43
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +287 -43
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-events-coordinator.d.ts +22 -0
- package/dist/mesh/mesh-events-pending.d.ts +7 -0
- package/dist/mesh/mesh-events-utils.d.ts +2 -0
- package/dist/mesh/mesh-events.d.ts +2 -2
- package/dist/mesh/mesh-ledger.d.ts +1 -1
- package/dist/mesh/mesh-routing.d.ts +70 -0
- package/dist/mesh/mesh-runtime-store.d.ts +3 -0
- package/package.json +1 -1
- package/src/boot/daemon-lifecycle.ts +8 -0
- package/src/commands/router.ts +12 -4
- package/src/mesh/mesh-events-coordinator.ts +110 -54
- package/src/mesh/mesh-events-pending.ts +57 -3
- package/src/mesh/mesh-events-utils.ts +20 -0
- package/src/mesh/mesh-events.ts +2 -0
- package/src/mesh/mesh-ledger.ts +1 -0
- package/src/mesh/mesh-routing.ts +272 -0
- package/src/mesh/mesh-runtime-store.ts +37 -0
|
@@ -62,6 +62,8 @@ export interface DaemonInitConfig {
|
|
|
62
62
|
dispatchMeshCommand?: (daemonId: string, command: string, args: Record<string, unknown>) => Promise<any>;
|
|
63
63
|
/** Returns selected-coordinator mesh peer telemetry for a target daemon when available. */
|
|
64
64
|
getMeshPeerConnectionStatus?: (daemonId: string) => Record<string, unknown> | null;
|
|
65
|
+
/** Cloud-only: P2P dashboard metadata sync after the core forwarder handles a mesh event. */
|
|
66
|
+
onMeshCoordinatorEventForwarded?: (payload: Record<string, unknown>) => void;
|
|
65
67
|
}
|
|
66
68
|
export interface DaemonComponents {
|
|
67
69
|
providerLoader: ProviderLoader;
|
|
@@ -79,6 +81,7 @@ export interface DaemonComponents {
|
|
|
79
81
|
};
|
|
80
82
|
refreshProviderAvailability: (providerType?: string) => Promise<void>;
|
|
81
83
|
dispatchMeshCommand?: (daemonId: string, command: string, args: Record<string, unknown>) => Promise<any>;
|
|
84
|
+
onMeshCoordinatorEventForwarded?: (payload: Record<string, unknown>) => void;
|
|
82
85
|
}
|
|
83
86
|
export interface DaemonDevSupportOptions {
|
|
84
87
|
components: DaemonComponents;
|
package/dist/index.js
CHANGED
|
@@ -3182,6 +3182,21 @@ var init_mesh_runtime_store = __esm({
|
|
|
3182
3182
|
expires_at INTEGER NOT NULL
|
|
3183
3183
|
);
|
|
3184
3184
|
|
|
3185
|
+
-- R3: idempotent coordinator inbox. When a terminal/force-inject event is
|
|
3186
|
+
-- direct-injected into a LIVE local CLI coordinator (coord.onEvent('send_message')),
|
|
3187
|
+
-- we record (coordinator_daemon_id, fingerprint) here. That same coordinator also
|
|
3188
|
+
-- polls get_pending_mesh_events, which would re-deliver the queued copy of the very
|
|
3189
|
+
-- event it just received in its PTY \u2192 user sees the completion twice. The drain for
|
|
3190
|
+
-- a coordinator daemon filters out events already direct-delivered to it, giving
|
|
3191
|
+
-- exactly-once-per-coordinator while keeping the queue for other consumers (idle /
|
|
3192
|
+
-- MCP-only / remote) that did NOT receive the direct inject.
|
|
3193
|
+
CREATE TABLE IF NOT EXISTS mesh_direct_delivered_events (
|
|
3194
|
+
coordinator_daemon_id TEXT NOT NULL,
|
|
3195
|
+
fingerprint TEXT NOT NULL,
|
|
3196
|
+
expires_at INTEGER NOT NULL,
|
|
3197
|
+
PRIMARY KEY (coordinator_daemon_id, fingerprint)
|
|
3198
|
+
);
|
|
3199
|
+
|
|
3185
3200
|
CREATE TABLE IF NOT EXISTS mesh_direct_dispatches (
|
|
3186
3201
|
task_id TEXT PRIMARY KEY,
|
|
3187
3202
|
mesh_id TEXT NOT NULL,
|
|
@@ -3337,6 +3352,25 @@ var init_mesh_runtime_store = __esm({
|
|
|
3337
3352
|
sweepExpiredFingerprints() {
|
|
3338
3353
|
this.db.prepare("DELETE FROM mesh_completion_fingerprints WHERE expires_at <= ?").run(Date.now());
|
|
3339
3354
|
}
|
|
3355
|
+
// R3: record that an event (by pending-event fingerprint) was direct-injected into a live
|
|
3356
|
+
// coordinator on the given daemon, so that coordinator's own drain skips the queued copy.
|
|
3357
|
+
recordDirectDelivered(coordinatorDaemonId, fingerprint, ttlMs) {
|
|
3358
|
+
if (!coordinatorDaemonId || !fingerprint) return;
|
|
3359
|
+
this.db.prepare(
|
|
3360
|
+
"INSERT OR REPLACE INTO mesh_direct_delivered_events (coordinator_daemon_id, fingerprint, expires_at) VALUES (?, ?, ?)"
|
|
3361
|
+
).run(coordinatorDaemonId, fingerprint, Date.now() + ttlMs);
|
|
3362
|
+
this.maybeCheckpointWal();
|
|
3363
|
+
}
|
|
3364
|
+
wasDirectDelivered(coordinatorDaemonId, fingerprint) {
|
|
3365
|
+
if (!coordinatorDaemonId || !fingerprint) return false;
|
|
3366
|
+
const row = this.db.prepare(
|
|
3367
|
+
"SELECT 1 FROM mesh_direct_delivered_events WHERE coordinator_daemon_id = ? AND fingerprint = ? AND expires_at > ?"
|
|
3368
|
+
).get(coordinatorDaemonId, fingerprint, Date.now());
|
|
3369
|
+
return row !== void 0;
|
|
3370
|
+
}
|
|
3371
|
+
sweepExpiredDirectDelivered() {
|
|
3372
|
+
this.db.prepare("DELETE FROM mesh_direct_delivered_events WHERE expires_at <= ?").run(Date.now());
|
|
3373
|
+
}
|
|
3340
3374
|
maybeCheckpointWal() {
|
|
3341
3375
|
if (++this.walWriteCounter < _MeshRuntimeStore.WAL_CHECK_INTERVAL) return;
|
|
3342
3376
|
this.walWriteCounter = 0;
|
|
@@ -5615,6 +5649,16 @@ function readNonEmptyString2(value) {
|
|
|
5615
5649
|
function readRecord3(value) {
|
|
5616
5650
|
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
5617
5651
|
}
|
|
5652
|
+
function canonicalDaemonId(value) {
|
|
5653
|
+
const id = readNonEmptyString2(value);
|
|
5654
|
+
if (!id) return "";
|
|
5655
|
+
return id.replace(/^(?:daemon|standalone)_/, "");
|
|
5656
|
+
}
|
|
5657
|
+
function sameDaemonId(a, b) {
|
|
5658
|
+
const ca = canonicalDaemonId(a);
|
|
5659
|
+
const cb = canonicalDaemonId(b);
|
|
5660
|
+
return ca !== "" && ca === cb;
|
|
5661
|
+
}
|
|
5618
5662
|
function resolveEventSessionId(event, fallback) {
|
|
5619
5663
|
return readNonEmptyString2(event.targetSessionId) || readNonEmptyString2(event.sessionId) || readNonEmptyString2(event.instanceId) || readNonEmptyString2(fallback);
|
|
5620
5664
|
}
|
|
@@ -5798,6 +5842,29 @@ function buildPendingEventFingerprint(event) {
|
|
|
5798
5842
|
timestamp || ""
|
|
5799
5843
|
].join("::");
|
|
5800
5844
|
}
|
|
5845
|
+
function markMeshCoordinatorEventDirectDelivered(coordinatorDaemonId, event) {
|
|
5846
|
+
const canonical = canonicalDaemonId(coordinatorDaemonId);
|
|
5847
|
+
if (!canonical) return;
|
|
5848
|
+
const fingerprint = buildPendingEventFingerprint(event);
|
|
5849
|
+
if (!fingerprint.trim()) return;
|
|
5850
|
+
try {
|
|
5851
|
+
const store = MeshRuntimeStore.getInstance();
|
|
5852
|
+
store.recordDirectDelivered(canonical, fingerprint, DIRECT_DELIVERED_TTL_MS);
|
|
5853
|
+
store.sweepExpiredDirectDelivered();
|
|
5854
|
+
} catch {
|
|
5855
|
+
}
|
|
5856
|
+
}
|
|
5857
|
+
function wasDirectDeliveredToCoordinator(coordinatorDaemonId, event) {
|
|
5858
|
+
const canonical = canonicalDaemonId(coordinatorDaemonId);
|
|
5859
|
+
if (!canonical) return false;
|
|
5860
|
+
const fingerprint = buildPendingEventFingerprint(event);
|
|
5861
|
+
if (!fingerprint.trim()) return false;
|
|
5862
|
+
try {
|
|
5863
|
+
return MeshRuntimeStore.getInstance().wasDirectDelivered(canonical, fingerprint);
|
|
5864
|
+
} catch {
|
|
5865
|
+
return false;
|
|
5866
|
+
}
|
|
5867
|
+
}
|
|
5801
5868
|
function hasPendingCoordinatorEventDuplicate(event) {
|
|
5802
5869
|
const fingerprint = buildPendingEventFingerprint(event);
|
|
5803
5870
|
if (!fingerprint.trim()) return false;
|
|
@@ -5996,7 +6063,9 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
5996
6063
|
for (const event of filtered) pushUnique(event);
|
|
5997
6064
|
}
|
|
5998
6065
|
if (merged.length === 0) return [];
|
|
5999
|
-
|
|
6066
|
+
const deliverable = coordinatorDaemonId ? merged.filter((event) => !wasDirectDeliveredToCoordinator(coordinatorDaemonId, event)) : merged;
|
|
6067
|
+
if (deliverable.length === 0) return [];
|
|
6068
|
+
return reconcilePendingMeshCoordinatorEvents(meshId, deliverable);
|
|
6000
6069
|
}
|
|
6001
6070
|
function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
6002
6071
|
if (!meshId) return [];
|
|
@@ -6023,7 +6092,8 @@ function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
6023
6092
|
for (const event of readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId)) {
|
|
6024
6093
|
pushUnique(event);
|
|
6025
6094
|
}
|
|
6026
|
-
|
|
6095
|
+
const deliverable = coordinatorDaemonId ? merged.filter((event) => !wasDirectDeliveredToCoordinator(coordinatorDaemonId, event)) : merged;
|
|
6096
|
+
return reconcilePendingMeshCoordinatorEvents(meshId, deliverable);
|
|
6027
6097
|
}
|
|
6028
6098
|
function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
6029
6099
|
if (!meshId) return;
|
|
@@ -6039,7 +6109,7 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
6039
6109
|
}
|
|
6040
6110
|
}
|
|
6041
6111
|
}
|
|
6042
|
-
var import_fs8, import_path8, import_crypto7, REFINE_TERMINAL_EVENTS, MAX_PENDING_EVENTS_BYTES, MAX_PENDING_EVENTS_KEEP;
|
|
6112
|
+
var import_fs8, import_path8, import_crypto7, REFINE_TERMINAL_EVENTS, DIRECT_DELIVERED_TTL_MS, MAX_PENDING_EVENTS_BYTES, MAX_PENDING_EVENTS_KEEP;
|
|
6043
6113
|
var init_mesh_events_pending = __esm({
|
|
6044
6114
|
"src/mesh/mesh-events-pending.ts"() {
|
|
6045
6115
|
"use strict";
|
|
@@ -6051,6 +6121,7 @@ var init_mesh_events_pending = __esm({
|
|
|
6051
6121
|
init_mesh_runtime_store();
|
|
6052
6122
|
init_mesh_events_utils();
|
|
6053
6123
|
REFINE_TERMINAL_EVENTS = /* @__PURE__ */ new Set(["refine:completed", "refine:failed"]);
|
|
6124
|
+
DIRECT_DELIVERED_TTL_MS = 10 * 60 * 1e3;
|
|
6054
6125
|
MAX_PENDING_EVENTS_BYTES = 100 * 1024;
|
|
6055
6126
|
MAX_PENDING_EVENTS_KEEP = 50;
|
|
6056
6127
|
}
|
|
@@ -6587,6 +6658,140 @@ var init_cli_detector = __esm({
|
|
|
6587
6658
|
}
|
|
6588
6659
|
});
|
|
6589
6660
|
|
|
6661
|
+
// src/mesh/mesh-routing.ts
|
|
6662
|
+
function readSettings(state) {
|
|
6663
|
+
return state?.settings && typeof state.settings === "object" ? state.settings : {};
|
|
6664
|
+
}
|
|
6665
|
+
function resolveWorkerDelegateRouting(components, instanceId, deps) {
|
|
6666
|
+
const sessionId = readNonEmptyString2(instanceId);
|
|
6667
|
+
let workspace = "";
|
|
6668
|
+
let coordinatorDaemonId = "";
|
|
6669
|
+
const reject = (rejectionReason) => ({
|
|
6670
|
+
isDelegate: false,
|
|
6671
|
+
meshId: "",
|
|
6672
|
+
nodeId: "",
|
|
6673
|
+
nodeLabel: "",
|
|
6674
|
+
coordinatorDaemonId,
|
|
6675
|
+
workspace,
|
|
6676
|
+
sessionId,
|
|
6677
|
+
rejectionReason
|
|
6678
|
+
});
|
|
6679
|
+
const sourceInstance = components.instanceManager.getInstance(instanceId);
|
|
6680
|
+
if (!sourceInstance || sourceInstance.category !== "cli") return reject("not_cli");
|
|
6681
|
+
const state = sourceInstance.getState();
|
|
6682
|
+
workspace = readNonEmptyString2(state.workspace);
|
|
6683
|
+
if (!workspace) return reject("no_workspace");
|
|
6684
|
+
const settings = readSettings(state);
|
|
6685
|
+
coordinatorDaemonId = readNonEmptyString2(settings.meshCoordinatorDaemonId);
|
|
6686
|
+
const coordinatorMeshId = readNonEmptyString2(settings.meshCoordinatorFor);
|
|
6687
|
+
let meshIdFromDirectDispatch = "";
|
|
6688
|
+
if (coordinatorMeshId) {
|
|
6689
|
+
let hasActiveDispatch = false;
|
|
6690
|
+
try {
|
|
6691
|
+
hasActiveDispatch = getActiveDirectDispatches(coordinatorMeshId).some((d) => d.sessionId === instanceId) || hasUnterminalDirectDispatchLedgerEntry(coordinatorMeshId, instanceId);
|
|
6692
|
+
} catch {
|
|
6693
|
+
}
|
|
6694
|
+
if (!hasActiveDispatch) return reject("coordinator_not_dispatch_target");
|
|
6695
|
+
meshIdFromDirectDispatch = coordinatorMeshId;
|
|
6696
|
+
}
|
|
6697
|
+
const meshIdFromRuntime = readNonEmptyString2(settings.meshNodeFor) || meshIdFromDirectDispatch;
|
|
6698
|
+
const hasWorkerEnvelope = Boolean(
|
|
6699
|
+
meshIdFromRuntime || settings.launchedByCoordinator || coordinatorDaemonId || readNonEmptyString2(settings.meshCoordinatorNodeId)
|
|
6700
|
+
);
|
|
6701
|
+
if (!hasWorkerEnvelope) return reject("no_worker_envelope");
|
|
6702
|
+
const mesh = meshIdFromRuntime ? deps.getMeshById(meshIdFromRuntime) : deps.getMeshByWorkspace(workspace);
|
|
6703
|
+
const meshId = meshIdFromRuntime || readNonEmptyString2(mesh?.id);
|
|
6704
|
+
if (!meshId) return reject("mesh_unresolved");
|
|
6705
|
+
const targetNode = mesh?.nodes?.find((n) => n.workspace === workspace);
|
|
6706
|
+
const runtimeNodeId = readNonEmptyString2(settings.meshNodeId);
|
|
6707
|
+
const nodeId = readNonEmptyString2(targetNode?.id) || runtimeNodeId;
|
|
6708
|
+
const nodeLabel = targetNode ? `Node '${targetNode.id}'` : runtimeNodeId ? `Node '${runtimeNodeId}'` : `Agent at ${workspace}`;
|
|
6709
|
+
return {
|
|
6710
|
+
isDelegate: true,
|
|
6711
|
+
meshId,
|
|
6712
|
+
nodeId,
|
|
6713
|
+
nodeLabel,
|
|
6714
|
+
coordinatorDaemonId,
|
|
6715
|
+
workspace,
|
|
6716
|
+
sessionId
|
|
6717
|
+
};
|
|
6718
|
+
}
|
|
6719
|
+
function isUnroutableDelegateRejection(routing) {
|
|
6720
|
+
return !routing.isDelegate && routing.rejectionReason === "mesh_unresolved";
|
|
6721
|
+
}
|
|
6722
|
+
function recordUnroutableDelegateEvent(routing, eventName) {
|
|
6723
|
+
if (!isUnroutableDelegateRejection(routing)) return false;
|
|
6724
|
+
const dedupKey = `${routing.sessionId}::${eventName}::${routing.workspace}`;
|
|
6725
|
+
const now = Date.now();
|
|
6726
|
+
const last = recentUnroutableDiagnostics.get(dedupKey);
|
|
6727
|
+
if (last !== void 0 && now - last < UNROUTABLE_DIAGNOSTIC_DEDUP_MS) return false;
|
|
6728
|
+
recentUnroutableDiagnostics.set(dedupKey, now);
|
|
6729
|
+
if (recentUnroutableDiagnostics.size > 256) {
|
|
6730
|
+
for (const [key, ts2] of recentUnroutableDiagnostics) {
|
|
6731
|
+
if (now - ts2 >= UNROUTABLE_DIAGNOSTIC_DEDUP_MS) recentUnroutableDiagnostics.delete(key);
|
|
6732
|
+
}
|
|
6733
|
+
}
|
|
6734
|
+
try {
|
|
6735
|
+
appendLedgerEntry(UNROUTABLE_DIAGNOSTIC_STREAM, {
|
|
6736
|
+
kind: "delivery_unroutable",
|
|
6737
|
+
sessionId: routing.sessionId || void 0,
|
|
6738
|
+
payload: {
|
|
6739
|
+
event: eventName,
|
|
6740
|
+
reason: routing.rejectionReason,
|
|
6741
|
+
workspace: routing.workspace || void 0,
|
|
6742
|
+
coordinatorDaemonId: routing.coordinatorDaemonId || void 0,
|
|
6743
|
+
detail: "Worker envelope was present but no mesh could be resolved; the event could not be routed to a coordinator."
|
|
6744
|
+
}
|
|
6745
|
+
});
|
|
6746
|
+
LOG.warn("MeshEvents", `delivery_unroutable: ${eventName} from session ${routing.sessionId || "(unknown)"} at ${routing.workspace || "(no workspace)"} \u2014 envelope present but mesh unresolved`);
|
|
6747
|
+
return true;
|
|
6748
|
+
} catch (e) {
|
|
6749
|
+
LOG.warn("MeshEvents", `Failed to record delivery_unroutable diagnostic: ${e?.message || e}`);
|
|
6750
|
+
return false;
|
|
6751
|
+
}
|
|
6752
|
+
}
|
|
6753
|
+
function getRecentUnroutableDeliveries(opts) {
|
|
6754
|
+
const sinceMs = opts?.sinceMs ?? 60 * 60 * 1e3;
|
|
6755
|
+
const limit = opts?.limit ?? 20;
|
|
6756
|
+
let entries;
|
|
6757
|
+
try {
|
|
6758
|
+
entries = readLedgerEntries(UNROUTABLE_DIAGNOSTIC_STREAM, { kind: ["delivery_unroutable"], tail: 200 });
|
|
6759
|
+
} catch {
|
|
6760
|
+
return [];
|
|
6761
|
+
}
|
|
6762
|
+
const cutoff = Date.now() - sinceMs;
|
|
6763
|
+
const out = [];
|
|
6764
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
6765
|
+
const entry = entries[i];
|
|
6766
|
+
const ts2 = new Date(entry.timestamp).getTime();
|
|
6767
|
+
if (!Number.isNaN(ts2) && ts2 < cutoff) continue;
|
|
6768
|
+
const payload = entry.payload && typeof entry.payload === "object" ? entry.payload : {};
|
|
6769
|
+
out.push({
|
|
6770
|
+
timestamp: entry.timestamp,
|
|
6771
|
+
event: readNonEmptyString2(payload.event),
|
|
6772
|
+
sessionId: readNonEmptyString2(entry.sessionId) || readNonEmptyString2(payload.sessionId) || void 0,
|
|
6773
|
+
workspace: readNonEmptyString2(payload.workspace) || void 0,
|
|
6774
|
+
coordinatorDaemonId: readNonEmptyString2(payload.coordinatorDaemonId) || void 0
|
|
6775
|
+
});
|
|
6776
|
+
if (out.length >= limit) break;
|
|
6777
|
+
}
|
|
6778
|
+
return out;
|
|
6779
|
+
}
|
|
6780
|
+
var UNROUTABLE_DIAGNOSTIC_STREAM, UNROUTABLE_DIAGNOSTIC_DEDUP_MS, recentUnroutableDiagnostics;
|
|
6781
|
+
var init_mesh_routing = __esm({
|
|
6782
|
+
"src/mesh/mesh-routing.ts"() {
|
|
6783
|
+
"use strict";
|
|
6784
|
+
init_mesh_work_queue();
|
|
6785
|
+
init_mesh_events_stale();
|
|
6786
|
+
init_mesh_ledger();
|
|
6787
|
+
init_logger();
|
|
6788
|
+
init_mesh_events_utils();
|
|
6789
|
+
UNROUTABLE_DIAGNOSTIC_STREAM = "__unroutable__";
|
|
6790
|
+
UNROUTABLE_DIAGNOSTIC_DEDUP_MS = 60 * 1e3;
|
|
6791
|
+
recentUnroutableDiagnostics = /* @__PURE__ */ new Map();
|
|
6792
|
+
}
|
|
6793
|
+
});
|
|
6794
|
+
|
|
6590
6795
|
// src/mesh/mesh-events-coordinator.ts
|
|
6591
6796
|
function getCachedMeshByWorkspace(workspace) {
|
|
6592
6797
|
const now = Date.now();
|
|
@@ -6599,6 +6804,9 @@ function getCachedMeshByWorkspace(workspace) {
|
|
|
6599
6804
|
function __resetIdleAutoFastForwardForTests() {
|
|
6600
6805
|
idleAutoFastForwardLastAttempt.clear();
|
|
6601
6806
|
}
|
|
6807
|
+
function __resetMeshWorkspaceCacheForTests() {
|
|
6808
|
+
meshByWorkspaceCache.clear();
|
|
6809
|
+
}
|
|
6602
6810
|
function sweepExpiredRemoteIdleSessions() {
|
|
6603
6811
|
try {
|
|
6604
6812
|
MeshRuntimeStore.getInstance().pruneExpiredRemoteIdleSessions();
|
|
@@ -7265,6 +7473,17 @@ function injectMeshSystemMessage(components, args) {
|
|
|
7265
7473
|
sourceSession?.getState()?.settings?.meshCoordinatorDaemonId
|
|
7266
7474
|
);
|
|
7267
7475
|
const localDaemonId = readNonEmptyString2(loadConfig().machineId);
|
|
7476
|
+
if (components.onMeshCoordinatorEventForwarded) {
|
|
7477
|
+
try {
|
|
7478
|
+
components.onMeshCoordinatorEventForwarded({
|
|
7479
|
+
event: args.event,
|
|
7480
|
+
meshId: args.meshId,
|
|
7481
|
+
nodeId: eventNodeId || void 0,
|
|
7482
|
+
...args.metadataEvent
|
|
7483
|
+
});
|
|
7484
|
+
} catch {
|
|
7485
|
+
}
|
|
7486
|
+
}
|
|
7268
7487
|
const intentionalCleanupStop = shouldSuppressIntentionalCleanupStop({
|
|
7269
7488
|
event: args.event,
|
|
7270
7489
|
meshId: args.meshId,
|
|
@@ -7609,10 +7828,38 @@ function injectMeshSystemMessage(components, args) {
|
|
|
7609
7828
|
const instState = inst.getState();
|
|
7610
7829
|
if (instState.settings?.meshCoordinatorFor !== args.meshId) return false;
|
|
7611
7830
|
if (args.sourceInstanceId && instState.instanceId === args.sourceInstanceId) return false;
|
|
7612
|
-
if (workerCoordinatorDaemonId && localDaemonId && workerCoordinatorDaemonId
|
|
7831
|
+
if (workerCoordinatorDaemonId && localDaemonId && !sameDaemonId(workerCoordinatorDaemonId, localDaemonId)) return false;
|
|
7613
7832
|
return true;
|
|
7614
7833
|
});
|
|
7615
7834
|
if (coordinatorInstances.length === 0) {
|
|
7835
|
+
const remoteCoordinatorDaemonId = workerCoordinatorDaemonId && localDaemonId && !sameDaemonId(workerCoordinatorDaemonId, localDaemonId) ? workerCoordinatorDaemonId : "";
|
|
7836
|
+
if (remoteCoordinatorDaemonId && components.dispatchMeshCommand) {
|
|
7837
|
+
const forwardPayload = {
|
|
7838
|
+
event: args.event,
|
|
7839
|
+
meshId: args.meshId,
|
|
7840
|
+
nodeId: args.nodeId || void 0,
|
|
7841
|
+
workspace: readNonEmptyString2(args.metadataEvent.workspace),
|
|
7842
|
+
...args.metadataEvent,
|
|
7843
|
+
...recoveryContext ? { recoveryContext } : {}
|
|
7844
|
+
};
|
|
7845
|
+
components.dispatchMeshCommand(remoteCoordinatorDaemonId, "mesh_forward_event", forwardPayload).then(() => {
|
|
7846
|
+
LOG.info("MeshEvents", `Forwarded ${args.event} for mesh ${args.meshId} to remote coordinator daemon ${remoteCoordinatorDaemonId.slice(0, 12)}\u2026`);
|
|
7847
|
+
}).catch((error) => {
|
|
7848
|
+
LOG.warn("MeshEvents", `Remote forward of ${args.event} failed (${error?.message || error}); queuing for backfill`);
|
|
7849
|
+
queuePendingMeshCoordinatorEvent({
|
|
7850
|
+
event: args.event,
|
|
7851
|
+
meshId: args.meshId,
|
|
7852
|
+
nodeLabel: args.nodeLabel,
|
|
7853
|
+
nodeId: args.nodeId || void 0,
|
|
7854
|
+
workspace: readNonEmptyString2(args.metadataEvent.workspace),
|
|
7855
|
+
metadataEvent: { ...args.metadataEvent, ...recoveryContext ? { recoveryContext } : {} },
|
|
7856
|
+
coordinatorMessage: messageText,
|
|
7857
|
+
queuedAt: Date.now(),
|
|
7858
|
+
targetCoordinatorDaemonId: remoteCoordinatorDaemonId
|
|
7859
|
+
});
|
|
7860
|
+
});
|
|
7861
|
+
return { success: true, forwarded: 0, remoteForwarded: true };
|
|
7862
|
+
}
|
|
7616
7863
|
if (queuePendingMeshCoordinatorEvent({
|
|
7617
7864
|
event: args.event,
|
|
7618
7865
|
meshId: args.meshId,
|
|
@@ -7631,7 +7878,7 @@ function injectMeshSystemMessage(components, args) {
|
|
|
7631
7878
|
}
|
|
7632
7879
|
return { success: true, forwarded: 0 };
|
|
7633
7880
|
}
|
|
7634
|
-
|
|
7881
|
+
const pendingEvent = {
|
|
7635
7882
|
event: args.event,
|
|
7636
7883
|
meshId: args.meshId,
|
|
7637
7884
|
nodeLabel: args.nodeLabel,
|
|
@@ -7644,9 +7891,13 @@ function injectMeshSystemMessage(components, args) {
|
|
|
7644
7891
|
coordinatorMessage: messageText,
|
|
7645
7892
|
queuedAt: Date.now(),
|
|
7646
7893
|
...workerCoordinatorDaemonId ? { targetCoordinatorDaemonId: workerCoordinatorDaemonId } : {}
|
|
7647
|
-
}
|
|
7894
|
+
};
|
|
7895
|
+
if (queuePendingMeshCoordinatorEvent(pendingEvent)) {
|
|
7648
7896
|
LOG.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
|
|
7649
7897
|
}
|
|
7898
|
+
if (localDaemonId) {
|
|
7899
|
+
markMeshCoordinatorEventDirectDelivered(localDaemonId, pendingEvent);
|
|
7900
|
+
}
|
|
7650
7901
|
const forceInject = shouldForceInjectMeshEvent(args.event);
|
|
7651
7902
|
for (const coord of coordinatorInstances) {
|
|
7652
7903
|
const coordState = coord.getState();
|
|
@@ -7714,15 +7965,15 @@ function setupMeshEventForwarding(components) {
|
|
|
7714
7965
|
if (flushSource && flushSource.category === "cli") {
|
|
7715
7966
|
const flushState = flushSource.getState();
|
|
7716
7967
|
const flushSettings = flushState.settings && typeof flushState.settings === "object" ? flushState.settings : {};
|
|
7717
|
-
const
|
|
7718
|
-
if (
|
|
7968
|
+
const coordinatorMeshId = readNonEmptyString2(flushSettings.meshCoordinatorFor);
|
|
7969
|
+
if (coordinatorMeshId) {
|
|
7719
7970
|
const status = readNonEmptyString2(flushState.status).toLowerCase();
|
|
7720
7971
|
if (status === "idle") {
|
|
7721
7972
|
try {
|
|
7722
7973
|
const localDaemonId = readNonEmptyString2(loadConfig().machineId) || void 0;
|
|
7723
|
-
const pendingEvents = drainPendingMeshCoordinatorEvents(
|
|
7974
|
+
const pendingEvents = drainPendingMeshCoordinatorEvents(coordinatorMeshId, localDaemonId);
|
|
7724
7975
|
if (pendingEvents.length > 0) {
|
|
7725
|
-
LOG.info("MeshEvents", `Auto-flushing ${pendingEvents.length} pending coordinator event(s) for mesh ${
|
|
7976
|
+
LOG.info("MeshEvents", `Auto-flushing ${pendingEvents.length} pending coordinator event(s) for mesh ${coordinatorMeshId} on coordinator idle`);
|
|
7726
7977
|
for (const pending of pendingEvents) {
|
|
7727
7978
|
if (!pending.coordinatorMessage) continue;
|
|
7728
7979
|
const forcePending = shouldForceInjectMeshEvent(pending.event);
|
|
@@ -7738,7 +7989,7 @@ function setupMeshEventForwarding(components) {
|
|
|
7738
7989
|
}
|
|
7739
7990
|
let hasDirectDispatch = false;
|
|
7740
7991
|
try {
|
|
7741
|
-
hasDirectDispatch = getActiveDirectDispatches(
|
|
7992
|
+
hasDirectDispatch = getActiveDirectDispatches(coordinatorMeshId).some((d) => d.sessionId === flushInstanceId) || hasUnterminalDirectDispatchLedgerEntry(coordinatorMeshId, flushInstanceId);
|
|
7742
7993
|
} catch {
|
|
7743
7994
|
}
|
|
7744
7995
|
if (!hasDirectDispatch) return;
|
|
@@ -7749,37 +8000,19 @@ function setupMeshEventForwarding(components) {
|
|
|
7749
8000
|
if (!isMeshCoordinatorEvent(event.event)) return;
|
|
7750
8001
|
const instanceId = readNonEmptyString2(event.instanceId);
|
|
7751
8002
|
if (!instanceId) return;
|
|
7752
|
-
const
|
|
7753
|
-
|
|
7754
|
-
|
|
7755
|
-
|
|
7756
|
-
if (!
|
|
7757
|
-
|
|
7758
|
-
|
|
7759
|
-
|
|
7760
|
-
if (coordinatorMeshId) {
|
|
7761
|
-
try {
|
|
7762
|
-
const hasActiveDispatch = getActiveDirectDispatches(coordinatorMeshId).some((d) => d.sessionId === instanceId) || hasUnterminalDirectDispatchLedgerEntry(coordinatorMeshId, instanceId);
|
|
7763
|
-
if (hasActiveDispatch) meshIdFromDirectDispatch = coordinatorMeshId;
|
|
7764
|
-
} catch {
|
|
7765
|
-
}
|
|
7766
|
-
if (!meshIdFromDirectDispatch) return;
|
|
7767
|
-
}
|
|
7768
|
-
const meshIdFromRuntime = readNonEmptyString2(settings.meshNodeFor) || meshIdFromDirectDispatch;
|
|
7769
|
-
const isMeshDelegate = Boolean(meshIdFromRuntime || settings.launchedByCoordinator);
|
|
7770
|
-
if (!isMeshDelegate) return;
|
|
7771
|
-
const mesh = meshIdFromRuntime ? getMeshWithCache(components, meshIdFromRuntime) : getCachedMeshByWorkspace(workspace);
|
|
7772
|
-
const meshId = meshIdFromRuntime || readNonEmptyString2(mesh?.id);
|
|
7773
|
-
if (!meshId) return;
|
|
7774
|
-
const targetNode = mesh?.nodes?.find((n) => n.workspace === workspace);
|
|
7775
|
-
const runtimeNodeId = readNonEmptyString2(settings.meshNodeId);
|
|
7776
|
-
const resolvedNodeId = targetNode?.id || runtimeNodeId;
|
|
7777
|
-
const nodeLabel = targetNode ? `Node '${targetNode.id}'` : runtimeNodeId ? `Node '${runtimeNodeId}'` : `Agent at ${workspace}`;
|
|
8003
|
+
const routing = resolveWorkerDelegateRouting(components, instanceId, {
|
|
8004
|
+
getMeshById: (meshId) => getMeshWithCache(components, meshId),
|
|
8005
|
+
getMeshByWorkspace: (workspace) => getCachedMeshByWorkspace(workspace)
|
|
8006
|
+
});
|
|
8007
|
+
if (!routing.isDelegate) {
|
|
8008
|
+
recordUnroutableDelegateEvent(routing, event.event);
|
|
8009
|
+
return;
|
|
8010
|
+
}
|
|
7778
8011
|
injectMeshSystemMessage(components, {
|
|
7779
|
-
meshId,
|
|
8012
|
+
meshId: routing.meshId,
|
|
7780
8013
|
sourceInstanceId: instanceId,
|
|
7781
|
-
nodeId:
|
|
7782
|
-
nodeLabel,
|
|
8014
|
+
nodeId: routing.nodeId,
|
|
8015
|
+
nodeLabel: routing.nodeLabel,
|
|
7783
8016
|
event: event.event,
|
|
7784
8017
|
metadataEvent: event
|
|
7785
8018
|
});
|
|
@@ -7800,6 +8033,7 @@ var init_mesh_events_coordinator = __esm({
|
|
|
7800
8033
|
init_mesh_delivery_policy();
|
|
7801
8034
|
init_mesh_runtime_store();
|
|
7802
8035
|
init_mesh_events_pending();
|
|
8036
|
+
init_mesh_routing();
|
|
7803
8037
|
init_mesh_events_stale();
|
|
7804
8038
|
init_mesh_events_utils();
|
|
7805
8039
|
REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
|
|
@@ -7847,11 +8081,13 @@ var init_mesh_events_coordinator = __esm({
|
|
|
7847
8081
|
var mesh_events_exports = {};
|
|
7848
8082
|
__export(mesh_events_exports, {
|
|
7849
8083
|
__resetIdleAutoFastForwardForTests: () => __resetIdleAutoFastForwardForTests,
|
|
8084
|
+
__resetMeshWorkspaceCacheForTests: () => __resetMeshWorkspaceCacheForTests,
|
|
7850
8085
|
clearPendingMeshCoordinatorEvents: () => clearPendingMeshCoordinatorEvents,
|
|
7851
8086
|
drainPendingMeshCoordinatorEvents: () => drainPendingMeshCoordinatorEvents,
|
|
7852
8087
|
getPendingMeshCoordinatorEvents: () => getPendingMeshCoordinatorEvents,
|
|
7853
8088
|
handleMeshForwardEvent: () => handleMeshForwardEvent,
|
|
7854
8089
|
isMeshCoordinatorEvent: () => isMeshCoordinatorEvent,
|
|
8090
|
+
markMeshCoordinatorEventDirectDelivered: () => markMeshCoordinatorEventDirectDelivered,
|
|
7855
8091
|
queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
|
|
7856
8092
|
reconcileDirectDispatchCompletionFromTranscript: () => reconcileDirectDispatchCompletionFromTranscript,
|
|
7857
8093
|
setupMeshEventForwarding: () => setupMeshEventForwarding,
|
|
@@ -38359,6 +38595,7 @@ var yaml3 = __toESM(require("js-yaml"));
|
|
|
38359
38595
|
init_logger();
|
|
38360
38596
|
init_mesh_coordinator();
|
|
38361
38597
|
init_mesh_events();
|
|
38598
|
+
init_mesh_routing();
|
|
38362
38599
|
init_mesh_host_ownership();
|
|
38363
38600
|
init_mesh_fast_forward();
|
|
38364
38601
|
|
|
@@ -45125,6 +45362,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
45125
45362
|
}
|
|
45126
45363
|
const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
|
|
45127
45364
|
const pendingCoordinatorEvents = getPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
|
|
45365
|
+
const unroutableDeliveries = getRecentUnroutableDeliveries();
|
|
45128
45366
|
const previewFreshness = (() => {
|
|
45129
45367
|
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs23.existsSync(candidate));
|
|
45130
45368
|
return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
|
|
@@ -45180,6 +45418,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
45180
45418
|
...asyncRefineJobs.length > 0 ? { asyncRefineJobs } : {},
|
|
45181
45419
|
...historicalSessions ? { historicalSessions } : {},
|
|
45182
45420
|
...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {},
|
|
45421
|
+
...unroutableDeliveries.length > 0 ? { unroutableDeliveries } : {},
|
|
45183
45422
|
activeRefineJobs: Array.from(this.runningRefineJobs.values()).filter((job) => job.meshId === meshId).map((job) => ({
|
|
45184
45423
|
jobId: job.jobId,
|
|
45185
45424
|
nodeId: job.targetNodeId,
|
|
@@ -45189,9 +45428,13 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
45189
45428
|
targetCoordinatorDaemonId: job.targetCoordinatorDaemonId
|
|
45190
45429
|
}))
|
|
45191
45430
|
};
|
|
45192
|
-
const { pendingCoordinatorEvents: _pendingCoordinatorEvents, ...cacheableStatusResult } = statusResult;
|
|
45431
|
+
const { pendingCoordinatorEvents: _pendingCoordinatorEvents, unroutableDeliveries: _unroutableDeliveries, ...cacheableStatusResult } = statusResult;
|
|
45193
45432
|
const rememberedStatus = this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
|
|
45194
|
-
const returnedStatus =
|
|
45433
|
+
const returnedStatus = {
|
|
45434
|
+
...rememberedStatus,
|
|
45435
|
+
...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {},
|
|
45436
|
+
...unroutableDeliveries.length > 0 ? { unroutableDeliveries } : {}
|
|
45437
|
+
};
|
|
45195
45438
|
logRepoMeshStatusDebug("return_live", {
|
|
45196
45439
|
meshId,
|
|
45197
45440
|
command: "mesh_status",
|
|
@@ -53513,7 +53756,8 @@ async function initDaemonComponents(config) {
|
|
|
53513
53756
|
sessionRegistry,
|
|
53514
53757
|
detectedIdes: detectedIdesRef,
|
|
53515
53758
|
refreshProviderAvailability,
|
|
53516
|
-
dispatchMeshCommand: config.dispatchMeshCommand
|
|
53759
|
+
dispatchMeshCommand: config.dispatchMeshCommand,
|
|
53760
|
+
onMeshCoordinatorEventForwarded: config.onMeshCoordinatorEventForwarded
|
|
53517
53761
|
};
|
|
53518
53762
|
setupMeshEventForwarding(components);
|
|
53519
53763
|
setImmediate(() => void router.resumePendingRefineJobsOnStartup());
|