@adhdev/daemon-standalone 0.9.77-rc.32 → 0.9.77-rc.33

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-standalone",
3
- "version": "0.9.77-rc.32",
3
+ "version": "0.9.77-rc.33",
4
4
  "description": "ADHDev standalone daemon — embedded HTTP/WS server for local dashboard",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -26312,10 +26312,12 @@ function triggerMeshQueue(components, meshId) {
26312
26312
  const state = inst.getState();
26313
26313
  const settings = state.settings || {};
26314
26314
  const instMeshId = readNonEmptyString(settings.meshNodeFor);
26315
- if (instMeshId !== meshId && !settings.launchedByCoordinator) continue;
26315
+ if (instMeshId !== meshId) continue;
26316
26316
  const nodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
26317
26317
  if (!nodeId) continue;
26318
- if (state.status !== "idle" && state.status !== "stopped" && state.activeChat?.status !== "waiting_input") continue;
26318
+ const status = readNonEmptyString(state.status).toLowerCase();
26319
+ if (["stopped", "failed", "terminated", "exited", "closed"].includes(status)) continue;
26320
+ if (status !== "idle" && state.activeChat?.status !== "waiting_input") continue;
26319
26321
  const sessionId = state.instanceId;
26320
26322
  const providerType = state.type || readNonEmptyString(settings.providerType);
26321
26323
  if (providerType) {
@@ -57489,6 +57491,26 @@ function unwrapCommandPayload(value) {
57489
57491
  }
57490
57492
  return current;
57491
57493
  }
57494
+ function isTerminalSessionRecord(session) {
57495
+ const status = typeof session?.status === "string" ? session.status.toLowerCase() : "";
57496
+ const lifecycle = typeof session?.lifecycle === "string" ? session.lifecycle.toLowerCase() : "";
57497
+ const state = typeof session?.state === "string" ? session.state.toLowerCase() : "";
57498
+ return [status, lifecycle, state].some((value) => ["stopped", "failed", "terminated", "exited", "closed"].includes(value));
57499
+ }
57500
+ function isIdleSessionRecord(session) {
57501
+ if (isTerminalSessionRecord(session)) return false;
57502
+ const status = typeof session?.status === "string" ? session.status.toLowerCase() : "";
57503
+ const chatStatus = typeof session?.activeChat?.status === "string" ? session.activeChat.status.toLowerCase() : "";
57504
+ return status === "idle" || chatStatus === "waiting_input";
57505
+ }
57506
+ function chooseDispatchableSession(sessions, providerType, meshId, nodeId) {
57507
+ const live = sessions.filter((session) => !isTerminalSessionRecord(session));
57508
+ const matchingProvider = (session) => !providerType || session?.providerType === providerType || session?.cliType === providerType;
57509
+ const meshSessions = live.filter(
57510
+ (session) => session?.settings?.meshNodeFor === meshId || session?.settings?.meshNodeId === nodeId
57511
+ );
57512
+ return meshSessions.find((session) => isIdleSessionRecord(session) && matchingProvider(session)) || meshSessions.find(matchingProvider) || live.find((session) => isIdleSessionRecord(session) && matchingProvider(session)) || live.find(matchingProvider) || live.find(isIdleSessionRecord) || live[0];
57513
+ }
57492
57514
  function findNestedPayload(value, predicate) {
57493
57515
  const seen = /* @__PURE__ */ new Set();
57494
57516
  const stack = [{ payload: value, depth: 0 }];
@@ -57529,18 +57551,12 @@ async function ipcDispatchToRemoteAgent(ctx, node, args) {
57529
57551
  const innerResult = relayResult?.result ?? relayResult;
57530
57552
  const statusObj = innerResult?.status ?? innerResult;
57531
57553
  const sessions = Array.isArray(statusObj?.sessions) ? statusObj.sessions : [];
57532
- const meshSessions = sessions.filter(
57533
- (s) => s?.settings?.meshNodeFor === ctx.mesh.id || s?.settings?.meshNodeId === node.id || s?.settings?.launchedByCoordinator === true
57534
- );
57535
- const targetSession = meshSessions[0] || sessions.find(
57536
- (s) => !resolvedProviderType || s?.providerType === resolvedProviderType || s?.cliType === resolvedProviderType
57537
- ) || sessions[0];
57554
+ const targetSession = chooseDispatchableSession(sessions, resolvedProviderType, ctx.mesh.id, node.id);
57538
57555
  if (targetSession?.id || targetSession?.sessionId) {
57539
57556
  sessionId = targetSession.id || targetSession.sessionId;
57540
57557
  if (!resolvedProviderType) {
57541
57558
  resolvedProviderType = targetSession.providerType || targetSession.cliType || "";
57542
57559
  }
57543
- } else {
57544
57560
  }
57545
57561
  } catch (e) {
57546
57562
  }
@@ -57549,13 +57565,17 @@ async function ipcDispatchToRemoteAgent(ctx, node, args) {
57549
57565
  return { success: false, error: `Cannot dispatch to remote node '${node.id}': providerType unknown. Set providerPriority on the node policy or call mesh_launch_session first.` };
57550
57566
  }
57551
57567
  try {
57552
- await transport.meshCommand(daemonId, "agent_command", {
57568
+ const dispatchResult = await transport.meshCommand(daemonId, "agent_command", {
57553
57569
  ...sessionId ? { targetSessionId: sessionId } : {},
57554
57570
  agentType: resolvedProviderType,
57555
57571
  cliType: resolvedProviderType,
57556
57572
  action: "send_chat",
57557
57573
  message: args.message
57558
57574
  });
57575
+ const dispatchPayload = unwrapCommandPayload(dispatchResult);
57576
+ if (dispatchPayload?.success === false || dispatchResult?.success === false) {
57577
+ return { success: false, error: `P2P dispatch failed: ${dispatchPayload?.error || dispatchResult?.error || "agent_command rejected the task"}` };
57578
+ }
57559
57579
  return { success: true, dispatched: true, sessionId: sessionId || resolvedProviderType };
57560
57580
  } catch (e) {
57561
57581
  return { success: false, error: `P2P dispatch failed: ${e?.message || String(e)}` };
@@ -58099,6 +58119,35 @@ async function meshSendTask(ctx, args) {
58099
58119
  }
58100
58120
  return JSON.stringify({ ...result, nodeId: args.node_id });
58101
58121
  }
58122
+ if (args.session_id && isLocalTransport(ctx.transport)) {
58123
+ const cached2 = meshSessionProviderMetadata.get(meshSessionCacheKey(args.node_id, args.session_id));
58124
+ const dispatchResult = await commandForNode(ctx, node, "agent_command", {
58125
+ targetSessionId: args.session_id,
58126
+ ...cached2?.providerType ? { agentType: cached2.providerType, cliType: cached2.providerType, providerType: cached2.providerType } : {},
58127
+ action: "send_chat",
58128
+ message: args.message
58129
+ });
58130
+ const dispatchPayload = unwrapCommandPayload(dispatchResult);
58131
+ if (dispatchPayload?.success === false || dispatchResult?.success === false) {
58132
+ return JSON.stringify({
58133
+ success: false,
58134
+ nodeId: args.node_id,
58135
+ sessionId: args.session_id,
58136
+ error: dispatchPayload?.error || dispatchResult?.error || "agent_command rejected the task"
58137
+ });
58138
+ }
58139
+ try {
58140
+ appendLedgerEntry(ctx.mesh.id, {
58141
+ kind: "task_dispatched",
58142
+ nodeId: args.node_id,
58143
+ sessionId: args.session_id,
58144
+ providerType: cached2?.providerType,
58145
+ payload: { message: args.message, via: "local_direct" }
58146
+ });
58147
+ } catch {
58148
+ }
58149
+ return JSON.stringify({ success: true, dispatched: true, nodeId: args.node_id, sessionId: args.session_id });
58150
+ }
58102
58151
  const task = enqueueTask(ctx.mesh.id, args.message, {
58103
58152
  targetNodeId: args.node_id,
58104
58153
  targetSessionId: args.session_id