@adhdev/daemon-core 0.9.82-rc.24 → 0.9.82-rc.25

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 CHANGED
@@ -1514,18 +1514,20 @@ function requeueTask(meshId, taskId, opts) {
1514
1514
  return entry;
1515
1515
  });
1516
1516
  }
1517
- function updateSessionTaskStatus(meshId, sessionId, status) {
1517
+ function updateSessionTaskStatus(meshId, sessionId, status, opts) {
1518
1518
  return withQueueLock(meshId, () => {
1519
1519
  const queue = readQueue(meshId);
1520
+ const occurredAtTime = opts?.occurredAt ? new Date(opts.occurredAt).getTime() : Number.NaN;
1521
+ const hasOccurredAt = Number.isFinite(occurredAtTime);
1520
1522
  let bestIdx = -1;
1521
1523
  let bestTime = 0;
1522
1524
  for (let i = queue.length - 1; i >= 0; i--) {
1523
- if (queue[i].assignedSessionId === sessionId && queue[i].status === "assigned") {
1524
- const time = new Date(queue[i].dispatchTimestamp || queue[i].updatedAt).getTime();
1525
- if (time > bestTime) {
1526
- bestTime = time;
1527
- bestIdx = i;
1528
- }
1525
+ if (queue[i].assignedSessionId !== sessionId || queue[i].status !== "assigned") continue;
1526
+ const time = new Date(queue[i].dispatchTimestamp || queue[i].updatedAt).getTime();
1527
+ if (hasOccurredAt && Number.isFinite(time) && time > occurredAtTime) continue;
1528
+ if (time > bestTime) {
1529
+ bestTime = time;
1530
+ bestIdx = i;
1529
1531
  }
1530
1532
  }
1531
1533
  if (bestIdx === -1) return null;
@@ -2051,6 +2053,38 @@ function shouldSuppressIntentionalCleanupStop(args) {
2051
2053
  if (isIntentionalCleanupStopMetadata(args.metadataEvent)) return true;
2052
2054
  return hasRecentIntentionalCleanupStop(args.meshId, args.sessionId, args.nodeId);
2053
2055
  }
2056
+ function readEventTimestamp(value) {
2057
+ if (typeof value === "number" && Number.isFinite(value)) return value;
2058
+ if (typeof value === "string" && value.trim()) {
2059
+ const numeric = Number(value);
2060
+ if (Number.isFinite(numeric)) return numeric;
2061
+ const parsed = Date.parse(value);
2062
+ if (Number.isFinite(parsed)) return parsed;
2063
+ }
2064
+ return null;
2065
+ }
2066
+ function buildMeshCompletionFingerprint(args) {
2067
+ const timestampPart = Number.isFinite(args.timestamp) ? String(args.timestamp) : readNonEmptyString(args.finalSummary).slice(0, 200);
2068
+ return [
2069
+ args.meshId,
2070
+ args.event,
2071
+ args.sessionId,
2072
+ args.providerType || "",
2073
+ args.providerSessionId || "",
2074
+ timestampPart
2075
+ ].join("::");
2076
+ }
2077
+ function isDuplicateMeshCompletionEvent(args) {
2078
+ const fingerprint = buildMeshCompletionFingerprint(args);
2079
+ if (!fingerprint) return false;
2080
+ const now = Date.now();
2081
+ for (const [key, seenAt] of recentCompletionFingerprints.entries()) {
2082
+ if (now - seenAt > RECENT_COMPLETION_FINGERPRINT_TTL_MS) recentCompletionFingerprints.delete(key);
2083
+ }
2084
+ if (recentCompletionFingerprints.has(fingerprint)) return true;
2085
+ recentCompletionFingerprints.set(fingerprint, now);
2086
+ return false;
2087
+ }
2054
2088
  function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType) {
2055
2089
  const task = claimNextTask(meshId, nodeId, sessionId);
2056
2090
  if (!task) {
@@ -2412,13 +2446,31 @@ function injectMeshSystemMessage(components, args) {
2412
2446
  LOG.info("MeshEvents", `Suppressed ${args.event} for intentionally cleanup-stopped session ${eventSessionId || "(unknown session)"}`);
2413
2447
  return { success: true, forwarded: 0, suppressed: true, intentionalCleanupStop: true };
2414
2448
  }
2449
+ const eventTimestamp = readEventTimestamp(args.metadataEvent.timestamp);
2450
+ if (args.event === "agent:generating_completed" && eventSessionId) {
2451
+ const duplicateCompletion = isDuplicateMeshCompletionEvent({
2452
+ meshId: args.meshId,
2453
+ event: args.event,
2454
+ sessionId: eventSessionId,
2455
+ providerType: readNonEmptyString(args.metadataEvent.providerType) || void 0,
2456
+ providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
2457
+ timestamp: eventTimestamp,
2458
+ finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
2459
+ });
2460
+ if (duplicateCompletion) {
2461
+ LOG.info("MeshEvents", `Suppressed duplicate completion for mesh ${args.meshId} session ${eventSessionId}`);
2462
+ return { success: true, forwarded: 0, suppressed: true, duplicateCompletion: true };
2463
+ }
2464
+ }
2415
2465
  let completedTaskForLedger = null;
2416
2466
  if (args.event === "agent:generating_completed") {
2417
2467
  const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
2418
2468
  const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
2419
2469
  const providerType = readNonEmptyString(args.metadataEvent.providerType);
2420
2470
  if (sessionId) {
2421
- const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed");
2471
+ const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed", {
2472
+ occurredAt: eventTimestamp !== null ? new Date(eventTimestamp).toISOString() : void 0
2473
+ });
2422
2474
  completedTaskForLedger = completedTask ? { id: completedTask.id } : null;
2423
2475
  if (nodeId && providerType) {
2424
2476
  setImmediate(() => {
@@ -2632,6 +2684,7 @@ function handleMeshForwardEvent(components, payload) {
2632
2684
  providerType: readNonEmptyString(payload.providerType),
2633
2685
  providerSessionId: readNonEmptyString(payload.providerSessionId),
2634
2686
  finalSummary: readNonEmptyString(payload.finalSummary) || readNonEmptyString(payload.summary),
2687
+ ...payload.timestamp !== void 0 ? { timestamp: payload.timestamp } : {},
2635
2688
  intentional: payload.intentional === true,
2636
2689
  intentionalStop: payload.intentionalStop === true,
2637
2690
  operatorCleanup: payload.operatorCleanup === true,
@@ -2674,7 +2727,7 @@ function setupMeshEventForwarding(components) {
2674
2727
  });
2675
2728
  });
2676
2729
  }
2677
- var import_fs6, import_path5, REMOTE_IDLE_SESSION_TTL_MS, remoteIdleSessions, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
2730
+ var import_fs6, import_path5, 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;
2678
2731
  var init_mesh_events = __esm({
2679
2732
  "src/mesh/mesh-events.ts"() {
2680
2733
  "use strict";
@@ -2703,6 +2756,8 @@ var init_mesh_events = __esm({
2703
2756
  "monitor:long_generating": "task_stalled"
2704
2757
  };
2705
2758
  INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS = 30 * 60 * 1e3;
2759
+ RECENT_COMPLETION_FINGERPRINT_TTL_MS = 10 * 60 * 1e3;
2760
+ recentCompletionFingerprints = /* @__PURE__ */ new Map();
2706
2761
  autoLaunchInProgress = /* @__PURE__ */ new Set();
2707
2762
  autoLaunchCooldownUntil = /* @__PURE__ */ new Map();
2708
2763
  AUTO_LAUNCH_COOLDOWN_MS = 5e3;