@adhdev/daemon-core 0.9.82-rc.60 → 0.9.82-rc.62
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 +84 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +84 -5
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-events.d.ts +11 -0
- package/package.json +1 -1
- package/src/commands/router.ts +8 -2
- package/src/mesh/mesh-events.ts +81 -0
package/dist/index.js
CHANGED
|
@@ -2342,12 +2342,34 @@ function sweepExpiredRemoteIdleSessions() {
|
|
|
2342
2342
|
if (session.expiresAt <= now) remoteIdleSessions.delete(key);
|
|
2343
2343
|
}
|
|
2344
2344
|
}
|
|
2345
|
+
function readRefineJobId(event) {
|
|
2346
|
+
const metadata = readRecord(event.metadataEvent) || event;
|
|
2347
|
+
const result = readRecord(metadata.result);
|
|
2348
|
+
const refineJob = readRecord(result?.refineJob);
|
|
2349
|
+
return readNonEmptyString2(metadata.jobId) || readNonEmptyString2(refineJob?.jobId);
|
|
2350
|
+
}
|
|
2351
|
+
function buildRefineTerminalEventFingerprint(meshId, eventName, metadataEvent) {
|
|
2352
|
+
const jobId = readRefineJobId({ metadataEvent });
|
|
2353
|
+
return jobId && REFINE_TERMINAL_EVENTS.has(eventName) ? `${meshId}::${eventName}::${jobId}` : "";
|
|
2354
|
+
}
|
|
2355
|
+
function hasPendingRefineTerminalEventDuplicate(event) {
|
|
2356
|
+
if (!REFINE_TERMINAL_EVENTS.has(event.event)) return false;
|
|
2357
|
+
const jobId = readRefineJobId(event);
|
|
2358
|
+
if (!jobId) return false;
|
|
2359
|
+
return getPendingMeshCoordinatorEvents(event.meshId).some(
|
|
2360
|
+
(pending) => pending.event === event.event && readRefineJobId(pending) === jobId
|
|
2361
|
+
);
|
|
2362
|
+
}
|
|
2345
2363
|
function getPendingEventsPath(meshId) {
|
|
2346
2364
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
2347
2365
|
return (0, import_path6.join)(getLedgerDir(), `${safe}.pending-events.jsonl`);
|
|
2348
2366
|
}
|
|
2349
2367
|
function queuePendingMeshCoordinatorEvent(event) {
|
|
2350
2368
|
try {
|
|
2369
|
+
if (hasPendingRefineTerminalEventDuplicate(event)) {
|
|
2370
|
+
LOG.info("MeshEvents", `Suppressed duplicate pending ${event.event} for refine job ${readRefineJobId(event)}`);
|
|
2371
|
+
return true;
|
|
2372
|
+
}
|
|
2351
2373
|
(0, import_fs7.appendFileSync)(getPendingEventsPath(event.meshId), JSON.stringify(event) + "\n", "utf-8");
|
|
2352
2374
|
return true;
|
|
2353
2375
|
} catch (e) {
|
|
@@ -2485,6 +2507,17 @@ function isDuplicateMeshCompletionEvent(args) {
|
|
|
2485
2507
|
recentCompletionFingerprints.set(fingerprint, now);
|
|
2486
2508
|
return false;
|
|
2487
2509
|
}
|
|
2510
|
+
function isDuplicateRefineTerminalEvent(meshId, eventName, metadataEvent) {
|
|
2511
|
+
const fingerprint = buildRefineTerminalEventFingerprint(meshId, eventName, metadataEvent);
|
|
2512
|
+
if (!fingerprint) return false;
|
|
2513
|
+
const now = Date.now();
|
|
2514
|
+
for (const [key, seenAt] of recentCompletionFingerprints.entries()) {
|
|
2515
|
+
if (now - seenAt > RECENT_COMPLETION_FINGERPRINT_TTL_MS) recentCompletionFingerprints.delete(key);
|
|
2516
|
+
}
|
|
2517
|
+
if (recentCompletionFingerprints.has(fingerprint)) return true;
|
|
2518
|
+
recentCompletionFingerprints.set(fingerprint, now);
|
|
2519
|
+
return false;
|
|
2520
|
+
}
|
|
2488
2521
|
function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType) {
|
|
2489
2522
|
const task = claimNextTask(meshId, nodeId, sessionId);
|
|
2490
2523
|
if (!task) {
|
|
@@ -2827,6 +2860,32 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
2827
2860
|
if (args.event === "monitor:long_generating") {
|
|
2828
2861
|
return `[System] ${args.nodeLabel} has been generating for a long time${metadata}. Use mesh_read_chat once for a status check, but do not poll repeatedly.`;
|
|
2829
2862
|
}
|
|
2863
|
+
if (args.event === "refine:accepted") {
|
|
2864
|
+
const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
|
|
2865
|
+
return `[System] Refinery accepted async job${jobId ? ` ${jobId}` : ""} for ${args.nodeLabel}. Completion/failure will be delivered as a terminal refine event; do not poll repeatedly.`;
|
|
2866
|
+
}
|
|
2867
|
+
if (args.event === "refine:completed") {
|
|
2868
|
+
const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
|
|
2869
|
+
const result = readRecord(args.metadataEvent.result);
|
|
2870
|
+
const validationSummary = readRecord(result?.validationSummary);
|
|
2871
|
+
const validationStatus = readNonEmptyString2(validationSummary?.status);
|
|
2872
|
+
const into = readNonEmptyString2(result?.into);
|
|
2873
|
+
const branch = readNonEmptyString2(result?.branch);
|
|
2874
|
+
const details = [
|
|
2875
|
+
jobId ? `job_id=${jobId}` : "",
|
|
2876
|
+
branch && into ? `${branch}\u2192${into}` : "",
|
|
2877
|
+
validationStatus ? `validation=${validationStatus}` : ""
|
|
2878
|
+
].filter(Boolean).join("; ");
|
|
2879
|
+
return `[System] Refinery async job for ${args.nodeLabel} completed successfully${details ? ` (${details})` : ""}. The worktree was merged and cleanup completed; continue from the updated mesh state.`;
|
|
2880
|
+
}
|
|
2881
|
+
if (args.event === "refine:failed") {
|
|
2882
|
+
const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
|
|
2883
|
+
const result = readRecord(args.metadataEvent.result);
|
|
2884
|
+
const code = readNonEmptyString2(result?.code);
|
|
2885
|
+
const error = readNonEmptyString2(result?.error);
|
|
2886
|
+
const details = [jobId ? `job_id=${jobId}` : "", code ? `code=${code}` : ""].filter(Boolean).join("; ");
|
|
2887
|
+
return `[System] Refinery async job for ${args.nodeLabel} failed${details ? ` (${details})` : ""}${error ? `: ${error}` : "."} Review the terminal refine event/ledger before retrying.`;
|
|
2888
|
+
}
|
|
2830
2889
|
return "";
|
|
2831
2890
|
}
|
|
2832
2891
|
function injectMeshSystemMessage(components, args) {
|
|
@@ -2846,6 +2905,10 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2846
2905
|
LOG.info("MeshEvents", `Suppressed ${args.event} for intentionally cleanup-stopped session ${eventSessionId || "(unknown session)"}`);
|
|
2847
2906
|
return { success: true, forwarded: 0, suppressed: true, intentionalCleanupStop: true };
|
|
2848
2907
|
}
|
|
2908
|
+
if (isDuplicateRefineTerminalEvent(args.meshId, args.event, args.metadataEvent)) {
|
|
2909
|
+
LOG.info("MeshEvents", `Suppressed duplicate ${args.event} for refine job ${readRefineJobId({ metadataEvent: args.metadataEvent })}`);
|
|
2910
|
+
return { success: true, forwarded: 0, suppressed: true, duplicateRefineTerminalEvent: true };
|
|
2911
|
+
}
|
|
2849
2912
|
const eventTimestamp = readEventTimestamp(args.metadataEvent.timestamp);
|
|
2850
2913
|
if (args.event === "agent:generating_completed" && eventSessionId) {
|
|
2851
2914
|
const duplicateCompletion = isDuplicateMeshCompletionEvent({
|
|
@@ -3095,6 +3158,14 @@ function handleMeshForwardEvent(components, payload) {
|
|
|
3095
3158
|
providerType: readNonEmptyString2(payload.providerType),
|
|
3096
3159
|
providerSessionId: readNonEmptyString2(payload.providerSessionId),
|
|
3097
3160
|
finalSummary: readNonEmptyString2(payload.finalSummary) || readNonEmptyString2(payload.summary),
|
|
3161
|
+
jobId: readNonEmptyString2(payload.jobId),
|
|
3162
|
+
interactionId: readNonEmptyString2(payload.interactionId),
|
|
3163
|
+
status: readNonEmptyString2(payload.status),
|
|
3164
|
+
targetDaemonId: readNonEmptyString2(payload.targetDaemonId),
|
|
3165
|
+
startedAt: readNonEmptyString2(payload.startedAt),
|
|
3166
|
+
completedAt: readNonEmptyString2(payload.completedAt),
|
|
3167
|
+
retryOfJobId: readNonEmptyString2(payload.retryOfJobId),
|
|
3168
|
+
...payload.result && typeof payload.result === "object" && !Array.isArray(payload.result) ? { result: payload.result } : {},
|
|
3098
3169
|
...payload.timestamp !== void 0 ? { timestamp: payload.timestamp } : {},
|
|
3099
3170
|
intentional: payload.intentional === true,
|
|
3100
3171
|
intentionalStop: payload.intentionalStop === true,
|
|
@@ -3138,7 +3209,7 @@ function setupMeshEventForwarding(components) {
|
|
|
3138
3209
|
});
|
|
3139
3210
|
});
|
|
3140
3211
|
}
|
|
3141
|
-
var import_fs7, import_path6, REMOTE_IDLE_SESSION_TTL_MS, remoteIdleSessions, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, recentCompletionFingerprints, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
|
|
3212
|
+
var import_fs7, import_path6, REMOTE_IDLE_SESSION_TTL_MS, remoteIdleSessions, REFINE_TERMINAL_EVENTS, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, recentCompletionFingerprints, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
|
|
3142
3213
|
var init_mesh_events = __esm({
|
|
3143
3214
|
"src/mesh/mesh-events.ts"() {
|
|
3144
3215
|
"use strict";
|
|
@@ -3152,13 +3223,17 @@ var init_mesh_events = __esm({
|
|
|
3152
3223
|
init_mesh_work_queue();
|
|
3153
3224
|
REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
|
|
3154
3225
|
remoteIdleSessions = /* @__PURE__ */ new Map();
|
|
3226
|
+
REFINE_TERMINAL_EVENTS = /* @__PURE__ */ new Set(["refine:completed", "refine:failed"]);
|
|
3155
3227
|
MESH_COORDINATOR_EVENTS = /* @__PURE__ */ new Set([
|
|
3156
3228
|
"agent:generating_started",
|
|
3157
3229
|
"agent:generating_completed",
|
|
3158
3230
|
"agent:waiting_approval",
|
|
3159
3231
|
"agent:stopped",
|
|
3160
3232
|
"agent:ready",
|
|
3161
|
-
"monitor:long_generating"
|
|
3233
|
+
"monitor:long_generating",
|
|
3234
|
+
"refine:accepted",
|
|
3235
|
+
"refine:completed",
|
|
3236
|
+
"refine:failed"
|
|
3162
3237
|
]);
|
|
3163
3238
|
EVENT_TO_LEDGER_KIND = {
|
|
3164
3239
|
"agent:generating_completed": "task_completed",
|
|
@@ -26904,6 +26979,7 @@ var DaemonCommandRouter = class {
|
|
|
26904
26979
|
workspace: readStringValue(args.node?.workspace),
|
|
26905
26980
|
startedAt: args.startedAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
26906
26981
|
...args.completedAt ? { completedAt: args.completedAt } : {},
|
|
26982
|
+
...args.retryOfJobId ? { retryOfJobId: args.retryOfJobId } : {},
|
|
26907
26983
|
eventDelivery: { pendingEvents: true, ledger: true },
|
|
26908
26984
|
evidence: {
|
|
26909
26985
|
pendingEventsCommand: "get_pending_mesh_events",
|
|
@@ -26930,6 +27006,7 @@ var DaemonCommandRouter = class {
|
|
|
26930
27006
|
status: handle.status,
|
|
26931
27007
|
startedAt: handle.startedAt,
|
|
26932
27008
|
completedAt: handle.completedAt,
|
|
27009
|
+
retryOfJobId: handle.retryOfJobId,
|
|
26933
27010
|
...result ? { result } : {}
|
|
26934
27011
|
},
|
|
26935
27012
|
queuedAt: Date.now()
|
|
@@ -26952,9 +27029,11 @@ var DaemonCommandRouter = class {
|
|
|
26952
27029
|
targetDaemonId: handle.targetDaemonId,
|
|
26953
27030
|
workspace: handle.workspace,
|
|
26954
27031
|
startedAt: handle.startedAt,
|
|
26955
|
-
completedAt: handle.completedAt
|
|
27032
|
+
completedAt: handle.completedAt,
|
|
27033
|
+
retryOfJobId: handle.retryOfJobId
|
|
26956
27034
|
},
|
|
26957
27035
|
async: true,
|
|
27036
|
+
retryOfJobId: handle.retryOfJobId,
|
|
26958
27037
|
...result ? {
|
|
26959
27038
|
success: result.success === true,
|
|
26960
27039
|
result,
|
|
@@ -27192,6 +27271,7 @@ var DaemonCommandRouter = class {
|
|
|
27192
27271
|
completedAt,
|
|
27193
27272
|
jobId: handle.jobId,
|
|
27194
27273
|
interactionId: handle.interactionId,
|
|
27274
|
+
retryOfJobId: handle.retryOfJobId,
|
|
27195
27275
|
node: { daemonId: handle.targetDaemonId, workspace: handle.workspace }
|
|
27196
27276
|
});
|
|
27197
27277
|
const terminal = { ...terminalHandle, result };
|
|
@@ -27206,13 +27286,12 @@ var DaemonCommandRouter = class {
|
|
|
27206
27286
|
const running = this.runningRefineJobs.get(key);
|
|
27207
27287
|
if (running) return { ...running, duplicate: true };
|
|
27208
27288
|
const terminal = this.terminalRefineJobs.get(key);
|
|
27209
|
-
if (terminal) return { ...terminal, duplicate: true };
|
|
27210
27289
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
|
|
27211
27290
|
const mesh = meshRecord?.mesh;
|
|
27212
27291
|
const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
|
|
27213
27292
|
if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
|
|
27214
27293
|
if (!node.isLocalWorktree || !node.workspace) return { success: false, error: `Refinery requires a local worktree node` };
|
|
27215
|
-
const handle = this.buildRefineJobHandle({ meshId, nodeId, node });
|
|
27294
|
+
const handle = this.buildRefineJobHandle({ meshId, nodeId, node, retryOfJobId: terminal?.jobId });
|
|
27216
27295
|
this.runningRefineJobs.set(key, handle);
|
|
27217
27296
|
await this.appendRefineJobLedger("task_dispatched", handle);
|
|
27218
27297
|
this.queueRefineJobEvent("refine:accepted", handle);
|