@adhdev/daemon-core 0.9.82-rc.339 → 0.9.82-rc.340
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/commands/router.d.ts +19 -0
- package/dist/index.js +71 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +71 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/commands/router.ts +97 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhdev/daemon-core",
|
|
3
|
-
"version": "0.9.82-rc.
|
|
3
|
+
"version": "0.9.82-rc.340",
|
|
4
4
|
"description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"author": "vilmire",
|
|
47
47
|
"license": "AGPL-3.0-or-later",
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@adhdev/mesh-shared": "0.9.82-rc.
|
|
49
|
+
"@adhdev/mesh-shared": "0.9.82-rc.340",
|
|
50
50
|
"@adhdev/session-host-core": "*",
|
|
51
51
|
"@agentclientprotocol/sdk": "^0.16.1",
|
|
52
52
|
"ajv": "^8.20.0",
|
package/src/commands/router.ts
CHANGED
|
@@ -1008,6 +1008,19 @@ export function readCachedInlineMeshActiveSessionDetails(node: any): Array<Recor
|
|
|
1008
1008
|
startedAt: readStringValue(fallbackSession.startedAt, fallbackSession.started_at) ?? null,
|
|
1009
1009
|
lastActivityAt: readStringValue(fallbackSession.lastActivityAt, fallbackSession.last_activity_at) ?? null,
|
|
1010
1010
|
recoveryState: readStringValue(fallbackSession.recoveryState, fallbackSession.recovery_state) ?? null,
|
|
1011
|
+
// [T2] Carry the worker-computed last-message preview through the cached inline-mesh
|
|
1012
|
+
// active-session entry. The worker's get_status_metadata slim now ships these
|
|
1013
|
+
// (mesh-tools.ts), and this is the surface the coordinator's inbox-preview path reads
|
|
1014
|
+
// (buildDaemonMetadataUpdateForSubscription → stampLocalAssistantPreviewOnCachedEntry).
|
|
1015
|
+
// Without carrying them here, the coordinator could only derive the preview from a live
|
|
1016
|
+
// in-process instance it doesn't host for a remote worker, so the inbox stuck on the
|
|
1017
|
+
// dispatched user task. Only present when the worker reported them.
|
|
1018
|
+
...(readStringValue(fallbackSession.lastMessagePreview, fallbackSession.last_message_preview)
|
|
1019
|
+
? { lastMessagePreview: readStringValue(fallbackSession.lastMessagePreview, fallbackSession.last_message_preview) } : {}),
|
|
1020
|
+
...(readStringValue(fallbackSession.lastMessageRole, fallbackSession.last_message_role)
|
|
1021
|
+
? { lastMessageRole: readStringValue(fallbackSession.lastMessageRole, fallbackSession.last_message_role) } : {}),
|
|
1022
|
+
...(readNumberValue(fallbackSession.lastMessageAt, fallbackSession.last_message_at) !== undefined
|
|
1023
|
+
? { lastMessageAt: readNumberValue(fallbackSession.lastMessageAt, fallbackSession.last_message_at) } : {}),
|
|
1011
1024
|
isCached: true,
|
|
1012
1025
|
}];
|
|
1013
1026
|
}
|
|
@@ -3384,6 +3397,23 @@ const CHAT_COMMANDS = [
|
|
|
3384
3397
|
'send_chat', 'new_chat', 'switch_chat', 'set_mode',
|
|
3385
3398
|
'change_model',
|
|
3386
3399
|
];
|
|
3400
|
+
|
|
3401
|
+
// [Z] Session-scoped commands that must be forwarded to the owning REMOTE worker daemon
|
|
3402
|
+
// when their target session is not hosted on this coordinator. These are the interactive
|
|
3403
|
+
// controlbar / modal mutations the dashboard issues against a specific session:
|
|
3404
|
+
// - invoke_provider_script: controlbar Model/Mode selectors run a provider script
|
|
3405
|
+
// - resolve_action: approve/reject a modal prompt
|
|
3406
|
+
// - set_mode / change_model / set_thought_level: direct control mutations
|
|
3407
|
+
// send_chat is intentionally NOT here — it already reaches the worker by its own route and
|
|
3408
|
+
// double-forwarding would be redundant. read_chat is also excluded: it can serve historical
|
|
3409
|
+
// transcript data locally and has its own inactive-session fallback in the CommandHandler.
|
|
3410
|
+
const MESH_FORWARDABLE_SESSION_COMMANDS = new Set([
|
|
3411
|
+
'invoke_provider_script',
|
|
3412
|
+
'resolve_action',
|
|
3413
|
+
'set_mode',
|
|
3414
|
+
'change_model',
|
|
3415
|
+
'set_thought_level',
|
|
3416
|
+
]);
|
|
3387
3417
|
const READ_DEBUG_ENABLED = process.argv.includes('--dev') || process.env.ADHDEV_READ_DEBUG === '1';
|
|
3388
3418
|
|
|
3389
3419
|
function normalizeCommandSource(source: string): CommandLogEntry['source'] {
|
|
@@ -3782,6 +3812,41 @@ export class DaemonCommandRouter {
|
|
|
3782
3812
|
return nodes;
|
|
3783
3813
|
}
|
|
3784
3814
|
|
|
3815
|
+
/**
|
|
3816
|
+
* Resolve the REMOTE worker daemonId that owns a given session, when the session
|
|
3817
|
+
* belongs to a mesh node hosted on a DIFFERENT daemon than this coordinator.
|
|
3818
|
+
*
|
|
3819
|
+
* The coordinator does not host remote-worker session instances in its own
|
|
3820
|
+
* instanceManager/sessionRegistry — only their cached mesh-node metadata. A
|
|
3821
|
+
* dashboard-issued session-scoped command (invoke_provider_script / resolve_action /
|
|
3822
|
+
* set_mode / …) lands on the coordinator with a targetSessionId the coordinator can't
|
|
3823
|
+
* find locally, and without forwarding it dies as "Live session not found". send_chat
|
|
3824
|
+
* happens to survive (its target resolves to the worker by another route), but the
|
|
3825
|
+
* controlbar commands do not — so the controlbar buttons appear to do nothing.
|
|
3826
|
+
*
|
|
3827
|
+
* Mirror the existing node-level remote-forward pattern (fast_forward_mesh_node etc.):
|
|
3828
|
+
* scan the cached inline-mesh nodes for the one whose active session matches the
|
|
3829
|
+
* targetSessionId, and return its daemonId when that daemonId is a remote daemon (i.e.
|
|
3830
|
+
* not this coordinator's own statusInstanceId). Returns undefined for a locally-hosted
|
|
3831
|
+
* session (no forward — execute locally as before) or when ownership can't be resolved.
|
|
3832
|
+
*/
|
|
3833
|
+
public resolveRemoteMeshSessionOwnerDaemonId(sessionId: string): string | undefined {
|
|
3834
|
+
const trimmed = typeof sessionId === 'string' ? sessionId.trim() : '';
|
|
3835
|
+
if (!trimmed) return undefined;
|
|
3836
|
+
const selfDaemonId = this.deps.statusInstanceId;
|
|
3837
|
+
for (const node of this.getCachedInlineMeshNodes()) {
|
|
3838
|
+
const nodeSessions = readCachedInlineMeshActiveSessions(node);
|
|
3839
|
+
if (!nodeSessions.includes(trimmed)) continue;
|
|
3840
|
+
const nodeDaemonId = readMeshNodeDaemonId(readObjectRecord(node));
|
|
3841
|
+
if (!nodeDaemonId) return undefined;
|
|
3842
|
+
// Only forward to a genuinely remote daemon. When the owning node is this
|
|
3843
|
+
// coordinator itself (locally hosted worker), fall through to local handling.
|
|
3844
|
+
if (selfDaemonId && nodeDaemonId === selfDaemonId) return undefined;
|
|
3845
|
+
return nodeDaemonId;
|
|
3846
|
+
}
|
|
3847
|
+
return undefined;
|
|
3848
|
+
}
|
|
3849
|
+
|
|
3785
3850
|
public getCachedInlineMesh(meshId: string, inlineMesh?: unknown): any | undefined {
|
|
3786
3851
|
if (inlineMesh && typeof inlineMesh === 'object') {
|
|
3787
3852
|
return this.warmInlineMeshCache(meshId, inlineMesh);
|
|
@@ -6115,6 +6180,38 @@ export class DaemonCommandRouter {
|
|
|
6115
6180
|
* Returns null if not handled at this level → caller delegates to CommandHandler.
|
|
6116
6181
|
*/
|
|
6117
6182
|
private async executeDaemonCommand(cmd: string, args: any): Promise<CommandRouterResult | null> {
|
|
6183
|
+
// [Z] Remote mesh worker session-scoped command forward.
|
|
6184
|
+
//
|
|
6185
|
+
// Session-scoped commands issued from the dashboard (the controlbar Model/Mode
|
|
6186
|
+
// selectors → invoke_provider_script, and modal approval → resolve_action, plus the
|
|
6187
|
+
// direct set_mode/change_model/set_thought_level mutations) target a session by
|
|
6188
|
+
// targetSessionId. When that session is a mesh worker hosted on a REMOTE daemon, this
|
|
6189
|
+
// coordinator never holds its live instance, so the CommandHandler delegation would
|
|
6190
|
+
// fail with "Live session not found". Forward to the owning worker daemon — the same
|
|
6191
|
+
// daemon that already executes send_chat for that session — so the controlbar acts on
|
|
6192
|
+
// the real worker. _meshDirectDispatch prevents re-forwarding once the call lands on
|
|
6193
|
+
// the owning daemon (it then handles the session locally). A locally-hosted worker (or
|
|
6194
|
+
// any session this coordinator owns) resolves to undefined below and falls through to
|
|
6195
|
+
// normal local handling — no regression.
|
|
6196
|
+
if (MESH_FORWARDABLE_SESSION_COMMANDS.has(cmd) && this.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
|
|
6197
|
+
const targetSessionId = readStringValue(args?.targetSessionId, args?.sessionId, args?.instanceId);
|
|
6198
|
+
if (targetSessionId) {
|
|
6199
|
+
const localInstance = this.deps.instanceManager?.getInstance(targetSessionId);
|
|
6200
|
+
const localRegistry = this.deps.sessionRegistry?.get?.(targetSessionId);
|
|
6201
|
+
if (!localInstance && !localRegistry) {
|
|
6202
|
+
const ownerDaemonId = this.resolveRemoteMeshSessionOwnerDaemonId(targetSessionId);
|
|
6203
|
+
if (ownerDaemonId) {
|
|
6204
|
+
LOG.info('Mesh', `[Mesh] Forwarding session-scoped '${cmd}' for remote worker session ${targetSessionId.split('_')[0]} → daemon ${ownerDaemonId.slice(0, 12)}`);
|
|
6205
|
+
const forwarded = await this.deps.dispatchMeshCommand(ownerDaemonId, cmd, {
|
|
6206
|
+
...(typeof args === 'object' && args !== null ? args as Record<string, unknown> : {}),
|
|
6207
|
+
_meshDirectDispatch: true,
|
|
6208
|
+
});
|
|
6209
|
+
return (forwarded ?? { success: false, error: 'no response from remote worker daemon' }) as CommandRouterResult;
|
|
6210
|
+
}
|
|
6211
|
+
}
|
|
6212
|
+
}
|
|
6213
|
+
}
|
|
6214
|
+
|
|
6118
6215
|
switch (cmd) {
|
|
6119
6216
|
// ─── CLI / ACP commands ───
|
|
6120
6217
|
case 'mesh_forward_event': {
|