@adhdev/daemon-core 0.9.77-rc.20 → 0.9.77-rc.22
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 +31 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +31 -7
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-events.d.ts +2 -7
- package/package.json +1 -1
- package/src/boot/daemon-lifecycle.ts +5 -0
- package/src/mesh/mesh-events.ts +38 -9
|
@@ -8,17 +8,12 @@ export interface PendingMeshCoordinatorEvent {
|
|
|
8
8
|
}
|
|
9
9
|
/** Drain and return all pending coordinator events, clearing the queue. */
|
|
10
10
|
export declare function drainPendingMeshCoordinatorEvents(): PendingMeshCoordinatorEvent[];
|
|
11
|
-
export declare function tryAssignQueueTask(components:
|
|
12
|
-
cliManager: any;
|
|
13
|
-
}, meshId: string, nodeId: string, sessionId: string, providerType: string): boolean;
|
|
11
|
+
export declare function tryAssignQueueTask(components: DaemonComponents, meshId: string, nodeId: string, sessionId: string, providerType: string): boolean;
|
|
14
12
|
/**
|
|
15
13
|
* Triggers a queue check for all nodes in the mesh.
|
|
16
14
|
* Called when a new task is enqueued, in case nodes are already idle.
|
|
17
15
|
*/
|
|
18
|
-
export declare function triggerMeshQueue(components:
|
|
19
|
-
instanceManager: any;
|
|
20
|
-
cliManager: any;
|
|
21
|
-
}, meshId: string): void;
|
|
16
|
+
export declare function triggerMeshQueue(components: DaemonComponents, meshId: string): void;
|
|
22
17
|
export declare function handleMeshForwardEvent(components: DaemonComponents, payload: Record<string, unknown>): {
|
|
23
18
|
success: boolean;
|
|
24
19
|
forwarded: number;
|
package/package.json
CHANGED
|
@@ -83,6 +83,9 @@ export interface DaemonInitConfig {
|
|
|
83
83
|
|
|
84
84
|
/** Fired before send_chat is dispatched — used for turn snapshot hooks */
|
|
85
85
|
onBeforeSendChat?: (params: { workspace: string; sessionId: string }) => void;
|
|
86
|
+
|
|
87
|
+
/** Relays a command to a remote mesh node daemon */
|
|
88
|
+
dispatchMeshCommand?: (daemonId: string, command: string, args: Record<string, unknown>) => Promise<any>;
|
|
86
89
|
}
|
|
87
90
|
|
|
88
91
|
// ─── Result ───
|
|
@@ -100,6 +103,7 @@ export interface DaemonComponents {
|
|
|
100
103
|
sessionRegistry: SessionRegistry;
|
|
101
104
|
detectedIdes: { value: IDEInfo[] };
|
|
102
105
|
refreshProviderAvailability: (providerType?: string) => Promise<void>;
|
|
106
|
+
dispatchMeshCommand?: (daemonId: string, command: string, args: Record<string, unknown>) => Promise<any>;
|
|
103
107
|
}
|
|
104
108
|
|
|
105
109
|
export interface DaemonDevSupportOptions {
|
|
@@ -331,6 +335,7 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
|
|
|
331
335
|
sessionRegistry,
|
|
332
336
|
detectedIdes: detectedIdesRef,
|
|
333
337
|
refreshProviderAvailability,
|
|
338
|
+
dispatchMeshCommand: config.dispatchMeshCommand,
|
|
334
339
|
};
|
|
335
340
|
|
|
336
341
|
// 11. Setup Mesh Event Forwarding
|
package/src/mesh/mesh-events.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { getMesh, getMeshByRepo } from '../config/mesh-config.js';
|
|
|
3
3
|
import { LOG } from '../logging/logger.js';
|
|
4
4
|
import { appendLedgerEntry, getSessionRecoveryContext } from './mesh-ledger.js';
|
|
5
5
|
import type { MeshLedgerKind, SessionRecoveryContext } from './mesh-ledger.js';
|
|
6
|
-
import { claimNextTask, updateSessionTaskStatus, enqueueTask } from './mesh-work-queue.js';
|
|
6
|
+
import { claimNextTask, updateSessionTaskStatus, enqueueTask, updateTaskStatus } from './mesh-work-queue.js';
|
|
7
7
|
|
|
8
8
|
// ---------------------------------------------------------------------------
|
|
9
9
|
// MCP coordinator pending-event queue
|
|
@@ -62,24 +62,49 @@ function formatCompletionMetadata(event: Record<string, unknown>): string {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
export function tryAssignQueueTask(
|
|
65
|
-
components:
|
|
65
|
+
components: DaemonComponents,
|
|
66
66
|
meshId: string,
|
|
67
67
|
nodeId: string,
|
|
68
68
|
sessionId: string,
|
|
69
69
|
providerType: string
|
|
70
70
|
): boolean {
|
|
71
71
|
const task = claimNextTask(meshId, nodeId, sessionId);
|
|
72
|
-
if (!task)
|
|
72
|
+
if (!task) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
73
75
|
|
|
74
76
|
LOG.info('MeshQueue', `Node ${nodeId} (${sessionId}) pulled task ${task.id}`);
|
|
77
|
+
|
|
78
|
+
// Check if the node is remote
|
|
79
|
+
const mesh = getMesh(meshId);
|
|
80
|
+
const node = mesh?.nodes.find((n: any) => n.id === nodeId);
|
|
75
81
|
|
|
82
|
+
// If the node is explicitly remote and we have a dispatch mechanism, route via P2P
|
|
83
|
+
if (node?.daemonId && components.dispatchMeshCommand) {
|
|
84
|
+
const isLocalNode = components.cliManager.adapters.has(sessionId);
|
|
85
|
+
if (!isLocalNode) {
|
|
86
|
+
components.dispatchMeshCommand(node.daemonId, 'agent_command', {
|
|
87
|
+
targetSessionId: sessionId,
|
|
88
|
+
cliType: providerType,
|
|
89
|
+
action: 'send_chat',
|
|
90
|
+
message: task.message,
|
|
91
|
+
}).catch((e: any) => {
|
|
92
|
+
LOG.error('MeshQueue', `Failed to dispatch task via P2P to remote node ${nodeId}: ${e?.message}`);
|
|
93
|
+
updateTaskStatus(meshId, task.id, 'failed');
|
|
94
|
+
});
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Local routing
|
|
76
100
|
components.cliManager.handleCliCommand('agent_command', {
|
|
77
101
|
targetSessionId: sessionId,
|
|
78
102
|
cliType: providerType,
|
|
79
103
|
action: 'send_chat',
|
|
80
104
|
message: task.message,
|
|
81
105
|
}).catch((e: any) => {
|
|
82
|
-
LOG.error('MeshQueue', `Failed to dispatch task to node ${nodeId}: ${e?.message}`);
|
|
106
|
+
LOG.error('MeshQueue', `Failed to dispatch task locally to node ${nodeId}: ${e?.message}`);
|
|
107
|
+
updateTaskStatus(meshId, task.id, 'failed');
|
|
83
108
|
});
|
|
84
109
|
|
|
85
110
|
return true;
|
|
@@ -89,7 +114,7 @@ export function tryAssignQueueTask(
|
|
|
89
114
|
* Triggers a queue check for all nodes in the mesh.
|
|
90
115
|
* Called when a new task is enqueued, in case nodes are already idle.
|
|
91
116
|
*/
|
|
92
|
-
export function triggerMeshQueue(components:
|
|
117
|
+
export function triggerMeshQueue(components: DaemonComponents, meshId: string) {
|
|
93
118
|
const mesh = getMesh(meshId);
|
|
94
119
|
if (!mesh) return;
|
|
95
120
|
|
|
@@ -165,6 +190,7 @@ function buildMeshSystemMessage(args: {
|
|
|
165
190
|
function injectMeshSystemMessage(components: DaemonComponents, args: {
|
|
166
191
|
meshId: string;
|
|
167
192
|
sourceInstanceId?: string;
|
|
193
|
+
nodeId?: string;
|
|
168
194
|
nodeLabel: string;
|
|
169
195
|
event: string;
|
|
170
196
|
metadataEvent: Record<string, unknown>;
|
|
@@ -172,7 +198,7 @@ function injectMeshSystemMessage(components: DaemonComponents, args: {
|
|
|
172
198
|
// ── Task Queue & Ledger ──
|
|
173
199
|
if (args.event === 'agent:generating_completed') {
|
|
174
200
|
const sessionId = readNonEmptyString(args.metadataEvent.targetSessionId);
|
|
175
|
-
const nodeId = readNonEmptyString(args.
|
|
201
|
+
const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
|
|
176
202
|
const providerType = readNonEmptyString(args.metadataEvent.providerType);
|
|
177
203
|
|
|
178
204
|
if (sessionId) {
|
|
@@ -186,7 +212,7 @@ function injectMeshSystemMessage(components: DaemonComponents, args: {
|
|
|
186
212
|
}
|
|
187
213
|
} else if (args.event === 'agent:ready') {
|
|
188
214
|
const sessionId = readNonEmptyString(args.metadataEvent.targetSessionId);
|
|
189
|
-
const nodeId = readNonEmptyString(args.
|
|
215
|
+
const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
|
|
190
216
|
const providerType = readNonEmptyString(args.metadataEvent.providerType);
|
|
191
217
|
|
|
192
218
|
if (sessionId && nodeId && providerType) {
|
|
@@ -206,7 +232,7 @@ function injectMeshSystemMessage(components: DaemonComponents, args: {
|
|
|
206
232
|
try {
|
|
207
233
|
appendLedgerEntry(args.meshId, {
|
|
208
234
|
kind: ledgerKind,
|
|
209
|
-
nodeId: readNonEmptyString(args.
|
|
235
|
+
nodeId: readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId) || undefined,
|
|
210
236
|
sessionId: readNonEmptyString(args.metadataEvent.targetSessionId) || undefined,
|
|
211
237
|
providerType: readNonEmptyString(args.metadataEvent.providerType) || undefined,
|
|
212
238
|
payload: {
|
|
@@ -230,7 +256,7 @@ function injectMeshSystemMessage(components: DaemonComponents, args: {
|
|
|
230
256
|
|
|
231
257
|
recoveryContext = getSessionRecoveryContext(args.meshId, {
|
|
232
258
|
sessionId: readNonEmptyString(args.metadataEvent.targetSessionId) || undefined,
|
|
233
|
-
nodeId: readNonEmptyString(args.
|
|
259
|
+
nodeId: readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId) || undefined,
|
|
234
260
|
maxRetries,
|
|
235
261
|
});
|
|
236
262
|
recoveryContext.failedProviderType = readNonEmptyString(args.metadataEvent.providerType) || null;
|
|
@@ -338,6 +364,7 @@ export function handleMeshForwardEvent(components: DaemonComponents, payload: Re
|
|
|
338
364
|
const nodeLabel = nodeId ? `Node '${nodeId}'` : workspace ? `Agent at ${workspace}` : 'Remote agent';
|
|
339
365
|
return injectMeshSystemMessage(components, {
|
|
340
366
|
meshId,
|
|
367
|
+
nodeId,
|
|
341
368
|
nodeLabel,
|
|
342
369
|
event: eventName,
|
|
343
370
|
metadataEvent: {
|
|
@@ -385,6 +412,7 @@ export function setupMeshEventForwarding(components: DaemonComponents) {
|
|
|
385
412
|
// Determine node label. Inline/cloud meshes may be unavailable here, so preserve runtime node id.
|
|
386
413
|
const targetNode = mesh?.nodes?.find((n: any) => n.workspace === workspace);
|
|
387
414
|
const runtimeNodeId = readNonEmptyString(settings.meshNodeId);
|
|
415
|
+
const resolvedNodeId = targetNode?.id || runtimeNodeId;
|
|
388
416
|
const nodeLabel = targetNode
|
|
389
417
|
? `Node '${targetNode.id}'`
|
|
390
418
|
: runtimeNodeId
|
|
@@ -394,6 +422,7 @@ export function setupMeshEventForwarding(components: DaemonComponents) {
|
|
|
394
422
|
injectMeshSystemMessage(components, {
|
|
395
423
|
meshId,
|
|
396
424
|
sourceInstanceId: instanceId,
|
|
425
|
+
nodeId: resolvedNodeId,
|
|
397
426
|
nodeLabel,
|
|
398
427
|
event: event.event,
|
|
399
428
|
metadataEvent: event,
|