@adhdev/daemon-standalone 0.9.77-rc.34 → 0.9.77-rc.36

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/public/index.html CHANGED
@@ -7,7 +7,7 @@
7
7
  <meta name="description" content="ADHDev self-hosted dashboard for controlling AI agents" />
8
8
  <link rel="icon" href="/otter-logo.png" />
9
9
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet" />
10
- <script type="module" crossorigin src="/assets/index-CWWeDAva.js"></script>
10
+ <script type="module" crossorigin src="/assets/index-Crr3Vqz7.js"></script>
11
11
  <link rel="modulepreload" crossorigin href="/assets/vendor-CLec0455.js">
12
12
  <link rel="stylesheet" crossorigin href="/assets/index-DftJ2WZr.css">
13
13
  </head>
@@ -26416,12 +26416,14 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
26416
26416
  return "";
26417
26417
  }
26418
26418
  function injectMeshSystemMessage(components, args) {
26419
+ let completedTaskForLedger = null;
26419
26420
  if (args.event === "agent:generating_completed") {
26420
26421
  const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
26421
26422
  const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
26422
26423
  const providerType = readNonEmptyString(args.metadataEvent.providerType);
26423
26424
  if (sessionId) {
26424
- updateSessionTaskStatus(args.meshId, sessionId, "completed");
26425
+ const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed");
26426
+ completedTaskForLedger = completedTask ? { id: completedTask.id } : null;
26425
26427
  if (nodeId && providerType) {
26426
26428
  setTimeout(() => {
26427
26429
  tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
@@ -26434,6 +26436,7 @@ function injectMeshSystemMessage(components, args) {
26434
26436
  const providerType = readNonEmptyString(args.metadataEvent.providerType);
26435
26437
  const completedTask = sessionId ? updateSessionTaskStatus(args.meshId, sessionId, "completed") : null;
26436
26438
  if (completedTask) {
26439
+ completedTaskForLedger = { id: completedTask.id };
26437
26440
  try {
26438
26441
  appendLedgerEntry(args.meshId, {
26439
26442
  kind: "task_completed",
@@ -26445,7 +26448,8 @@ function injectMeshSystemMessage(components, args) {
26445
26448
  nodeLabel: args.nodeLabel,
26446
26449
  taskId: completedTask.id,
26447
26450
  completedViaReady: true,
26448
- providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0
26451
+ providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
26452
+ finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
26449
26453
  }
26450
26454
  });
26451
26455
  } catch (e) {
@@ -26488,7 +26492,9 @@ function injectMeshSystemMessage(components, args) {
26488
26492
  payload: {
26489
26493
  event: args.event,
26490
26494
  nodeLabel: args.nodeLabel,
26491
- providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0
26495
+ taskId: completedTaskForLedger?.id || void 0,
26496
+ providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
26497
+ finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
26492
26498
  }
26493
26499
  });
26494
26500
  } catch (e) {
@@ -26603,7 +26609,8 @@ function handleMeshForwardEvent(components, payload) {
26603
26609
  metadataEvent: {
26604
26610
  targetSessionId: readNonEmptyString(payload.targetSessionId) || readNonEmptyString(payload.sessionId) || readNonEmptyString(payload.instanceId),
26605
26611
  providerType: readNonEmptyString(payload.providerType),
26606
- providerSessionId: readNonEmptyString(payload.providerSessionId)
26612
+ providerSessionId: readNonEmptyString(payload.providerSessionId),
26613
+ finalSummary: readNonEmptyString(payload.finalSummary) || readNonEmptyString(payload.summary)
26607
26614
  }
26608
26615
  });
26609
26616
  }
@@ -42098,7 +42105,7 @@ ${lastSnapshot}`;
42098
42105
  }
42099
42106
  getFreshParsedStatusCache() {
42100
42107
  const cached2 = this.parsedStatusCache;
42101
- if (cached2 && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.screenText === this.lastScreenText && cached2.currentStatus === this.currentStatus && cached2.activeModal === this.activeModal && cached2.cliName === this.cliName) {
42108
+ if (cached2 && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.accumulatedRawBuffer === this.accumulatedRawBuffer && cached2.screenText === this.lastScreenText && cached2.currentStatus === this.currentStatus && cached2.activeModal === this.activeModal && cached2.cliName === this.cliName) {
42102
42109
  return cached2.result;
42103
42110
  }
42104
42111
  return null;
@@ -43073,6 +43080,11 @@ ${lastSnapshot}`;
43073
43080
  };
43074
43081
  }
43075
43082
  // ─── Script Execution ──────────────────────────
43083
+ invokeCliScript(script, input) {
43084
+ const hasStateFactory = typeof this.cliScripts?.createState === "function";
43085
+ const expectsStateArgument = hasStateFactory || this.scriptState !== null || script.length >= 2;
43086
+ return expectsStateArgument ? script(this.scriptState, input) : script(input);
43087
+ }
43076
43088
  runParseSession() {
43077
43089
  if (typeof this.cliScripts?.parseSession !== "function") {
43078
43090
  this.parseErrorMessage = `${this.cliType} parseSession unavailable`;
@@ -43093,7 +43105,10 @@ ${lastSnapshot}`;
43093
43105
  scope: this.currentTurnScope,
43094
43106
  runtimeSettings: this.runtimeSettings
43095
43107
  });
43096
- const session = this.cliScripts.parseSession(this.scriptState, { ...input, tail, tailScreen: buildCliScreenSnapshot(tail) });
43108
+ const session = this.invokeCliScript(
43109
+ this.cliScripts.parseSession,
43110
+ { ...input, tail, tailScreen: buildCliScreenSnapshot(tail) }
43111
+ );
43097
43112
  this.parseErrorMessage = null;
43098
43113
  return session && typeof session === "object" ? session : null;
43099
43114
  } catch (e) {
@@ -43107,7 +43122,7 @@ ${lastSnapshot}`;
43107
43122
  if (!this.cliScripts?.detectStatus) return null;
43108
43123
  try {
43109
43124
  const screenText = this.terminalScreen.getText();
43110
- const status = this.cliScripts.detectStatus(this.scriptState, {
43125
+ const status = this.invokeCliScript(this.cliScripts.detectStatus, {
43111
43126
  tail: text.slice(-500),
43112
43127
  screenText,
43113
43128
  rawBuffer: this.accumulatedRawBuffer,
@@ -43126,7 +43141,7 @@ ${lastSnapshot}`;
43126
43141
  try {
43127
43142
  const screenText = this.terminalScreen.getText();
43128
43143
  const buffer = screenText || this.accumulatedBuffer;
43129
- return this.cliScripts.parseApproval(this.scriptState, {
43144
+ return this.invokeCliScript(this.cliScripts.parseApproval, {
43130
43145
  buffer,
43131
43146
  screenText,
43132
43147
  rawBuffer: this.accumulatedRawBuffer,
@@ -43182,7 +43197,7 @@ ${lastSnapshot}`;
43182
43197
  const screenText = this.readTerminalScreenText();
43183
43198
  const parseScreenText = this.getParseScreenText(screenText);
43184
43199
  const cached2 = this.parsedStatusCache;
43185
- if (cached2 && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.screenText === parseScreenText && cached2.currentStatus === this.currentStatus && cached2.activeModal === this.activeModal && cached2.cliName === this.cliName) {
43200
+ if (cached2 && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.accumulatedRawBuffer === this.accumulatedRawBuffer && cached2.screenText === parseScreenText && cached2.currentStatus === this.currentStatus && cached2.activeModal === this.activeModal && cached2.cliName === this.cliName) {
43186
43201
  return cached2.result;
43187
43202
  }
43188
43203
  const parsed = this.runParseSession();
@@ -43210,6 +43225,7 @@ ${lastSnapshot}`;
43210
43225
  currentTurnScope: this.currentTurnScope,
43211
43226
  recentOutputBuffer: this.recentOutputBuffer,
43212
43227
  accumulatedBuffer: this.accumulatedBuffer,
43228
+ accumulatedRawBuffer: this.accumulatedRawBuffer,
43213
43229
  screenText: parseScreenText,
43214
43230
  currentStatus: this.currentStatus,
43215
43231
  activeModal: this.activeModal,
@@ -53375,7 +53391,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
53375
53391
  appendLedgerEntry2(meshId, {
53376
53392
  kind: "node_removed",
53377
53393
  nodeId,
53378
- payload: { worktree: !!node?.isLocalWorktree, sessionCleanupMode }
53394
+ payload: {
53395
+ worktree: !!node?.isLocalWorktree,
53396
+ sessionCleanupMode,
53397
+ workspace: typeof node?.workspace === "string" ? node.workspace : void 0,
53398
+ daemonId: typeof node?.daemonId === "string" ? node.daemonId : void 0,
53399
+ worktreeBranch: typeof node?.worktreeBranch === "string" ? node.worktreeBranch : void 0
53400
+ }
53379
53401
  });
53380
53402
  } catch {
53381
53403
  }
@@ -57531,6 +57553,11 @@ function annotateRapidReadChatAdvisory(payload, options) {
57531
57553
  // src/tools/mesh-tools.ts
57532
57554
  init_dist2();
57533
57555
  var meshSessionProviderMetadata = /* @__PURE__ */ new Map();
57556
+ function readString(value) {
57557
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
57558
+ }
57559
+ var DUPLICATE_DISPATCH_WINDOW_MS = 6e4;
57560
+ var STALE_ASSIGNED_QUEUE_MS = 30 * 6e4;
57534
57561
  async function refreshMeshFromDaemon(ctx) {
57535
57562
  if (!(ctx.transport instanceof IpcTransport)) return;
57536
57563
  try {
@@ -57551,6 +57578,138 @@ async function findNodeWithRefresh(ctx, nodeId) {
57551
57578
  if (!refreshed) throw new Error(`Node '${nodeId}' is not a member of mesh '${ctx.mesh.name}'`);
57552
57579
  return refreshed;
57553
57580
  }
57581
+ async function findOptionalNodeWithRefresh(ctx, nodeId) {
57582
+ const hit = ctx.mesh.nodes.find((n) => n.id === nodeId);
57583
+ if (hit) return hit;
57584
+ await refreshMeshFromDaemon(ctx);
57585
+ return ctx.mesh.nodes.find((n) => n.id === nodeId) ?? null;
57586
+ }
57587
+ function hasRecentDuplicateDispatch(ctx, args) {
57588
+ const now = Date.now();
57589
+ const normalizedMessage = args.message.trim();
57590
+ for (const task of getQueue(ctx.mesh.id)) {
57591
+ const timestamp2 = new Date(task.updatedAt || task.createdAt).getTime();
57592
+ if (!Number.isFinite(timestamp2) || now - timestamp2 > DUPLICATE_DISPATCH_WINDOW_MS) continue;
57593
+ if (task.targetNodeId && task.targetNodeId !== args.node_id) continue;
57594
+ if (task.assignedNodeId && task.assignedNodeId !== args.node_id) continue;
57595
+ if (args.session_id && task.targetSessionId !== args.session_id && task.assignedSessionId !== args.session_id) continue;
57596
+ if (task.message?.trim() === normalizedMessage) {
57597
+ return { duplicate: true, entry: task, source: "queue" };
57598
+ }
57599
+ }
57600
+ const entries = readLedgerEntries(ctx.mesh.id, { tail: 200 });
57601
+ for (let i = entries.length - 1; i >= 0; i -= 1) {
57602
+ const entry = entries[i];
57603
+ const timestamp2 = new Date(entry.timestamp).getTime();
57604
+ if (Number.isFinite(timestamp2) && now - timestamp2 > DUPLICATE_DISPATCH_WINDOW_MS) break;
57605
+ if (entry.kind !== "task_dispatched") continue;
57606
+ if (entry.nodeId !== args.node_id) continue;
57607
+ if (args.session_id && entry.sessionId !== args.session_id) continue;
57608
+ if (typeof entry.payload?.message !== "string") continue;
57609
+ if (entry.payload.message.trim() === normalizedMessage) {
57610
+ return { duplicate: true, entry, source: "ledger" };
57611
+ }
57612
+ }
57613
+ return { duplicate: false };
57614
+ }
57615
+ function buildMissingNodeReadChatRecovery(ctx, args) {
57616
+ const entries = readLedgerEntries(ctx.mesh.id, { tail: 300 });
57617
+ const relatedEntries = entries.filter((entry) => entry.nodeId === args.node_id || entry.sessionId === args.session_id);
57618
+ const completedEntries = relatedEntries.filter((entry) => entry.kind === "task_completed");
57619
+ const lastDispatch = [...relatedEntries].reverse().find((entry) => entry.kind === "task_dispatched");
57620
+ const lastTerminal = [...relatedEntries].reverse().find((entry) => entry.kind === "task_completed" || entry.kind === "task_failed" || entry.kind === "task_stalled");
57621
+ const lastRemoved = [...relatedEntries].reverse().find((entry) => entry.kind === "node_removed");
57622
+ const lastLaunch = [...relatedEntries].reverse().find((entry) => entry.kind === "session_launched");
57623
+ const providerSessionId = args.provider_session_id || readString(lastTerminal?.payload?.providerSessionId) || readString(lastLaunch?.payload?.providerSessionId) || readString(lastDispatch?.payload?.providerSessionId);
57624
+ const finalSummary = readString(lastTerminal?.payload?.finalSummary) || readString(lastTerminal?.payload?.compactSummary) || readString(lastTerminal?.payload?.summary);
57625
+ const ledger = {
57626
+ taskCompletedFound: completedEntries.length > 0,
57627
+ nodeRemovedFound: !!lastRemoved,
57628
+ providerType: lastTerminal?.providerType || lastLaunch?.providerType || lastDispatch?.providerType,
57629
+ providerSessionId,
57630
+ nodeRemovedAt: lastRemoved?.timestamp,
57631
+ sessionCleanupMode: readString(lastRemoved?.payload?.sessionCleanupMode),
57632
+ readDebugLocator: readString(lastTerminal?.payload?.readDebugLocator) || readString(lastTerminal?.payload?.debugBundlePath)
57633
+ };
57634
+ if (finalSummary) {
57635
+ return {
57636
+ success: true,
57637
+ compact: args.compact === true,
57638
+ recoveredFromLedger: true,
57639
+ nodeId: args.node_id,
57640
+ sessionId: args.session_id,
57641
+ summary: finalSummary,
57642
+ ledger,
57643
+ messages: [{ role: "assistant", content: finalSummary, isHistorical: true }]
57644
+ };
57645
+ }
57646
+ return {
57647
+ success: false,
57648
+ recoverable: true,
57649
+ code: "mesh_removed_node_transcript_unavailable",
57650
+ error: `Node '${args.node_id}' is not a current member of mesh '${ctx.mesh.name}'.`,
57651
+ nodeId: args.node_id,
57652
+ sessionId: args.session_id,
57653
+ providerSessionId,
57654
+ reason: "node_not_in_current_mesh_snapshot",
57655
+ ledger,
57656
+ completedSessionSeenInLedger: ledger.taskCompletedFound,
57657
+ lastDispatch: lastDispatch ? {
57658
+ timestamp: lastDispatch.timestamp,
57659
+ sessionId: lastDispatch.sessionId,
57660
+ providerType: lastDispatch.providerType,
57661
+ taskId: typeof lastDispatch.payload?.taskId === "string" ? lastDispatch.payload.taskId : void 0,
57662
+ messagePreview: typeof lastDispatch.payload?.message === "string" ? lastDispatch.payload.message.slice(0, 500) : void 0
57663
+ } : null,
57664
+ lastTerminalEvent: lastTerminal ? {
57665
+ kind: lastTerminal.kind,
57666
+ timestamp: lastTerminal.timestamp,
57667
+ sessionId: lastTerminal.sessionId,
57668
+ providerType: lastTerminal.providerType,
57669
+ taskId: typeof lastTerminal.payload?.taskId === "string" ? lastTerminal.payload.taskId : void 0,
57670
+ payload: lastTerminal.payload
57671
+ } : null,
57672
+ nextSteps: [
57673
+ providerSessionId ? `Retry mesh_read_chat with provider_session_id='${providerSessionId}' on a current live node for the same daemon if one exists.` : "If the node UI shows a provider transcript id, retry mesh_read_chat/mesh_read_debug with provider_session_id.",
57674
+ "Use mesh_read_debug with the provider_session_id or daemon-side debug bundle locator if available.",
57675
+ "Check mesh_task_history for task_completed and node_removed entries before redispatching; do not resend solely because transcript recovery failed.",
57676
+ "If this node was removed with stop_and_delete, the runtime transcript may be gone; rely on the ledger summary/locator or ask the operator for the saved UI output."
57677
+ ],
57678
+ recoveryHints: [
57679
+ "The worktree/node may have been removed or the mesh snapshot may be stale after task completion.",
57680
+ "If you have a provider_session_id, retry mesh_read_chat with that value while targeting a live node for the same daemon if available.",
57681
+ "Use mesh_read_debug with provider_session_id, or inspect the daemon/session-host history locator if the transcript has already been archived.",
57682
+ "Avoid redispatching the same task solely because read_chat could not recover the transcript; check task_history and git status first."
57683
+ ]
57684
+ };
57685
+ }
57686
+ function annotateQueueStaleness(queue) {
57687
+ const now = Date.now();
57688
+ return queue.map((task) => {
57689
+ const taskStatus = typeof task?.status === "string" ? task.status : void 0;
57690
+ const annotated = {
57691
+ ...task,
57692
+ taskStatus,
57693
+ dispatchedAt: task?.createdAt,
57694
+ ...taskStatus === "assigned" ? { activeTaskId: task.id } : {},
57695
+ ...taskStatus === "completed" || taskStatus === "failed" ? {
57696
+ isHistorical: true,
57697
+ completedAt: task.updatedAt
57698
+ } : {}
57699
+ };
57700
+ if (taskStatus !== "assigned") return annotated;
57701
+ const updatedAt = new Date(task.updatedAt).getTime();
57702
+ const ageMs = Number.isFinite(updatedAt) ? now - updatedAt : null;
57703
+ if (ageMs === null || ageMs < STALE_ASSIGNED_QUEUE_MS) return annotated;
57704
+ return {
57705
+ ...annotated,
57706
+ stale: true,
57707
+ staleAssigned: true,
57708
+ staleReason: "assigned task has not reached a terminal state within 30 minutes",
57709
+ assignedAgeMs: ageMs
57710
+ };
57711
+ });
57712
+ }
57554
57713
  function unwrapCommandPayload(value) {
57555
57714
  let current = value;
57556
57715
  const seen = /* @__PURE__ */ new Set();
@@ -58180,8 +58339,16 @@ async function meshEnqueueTask(ctx, args) {
58180
58339
  }
58181
58340
  async function meshViewQueue(ctx, args) {
58182
58341
  try {
58183
- const queue = getQueue(ctx.mesh.id, { status: args.status });
58184
- return JSON.stringify({ success: true, queue }, null, 2);
58342
+ const queue = annotateQueueStaleness(getQueue(ctx.mesh.id, { status: args.status }));
58343
+ const staleAssignedTasks = queue.filter((task) => task?.status === "assigned" && task?.staleAssigned);
58344
+ return JSON.stringify({
58345
+ success: true,
58346
+ queue,
58347
+ staleAssignedTasks,
58348
+ staleAssignedCount: staleAssignedTasks.length,
58349
+ // Back-compat alias for callers already reading the first hardening payload.
58350
+ staleAssignments: staleAssignedTasks
58351
+ }, null, 2);
58185
58352
  } catch (e) {
58186
58353
  return JSON.stringify({ success: false, error: e.message });
58187
58354
  }
@@ -58226,6 +58393,24 @@ async function meshSendTask(ctx, args) {
58226
58393
  if (node.policy?.readOnly) {
58227
58394
  return JSON.stringify({ error: `Node '${args.node_id}' is read-only` });
58228
58395
  }
58396
+ const duplicate = hasRecentDuplicateDispatch(ctx, args);
58397
+ if (duplicate.duplicate) {
58398
+ return JSON.stringify({
58399
+ success: true,
58400
+ duplicate: true,
58401
+ dispatched: false,
58402
+ warning: "Duplicate mesh_send_task suppressed: the same node/session/message was dispatched recently.",
58403
+ nodeId: args.node_id,
58404
+ sessionId: args.session_id,
58405
+ source: duplicate.source,
58406
+ previousDispatch: duplicate.entry ? {
58407
+ id: duplicate.entry.id,
58408
+ timestamp: duplicate.entry.timestamp || duplicate.entry.updatedAt || duplicate.entry.createdAt,
58409
+ nodeId: duplicate.entry.nodeId || duplicate.entry.targetNodeId || duplicate.entry.assignedNodeId,
58410
+ sessionId: duplicate.entry.sessionId || duplicate.entry.targetSessionId || duplicate.entry.assignedSessionId
58411
+ } : void 0
58412
+ });
58413
+ }
58229
58414
  try {
58230
58415
  if (!isLocalTransport(ctx.transport) && node.daemonId) {
58231
58416
  const res = await ctx.transport.meshEnqueueTask(node.daemonId, {
@@ -58244,17 +58429,22 @@ async function meshSendTask(ctx, args) {
58244
58429
  providerType: cached2?.providerType
58245
58430
  });
58246
58431
  if (result.success) {
58432
+ const dispatchedSessionId = args.session_id || result.sessionId;
58247
58433
  try {
58248
58434
  appendLedgerEntry(ctx.mesh.id, {
58249
58435
  kind: "task_dispatched",
58250
58436
  nodeId: args.node_id,
58251
- sessionId: result.sessionId,
58252
- payload: { message: args.message, via: "p2p_direct" }
58437
+ sessionId: dispatchedSessionId,
58438
+ payload: {
58439
+ message: args.message,
58440
+ via: "p2p_direct",
58441
+ ...dispatchedSessionId ? { targetSessionId: dispatchedSessionId } : {}
58442
+ }
58253
58443
  });
58254
58444
  } catch {
58255
58445
  }
58256
58446
  }
58257
- return JSON.stringify({ ...result, nodeId: args.node_id });
58447
+ return JSON.stringify({ ...result, nodeId: args.node_id, dispatched: result.success === true });
58258
58448
  }
58259
58449
  if (args.session_id && isLocalTransport(ctx.transport)) {
58260
58450
  const cached2 = meshSessionProviderMetadata.get(meshSessionCacheKey(args.node_id, args.session_id));
@@ -58299,7 +58489,10 @@ async function meshSendTask(ctx, args) {
58299
58489
  }
58300
58490
  }
58301
58491
  async function meshReadChat(ctx, args) {
58302
- const node = await findNodeWithRefresh(ctx, args.node_id);
58492
+ const node = await findOptionalNodeWithRefresh(ctx, args.node_id);
58493
+ if (!node) {
58494
+ return JSON.stringify(buildMissingNodeReadChatRecovery(ctx, args), null, 2);
58495
+ }
58303
58496
  if (isLocalTransport(ctx.transport)) {
58304
58497
  const cached2 = meshSessionProviderMetadata.get(meshSessionCacheKey(args.node_id, args.session_id));
58305
58498
  const providerSessionId = typeof args.provider_session_id === "string" && args.provider_session_id.trim() ? args.provider_session_id.trim() : cached2?.providerSessionId;