@adhdev/daemon-standalone 0.9.77-rc.34 → 0.9.77-rc.35
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-
|
|
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
|
-
|
|
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
|
}
|
|
@@ -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.
|
|
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
|
|
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
|
|
43144
|
+
return this.invokeCliScript(this.cliScripts.parseApproval, {
|
|
43130
43145
|
buffer,
|
|
43131
43146
|
screenText,
|
|
43132
43147
|
rawBuffer: this.accumulatedRawBuffer,
|
|
@@ -53375,7 +53390,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
53375
53390
|
appendLedgerEntry2(meshId, {
|
|
53376
53391
|
kind: "node_removed",
|
|
53377
53392
|
nodeId,
|
|
53378
|
-
payload: {
|
|
53393
|
+
payload: {
|
|
53394
|
+
worktree: !!node?.isLocalWorktree,
|
|
53395
|
+
sessionCleanupMode,
|
|
53396
|
+
workspace: typeof node?.workspace === "string" ? node.workspace : void 0,
|
|
53397
|
+
daemonId: typeof node?.daemonId === "string" ? node.daemonId : void 0,
|
|
53398
|
+
worktreeBranch: typeof node?.worktreeBranch === "string" ? node.worktreeBranch : void 0
|
|
53399
|
+
}
|
|
53379
53400
|
});
|
|
53380
53401
|
} catch {
|
|
53381
53402
|
}
|
|
@@ -57531,6 +57552,11 @@ function annotateRapidReadChatAdvisory(payload, options) {
|
|
|
57531
57552
|
// src/tools/mesh-tools.ts
|
|
57532
57553
|
init_dist2();
|
|
57533
57554
|
var meshSessionProviderMetadata = /* @__PURE__ */ new Map();
|
|
57555
|
+
function readString(value) {
|
|
57556
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
57557
|
+
}
|
|
57558
|
+
var DUPLICATE_DISPATCH_WINDOW_MS = 6e4;
|
|
57559
|
+
var STALE_ASSIGNED_QUEUE_MS = 30 * 6e4;
|
|
57534
57560
|
async function refreshMeshFromDaemon(ctx) {
|
|
57535
57561
|
if (!(ctx.transport instanceof IpcTransport)) return;
|
|
57536
57562
|
try {
|
|
@@ -57551,6 +57577,138 @@ async function findNodeWithRefresh(ctx, nodeId) {
|
|
|
57551
57577
|
if (!refreshed) throw new Error(`Node '${nodeId}' is not a member of mesh '${ctx.mesh.name}'`);
|
|
57552
57578
|
return refreshed;
|
|
57553
57579
|
}
|
|
57580
|
+
async function findOptionalNodeWithRefresh(ctx, nodeId) {
|
|
57581
|
+
const hit = ctx.mesh.nodes.find((n) => n.id === nodeId);
|
|
57582
|
+
if (hit) return hit;
|
|
57583
|
+
await refreshMeshFromDaemon(ctx);
|
|
57584
|
+
return ctx.mesh.nodes.find((n) => n.id === nodeId) ?? null;
|
|
57585
|
+
}
|
|
57586
|
+
function hasRecentDuplicateDispatch(ctx, args) {
|
|
57587
|
+
const now = Date.now();
|
|
57588
|
+
const normalizedMessage = args.message.trim();
|
|
57589
|
+
for (const task of getQueue(ctx.mesh.id)) {
|
|
57590
|
+
const timestamp2 = new Date(task.updatedAt || task.createdAt).getTime();
|
|
57591
|
+
if (!Number.isFinite(timestamp2) || now - timestamp2 > DUPLICATE_DISPATCH_WINDOW_MS) continue;
|
|
57592
|
+
if (task.targetNodeId && task.targetNodeId !== args.node_id) continue;
|
|
57593
|
+
if (task.assignedNodeId && task.assignedNodeId !== args.node_id) continue;
|
|
57594
|
+
if (args.session_id && task.targetSessionId !== args.session_id && task.assignedSessionId !== args.session_id) continue;
|
|
57595
|
+
if (task.message?.trim() === normalizedMessage) {
|
|
57596
|
+
return { duplicate: true, entry: task, source: "queue" };
|
|
57597
|
+
}
|
|
57598
|
+
}
|
|
57599
|
+
const entries = readLedgerEntries(ctx.mesh.id, { tail: 200 });
|
|
57600
|
+
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
57601
|
+
const entry = entries[i];
|
|
57602
|
+
const timestamp2 = new Date(entry.timestamp).getTime();
|
|
57603
|
+
if (Number.isFinite(timestamp2) && now - timestamp2 > DUPLICATE_DISPATCH_WINDOW_MS) break;
|
|
57604
|
+
if (entry.kind !== "task_dispatched") continue;
|
|
57605
|
+
if (entry.nodeId !== args.node_id) continue;
|
|
57606
|
+
if (args.session_id && entry.sessionId !== args.session_id) continue;
|
|
57607
|
+
if (typeof entry.payload?.message !== "string") continue;
|
|
57608
|
+
if (entry.payload.message.trim() === normalizedMessage) {
|
|
57609
|
+
return { duplicate: true, entry, source: "ledger" };
|
|
57610
|
+
}
|
|
57611
|
+
}
|
|
57612
|
+
return { duplicate: false };
|
|
57613
|
+
}
|
|
57614
|
+
function buildMissingNodeReadChatRecovery(ctx, args) {
|
|
57615
|
+
const entries = readLedgerEntries(ctx.mesh.id, { tail: 300 });
|
|
57616
|
+
const relatedEntries = entries.filter((entry) => entry.nodeId === args.node_id || entry.sessionId === args.session_id);
|
|
57617
|
+
const completedEntries = relatedEntries.filter((entry) => entry.kind === "task_completed");
|
|
57618
|
+
const lastDispatch = [...relatedEntries].reverse().find((entry) => entry.kind === "task_dispatched");
|
|
57619
|
+
const lastTerminal = [...relatedEntries].reverse().find((entry) => entry.kind === "task_completed" || entry.kind === "task_failed" || entry.kind === "task_stalled");
|
|
57620
|
+
const lastRemoved = [...relatedEntries].reverse().find((entry) => entry.kind === "node_removed");
|
|
57621
|
+
const lastLaunch = [...relatedEntries].reverse().find((entry) => entry.kind === "session_launched");
|
|
57622
|
+
const providerSessionId = args.provider_session_id || readString(lastTerminal?.payload?.providerSessionId) || readString(lastLaunch?.payload?.providerSessionId) || readString(lastDispatch?.payload?.providerSessionId);
|
|
57623
|
+
const finalSummary = readString(lastTerminal?.payload?.finalSummary) || readString(lastTerminal?.payload?.compactSummary) || readString(lastTerminal?.payload?.summary);
|
|
57624
|
+
const ledger = {
|
|
57625
|
+
taskCompletedFound: completedEntries.length > 0,
|
|
57626
|
+
nodeRemovedFound: !!lastRemoved,
|
|
57627
|
+
providerType: lastTerminal?.providerType || lastLaunch?.providerType || lastDispatch?.providerType,
|
|
57628
|
+
providerSessionId,
|
|
57629
|
+
nodeRemovedAt: lastRemoved?.timestamp,
|
|
57630
|
+
sessionCleanupMode: readString(lastRemoved?.payload?.sessionCleanupMode),
|
|
57631
|
+
readDebugLocator: readString(lastTerminal?.payload?.readDebugLocator) || readString(lastTerminal?.payload?.debugBundlePath)
|
|
57632
|
+
};
|
|
57633
|
+
if (finalSummary) {
|
|
57634
|
+
return {
|
|
57635
|
+
success: true,
|
|
57636
|
+
compact: args.compact === true,
|
|
57637
|
+
recoveredFromLedger: true,
|
|
57638
|
+
nodeId: args.node_id,
|
|
57639
|
+
sessionId: args.session_id,
|
|
57640
|
+
summary: finalSummary,
|
|
57641
|
+
ledger,
|
|
57642
|
+
messages: [{ role: "assistant", content: finalSummary, isHistorical: true }]
|
|
57643
|
+
};
|
|
57644
|
+
}
|
|
57645
|
+
return {
|
|
57646
|
+
success: false,
|
|
57647
|
+
recoverable: true,
|
|
57648
|
+
code: "mesh_removed_node_transcript_unavailable",
|
|
57649
|
+
error: `Node '${args.node_id}' is not a current member of mesh '${ctx.mesh.name}'.`,
|
|
57650
|
+
nodeId: args.node_id,
|
|
57651
|
+
sessionId: args.session_id,
|
|
57652
|
+
providerSessionId,
|
|
57653
|
+
reason: "node_not_in_current_mesh_snapshot",
|
|
57654
|
+
ledger,
|
|
57655
|
+
completedSessionSeenInLedger: ledger.taskCompletedFound,
|
|
57656
|
+
lastDispatch: lastDispatch ? {
|
|
57657
|
+
timestamp: lastDispatch.timestamp,
|
|
57658
|
+
sessionId: lastDispatch.sessionId,
|
|
57659
|
+
providerType: lastDispatch.providerType,
|
|
57660
|
+
taskId: typeof lastDispatch.payload?.taskId === "string" ? lastDispatch.payload.taskId : void 0,
|
|
57661
|
+
messagePreview: typeof lastDispatch.payload?.message === "string" ? lastDispatch.payload.message.slice(0, 500) : void 0
|
|
57662
|
+
} : null,
|
|
57663
|
+
lastTerminalEvent: lastTerminal ? {
|
|
57664
|
+
kind: lastTerminal.kind,
|
|
57665
|
+
timestamp: lastTerminal.timestamp,
|
|
57666
|
+
sessionId: lastTerminal.sessionId,
|
|
57667
|
+
providerType: lastTerminal.providerType,
|
|
57668
|
+
taskId: typeof lastTerminal.payload?.taskId === "string" ? lastTerminal.payload.taskId : void 0,
|
|
57669
|
+
payload: lastTerminal.payload
|
|
57670
|
+
} : null,
|
|
57671
|
+
nextSteps: [
|
|
57672
|
+
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.",
|
|
57673
|
+
"Use mesh_read_debug with the provider_session_id or daemon-side debug bundle locator if available.",
|
|
57674
|
+
"Check mesh_task_history for task_completed and node_removed entries before redispatching; do not resend solely because transcript recovery failed.",
|
|
57675
|
+
"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."
|
|
57676
|
+
],
|
|
57677
|
+
recoveryHints: [
|
|
57678
|
+
"The worktree/node may have been removed or the mesh snapshot may be stale after task completion.",
|
|
57679
|
+
"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.",
|
|
57680
|
+
"Use mesh_read_debug with provider_session_id, or inspect the daemon/session-host history locator if the transcript has already been archived.",
|
|
57681
|
+
"Avoid redispatching the same task solely because read_chat could not recover the transcript; check task_history and git status first."
|
|
57682
|
+
]
|
|
57683
|
+
};
|
|
57684
|
+
}
|
|
57685
|
+
function annotateQueueStaleness(queue) {
|
|
57686
|
+
const now = Date.now();
|
|
57687
|
+
return queue.map((task) => {
|
|
57688
|
+
const taskStatus = typeof task?.status === "string" ? task.status : void 0;
|
|
57689
|
+
const annotated = {
|
|
57690
|
+
...task,
|
|
57691
|
+
taskStatus,
|
|
57692
|
+
dispatchedAt: task?.createdAt,
|
|
57693
|
+
...taskStatus === "assigned" ? { activeTaskId: task.id } : {},
|
|
57694
|
+
...taskStatus === "completed" || taskStatus === "failed" ? {
|
|
57695
|
+
isHistorical: true,
|
|
57696
|
+
completedAt: task.updatedAt
|
|
57697
|
+
} : {}
|
|
57698
|
+
};
|
|
57699
|
+
if (taskStatus !== "assigned") return annotated;
|
|
57700
|
+
const updatedAt = new Date(task.updatedAt).getTime();
|
|
57701
|
+
const ageMs = Number.isFinite(updatedAt) ? now - updatedAt : null;
|
|
57702
|
+
if (ageMs === null || ageMs < STALE_ASSIGNED_QUEUE_MS) return annotated;
|
|
57703
|
+
return {
|
|
57704
|
+
...annotated,
|
|
57705
|
+
stale: true,
|
|
57706
|
+
staleAssigned: true,
|
|
57707
|
+
staleReason: "assigned task has not reached a terminal state within 30 minutes",
|
|
57708
|
+
assignedAgeMs: ageMs
|
|
57709
|
+
};
|
|
57710
|
+
});
|
|
57711
|
+
}
|
|
57554
57712
|
function unwrapCommandPayload(value) {
|
|
57555
57713
|
let current = value;
|
|
57556
57714
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -58180,8 +58338,16 @@ async function meshEnqueueTask(ctx, args) {
|
|
|
58180
58338
|
}
|
|
58181
58339
|
async function meshViewQueue(ctx, args) {
|
|
58182
58340
|
try {
|
|
58183
|
-
const queue = getQueue(ctx.mesh.id, { status: args.status });
|
|
58184
|
-
|
|
58341
|
+
const queue = annotateQueueStaleness(getQueue(ctx.mesh.id, { status: args.status }));
|
|
58342
|
+
const staleAssignedTasks = queue.filter((task) => task?.status === "assigned" && task?.staleAssigned);
|
|
58343
|
+
return JSON.stringify({
|
|
58344
|
+
success: true,
|
|
58345
|
+
queue,
|
|
58346
|
+
staleAssignedTasks,
|
|
58347
|
+
staleAssignedCount: staleAssignedTasks.length,
|
|
58348
|
+
// Back-compat alias for callers already reading the first hardening payload.
|
|
58349
|
+
staleAssignments: staleAssignedTasks
|
|
58350
|
+
}, null, 2);
|
|
58185
58351
|
} catch (e) {
|
|
58186
58352
|
return JSON.stringify({ success: false, error: e.message });
|
|
58187
58353
|
}
|
|
@@ -58226,6 +58392,24 @@ async function meshSendTask(ctx, args) {
|
|
|
58226
58392
|
if (node.policy?.readOnly) {
|
|
58227
58393
|
return JSON.stringify({ error: `Node '${args.node_id}' is read-only` });
|
|
58228
58394
|
}
|
|
58395
|
+
const duplicate = hasRecentDuplicateDispatch(ctx, args);
|
|
58396
|
+
if (duplicate.duplicate) {
|
|
58397
|
+
return JSON.stringify({
|
|
58398
|
+
success: true,
|
|
58399
|
+
duplicate: true,
|
|
58400
|
+
dispatched: false,
|
|
58401
|
+
warning: "Duplicate mesh_send_task suppressed: the same node/session/message was dispatched recently.",
|
|
58402
|
+
nodeId: args.node_id,
|
|
58403
|
+
sessionId: args.session_id,
|
|
58404
|
+
source: duplicate.source,
|
|
58405
|
+
previousDispatch: duplicate.entry ? {
|
|
58406
|
+
id: duplicate.entry.id,
|
|
58407
|
+
timestamp: duplicate.entry.timestamp || duplicate.entry.updatedAt || duplicate.entry.createdAt,
|
|
58408
|
+
nodeId: duplicate.entry.nodeId || duplicate.entry.targetNodeId || duplicate.entry.assignedNodeId,
|
|
58409
|
+
sessionId: duplicate.entry.sessionId || duplicate.entry.targetSessionId || duplicate.entry.assignedSessionId
|
|
58410
|
+
} : void 0
|
|
58411
|
+
});
|
|
58412
|
+
}
|
|
58229
58413
|
try {
|
|
58230
58414
|
if (!isLocalTransport(ctx.transport) && node.daemonId) {
|
|
58231
58415
|
const res = await ctx.transport.meshEnqueueTask(node.daemonId, {
|
|
@@ -58244,17 +58428,22 @@ async function meshSendTask(ctx, args) {
|
|
|
58244
58428
|
providerType: cached2?.providerType
|
|
58245
58429
|
});
|
|
58246
58430
|
if (result.success) {
|
|
58431
|
+
const dispatchedSessionId = args.session_id || result.sessionId;
|
|
58247
58432
|
try {
|
|
58248
58433
|
appendLedgerEntry(ctx.mesh.id, {
|
|
58249
58434
|
kind: "task_dispatched",
|
|
58250
58435
|
nodeId: args.node_id,
|
|
58251
|
-
sessionId:
|
|
58252
|
-
payload: {
|
|
58436
|
+
sessionId: dispatchedSessionId,
|
|
58437
|
+
payload: {
|
|
58438
|
+
message: args.message,
|
|
58439
|
+
via: "p2p_direct",
|
|
58440
|
+
...dispatchedSessionId ? { targetSessionId: dispatchedSessionId } : {}
|
|
58441
|
+
}
|
|
58253
58442
|
});
|
|
58254
58443
|
} catch {
|
|
58255
58444
|
}
|
|
58256
58445
|
}
|
|
58257
|
-
return JSON.stringify({ ...result, nodeId: args.node_id });
|
|
58446
|
+
return JSON.stringify({ ...result, nodeId: args.node_id, dispatched: result.success === true });
|
|
58258
58447
|
}
|
|
58259
58448
|
if (args.session_id && isLocalTransport(ctx.transport)) {
|
|
58260
58449
|
const cached2 = meshSessionProviderMetadata.get(meshSessionCacheKey(args.node_id, args.session_id));
|
|
@@ -58299,7 +58488,10 @@ async function meshSendTask(ctx, args) {
|
|
|
58299
58488
|
}
|
|
58300
58489
|
}
|
|
58301
58490
|
async function meshReadChat(ctx, args) {
|
|
58302
|
-
const node = await
|
|
58491
|
+
const node = await findOptionalNodeWithRefresh(ctx, args.node_id);
|
|
58492
|
+
if (!node) {
|
|
58493
|
+
return JSON.stringify(buildMissingNodeReadChatRecovery(ctx, args), null, 2);
|
|
58494
|
+
}
|
|
58303
58495
|
if (isLocalTransport(ctx.transport)) {
|
|
58304
58496
|
const cached2 = meshSessionProviderMetadata.get(meshSessionCacheKey(args.node_id, args.session_id));
|
|
58305
58497
|
const providerSessionId = typeof args.provider_session_id === "string" && args.provider_session_id.trim() ? args.provider_session_id.trim() : cached2?.providerSessionId;
|