@adhdev/daemon-core 1.0.28-rc.15 → 1.0.28-rc.17
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.d.ts +1 -1
- package/dist/index.js +258 -32
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +257 -32
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-events-stale.d.ts +59 -0
- package/dist/mesh/mesh-queue-assignment.d.ts +1 -0
- package/dist/providers/cli-provider-instance.d.ts +34 -0
- package/package.json +3 -3
- package/src/cli-adapters/provider-cli-adapter.ts +7 -1
- package/src/commands/med-family/cli-agent.ts +32 -13
- package/src/index.ts +1 -0
- package/src/mesh/mesh-completion-synthesis.ts +35 -1
- package/src/mesh/mesh-event-forwarding.ts +129 -1
- package/src/mesh/mesh-events-stale.ts +109 -0
- package/src/mesh/mesh-queue-assignment.ts +19 -1
- package/src/mesh/mesh-reconcile-loop.ts +59 -12
- package/src/providers/cli-provider-instance.ts +135 -7
package/dist/index.mjs
CHANGED
|
@@ -786,10 +786,10 @@ function readInjected(value) {
|
|
|
786
786
|
}
|
|
787
787
|
function getDaemonBuildInfo() {
|
|
788
788
|
if (cached) return cached;
|
|
789
|
-
const commit = readInjected(true ? "
|
|
790
|
-
const commitShort = readInjected(true ? "
|
|
791
|
-
const version = readInjected(true ? "1.0.28-rc.
|
|
792
|
-
const builtAt = readInjected(true ? "2026-07-
|
|
789
|
+
const commit = readInjected(true ? "9452bd039720355425e62fc7469808a0dda3ab80" : void 0) ?? "unknown";
|
|
790
|
+
const commitShort = readInjected(true ? "9452bd03" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
791
|
+
const version = readInjected(true ? "1.0.28-rc.17" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
792
|
+
const builtAt = readInjected(true ? "2026-07-27T01:42:15.160Z" : void 0);
|
|
793
793
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
794
794
|
return cached;
|
|
795
795
|
}
|
|
@@ -16439,6 +16439,31 @@ var init_debug_trace = __esm({
|
|
|
16439
16439
|
function recordSynthCompletionGateTrace(stage, payload) {
|
|
16440
16440
|
recordDebugTrace({ category: "completion-gate", stage, level: "debug", payload });
|
|
16441
16441
|
}
|
|
16442
|
+
function evaluateTranscriptSynthAdmission(admission) {
|
|
16443
|
+
if (!admission) return { admitted: true };
|
|
16444
|
+
if (admission.trailingToolActivityAfterFinalAssistant === true) {
|
|
16445
|
+
return { admitted: false, reason: "trailing_tool_activity_after_final_assistant" };
|
|
16446
|
+
}
|
|
16447
|
+
if (!admission.boundedBackstop && typeof admission.liveTurnPendingEvidence === "function") {
|
|
16448
|
+
let pending = false;
|
|
16449
|
+
try {
|
|
16450
|
+
pending = admission.liveTurnPendingEvidence() === true;
|
|
16451
|
+
} catch {
|
|
16452
|
+
}
|
|
16453
|
+
if (pending) return { admitted: false, reason: "live_turn_pending_evidence" };
|
|
16454
|
+
}
|
|
16455
|
+
return { admitted: true };
|
|
16456
|
+
}
|
|
16457
|
+
function resolveLiveTurnPendingEvidence(components, sessionId) {
|
|
16458
|
+
try {
|
|
16459
|
+
const instance = components?.instanceManager?.getInstance?.(sessionId);
|
|
16460
|
+
if (typeof instance?.hasLiveTurnPendingEvidence !== "function") return void 0;
|
|
16461
|
+
const probe = instance.hasLiveTurnPendingEvidence.bind(instance);
|
|
16462
|
+
return () => probe();
|
|
16463
|
+
} catch {
|
|
16464
|
+
return void 0;
|
|
16465
|
+
}
|
|
16466
|
+
}
|
|
16442
16467
|
function findRecentTerminalLedgerEvidence(args) {
|
|
16443
16468
|
if (!args.sessionId && !args.nodeId) return null;
|
|
16444
16469
|
const entries = readLedgerEntries(args.meshId, { tail: 200 });
|
|
@@ -16559,6 +16584,17 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
|
|
|
16559
16584
|
})) {
|
|
16560
16585
|
return { reconciled: false, alreadyTerminal: true, reason: "terminal_ledger_entry_exists" };
|
|
16561
16586
|
}
|
|
16587
|
+
const admission = evaluateTranscriptSynthAdmission(args.causalAdmission);
|
|
16588
|
+
if (!admission.admitted) {
|
|
16589
|
+
LOG.info("MeshEvents", `Transcript synth vetoed for task ${args.taskId} session ${args.sessionId} (source ${args.source || "direct_task_transcript_reconciliation"}): ${admission.reason} \u2014 holding the completion; it re-evaluates on the next reconcile pass`);
|
|
16590
|
+
recordSynthCompletionGateTrace("synth-veto", {
|
|
16591
|
+
producer: "transcript_reconcile",
|
|
16592
|
+
source: args.source || "direct_task_transcript_reconciliation",
|
|
16593
|
+
taskId: args.taskId,
|
|
16594
|
+
reason: admission.reason
|
|
16595
|
+
});
|
|
16596
|
+
return { reconciled: false, reason: admission.reason };
|
|
16597
|
+
}
|
|
16562
16598
|
const nodeId = readNonEmptyString(args.nodeId) || dispatch?.nodeId;
|
|
16563
16599
|
const providerType = readNonEmptyString(args.providerType) || dispatch?.providerType || readNonEmptyString(dispatch?.payload.providerType);
|
|
16564
16600
|
const completedAt = args.completedAt || (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -16720,6 +16756,7 @@ var init_mesh_events_stale = __esm({
|
|
|
16720
16756
|
init_mesh_events_pending();
|
|
16721
16757
|
init_mesh_events_utils();
|
|
16722
16758
|
init_debug_trace();
|
|
16759
|
+
init_logger();
|
|
16723
16760
|
init_dist();
|
|
16724
16761
|
DIRECT_DISPATCH_RECONCILE_GRACE_MS = 6e4;
|
|
16725
16762
|
DIRECT_DISPATCH_IDLE_SESSION_RECONCILE_GRACE_MS = 12e4;
|
|
@@ -19751,6 +19788,9 @@ function nodeHasActiveMeshWork(components, meshId, nodeId, currentSessionId) {
|
|
|
19751
19788
|
}
|
|
19752
19789
|
function isLaunchableNode(node) {
|
|
19753
19790
|
if (!node || node.status === "disabled" || node.status === "removed") return false;
|
|
19791
|
+
if (shouldDeferDispatchForBootstrap(node)) {
|
|
19792
|
+
return false;
|
|
19793
|
+
}
|
|
19754
19794
|
return isMeshNodeHealthLaunchable(node);
|
|
19755
19795
|
}
|
|
19756
19796
|
function isLocalAutoLaunchNode(node) {
|
|
@@ -22987,8 +23027,27 @@ function resolveActiveDirectDispatchTaskId(meshId, sessionId) {
|
|
|
22987
23027
|
return void 0;
|
|
22988
23028
|
}
|
|
22989
23029
|
}
|
|
23030
|
+
function findInWindowUnclaimedAutoLaunchTask(meshId, sessionId, nowMs) {
|
|
23031
|
+
return getQueue(meshId, { status: ["pending"] }).find((task) => {
|
|
23032
|
+
const al = task.autoLaunch;
|
|
23033
|
+
if (!al || al.status !== "completed" || !al.sessionId) return false;
|
|
23034
|
+
if (!sessionIdsEquivalent(al.sessionId, sessionId)) return false;
|
|
23035
|
+
const launchedAtMs = Date.parse(al.updatedAt);
|
|
23036
|
+
return Number.isFinite(launchedAtMs) && nowMs - launchedAtMs < AUTO_LAUNCH_AWAIT_CLAIM_MS;
|
|
23037
|
+
});
|
|
23038
|
+
}
|
|
23039
|
+
function hasMatchingTaskDispatchedLedgerEntry(meshId, taskId, sessionId) {
|
|
23040
|
+
const entries = readLedgerEntries(meshId, { tail: 200 });
|
|
23041
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
23042
|
+
const entry = entries[i];
|
|
23043
|
+
if (entry.kind !== "task_dispatched") continue;
|
|
23044
|
+
if (!sessionIdsEquivalent(entry.sessionId, sessionId)) continue;
|
|
23045
|
+
if (readNonEmptyString(entry.payload?.taskId) === taskId) return true;
|
|
23046
|
+
}
|
|
23047
|
+
return false;
|
|
23048
|
+
}
|
|
22990
23049
|
function evaluateMeshEventSuppression(args, ctx) {
|
|
22991
|
-
const { traceCtx, eventSessionId, eventNodeId, eventTimestamp, workerCoordinatorDaemonId } = ctx;
|
|
23050
|
+
const { traceCtx, eventSessionId, eventNodeId, eventTimestamp, workerCoordinatorDaemonId, components } = ctx;
|
|
22992
23051
|
const intentionalCleanupStop = shouldSuppressIntentionalCleanupStop({
|
|
22993
23052
|
event: args.event,
|
|
22994
23053
|
meshId: args.meshId,
|
|
@@ -23055,6 +23114,42 @@ function evaluateMeshEventSuppression(args, ctx) {
|
|
|
23055
23114
|
}
|
|
23056
23115
|
}
|
|
23057
23116
|
if (args.event === "agent:generating_completed" && eventSessionId) {
|
|
23117
|
+
const liveInstance = components.instanceManager?.getInstance?.(eventSessionId);
|
|
23118
|
+
if (typeof liveInstance?.hasLiveTurnPendingEvidence === "function") {
|
|
23119
|
+
let midTurnPending = false;
|
|
23120
|
+
try {
|
|
23121
|
+
midTurnPending = liveInstance.hasLiveTurnPendingEvidence() === true;
|
|
23122
|
+
} catch {
|
|
23123
|
+
}
|
|
23124
|
+
if (midTurnPending) {
|
|
23125
|
+
LOG.info("MeshEvents", `Suppressed agent:generating_completed for session ${eventSessionId} (mesh ${args.meshId}): live adapter re-check shows the turn is still pending (mid-tool / streaming / modal) \u2014 treating as a premature/redraw-race emit; the adapter's own finalization retry or the reconcile loop's transcript evidence will surface the real completion`);
|
|
23126
|
+
traceMeshEventDrop("mid_turn_live_state_pending", traceCtx);
|
|
23127
|
+
return {
|
|
23128
|
+
kind: "suppress",
|
|
23129
|
+
result: { success: true, forwarded: 0, suppressed: true, midTurnLiveStatePending: true }
|
|
23130
|
+
};
|
|
23131
|
+
}
|
|
23132
|
+
}
|
|
23133
|
+
if (!readNonEmptyString(args.metadataEvent.taskId) && !sessionHasActiveAssignment(args.meshId, eventSessionId) && !findRecentTerminalLedgerEvidence({ meshId: args.meshId, sessionId: eventSessionId, nodeId: eventNodeId || void 0 }) && isWeakCompletionEvidence(args.metadataEvent)) {
|
|
23134
|
+
LOG.info("MeshEvents", `Suppressed agent:generating_completed for session ${eventSessionId} (mesh ${args.meshId}): no taskId, no active assignment, and no prior terminal ledger evidence \u2014 a pre-dispatch startup/greeting artifact, not a real task completion`);
|
|
23135
|
+
traceMeshEventDrop("no_dispatch_native_completion", traceCtx);
|
|
23136
|
+
return {
|
|
23137
|
+
kind: "suppress",
|
|
23138
|
+
result: { success: true, forwarded: 0, suppressed: true, noDispatchNativeCompletion: true }
|
|
23139
|
+
};
|
|
23140
|
+
}
|
|
23141
|
+
const inWindowTask = findInWindowUnclaimedAutoLaunchTask(args.meshId, eventSessionId, Date.now());
|
|
23142
|
+
if (inWindowTask) {
|
|
23143
|
+
const causalEvidence = MeshRuntimeStore.getInstance().taskDeliveryConsumed(args.meshId, inWindowTask.id) || hasMatchingTaskDispatchedLedgerEntry(args.meshId, inWindowTask.id, eventSessionId);
|
|
23144
|
+
if (!causalEvidence) {
|
|
23145
|
+
LOG.warn("MeshEvents", `Suppressed premature agent:generating_completed for auto-launch session ${eventSessionId} (mesh ${args.meshId}): task ${inWindowTask.id} delivery not yet consumed and no turn-start evidence \u2014 likely a boot artifact before the task was ever dispatched`);
|
|
23146
|
+
traceMeshEventDrop("autolaunch_completion_before_causal_evidence", traceCtx, `taskId=${inWindowTask.id}`);
|
|
23147
|
+
return {
|
|
23148
|
+
kind: "suppress",
|
|
23149
|
+
result: { success: true, forwarded: 0, suppressed: true, autoLaunchCausalGateFailed: true, taskId: inWindowTask.id }
|
|
23150
|
+
};
|
|
23151
|
+
}
|
|
23152
|
+
}
|
|
23058
23153
|
const terminal = findRecentTerminalLedgerEvidence({
|
|
23059
23154
|
meshId: args.meshId,
|
|
23060
23155
|
sessionId: eventSessionId,
|
|
@@ -23287,7 +23382,8 @@ function injectMeshSystemMessage(components, args) {
|
|
|
23287
23382
|
eventSessionId,
|
|
23288
23383
|
eventNodeId,
|
|
23289
23384
|
eventTimestamp,
|
|
23290
|
-
workerCoordinatorDaemonId
|
|
23385
|
+
workerCoordinatorDaemonId,
|
|
23386
|
+
components
|
|
23291
23387
|
});
|
|
23292
23388
|
if (suppression) {
|
|
23293
23389
|
if (suppression.kind === "reconcile") {
|
|
@@ -24798,6 +24894,18 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
|
|
|
24798
24894
|
}
|
|
24799
24895
|
const messages = Array.isArray(payload.messages) ? payload.messages : [];
|
|
24800
24896
|
const evidence = extractFinalAssistantSummaryEvidence(messages);
|
|
24897
|
+
if (hasTrailingToolActivityAfterFinalAssistant(messages)) {
|
|
24898
|
+
setHoldState(synthKey, mesh.id, { liveConfirmedSinceAck: true, consecutiveReadFailures: 0 });
|
|
24899
|
+
LOG.info("MeshReconcile", `Mid-turn causal admission: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) \u2014 the latest final-looking assistant bubble is followed by trailing tool/terminal activity (interim narration; the turn is still executing); holding the transcript synth`);
|
|
24900
|
+
traceMeshEventDrop("reconcile_synth_veto_trailing_tool_activity", {
|
|
24901
|
+
taskId,
|
|
24902
|
+
sessionId,
|
|
24903
|
+
nodeId,
|
|
24904
|
+
meshId: mesh.id,
|
|
24905
|
+
event: "agent:generating_completed"
|
|
24906
|
+
});
|
|
24907
|
+
continue;
|
|
24908
|
+
}
|
|
24801
24909
|
if (isAcked) {
|
|
24802
24910
|
const ackedAtMs = Date.parse(readNonEmptyString(dispatch.updatedAt));
|
|
24803
24911
|
const sinceAckMs = Number.isFinite(ackedAtMs) ? nowMs - ackedAtMs : Number.POSITIVE_INFINITY;
|
|
@@ -24872,6 +24980,17 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
|
|
|
24872
24980
|
// The ledger-recovered dispatching-coordinator daemon (inside the reconcile fn)
|
|
24873
24981
|
// takes PRIORITY over this arg; this remains the best-available fallback.
|
|
24874
24982
|
...coordinatorDaemonId ? { targetCoordinatorDaemonId: coordinatorDaemonId } : {},
|
|
24983
|
+
// MID-TURN-CAUSAL-ADMISSION (rc.16): pass the LOCAL live adapter's synchronous
|
|
24984
|
+
// turn-state probe into the unified choke point — a pending verdict vetoes this
|
|
24985
|
+
// eager synth (never-acked first-idle / acked fast-track). The death-deadline
|
|
24986
|
+
// backstop is the bounded max-wait net and overrides the veto (genuine-final
|
|
24987
|
+
// fail-open preserved); a remote/missing live source resolves to undefined and
|
|
24988
|
+
// fails open onto the bounded transcript evidence above. The trailing-tool veto
|
|
24989
|
+
// already ran at the top of this tick.
|
|
24990
|
+
causalAdmission: {
|
|
24991
|
+
liveTurnPendingEvidence: resolveLiveTurnPendingEvidence(components, sessionId),
|
|
24992
|
+
boundedBackstop: backstopKind === "ackedHoldDeathDeadlineFired"
|
|
24993
|
+
},
|
|
24875
24994
|
source: "daemon_reconcile_transcript_completion"
|
|
24876
24995
|
});
|
|
24877
24996
|
if (result.reconciled) {
|
|
@@ -25317,10 +25436,10 @@ async function evaluateEarlyIdleTranscriptArm(components, mesh, store, row, loca
|
|
|
25317
25436
|
if (profile) return profile.emitsPtyTurnEvents === false;
|
|
25318
25437
|
return verdict === "UNKNOWN";
|
|
25319
25438
|
}
|
|
25320
|
-
function propagateWatchdogTranscriptCompletion(meshId, row, evidence, source) {
|
|
25439
|
+
function propagateWatchdogTranscriptCompletion(components, meshId, row, evidence, source, opts) {
|
|
25321
25440
|
const sessionId = readNonEmptyString(row.assignedSessionId) || evidence.sessionId;
|
|
25322
25441
|
if (!sessionId || !readNonEmptyString(evidence.finalSummary)) {
|
|
25323
|
-
return
|
|
25442
|
+
return "unavailable";
|
|
25324
25443
|
}
|
|
25325
25444
|
try {
|
|
25326
25445
|
const result = reconcileDirectDispatchCompletionFromTranscript({
|
|
@@ -25336,11 +25455,26 @@ function propagateWatchdogTranscriptCompletion(meshId, row, evidence, source) {
|
|
|
25336
25455
|
// The watchdog poll already enforced idle + post-dispatch + no-trailing-tool + streak;
|
|
25337
25456
|
// skip the reconcile's own grace/transcript_not_proven gates (dedup backstops remain).
|
|
25338
25457
|
preValidatedTranscriptEvidence: true,
|
|
25458
|
+
// MID-TURN-CAUSAL-ADMISSION (rc.16): the transcript poll's structural evidence can
|
|
25459
|
+
// still straddle a genuinely mid-turn LOCAL worker (the incident shape: transcript
|
|
25460
|
+
// reads idle-with-final-assistant while the raw PTY is mid-tool). Route the live
|
|
25461
|
+
// adapter's synchronous probe through the unified choke point. The EARLY-IDLE
|
|
25462
|
+
// caller is an eager path (no opts) → a pending verdict defers; the redrive-deadline
|
|
25463
|
+
// caller passes boundedBackstop (the max-wait net) → the veto yields, preserving the
|
|
25464
|
+
// genuine-final fail-open semantics.
|
|
25465
|
+
causalAdmission: {
|
|
25466
|
+
liveTurnPendingEvidence: resolveLiveTurnPendingEvidence(components, sessionId),
|
|
25467
|
+
boundedBackstop: opts?.boundedBackstop === true
|
|
25468
|
+
},
|
|
25339
25469
|
source
|
|
25340
25470
|
});
|
|
25341
|
-
|
|
25471
|
+
if (result.reconciled || result.alreadyTerminal === true) return "propagated";
|
|
25472
|
+
if (result.reason === "live_turn_pending_evidence" || result.reason === "trailing_tool_activity_after_final_assistant") {
|
|
25473
|
+
return "deferred";
|
|
25474
|
+
}
|
|
25475
|
+
return "unavailable";
|
|
25342
25476
|
} catch {
|
|
25343
|
-
return
|
|
25477
|
+
return "unavailable";
|
|
25344
25478
|
}
|
|
25345
25479
|
}
|
|
25346
25480
|
async function recoverStrandedAssignedDispatches(components, mesh, store, localDaemonId, selfIds = []) {
|
|
@@ -25374,14 +25508,28 @@ async function recoverStrandedAssignedDispatches(components, mesh, store, localD
|
|
|
25374
25508
|
minFinalAssistantAgeMs: ASSIGNED_IDLE_TRANSCRIPT_COMPLETE_MS
|
|
25375
25509
|
});
|
|
25376
25510
|
if (terminalEvidence) {
|
|
25377
|
-
|
|
25378
|
-
|
|
25379
|
-
const propagated = propagateWatchdogTranscriptCompletion(
|
|
25511
|
+
const propagation = propagateWatchdogTranscriptCompletion(
|
|
25512
|
+
components,
|
|
25380
25513
|
meshId,
|
|
25381
25514
|
row,
|
|
25382
25515
|
terminalEvidence,
|
|
25383
25516
|
"early_idle_transcript_evidence"
|
|
25384
25517
|
);
|
|
25518
|
+
if (propagation === "deferred") {
|
|
25519
|
+
assignedIdleFinalAssistantSince.delete(idleTranscriptStreakKey);
|
|
25520
|
+
LOG.info("MeshReconcile", `Deferred early transcript completion for task ${row.id} on mesh ${meshId} (node=${row.assignedNodeId ?? "?"} session=${row.assignedSessionId ?? "?"}): the live adapter still reports the turn pending (mid-tool / streaming / modal) \u2014 holding; the completion re-evaluates next tick`);
|
|
25521
|
+
traceMeshEventDrop("early_idle_completion_deferred_live_pending", {
|
|
25522
|
+
taskId: row.id,
|
|
25523
|
+
sessionId: row.assignedSessionId,
|
|
25524
|
+
nodeId: row.assignedNodeId,
|
|
25525
|
+
meshId,
|
|
25526
|
+
event: "agent:generating_completed"
|
|
25527
|
+
});
|
|
25528
|
+
continue;
|
|
25529
|
+
}
|
|
25530
|
+
assignedIdleFinalAssistantSince.delete(idleTranscriptStreakKey);
|
|
25531
|
+
updateTaskStatus(meshId, row.id, terminalEvidence.outcome);
|
|
25532
|
+
const propagated = propagation === "propagated";
|
|
25385
25533
|
if (!propagated && !findTerminalLedgerEvidenceForTask({ meshId, taskId: row.id })) {
|
|
25386
25534
|
try {
|
|
25387
25535
|
appendLedgerEntry(meshId, {
|
|
@@ -25556,12 +25704,15 @@ async function recoverStrandedAssignedDispatches(components, mesh, store, localD
|
|
|
25556
25704
|
if (terminalEvidence) {
|
|
25557
25705
|
deliveredNoTurnUnknownStreak.delete(streakKey);
|
|
25558
25706
|
updateTaskStatus(meshId, row.id, terminalEvidence.outcome);
|
|
25559
|
-
const
|
|
25707
|
+
const propagation = propagateWatchdogTranscriptCompletion(
|
|
25708
|
+
components,
|
|
25560
25709
|
meshId,
|
|
25561
25710
|
row,
|
|
25562
25711
|
terminalEvidence,
|
|
25563
|
-
"redrive_deadline_transcript_evidence"
|
|
25712
|
+
"redrive_deadline_transcript_evidence",
|
|
25713
|
+
{ boundedBackstop: true }
|
|
25564
25714
|
);
|
|
25715
|
+
const propagated = propagation === "propagated";
|
|
25565
25716
|
if (!propagated && !findTerminalLedgerEvidenceForTask({ meshId, taskId: row.id })) {
|
|
25566
25717
|
try {
|
|
25567
25718
|
appendLedgerEntry(meshId, {
|
|
@@ -31100,7 +31251,9 @@ ${lastSnapshot}`;
|
|
|
31100
31251
|
const requiredStreak = this.isAutonomousMeshSession() ? _ProviderCliAdapter.STATIC_IDLE_POLL_CONFIRM_COUNT : 1;
|
|
31101
31252
|
this.staticIdlePollStreak += 1;
|
|
31102
31253
|
if (this.staticIdlePollStreak >= requiredStreak) {
|
|
31103
|
-
this.engine.confirmPollStaticIdle("poll_static_idle")
|
|
31254
|
+
if (this.engine.confirmPollStaticIdle("poll_static_idle")) {
|
|
31255
|
+
this.onStatusChange?.();
|
|
31256
|
+
}
|
|
31104
31257
|
this.staticIdlePollStreak = 0;
|
|
31105
31258
|
}
|
|
31106
31259
|
} else {
|
|
@@ -51121,6 +51274,50 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
51121
51274
|
isModalParked() {
|
|
51122
51275
|
return this.resolveModalParkStatus() !== null;
|
|
51123
51276
|
}
|
|
51277
|
+
/**
|
|
51278
|
+
* MID-TURN-LIVE-STATE-GATE (broader false-idle RCA, mid-turn follow-up): a live,
|
|
51279
|
+
* synchronous re-check of whether this session's CURRENT turn genuinely still has
|
|
51280
|
+
* unresolved work. Public wrapper so the coordinator (mesh-event-forwarding) can
|
|
51281
|
+
* independently re-verify an incoming agent:generating_completed for a LOCAL session
|
|
51282
|
+
* before trusting it — defense-in-depth against a race where the completion emit and the
|
|
51283
|
+
* coordinator's receipt straddle a state change (screen-redraw parse artifact, decoupled-
|
|
51284
|
+
* immediate emit). Reuses the EXACT same discriminators this instance's own finalization
|
|
51285
|
+
* gate (getCompletedFinalizationBlock) uses — hasAdapterPendingResponse() (adapter
|
|
51286
|
+
* isWaitingForResponse / currentTurnScope / isProcessing() / a non-empty partial response)
|
|
51287
|
+
* OR isModalParked() (a live approval/choice modal) — so a session this method reports
|
|
51288
|
+
* pending is, by construction, one the local finalization gate would also refuse to
|
|
51289
|
+
* finalize right now.
|
|
51290
|
+
*
|
|
51291
|
+
* NATIVE-TRAILING-TOOL-GATE (rc.16 follow-up): the three adapter-state discriminators
|
|
51292
|
+
* above are blind to a background shell tool that keeps a turn alive without the adapter
|
|
51293
|
+
* reporting a pending response — e.g. a backgrounded `sleep 40 &` between narration
|
|
51294
|
+
* bubbles on a write-lag native-source provider (claude-cli), which is deliberately
|
|
51295
|
+
* un-floored (noExternalTranscriptSource omitted, mission f2f6da1b owner decision) so its
|
|
51296
|
+
* transcript write-lag emits promptly. That un-flooring is correct for the ordinary
|
|
51297
|
+
* fraction-of-a-second trail, but it also means the growth-hold / busy-lease protections
|
|
51298
|
+
* in getCompletedFinalizationBlock never engage for claude-cli, so an interim final-
|
|
51299
|
+
* LOOKING bubble followed by continuing tool calls can still finalize as a completion
|
|
51300
|
+
* while the transcript demonstrably shows the turn still executing. Close that gap here,
|
|
51301
|
+
* narrowly: for a native-source provider only, reuse the SAME bounded transcript read the
|
|
51302
|
+
* class's own completion judgment already performs (probeNativeTranscriptSignals) and
|
|
51303
|
+
* apply the SAME trailing-tool-activity veto the transcript-synth admission choke point
|
|
51304
|
+
* uses (hasTrailingToolActivityAfterFinalAssistant) — the latest final-looking assistant
|
|
51305
|
+
* bubble followed by tool/terminal activity is interim narration, not a turn end. Fail-open
|
|
51306
|
+
* by construction: a non-native-source class (probe returns null), an unresolved
|
|
51307
|
+
* transcript, or a read error never reaches the veto, so a missing/unavailable transcript
|
|
51308
|
+
* can never wedge a session as "pending" forever.
|
|
51309
|
+
*/
|
|
51310
|
+
hasLiveTurnPendingEvidence() {
|
|
51311
|
+
if (this.hasAdapterPendingResponse() || this.isModalParked()) return true;
|
|
51312
|
+
try {
|
|
51313
|
+
const probe = this.probeNativeTranscriptSignals();
|
|
51314
|
+
if (probe?.snapshot?.available === true && Array.isArray(probe.messages)) {
|
|
51315
|
+
if (hasTrailingToolActivityAfterFinalAssistant(probe.messages)) return true;
|
|
51316
|
+
}
|
|
51317
|
+
} catch {
|
|
51318
|
+
}
|
|
51319
|
+
return false;
|
|
51320
|
+
}
|
|
51124
51321
|
/**
|
|
51125
51322
|
* PTY-OVERTRUST-DRAIN (Defect B). The deliverability/drain status the mesh
|
|
51126
51323
|
* reconcile loop must consult — the RAW adapter turn-state, with the
|
|
@@ -51611,7 +51808,8 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
51611
51808
|
}
|
|
51612
51809
|
completionFinalAssistantEvidence(parsedMessages, turnStartedAt) {
|
|
51613
51810
|
const turnClosed = !this.hasAdapterPendingResponse();
|
|
51614
|
-
|
|
51811
|
+
const preferNativeOverParsed = this.adapter?.chatMessagesOwnedExternally === true && this.busyLeaseGateEnabled();
|
|
51812
|
+
if (!preferNativeOverParsed && this.completionHasFinalAssistantMessage(parsedMessages, turnStartedAt)) {
|
|
51615
51813
|
return {
|
|
51616
51814
|
present: turnClosed,
|
|
51617
51815
|
messages: Array.isArray(parsedMessages) ? parsedMessages : [],
|
|
@@ -51621,7 +51819,8 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
51621
51819
|
const externalMessages = this.readExternalCompletionMessages();
|
|
51622
51820
|
if (externalMessages) {
|
|
51623
51821
|
const injectedTaskGenerating = this.injectedTaskHasStartedGenerating();
|
|
51624
|
-
const
|
|
51822
|
+
const trailingToolActivity = hasTrailingToolActivityAfterFinalAssistant(externalMessages);
|
|
51823
|
+
const present = injectedTaskGenerating && turnClosed && !trailingToolActivity && this.completionHasFinalAssistantMessage(externalMessages, turnStartedAt);
|
|
51625
51824
|
const lastVisibleAssistant = this.lastVisibleAssistantSummaryDetail(externalMessages);
|
|
51626
51825
|
if (lastVisibleAssistant.content) {
|
|
51627
51826
|
this.lastCompletionSummary = { content: lastVisibleAssistant.content, receivedAt: Date.now(), sourceTimestampMs: lastVisibleAssistant.timestampMs };
|
|
@@ -51632,6 +51831,13 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
51632
51831
|
source: "external-native"
|
|
51633
51832
|
};
|
|
51634
51833
|
}
|
|
51834
|
+
if (preferNativeOverParsed && this.completionHasFinalAssistantMessage(parsedMessages, turnStartedAt)) {
|
|
51835
|
+
return {
|
|
51836
|
+
present: turnClosed,
|
|
51837
|
+
messages: Array.isArray(parsedMessages) ? parsedMessages : [],
|
|
51838
|
+
source: "parsed"
|
|
51839
|
+
};
|
|
51840
|
+
}
|
|
51635
51841
|
return {
|
|
51636
51842
|
present: false,
|
|
51637
51843
|
messages: Array.isArray(parsedMessages) ? parsedMessages : [],
|
|
@@ -51859,6 +52065,18 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
51859
52065
|
} catch {
|
|
51860
52066
|
}
|
|
51861
52067
|
}
|
|
52068
|
+
if (adapterOwnsMessagesElsewhere && finalAssistantEvidence.source === "external-native" && this.busyLeaseGateEnabled()) {
|
|
52069
|
+
try {
|
|
52070
|
+
const snapshot = this.lastTranscriptSignalSnapshot;
|
|
52071
|
+
const transcriptAgeMs = snapshot?.available === true && typeof snapshot.detail?.ageMs === "number" && Number.isFinite(snapshot.detail.ageMs) ? snapshot.detail.ageMs : void 0;
|
|
52072
|
+
if (typeof transcriptAgeMs === "number") {
|
|
52073
|
+
if (transcriptAgeMs < PTY_PARSED_FINAL_ASSISTANT_QUIET_DWELL_MS) {
|
|
52074
|
+
return { reason: "native_source_final_assistant_quiet_dwell", terminal: false };
|
|
52075
|
+
}
|
|
52076
|
+
}
|
|
52077
|
+
} catch {
|
|
52078
|
+
}
|
|
52079
|
+
}
|
|
51862
52080
|
return null;
|
|
51863
52081
|
}
|
|
51864
52082
|
// (FALSEIDLE-a) Positive, structural proof that the latest approval entry was resolved
|
|
@@ -52486,7 +52704,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
52486
52704
|
return;
|
|
52487
52705
|
}
|
|
52488
52706
|
const latestOutputAt = typeof latestStatus?.lastOutputAt === "number" ? latestStatus.lastOutputAt : void 0;
|
|
52489
|
-
if (typeof pending.lastOutputAtArm === "number" && typeof latestOutputAt === "number" && latestOutputAt > pending.lastOutputAtArm) {
|
|
52707
|
+
if (!pending.loggedBlockReason && typeof pending.lastOutputAtArm === "number" && typeof latestOutputAt === "number" && latestOutputAt > pending.lastOutputAtArm) {
|
|
52490
52708
|
LOG.info("CLI", `[${this.type}] cancelled pending completed (new PTY output during settle: ${pending.lastOutputAtArm}\u2192${latestOutputAt})`);
|
|
52491
52709
|
if (this.completionTraceOn()) this.recordCompletionGateTrace("cancel", {
|
|
52492
52710
|
blockReason: "new_pty_output",
|
|
@@ -56480,6 +56698,7 @@ init_state_store();
|
|
|
56480
56698
|
init_recent_activity();
|
|
56481
56699
|
init_chat_history();
|
|
56482
56700
|
init_mesh_events_utils();
|
|
56701
|
+
init_mesh_queue_assignment();
|
|
56483
56702
|
init_logger();
|
|
56484
56703
|
async function forwardConversationPrefsToCoordinator(ctx, sessionId, patch) {
|
|
56485
56704
|
const dispatch = ctx.deps.dispatchMeshCommand;
|
|
@@ -56594,8 +56813,8 @@ var cliAgentHandlers = {
|
|
|
56594
56813
|
};
|
|
56595
56814
|
},
|
|
56596
56815
|
agent_command: async (ctx, args) => {
|
|
56816
|
+
const dispatchSessionId = readStringValue(args?.targetSessionId, args?.sessionId, args?.instanceId);
|
|
56597
56817
|
{
|
|
56598
|
-
const dispatchSessionId = readStringValue(args?.targetSessionId, args?.sessionId, args?.instanceId);
|
|
56599
56818
|
const dispatchMeshContext = args?.meshContext;
|
|
56600
56819
|
if (dispatchSessionId && dispatchMeshContext) {
|
|
56601
56820
|
try {
|
|
@@ -56629,18 +56848,23 @@ var cliAgentHandlers = {
|
|
|
56629
56848
|
const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => meshNodeIdMatches(n, dispatchNodeId)) : void 0;
|
|
56630
56849
|
const { shouldDeferDispatchForBootstrap: shouldDeferDispatchForBootstrap2 } = await Promise.resolve().then(() => (init_worktree_bootstrap_config(), worktree_bootstrap_config_exports));
|
|
56631
56850
|
if (shouldDeferDispatchForBootstrap2(nodeObj)) {
|
|
56632
|
-
|
|
56633
|
-
|
|
56634
|
-
|
|
56635
|
-
|
|
56636
|
-
|
|
56637
|
-
|
|
56638
|
-
|
|
56639
|
-
|
|
56640
|
-
|
|
56641
|
-
|
|
56642
|
-
|
|
56643
|
-
|
|
56851
|
+
const dispatchSessionState = dispatchSessionId ? ctx.deps.instanceManager?.getInstance?.(dispatchSessionId)?.getState?.() : void 0;
|
|
56852
|
+
const sessionConfirmedReady = !!dispatchSessionState && isIdleSessionState(dispatchSessionState);
|
|
56853
|
+
if (!sessionConfirmedReady) {
|
|
56854
|
+
return {
|
|
56855
|
+
success: false,
|
|
56856
|
+
recoverable: true,
|
|
56857
|
+
dispatched: false,
|
|
56858
|
+
code: "mesh_node_bootstrap_pending",
|
|
56859
|
+
reason: "bootstrap_still_running",
|
|
56860
|
+
nodeId: dispatchNodeId,
|
|
56861
|
+
meshId: dispatchMeshId,
|
|
56862
|
+
...readStringValue(meshCtx?.taskId) ? { taskId: readStringValue(meshCtx?.taskId) } : {},
|
|
56863
|
+
error: `Node '${dispatchNodeId}' worktree bootstrap is still running; a task injected now would land in the session input buffer before the provider is ready to consume it and be silently lost. Dispatch deferred.`,
|
|
56864
|
+
nextAction: "Wait for the worktree_bootstrap_complete event (or poll mesh_status until the node session is ready), then re-send the task with mesh_send_task. Alternatively use mesh_enqueue_task so the queue auto-assigns it once a ready session is available."
|
|
56865
|
+
};
|
|
56866
|
+
}
|
|
56867
|
+
LOG.info("MeshQueue", `Overriding stale worktreeBootstrap 'running' flag for node ${dispatchNodeId}: explicit target session ${dispatchSessionId} is independently confirmed idle/ready \u2014 dispatching mesh_send_task directly.`);
|
|
56644
56868
|
}
|
|
56645
56869
|
} catch {
|
|
56646
56870
|
}
|
|
@@ -78316,6 +78540,7 @@ export {
|
|
|
78316
78540
|
handleGitCommand,
|
|
78317
78541
|
hasCdpManager,
|
|
78318
78542
|
hasPendingDependents,
|
|
78543
|
+
hasTrailingToolActivityAfterFinalAssistant,
|
|
78319
78544
|
hashSignatureParts,
|
|
78320
78545
|
initDaemonComponents,
|
|
78321
78546
|
insertDirectDispatch,
|