@adhdev/daemon-core 0.9.82-rc.405 → 0.9.82-rc.407
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/cli-adapters/cli-state-engine.d.ts +1 -0
- package/dist/cli-adapters/provider-cli-adapter.d.ts +1 -0
- package/dist/index.js +91 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +91 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/cli-adapters/cli-state-engine.ts +10 -0
- package/src/cli-adapters/provider-cli-adapter.ts +5 -0
- package/src/mesh/mesh-reconcile-loop.ts +129 -14
- package/src/providers/cli-provider-instance.ts +29 -3
|
@@ -231,6 +231,7 @@ export declare class ProviderCliAdapter implements CliAdapter {
|
|
|
231
231
|
get currentTurnScope(): TurnParseScope | null;
|
|
232
232
|
set currentTurnScope(v: TurnParseScope | null);
|
|
233
233
|
get currentTurnTaskId(): string | null;
|
|
234
|
+
get currentTurnStartedAt(): number;
|
|
234
235
|
get responseEpoch(): number;
|
|
235
236
|
set responseEpoch(v: number);
|
|
236
237
|
get submitRetryUsed(): boolean;
|
package/dist/index.js
CHANGED
|
@@ -399,10 +399,10 @@ function readInjected(value) {
|
|
|
399
399
|
}
|
|
400
400
|
function getDaemonBuildInfo() {
|
|
401
401
|
if (cached) return cached;
|
|
402
|
-
const commit = readInjected(true ? "
|
|
403
|
-
const commitShort = readInjected(true ? "
|
|
404
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
405
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
402
|
+
const commit = readInjected(true ? "bfd7d9b1d38a7d1f4709fbad2627c56b5a1ae342" : void 0) ?? "unknown";
|
|
403
|
+
const commitShort = readInjected(true ? "bfd7d9b1" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
404
|
+
const version = readInjected(true ? "0.9.82-rc.407" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
405
|
+
const builtAt = readInjected(true ? "2026-06-28T06:12:15.473Z" : void 0);
|
|
406
406
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
407
407
|
return cached;
|
|
408
408
|
}
|
|
@@ -16371,6 +16371,20 @@ function resolveReconcileIntervalMs() {
|
|
|
16371
16371
|
}
|
|
16372
16372
|
return DEFAULT_RECONCILE_INTERVAL_MS;
|
|
16373
16373
|
}
|
|
16374
|
+
function resolveTunedReconcileMs(envName, def, min, max) {
|
|
16375
|
+
const raw = readNonEmptyString2(process.env[envName]);
|
|
16376
|
+
if (raw) {
|
|
16377
|
+
const parsed = Number.parseInt(raw, 10);
|
|
16378
|
+
if (Number.isFinite(parsed) && parsed >= min && parsed <= max) return parsed;
|
|
16379
|
+
}
|
|
16380
|
+
return def;
|
|
16381
|
+
}
|
|
16382
|
+
function resolveMinIdleSettleMs() {
|
|
16383
|
+
return resolveTunedReconcileMs("MESH_INFLIGHT_MIN_IDLE_SETTLE_MS", 16e3, 0, 12e4);
|
|
16384
|
+
}
|
|
16385
|
+
function resolveAckedTurnSettleMs() {
|
|
16386
|
+
return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_TURN_SETTLE_MS", 2e4, 0, 18e4);
|
|
16387
|
+
}
|
|
16374
16388
|
function inFlightSynthKey(meshId, taskId) {
|
|
16375
16389
|
return `${meshId}::${taskId}`;
|
|
16376
16390
|
}
|
|
@@ -16947,6 +16961,33 @@ function unwrapReadChatPayload(raw) {
|
|
|
16947
16961
|
function readChatPayloadStatus(payload) {
|
|
16948
16962
|
return readNonEmptyString2(payload?.status).toLowerCase();
|
|
16949
16963
|
}
|
|
16964
|
+
function realTerminalEmitPendingForTask(meshId, taskId) {
|
|
16965
|
+
let pending;
|
|
16966
|
+
try {
|
|
16967
|
+
pending = getPendingMeshCoordinatorEvents(meshId);
|
|
16968
|
+
} catch {
|
|
16969
|
+
return false;
|
|
16970
|
+
}
|
|
16971
|
+
return pending.some((e) => readNonEmptyString2(e.metadataEvent?.taskId) === taskId && (e.event === "agent:generating_completed" || e.event === "agent:stopped"));
|
|
16972
|
+
}
|
|
16973
|
+
async function reprobeWorkerStatus(components, args) {
|
|
16974
|
+
try {
|
|
16975
|
+
if (args.isLocalNode) {
|
|
16976
|
+
const r = await components.commandHandler.handle("read_chat", args.readArgs);
|
|
16977
|
+
if (r && r.success === false) return null;
|
|
16978
|
+
return readChatPayloadStatus(unwrapReadChatPayload(r));
|
|
16979
|
+
}
|
|
16980
|
+
if (components.dispatchMeshCommand) {
|
|
16981
|
+
const r = await components.dispatchMeshCommand(args.nodeDaemonId, "read_chat", args.readArgs);
|
|
16982
|
+
const p = unwrapReadChatPayload(r);
|
|
16983
|
+
if (p && p.success === false) return null;
|
|
16984
|
+
return readChatPayloadStatus(p);
|
|
16985
|
+
}
|
|
16986
|
+
} catch {
|
|
16987
|
+
return null;
|
|
16988
|
+
}
|
|
16989
|
+
return null;
|
|
16990
|
+
}
|
|
16950
16991
|
async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds, localDaemonId) {
|
|
16951
16992
|
const dispatches = getActiveDirectDispatches(mesh.id);
|
|
16952
16993
|
if (dispatches.length === 0) return;
|
|
@@ -16994,18 +17035,34 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
|
|
|
16994
17035
|
}
|
|
16995
17036
|
if (!payload) continue;
|
|
16996
17037
|
const synthKey = inFlightSynthKey(mesh.id, taskId);
|
|
17038
|
+
const nowMs = Date.now();
|
|
16997
17039
|
if (readChatPayloadStatus(payload) !== "idle") {
|
|
16998
17040
|
inFlightIdleObservationCounts.delete(synthKey);
|
|
16999
17041
|
continue;
|
|
17000
17042
|
}
|
|
17001
17043
|
if (dispatch.status === "acked") {
|
|
17002
|
-
const
|
|
17003
|
-
|
|
17004
|
-
|
|
17005
|
-
|
|
17044
|
+
const prior = inFlightIdleObservationCounts.get(synthKey);
|
|
17045
|
+
const firstIdleAtMs = prior?.firstIdleAtMs ?? nowMs;
|
|
17046
|
+
const idleStreak = (prior?.count ?? 0) + 1;
|
|
17047
|
+
inFlightIdleObservationCounts.set(synthKey, { count: idleStreak, firstIdleAtMs });
|
|
17048
|
+
const idleSettleMs = nowMs - firstIdleAtMs;
|
|
17049
|
+
const minIdleSettleMs = resolveMinIdleSettleMs();
|
|
17050
|
+
const ackedTurnSettleMs = resolveAckedTurnSettleMs();
|
|
17051
|
+
const ackedAtMs = Date.parse(readNonEmptyString2(dispatch.updatedAt));
|
|
17052
|
+
const sinceAckMs = Number.isFinite(ackedAtMs) ? nowMs - ackedAtMs : Number.POSITIVE_INFINITY;
|
|
17053
|
+
const tickGuardMet = idleStreak >= REQUIRED_CONSECUTIVE_IDLE_TICKS_FOR_INFLIGHT_SYNTH;
|
|
17054
|
+
const settleGuardMet = idleSettleMs >= minIdleSettleMs;
|
|
17055
|
+
const ackGuardMet = sinceAckMs >= ackedTurnSettleMs;
|
|
17056
|
+
if (!tickGuardMet || !settleGuardMet || !ackGuardMet) {
|
|
17057
|
+
LOG.info("MeshReconcile", `In-flight synth hold: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) idle ${idleStreak}/${REQUIRED_CONSECUTIVE_IDLE_TICKS_FOR_INFLIGHT_SYNTH} tick(s), settle ${Math.round(idleSettleMs / 1e3)}s/${Math.round(minIdleSettleMs / 1e3)}s, since-ack ${Number.isFinite(sinceAckMs) ? Math.round(sinceAckMs / 1e3) + "s" : "\u221E"}/${Math.round(ackedTurnSettleMs / 1e3)}s \u2014 deferring completion synth until the worker's turn genuinely settles (guards against a mid-turn idle window pre-empting the real completion)`);
|
|
17006
17058
|
continue;
|
|
17007
17059
|
}
|
|
17008
17060
|
}
|
|
17061
|
+
if (realTerminalEmitPendingForTask(mesh.id, taskId)) {
|
|
17062
|
+
inFlightIdleObservationCounts.delete(synthKey);
|
|
17063
|
+
LOG.info("MeshReconcile", `Worker-emit priority: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) has a real terminal completion already queued \u2014 yielding synth to the worker's own emit`);
|
|
17064
|
+
continue;
|
|
17065
|
+
}
|
|
17009
17066
|
const messages = Array.isArray(payload.messages) ? payload.messages : [];
|
|
17010
17067
|
const evidence = extractFinalAssistantSummaryEvidence(messages);
|
|
17011
17068
|
if (!evidence.finalSummary) continue;
|
|
@@ -17022,6 +17079,12 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
|
|
|
17022
17079
|
}, `transcriptAt=${evidence.transcriptMessageAt} < dispatchedAt=${dispatch.dispatchedAt}`);
|
|
17023
17080
|
continue;
|
|
17024
17081
|
}
|
|
17082
|
+
const reprobeStatus = await reprobeWorkerStatus(components, { isLocalNode, nodeDaemonId, readArgs });
|
|
17083
|
+
if (reprobeStatus && reprobeStatus !== "idle") {
|
|
17084
|
+
inFlightIdleObservationCounts.delete(synthKey);
|
|
17085
|
+
LOG.info("MeshReconcile", `Live re-probe defer: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read '${reprobeStatus}' at synth-commit time \u2014 worker resumed generating; deferring synth to a later tick`);
|
|
17086
|
+
continue;
|
|
17087
|
+
}
|
|
17025
17088
|
const providerSessionId = readNonEmptyString2(payload.providerSessionId);
|
|
17026
17089
|
const coordinatorDaemonId = selfIds.find((id) => !!id);
|
|
17027
17090
|
try {
|
|
@@ -19664,6 +19727,13 @@ var init_cli_state_engine = __esm({
|
|
|
19664
19727
|
// queued in pendingOutbound and only flushed asynchronously after idle), so the
|
|
19665
19728
|
// completion event carries the correct id instead of the racy session scalar.
|
|
19666
19729
|
currentTurnTaskId = null;
|
|
19730
|
+
// GENERATING-BOUNDARY (R4d): wall-clock when the most recently STARTED turn began
|
|
19731
|
+
// (set by onTurnStarted, persists past completion until the next turn starts).
|
|
19732
|
+
// The startup-grace idle-stayed synthesis anchors its window on when the FIRST turn
|
|
19733
|
+
// STARTED — not on when it finished — so a turn dispatched a few seconds after the
|
|
19734
|
+
// grace collapse and then running for a non-trivial duration is still attributed to
|
|
19735
|
+
// the startup collapse even though its COMPLETION lands past a now-anchored window.
|
|
19736
|
+
currentTurnStartedAt = 0;
|
|
19667
19737
|
activeModal = null;
|
|
19668
19738
|
// ── Approval ─────────────────────────────────────
|
|
19669
19739
|
lastApprovalResolvedAt = 0;
|
|
@@ -19774,6 +19844,7 @@ var init_cli_state_engine = __esm({
|
|
|
19774
19844
|
this.clearIdleFinishCandidate("send_message");
|
|
19775
19845
|
this.currentTurnScope = turnScope;
|
|
19776
19846
|
this.currentTurnTaskId = typeof turnScope.taskId === "string" && turnScope.taskId.trim() ? turnScope.taskId : null;
|
|
19847
|
+
this.currentTurnStartedAt = Date.now();
|
|
19777
19848
|
this.responseEpoch += 1;
|
|
19778
19849
|
}
|
|
19779
19850
|
/** Called when PTY exits */
|
|
@@ -22252,6 +22323,13 @@ ${lastSnapshot}`;
|
|
|
22252
22323
|
get currentTurnTaskId() {
|
|
22253
22324
|
return this.engine.currentTurnTaskId;
|
|
22254
22325
|
}
|
|
22326
|
+
// R4d: wall-clock when the most recently started turn began (persists past settle).
|
|
22327
|
+
// The provider instance's startup-grace idle-stayed synthesis anchors its window on
|
|
22328
|
+
// this so a delayed-dispatch first turn whose duration overruns the now-anchored
|
|
22329
|
+
// window is still attributed to the startup collapse.
|
|
22330
|
+
get currentTurnStartedAt() {
|
|
22331
|
+
return this.engine.currentTurnStartedAt;
|
|
22332
|
+
}
|
|
22255
22333
|
get responseEpoch() {
|
|
22256
22334
|
return this.engine.responseEpoch;
|
|
22257
22335
|
}
|
|
@@ -41365,7 +41443,11 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
41365
41443
|
}
|
|
41366
41444
|
this.lastStatus = newStatus;
|
|
41367
41445
|
}
|
|
41368
|
-
|
|
41446
|
+
const firstTurnStartedAt = typeof this.adapter?.currentTurnStartedAt === "number" ? this.adapter.currentTurnStartedAt : 0;
|
|
41447
|
+
const collapsedAt = this.startupGraceCollapseAt;
|
|
41448
|
+
const turnStartedWithinCollapseWindow = collapsedAt !== null && firstTurnStartedAt > 0 && firstTurnStartedAt >= collapsedAt && firstTurnStartedAt - collapsedAt < STARTUP_GRACE_IDLE_COLLAPSE_WINDOW_MS;
|
|
41449
|
+
const nowWithinCollapseWindow = collapsedAt !== null && now - collapsedAt < STARTUP_GRACE_IDLE_COLLAPSE_WINDOW_MS;
|
|
41450
|
+
if (newStatus === "idle" && previousStatus === "idle" && (turnStartedWithinCollapseWindow || nowWithinCollapseWindow)) {
|
|
41369
41451
|
this.maybeSynthesizeStartupGraceCollapse(chatTitle, now, "startup_grace_idle_turn_collapse");
|
|
41370
41452
|
}
|
|
41371
41453
|
if (newStatus === "idle" && adapterStatus.fsmReadySeen === true && !this.agentReadyEmitted) {
|