@adhdev/daemon-standalone 0.9.82-rc.121 → 0.9.82-rc.122
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/index.js +268 -33
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/index--3Wc6sJr.js +100 -0
- package/public/index.html +1 -1
- package/vendor/mcp-server/index.js +61 -3
- package/vendor/mcp-server/index.js.map +1 -1
package/dist/index.js
CHANGED
|
@@ -24713,7 +24713,7 @@ Follow these recovery rules:
|
|
|
24713
24713
|
if (!REFINE_TERMINAL_EVENTS.has(event.event)) return false;
|
|
24714
24714
|
const jobId = readRefineJobId(event);
|
|
24715
24715
|
if (!jobId) return false;
|
|
24716
|
-
return
|
|
24716
|
+
return readPendingMeshCoordinatorEventsFromDisk(event.meshId).some(
|
|
24717
24717
|
(pending) => pending.event === event.event && readRefineJobId(pending) === jobId
|
|
24718
24718
|
);
|
|
24719
24719
|
}
|
|
@@ -24738,12 +24738,91 @@ Follow these recovery rules:
|
|
|
24738
24738
|
function hasPendingCoordinatorEventDuplicate(event) {
|
|
24739
24739
|
const fingerprint = buildPendingEventFingerprint(event);
|
|
24740
24740
|
if (!fingerprint.trim()) return false;
|
|
24741
|
-
return
|
|
24741
|
+
return readPendingMeshCoordinatorEventsFromDisk(event.meshId).some((pending) => buildPendingEventFingerprint(pending) === fingerprint);
|
|
24742
24742
|
}
|
|
24743
24743
|
function getPendingEventsPath(meshId) {
|
|
24744
24744
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
24745
24745
|
return (0, import_path7.join)(getLedgerDir(), `${safe}.pending-events.jsonl`);
|
|
24746
24746
|
}
|
|
24747
|
+
function readPendingMeshCoordinatorEventsFromDisk(meshId) {
|
|
24748
|
+
if (!meshId) return [];
|
|
24749
|
+
const path28 = getPendingEventsPath(meshId);
|
|
24750
|
+
if (!(0, import_fs8.existsSync)(path28)) return [];
|
|
24751
|
+
try {
|
|
24752
|
+
const raw = (0, import_fs8.readFileSync)(path28, "utf-8");
|
|
24753
|
+
return raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
24754
|
+
try {
|
|
24755
|
+
return [JSON.parse(line)];
|
|
24756
|
+
} catch {
|
|
24757
|
+
return [];
|
|
24758
|
+
}
|
|
24759
|
+
});
|
|
24760
|
+
} catch {
|
|
24761
|
+
return [];
|
|
24762
|
+
}
|
|
24763
|
+
}
|
|
24764
|
+
function refineTerminalEventFromLedger(meshId, pending) {
|
|
24765
|
+
const acceptedJobIds = new Set(
|
|
24766
|
+
pending.filter((event) => event.event === "refine:accepted").map((event) => readRefineJobId(event)).filter(Boolean)
|
|
24767
|
+
);
|
|
24768
|
+
if (acceptedJobIds.size === 0) return [];
|
|
24769
|
+
const existingTerminalJobIds = new Set(
|
|
24770
|
+
pending.filter((event) => REFINE_TERMINAL_EVENTS.has(event.event)).map((event) => `${event.event}:${readRefineJobId(event)}`).filter((value) => !value.endsWith(":"))
|
|
24771
|
+
);
|
|
24772
|
+
const backfilled = [];
|
|
24773
|
+
const entries = readLedgerEntries(meshId);
|
|
24774
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
24775
|
+
const entry = entries[i];
|
|
24776
|
+
if (entry.kind !== "task_completed" && entry.kind !== "task_failed") continue;
|
|
24777
|
+
const payload = readRecord2(entry.payload);
|
|
24778
|
+
if (payload?.source !== "refine_mesh_node_async_job") continue;
|
|
24779
|
+
const refineJob = readRecord2(payload.refineJob);
|
|
24780
|
+
const jobId = readNonEmptyString2(refineJob?.jobId);
|
|
24781
|
+
if (!jobId || !acceptedJobIds.has(jobId)) continue;
|
|
24782
|
+
const eventName = entry.kind === "task_completed" ? "refine:completed" : "refine:failed";
|
|
24783
|
+
if (existingTerminalJobIds.has(`${eventName}:${jobId}`)) continue;
|
|
24784
|
+
existingTerminalJobIds.add(`${eventName}:${jobId}`);
|
|
24785
|
+
const result = readRecord2(payload.result);
|
|
24786
|
+
const metadataEvent = {
|
|
24787
|
+
source: "refine_mesh_node_async_job",
|
|
24788
|
+
jobId,
|
|
24789
|
+
interactionId: readNonEmptyString2(refineJob?.interactionId),
|
|
24790
|
+
meshId,
|
|
24791
|
+
nodeId: readNonEmptyString2(refineJob?.nodeId) || entry.nodeId,
|
|
24792
|
+
targetDaemonId: readNonEmptyString2(refineJob?.targetDaemonId),
|
|
24793
|
+
workspace: readNonEmptyString2(refineJob?.workspace),
|
|
24794
|
+
status: eventName === "refine:completed" ? "completed" : "failed",
|
|
24795
|
+
startedAt: readNonEmptyString2(refineJob?.startedAt),
|
|
24796
|
+
completedAt: readNonEmptyString2(refineJob?.completedAt) || entry.timestamp,
|
|
24797
|
+
retryOfJobId: readNonEmptyString2(refineJob?.retryOfJobId) || readNonEmptyString2(payload.retryOfJobId),
|
|
24798
|
+
...result ? { result } : {}
|
|
24799
|
+
};
|
|
24800
|
+
backfilled.push({
|
|
24801
|
+
event: eventName,
|
|
24802
|
+
meshId,
|
|
24803
|
+
nodeLabel: readNonEmptyString2(refineJob?.nodeId) || entry.nodeId || "refine job",
|
|
24804
|
+
nodeId: readNonEmptyString2(refineJob?.nodeId) || entry.nodeId,
|
|
24805
|
+
workspace: readNonEmptyString2(refineJob?.workspace),
|
|
24806
|
+
metadataEvent,
|
|
24807
|
+
coordinatorMessage: buildMeshSystemMessage({
|
|
24808
|
+
event: eventName,
|
|
24809
|
+
nodeLabel: readNonEmptyString2(refineJob?.nodeId) || entry.nodeId || "refine job",
|
|
24810
|
+
metadataEvent
|
|
24811
|
+
}),
|
|
24812
|
+
queuedAt: Date.now()
|
|
24813
|
+
});
|
|
24814
|
+
}
|
|
24815
|
+
return backfilled.reverse();
|
|
24816
|
+
}
|
|
24817
|
+
function reconcilePendingMeshCoordinatorEvents(meshId, events) {
|
|
24818
|
+
const backfilled = refineTerminalEventFromLedger(meshId, events);
|
|
24819
|
+
if (backfilled.length === 0) return events;
|
|
24820
|
+
const terminalJobIds = new Set(backfilled.map((event) => readRefineJobId(event)).filter(Boolean));
|
|
24821
|
+
return [
|
|
24822
|
+
...events.filter((event) => !(event.event === "refine:accepted" && terminalJobIds.has(readRefineJobId(event)))),
|
|
24823
|
+
...backfilled
|
|
24824
|
+
];
|
|
24825
|
+
}
|
|
24747
24826
|
function queuePendingMeshCoordinatorEvent(event) {
|
|
24748
24827
|
try {
|
|
24749
24828
|
if (hasPendingRefineTerminalEventDuplicate(event)) {
|
|
@@ -24766,38 +24845,19 @@ Follow these recovery rules:
|
|
|
24766
24845
|
const path28 = getPendingEventsPath(meshId);
|
|
24767
24846
|
if (!(0, import_fs8.existsSync)(path28)) return [];
|
|
24768
24847
|
try {
|
|
24769
|
-
const
|
|
24848
|
+
const parsed = readPendingMeshCoordinatorEventsFromDisk(meshId);
|
|
24770
24849
|
try {
|
|
24771
24850
|
(0, import_fs8.unlinkSync)(path28);
|
|
24772
24851
|
} catch {
|
|
24773
24852
|
}
|
|
24774
|
-
return
|
|
24775
|
-
try {
|
|
24776
|
-
return [JSON.parse(line)];
|
|
24777
|
-
} catch {
|
|
24778
|
-
return [];
|
|
24779
|
-
}
|
|
24780
|
-
});
|
|
24853
|
+
return reconcilePendingMeshCoordinatorEvents(meshId, parsed);
|
|
24781
24854
|
} catch {
|
|
24782
24855
|
return [];
|
|
24783
24856
|
}
|
|
24784
24857
|
}
|
|
24785
24858
|
function getPendingMeshCoordinatorEvents(meshId) {
|
|
24786
24859
|
if (!meshId) return [];
|
|
24787
|
-
|
|
24788
|
-
if (!(0, import_fs8.existsSync)(path28)) return [];
|
|
24789
|
-
try {
|
|
24790
|
-
const raw = (0, import_fs8.readFileSync)(path28, "utf-8");
|
|
24791
|
-
return raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
24792
|
-
try {
|
|
24793
|
-
return [JSON.parse(line)];
|
|
24794
|
-
} catch {
|
|
24795
|
-
return [];
|
|
24796
|
-
}
|
|
24797
|
-
});
|
|
24798
|
-
} catch {
|
|
24799
|
-
return [];
|
|
24800
|
-
}
|
|
24860
|
+
return reconcilePendingMeshCoordinatorEvents(meshId, readPendingMeshCoordinatorEventsFromDisk(meshId));
|
|
24801
24861
|
}
|
|
24802
24862
|
function clearPendingMeshCoordinatorEvents(meshId) {
|
|
24803
24863
|
if (!meshId) return;
|
|
@@ -24902,6 +24962,62 @@ Follow these recovery rules:
|
|
|
24902
24962
|
recentCompletionFingerprints.set(fingerprint, now);
|
|
24903
24963
|
return false;
|
|
24904
24964
|
}
|
|
24965
|
+
function findRecentTerminalLedgerEvidence(args) {
|
|
24966
|
+
if (!args.sessionId && !args.nodeId) return null;
|
|
24967
|
+
const entries = readLedgerEntries(args.meshId);
|
|
24968
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
24969
|
+
const entry = entries[i];
|
|
24970
|
+
if (entry.kind !== "task_completed" && entry.kind !== "task_failed" && entry.kind !== "task_stalled") continue;
|
|
24971
|
+
if (args.sessionId && entry.sessionId === args.sessionId) {
|
|
24972
|
+
return { kind: entry.kind, payload: entry.payload || {}, timestamp: entry.timestamp };
|
|
24973
|
+
}
|
|
24974
|
+
if (!args.sessionId && args.nodeId && entry.nodeId === args.nodeId) {
|
|
24975
|
+
return { kind: entry.kind, payload: entry.payload || {}, timestamp: entry.timestamp };
|
|
24976
|
+
}
|
|
24977
|
+
}
|
|
24978
|
+
return null;
|
|
24979
|
+
}
|
|
24980
|
+
function buildLongGeneratingCompletionReconciliation(args) {
|
|
24981
|
+
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
24982
|
+
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
24983
|
+
const providerType = readNonEmptyString2(args.metadataEvent.providerType);
|
|
24984
|
+
const providerSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId);
|
|
24985
|
+
const workerResult = readWorkerResultMetadata(args.metadataEvent);
|
|
24986
|
+
const completionDiagnostic = readRecord2(args.metadataEvent.completionDiagnostic);
|
|
24987
|
+
const finalSummary = readNonEmptyString2(args.metadataEvent.finalSummary);
|
|
24988
|
+
const status = readNonEmptyString2(args.metadataEvent.status).toLowerCase();
|
|
24989
|
+
const explicitCompletionEvidence = Boolean(
|
|
24990
|
+
finalSummary || workerResult || completionDiagnostic?.finalAssistantPresent === true || status === "idle" || status === "ready" || status === "completed"
|
|
24991
|
+
);
|
|
24992
|
+
if (explicitCompletionEvidence) {
|
|
24993
|
+
return {
|
|
24994
|
+
...args.metadataEvent,
|
|
24995
|
+
targetSessionId: sessionId,
|
|
24996
|
+
providerType,
|
|
24997
|
+
providerSessionId,
|
|
24998
|
+
finalSummary,
|
|
24999
|
+
source: "long_generating_reconciliation",
|
|
25000
|
+
reconciledFromEvent: "monitor:long_generating",
|
|
25001
|
+
timestamp: args.metadataEvent.timestamp ?? Date.now(),
|
|
25002
|
+
completionDiagnostic: {
|
|
25003
|
+
...completionDiagnostic || {},
|
|
25004
|
+
reconciliationReason: "provider_completion_evidence"
|
|
25005
|
+
}
|
|
25006
|
+
};
|
|
25007
|
+
}
|
|
25008
|
+
const terminal = findRecentTerminalLedgerEvidence({
|
|
25009
|
+
meshId: args.meshId,
|
|
25010
|
+
sessionId: sessionId || void 0,
|
|
25011
|
+
nodeId: nodeId || void 0
|
|
25012
|
+
});
|
|
25013
|
+
if (!terminal) return null;
|
|
25014
|
+
return {
|
|
25015
|
+
...args.metadataEvent,
|
|
25016
|
+
source: "long_generating_terminal_ledger_suppression",
|
|
25017
|
+
terminalLedgerKind: terminal.kind,
|
|
25018
|
+
terminalLedgerAt: terminal.timestamp
|
|
25019
|
+
};
|
|
25020
|
+
}
|
|
24905
25021
|
function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType) {
|
|
24906
25022
|
const task = claimNextTask(meshId, nodeId, sessionId);
|
|
24907
25023
|
if (!task) {
|
|
@@ -24995,6 +25111,9 @@ Follow these recovery rules:
|
|
|
24995
25111
|
function nodeHasActiveAssignment(meshId, nodeId) {
|
|
24996
25112
|
return getQueue(meshId, { status: ["assigned"] }).some((task) => task.assignedNodeId === nodeId);
|
|
24997
25113
|
}
|
|
25114
|
+
function sessionHasActiveAssignment(meshId, sessionId) {
|
|
25115
|
+
return getQueue(meshId, { status: ["assigned"] }).some((task) => task.assignedSessionId === sessionId);
|
|
25116
|
+
}
|
|
24998
25117
|
function liveSessionCountForNode(components, meshId, nodeId) {
|
|
24999
25118
|
return components.instanceManager.getByCategory("cli").filter((inst) => {
|
|
25000
25119
|
const state = inst.getState();
|
|
@@ -25205,6 +25324,9 @@ Follow these recovery rules:
|
|
|
25205
25324
|
function buildMeshSystemMessage(args) {
|
|
25206
25325
|
const metadata = formatCompletionMetadata(args.metadataEvent);
|
|
25207
25326
|
if (args.event === "agent:generating_completed") {
|
|
25327
|
+
if (args.metadataEvent.source === "long_generating_reconciliation") {
|
|
25328
|
+
return `[System] ${args.nodeLabel} already has completion evidence${metadata}. The long-generating monitor reconciled the terminal handoff and marked the session complete; wait for the queued completion event/status refresh before doing any manual transcript check.`;
|
|
25329
|
+
}
|
|
25208
25330
|
return `[System] ${args.nodeLabel} has completed its task and is now idle${metadata}. This completion came from the agent status event path; use mesh_read_chat once to review its final progress, but do not poll repeatedly.`;
|
|
25209
25331
|
}
|
|
25210
25332
|
if (args.event === "agent:waiting_approval") {
|
|
@@ -25242,7 +25364,7 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
25242
25364
|
return `[System] ${args.nodeLabel} has stopped${metadata}. Use mesh_read_chat once if you need to inspect its last output.`;
|
|
25243
25365
|
}
|
|
25244
25366
|
if (args.event === "monitor:long_generating") {
|
|
25245
|
-
return `[System] ${args.nodeLabel}
|
|
25367
|
+
return `[System] ${args.nodeLabel} is still reported as generating after a long interval${metadata}. Wait for pendingCoordinatorEvents or a completion/status event; if the user explicitly asks for status, make one bounded status check and then wait again.`;
|
|
25246
25368
|
}
|
|
25247
25369
|
if (args.event === "refine:accepted") {
|
|
25248
25370
|
const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
|
|
@@ -25320,12 +25442,54 @@ Next step: ${nextStep}`;
|
|
|
25320
25442
|
LOG2.info("MeshEvents", `Suppressed ${args.event} for intentionally cleanup-stopped session ${eventSessionId || "(unknown session)"}`);
|
|
25321
25443
|
return { success: true, forwarded: 0, suppressed: true, intentionalCleanupStop: true };
|
|
25322
25444
|
}
|
|
25445
|
+
if (args.event === "monitor:long_generating") {
|
|
25446
|
+
const reconciledCompletion = buildLongGeneratingCompletionReconciliation({
|
|
25447
|
+
meshId: args.meshId,
|
|
25448
|
+
nodeId: args.nodeId,
|
|
25449
|
+
nodeLabel: args.nodeLabel,
|
|
25450
|
+
metadataEvent: args.metadataEvent,
|
|
25451
|
+
sourceInstanceId: args.sourceInstanceId
|
|
25452
|
+
});
|
|
25453
|
+
if (reconciledCompletion?.source === "long_generating_reconciliation") {
|
|
25454
|
+
LOG2.info("MeshEvents", `Reconciled long-generating monitor to completion for session ${eventSessionId || "(unknown session)"}`);
|
|
25455
|
+
return injectMeshSystemMessage(components, {
|
|
25456
|
+
...args,
|
|
25457
|
+
event: "agent:generating_completed",
|
|
25458
|
+
metadataEvent: reconciledCompletion
|
|
25459
|
+
});
|
|
25460
|
+
}
|
|
25461
|
+
if (reconciledCompletion?.source === "long_generating_terminal_ledger_suppression") {
|
|
25462
|
+
LOG2.info("MeshEvents", `Suppressed long-generating monitor because terminal ledger evidence already exists for session ${eventSessionId || "(unknown session)"}`);
|
|
25463
|
+
return {
|
|
25464
|
+
success: true,
|
|
25465
|
+
forwarded: 0,
|
|
25466
|
+
suppressed: true,
|
|
25467
|
+
terminalLedgerEvidence: true,
|
|
25468
|
+
terminalLedgerKind: reconciledCompletion.terminalLedgerKind
|
|
25469
|
+
};
|
|
25470
|
+
}
|
|
25471
|
+
}
|
|
25323
25472
|
if (isDuplicateRefineTerminalEvent(args.meshId, args.event, args.metadataEvent)) {
|
|
25324
25473
|
LOG2.info("MeshEvents", `Suppressed duplicate ${args.event} for refine job ${readRefineJobId({ metadataEvent: args.metadataEvent })}`);
|
|
25325
25474
|
return { success: true, forwarded: 0, suppressed: true, duplicateRefineTerminalEvent: true };
|
|
25326
25475
|
}
|
|
25327
25476
|
const eventTimestamp = readEventTimestamp(args.metadataEvent.timestamp);
|
|
25328
25477
|
if (args.event === "agent:generating_completed" && eventSessionId) {
|
|
25478
|
+
const terminal = findRecentTerminalLedgerEvidence({
|
|
25479
|
+
meshId: args.meshId,
|
|
25480
|
+
sessionId: eventSessionId,
|
|
25481
|
+
nodeId: eventNodeId || void 0
|
|
25482
|
+
});
|
|
25483
|
+
if (terminal?.kind === "task_completed" && !sessionHasActiveAssignment(args.meshId, eventSessionId)) {
|
|
25484
|
+
const terminalProviderSessionId = readNonEmptyString2(terminal.payload.providerSessionId);
|
|
25485
|
+
const terminalFinalSummary = readNonEmptyString2(terminal.payload.finalSummary);
|
|
25486
|
+
const eventProviderSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId);
|
|
25487
|
+
const eventFinalSummary = readNonEmptyString2(args.metadataEvent.finalSummary);
|
|
25488
|
+
if (terminalProviderSessionId && terminalProviderSessionId === eventProviderSessionId || terminalFinalSummary && terminalFinalSummary === eventFinalSummary || args.metadataEvent.source === "long_generating_reconciliation") {
|
|
25489
|
+
LOG2.info("MeshEvents", `Suppressed duplicate completion with existing terminal ledger evidence for mesh ${args.meshId} session ${eventSessionId}`);
|
|
25490
|
+
return { success: true, forwarded: 0, suppressed: true, duplicateCompletion: true, terminalLedgerEvidence: true };
|
|
25491
|
+
}
|
|
25492
|
+
}
|
|
25329
25493
|
const duplicateCompletion = isDuplicateMeshCompletionEvent({
|
|
25330
25494
|
meshId: args.meshId,
|
|
25331
25495
|
event: args.event,
|
|
@@ -25602,6 +25766,10 @@ Next step: ${nextStep}`;
|
|
|
25602
25766
|
completedAt: readNonEmptyString2(payload.completedAt),
|
|
25603
25767
|
retryOfJobId: readNonEmptyString2(payload.retryOfJobId),
|
|
25604
25768
|
...payload.result && typeof payload.result === "object" && !Array.isArray(payload.result) ? { result: payload.result } : {},
|
|
25769
|
+
...payload.completionDiagnostic && typeof payload.completionDiagnostic === "object" && !Array.isArray(payload.completionDiagnostic) ? { completionDiagnostic: payload.completionDiagnostic } : {},
|
|
25770
|
+
...payload.workerResult && typeof payload.workerResult === "object" && !Array.isArray(payload.workerResult) ? { workerResult: payload.workerResult } : {},
|
|
25771
|
+
...payload.meshWorkerResult && typeof payload.meshWorkerResult === "object" && !Array.isArray(payload.meshWorkerResult) ? { meshWorkerResult: payload.meshWorkerResult } : {},
|
|
25772
|
+
...payload.structuredResult && typeof payload.structuredResult === "object" && !Array.isArray(payload.structuredResult) ? { structuredResult: payload.structuredResult } : {},
|
|
25605
25773
|
...payload.timestamp !== void 0 ? { timestamp: payload.timestamp } : {},
|
|
25606
25774
|
intentional: payload.intentional === true,
|
|
25607
25775
|
intentionalStop: payload.intentionalStop === true,
|
|
@@ -28509,9 +28677,27 @@ ${lastSnapshot}`;
|
|
|
28509
28677
|
nextScreenChangeAt
|
|
28510
28678
|
), 50);
|
|
28511
28679
|
}
|
|
28512
|
-
async sendMessage(text) {
|
|
28680
|
+
async sendMessage(text, options = {}) {
|
|
28681
|
+
if (options.force === true) {
|
|
28682
|
+
await this.forceSendMessage(text);
|
|
28683
|
+
return;
|
|
28684
|
+
}
|
|
28513
28685
|
await this.sendMessageNow(text, true);
|
|
28514
28686
|
}
|
|
28687
|
+
async forceSendMessage(text) {
|
|
28688
|
+
if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
|
|
28689
|
+
const content = String(text || "");
|
|
28690
|
+
if (!content.trim()) return;
|
|
28691
|
+
this.recordTrace("force_send_message", {
|
|
28692
|
+
text: summarizeCliTraceText(content, 500),
|
|
28693
|
+
status: this.currentStatus,
|
|
28694
|
+
isWaitingForResponse: this.isWaitingForResponse,
|
|
28695
|
+
queueLength: this.pendingOutboundQueue.length
|
|
28696
|
+
});
|
|
28697
|
+
LOG2.info("CLI", `[${this.cliType}] force-sending prompt while status=${this.currentStatus}`);
|
|
28698
|
+
await this.writeToPty(content + this.sendKey);
|
|
28699
|
+
this.onStatusChange?.();
|
|
28700
|
+
}
|
|
28515
28701
|
enqueuePendingOutboundMessage(text, reason) {
|
|
28516
28702
|
const content = String(text || "");
|
|
28517
28703
|
const duplicate = this.pendingOutboundQueue.some((message2) => message2.content === content);
|
|
@@ -40144,8 +40330,18 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40144
40330
|
assertTextOnlyInput(provider, input);
|
|
40145
40331
|
if (!text) return { success: false, error: "text required for PTY send" };
|
|
40146
40332
|
await waitOnceForFreshHermesCliStart(adapter, _log);
|
|
40147
|
-
|
|
40148
|
-
|
|
40333
|
+
const forceSend = args?.force === true || args?.forceSend === true;
|
|
40334
|
+
if (forceSend && typeof adapter.forceSendMessage === "function") {
|
|
40335
|
+
await adapter.forceSendMessage(text);
|
|
40336
|
+
} else if (forceSend) {
|
|
40337
|
+
await adapter.sendMessage(text, { force: true });
|
|
40338
|
+
} else {
|
|
40339
|
+
await adapter.sendMessage(text);
|
|
40340
|
+
}
|
|
40341
|
+
return {
|
|
40342
|
+
..._logSendSuccess(`${transport}-adapter`, adapter.cliType),
|
|
40343
|
+
...forceSend ? { forceSent: true } : {}
|
|
40344
|
+
};
|
|
40149
40345
|
} catch (e) {
|
|
40150
40346
|
return { success: false, error: `${transport} send failed: ${e.message}` };
|
|
40151
40347
|
}
|
|
@@ -42474,6 +42670,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
42474
42670
|
lastApprovalEventAt = 0;
|
|
42475
42671
|
autoApproveBusy = false;
|
|
42476
42672
|
autoApproveBusyTimer = null;
|
|
42673
|
+
lastAutoApprovalSignature = "";
|
|
42477
42674
|
controlValues = {};
|
|
42478
42675
|
summaryMetadata = void 0;
|
|
42479
42676
|
appliedEffectKeys = /* @__PURE__ */ new Set();
|
|
@@ -42983,15 +43180,26 @@ ${effect.notification.body || ""}`.trim();
|
|
|
42983
43180
|
}
|
|
42984
43181
|
maybeAutoApproveStatus(adapterStatus, now = Date.now()) {
|
|
42985
43182
|
const autoApproveActive = adapterStatus?.status === "waiting_approval" && this.shouldAutoApprove();
|
|
42986
|
-
if (autoApproveActive
|
|
43183
|
+
if (!autoApproveActive) {
|
|
43184
|
+
this.lastAutoApprovalSignature = "";
|
|
43185
|
+
return autoApproveActive;
|
|
43186
|
+
}
|
|
43187
|
+
const modal = adapterStatus.activeModal;
|
|
43188
|
+
const { index: buttonIndex, label: buttonLabel } = pickApprovalButton(modal?.buttons, this.provider);
|
|
43189
|
+
const signature = [
|
|
43190
|
+
typeof modal?.message === "string" ? modal.message.trim() : "",
|
|
43191
|
+
Array.isArray(modal?.buttons) ? modal.buttons.join("|") : "",
|
|
43192
|
+
buttonIndex
|
|
43193
|
+
].join("::");
|
|
43194
|
+
if (!this.autoApproveBusy || signature !== this.lastAutoApprovalSignature) {
|
|
42987
43195
|
this.autoApproveBusy = true;
|
|
43196
|
+
this.lastAutoApprovalSignature = signature;
|
|
42988
43197
|
if (this.autoApproveBusyTimer) clearTimeout(this.autoApproveBusyTimer);
|
|
42989
43198
|
this.autoApproveBusyTimer = setTimeout(() => {
|
|
42990
43199
|
this.autoApproveBusy = false;
|
|
42991
43200
|
this.autoApproveBusyTimer = null;
|
|
43201
|
+
this.lastAutoApprovalSignature = "";
|
|
42992
43202
|
}, 2e3);
|
|
42993
|
-
const modal = adapterStatus.activeModal;
|
|
42994
|
-
const { index: buttonIndex, label: buttonLabel } = pickApprovalButton(modal?.buttons, this.provider);
|
|
42995
43203
|
this.recordAutoApproval(modal?.message, buttonLabel, now);
|
|
42996
43204
|
setTimeout(() => {
|
|
42997
43205
|
this.adapter.resolveModal(buttonIndex);
|
|
@@ -43133,7 +43341,26 @@ ${effect.notification.body || ""}`.trim();
|
|
|
43133
43341
|
});
|
|
43134
43342
|
const agentKey = `${this.type}:cli`;
|
|
43135
43343
|
const monitorEvents = this.monitor.check(agentKey, newStatus, now, progressFingerprint);
|
|
43344
|
+
const monitorParsedStatus = parsedStatus;
|
|
43136
43345
|
for (const me of monitorEvents) {
|
|
43346
|
+
if (me.type === "monitor:long_generating" && this.completionHasFinalAssistantMessage(monitorParsedStatus?.messages) && !this.hasAdapterPendingResponse() && !hasNonEmptyCliModalButtons(monitorParsedStatus?.activeModal ?? monitorParsedStatus?.modal)) {
|
|
43347
|
+
this.pushEvent({
|
|
43348
|
+
event: "agent:generating_completed",
|
|
43349
|
+
chatTitle,
|
|
43350
|
+
duration: this.generatingStartedAt ? Math.round((now - this.generatingStartedAt) / 1e3) : void 0,
|
|
43351
|
+
timestamp: me.timestamp,
|
|
43352
|
+
finalSummary: extractFinalSummaryFromMessages(monitorParsedStatus?.messages),
|
|
43353
|
+
completionDiagnostic: {
|
|
43354
|
+
providerType: this.type,
|
|
43355
|
+
sessionId: this.instanceId,
|
|
43356
|
+
providerSessionId: this.providerSessionId || null,
|
|
43357
|
+
reconciliationReason: "long_generating_monitor_final_summary",
|
|
43358
|
+
finalAssistantPresent: true
|
|
43359
|
+
}
|
|
43360
|
+
});
|
|
43361
|
+
this.generatingStartedAt = 0;
|
|
43362
|
+
continue;
|
|
43363
|
+
}
|
|
43137
43364
|
this.pushEvent({ event: me.type, agentKey: me.agentKey, message: me.message, elapsedSec: me.elapsedSec, timestamp: me.timestamp });
|
|
43138
43365
|
}
|
|
43139
43366
|
}
|
|
@@ -45727,11 +45954,19 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45727
45954
|
}
|
|
45728
45955
|
const message = input.textFallback;
|
|
45729
45956
|
if (!message) throw new Error("message required for send_chat");
|
|
45730
|
-
|
|
45957
|
+
const forceSend = args?.force === true || args?.forceSend === true;
|
|
45958
|
+
if (forceSend && typeof adapter.forceSendMessage === "function") {
|
|
45959
|
+
await adapter.forceSendMessage(message);
|
|
45960
|
+
} else if (forceSend) {
|
|
45961
|
+
await adapter.sendMessage(message, { force: true });
|
|
45962
|
+
} else {
|
|
45963
|
+
await adapter.sendMessage(message);
|
|
45964
|
+
}
|
|
45731
45965
|
return {
|
|
45732
45966
|
success: true,
|
|
45733
45967
|
status: BUSY_AGENT_STATUSES.has(currentStatus) ? currentStatus : "generating",
|
|
45734
|
-
...BUSY_AGENT_STATUSES.has(currentStatus) ? { queued: true, queuedReason: "agent_runtime_busy" } : {}
|
|
45968
|
+
...BUSY_AGENT_STATUSES.has(currentStatus) ? { queued: true, queuedReason: "agent_runtime_busy" } : {},
|
|
45969
|
+
...forceSend ? { forceSent: true, queued: false } : {}
|
|
45735
45970
|
};
|
|
45736
45971
|
} else if (action === "clear_history") {
|
|
45737
45972
|
if (typeof adapter.clearHistory === "function") adapter.clearHistory();
|