@adhdev/daemon-standalone 1.0.49-rc.1 → 1.0.49-rc.11
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 +324 -50
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/public/assets/index-BeC2kIKA.js +116 -0
- package/public/assets/index-CqyS0XiL.css +1 -0
- package/public/index.html +2 -2
- package/vendor/mcp-server/index.js +7 -3
- package/vendor/mcp-server/index.js.map +1 -1
- package/public/assets/index-BjPWjmsH.css +0 -1
- package/public/assets/index-C5f45LAh.js +0 -116
package/dist/index.js
CHANGED
|
@@ -37056,10 +37056,10 @@ var require_dist3 = __commonJS({
|
|
|
37056
37056
|
}
|
|
37057
37057
|
function getDaemonBuildInfo() {
|
|
37058
37058
|
if (cached2) return cached2;
|
|
37059
|
-
const commit = readInjected(true ? "
|
|
37060
|
-
const commitShort = readInjected(true ? "
|
|
37061
|
-
const version2 = readInjected(true ? "1.0.49-rc.
|
|
37062
|
-
const builtAt = readInjected(true ? "2026-08-
|
|
37059
|
+
const commit = readInjected(true ? "a21460656698fe5b5567132109fe159f8ae2c56b" : void 0) ?? "unknown";
|
|
37060
|
+
const commitShort = readInjected(true ? "a2146065" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
37061
|
+
const version2 = readInjected(true ? "1.0.49-rc.11" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
37062
|
+
const builtAt = readInjected(true ? "2026-08-15T02:43:45.229Z" : void 0);
|
|
37063
37063
|
cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
|
|
37064
37064
|
return cached2;
|
|
37065
37065
|
}
|
|
@@ -40501,6 +40501,13 @@ child.on('exit', () => process.exit(0));
|
|
|
40501
40501
|
if (typeof retryAtMs !== "number" || retryAtMs > now) return false;
|
|
40502
40502
|
return (failureRetries.get(provider)?.failures ?? 0) <= QUOTA_FAILURE_MAX_RETRIES;
|
|
40503
40503
|
}
|
|
40504
|
+
function isSnapshotStaleForRouting(provider, now = Date.now()) {
|
|
40505
|
+
const entry = cache.get(provider);
|
|
40506
|
+
if (!entry) return false;
|
|
40507
|
+
const updatedAt = Number(entry.updatedAt);
|
|
40508
|
+
if (!Number.isFinite(updatedAt) || updatedAt <= 0) return true;
|
|
40509
|
+
return now - updatedAt >= QUOTA_ROUTABLE_MAX_AGE_MS;
|
|
40510
|
+
}
|
|
40504
40511
|
function updateFailureRetry(provider, fetch2, isEnabled) {
|
|
40505
40512
|
const entry = cache.get(provider);
|
|
40506
40513
|
const retryAtMs = entry && entry.status !== "ok" ? entry.metadata?.retryAtMs : void 0;
|
|
@@ -40551,7 +40558,7 @@ child.on('exit', () => process.exit(0));
|
|
|
40551
40558
|
} catch {
|
|
40552
40559
|
active = false;
|
|
40553
40560
|
}
|
|
40554
|
-
const needsBackfill = options.isEnabled ? fetchers.some(({ provider }) => options.isEnabled(provider) && (!cache.has(provider) || isFailureRetryDue(provider))) : false;
|
|
40561
|
+
const needsBackfill = options.isEnabled ? fetchers.some(({ provider }) => options.isEnabled(provider) && (!cache.has(provider) || isFailureRetryDue(provider) || isSnapshotStaleForRouting(provider))) : false;
|
|
40555
40562
|
if (!active && !needsBackfill) return;
|
|
40556
40563
|
running = true;
|
|
40557
40564
|
void refreshQuotaCacheOnce(fetchers, options.isEnabled).catch((e) => LOG2.warn("Quota", `Quota refresh tick error: ${e?.message || e}`)).finally(() => {
|
|
@@ -40613,6 +40620,7 @@ child.on('exit', () => process.exit(0));
|
|
|
40613
40620
|
var hydrated;
|
|
40614
40621
|
var QUOTA_FAILURE_MAX_RETRIES;
|
|
40615
40622
|
var failureRetries;
|
|
40623
|
+
var QUOTA_ROUTABLE_MAX_AGE_MS;
|
|
40616
40624
|
var WORKING_STATUSES;
|
|
40617
40625
|
var bootRefreshInFlight;
|
|
40618
40626
|
var QUOTA_EVENT_REFRESH_DEBOUNCE_MS;
|
|
@@ -40639,6 +40647,7 @@ child.on('exit', () => process.exit(0));
|
|
|
40639
40647
|
hydrated = false;
|
|
40640
40648
|
QUOTA_FAILURE_MAX_RETRIES = 4;
|
|
40641
40649
|
failureRetries = /* @__PURE__ */ new Map();
|
|
40650
|
+
QUOTA_ROUTABLE_MAX_AGE_MS = 30 * 60 * 1e3;
|
|
40642
40651
|
WORKING_STATUSES = /* @__PURE__ */ new Set([
|
|
40643
40652
|
"generating",
|
|
40644
40653
|
"waiting_approval",
|
|
@@ -42270,6 +42279,8 @@ ${error48.message || ""}`;
|
|
|
42270
42279
|
interpolateArgs: () => interpolateArgs,
|
|
42271
42280
|
interpolateString: () => interpolateString,
|
|
42272
42281
|
isMeshTaskDifficulty: () => isMeshTaskDifficulty,
|
|
42282
|
+
isPhantomDaemonEntry: () => isPhantomDaemonEntry,
|
|
42283
|
+
isRawDaemonDoId: () => isRawDaemonDoId,
|
|
42273
42284
|
joinRepoPath: () => joinRepoPath,
|
|
42274
42285
|
machineCoreFromDaemonId: () => machineCoreFromDaemonId,
|
|
42275
42286
|
meshNodeIdMatches: () => meshNodeIdMatches,
|
|
@@ -42565,6 +42576,18 @@ ${error48.message || ""}`;
|
|
|
42565
42576
|
if (!left || !right) return false;
|
|
42566
42577
|
return left === right;
|
|
42567
42578
|
}
|
|
42579
|
+
function isRawDaemonDoId(id) {
|
|
42580
|
+
const trimmed = readString2(id);
|
|
42581
|
+
return !!trimmed && /^[0-9a-f]{64}$/i.test(trimmed);
|
|
42582
|
+
}
|
|
42583
|
+
function isPhantomDaemonEntry(entry) {
|
|
42584
|
+
if (!entry) return false;
|
|
42585
|
+
if (!isRawDaemonDoId(entry.id)) return false;
|
|
42586
|
+
const hasMachineEvidence = Boolean(
|
|
42587
|
+
readString2(entry.machineNickname) || readString2(entry.nickname) || readString2(entry.hostname) || readString2(entry.platform) || readString2(entry.machine?.hostname) || readString2(entry.machine?.platform) || readString2(entry.machineId) || Array.isArray(entry.sessions) && entry.sessions.length > 0
|
|
42588
|
+
);
|
|
42589
|
+
return !hasMachineEvidence;
|
|
42590
|
+
}
|
|
42568
42591
|
function machineCoreFromDaemonId(id) {
|
|
42569
42592
|
const trimmed = readString2(id);
|
|
42570
42593
|
if (!trimmed) return void 0;
|
|
@@ -55444,6 +55467,8 @@ ${rendered}`, "utf-8");
|
|
|
55444
55467
|
});
|
|
55445
55468
|
function readProviderPriorityFromPolicy(policy) {
|
|
55446
55469
|
const record2 = policy && typeof policy === "object" && !Array.isArray(policy) ? policy : {};
|
|
55470
|
+
const derived = deriveProviderPriorityFromSlots(record2.slots);
|
|
55471
|
+
if (derived.length) return derived;
|
|
55447
55472
|
const raw = record2.providerPriority;
|
|
55448
55473
|
if (Array.isArray(raw)) {
|
|
55449
55474
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -55454,7 +55479,7 @@ ${rendered}`, "utf-8");
|
|
|
55454
55479
|
});
|
|
55455
55480
|
if (explicit.length) return explicit;
|
|
55456
55481
|
}
|
|
55457
|
-
return
|
|
55482
|
+
return [];
|
|
55458
55483
|
}
|
|
55459
55484
|
function normalizeProviderRoles(value) {
|
|
55460
55485
|
if (!Array.isArray(value)) return [];
|
|
@@ -55536,7 +55561,7 @@ ${rendered}`, "utf-8");
|
|
|
55536
55561
|
const workspace = readStringValue(node.workspace, node.repoRoot, node.repo_root);
|
|
55537
55562
|
const workspaceName = workspace ? workingDirBasename(workspace) : void 0;
|
|
55538
55563
|
const host = readStringValue(node.machineName, node.machine_name, node.hostname, node.host, node.daemonId, node.daemon_id, node.machineId, node.machine_id);
|
|
55539
|
-
const provider = providerPriority[0] || (Array.isArray(node.providers) ? readStringValue(...node.providers) : void 0);
|
|
55564
|
+
const provider = readProviderPriorityFromPolicy(node.policy)[0] || providerPriority[0] || (Array.isArray(node.providers) ? readStringValue(...node.providers) : void 0);
|
|
55540
55565
|
const parts = [workspaceName, host, provider].filter(Boolean);
|
|
55541
55566
|
if (parts.length > 0) return parts.join(" \xB7 ");
|
|
55542
55567
|
return nodeId || "unidentified mesh node";
|
|
@@ -57712,7 +57737,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57712
57737
|
init_mesh_work_queue();
|
|
57713
57738
|
}
|
|
57714
57739
|
});
|
|
57715
|
-
function
|
|
57740
|
+
function directQuotaEntryFor(node, providerType) {
|
|
57716
57741
|
const facts = node?.nodeFacts;
|
|
57717
57742
|
if (!facts || typeof facts !== "object") return null;
|
|
57718
57743
|
const reportedAt = Number(facts.reportedAt);
|
|
@@ -57721,6 +57746,14 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57721
57746
|
if (!quota || typeof quota !== "object") return null;
|
|
57722
57747
|
return { facts: { reportedAt }, quota };
|
|
57723
57748
|
}
|
|
57749
|
+
function quotaEntryFor(node, providerType, context) {
|
|
57750
|
+
const direct = directQuotaEntryFor(node, providerType);
|
|
57751
|
+
if (direct) return direct;
|
|
57752
|
+
const sourceNodeId = typeof node?.clonedFromNodeId === "string" ? node.clonedFromNodeId.trim() : "";
|
|
57753
|
+
if (!sourceNodeId || !Array.isArray(context?.nodes)) return null;
|
|
57754
|
+
const sourceNode = context.nodes.find((candidate) => candidate !== node && meshNodeIdMatches(candidate, sourceNodeId));
|
|
57755
|
+
return sourceNode ? directQuotaEntryFor(sourceNode, providerType) : null;
|
|
57756
|
+
}
|
|
57724
57757
|
function quotaSnapshotAgeMs(facts, quota, now = Date.now()) {
|
|
57725
57758
|
const updatedAt = Number(quota.updatedAt);
|
|
57726
57759
|
if (!Number.isFinite(updatedAt) || updatedAt <= 0) return Number.POSITIVE_INFINITY;
|
|
@@ -57743,10 +57776,23 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57743
57776
|
const reporterNowMs = Number(quota.updatedAt) + ageMs2;
|
|
57744
57777
|
return resetsAt - reporterNowMs < imminentMs;
|
|
57745
57778
|
}
|
|
57746
|
-
function
|
|
57747
|
-
const
|
|
57779
|
+
function isRetainedWindowTrustworthy(window, facts, quota, policy, now) {
|
|
57780
|
+
const resetsAt = Number(window?.resetsAt);
|
|
57781
|
+
if (!Number.isFinite(resetsAt) || resetsAt <= 0) {
|
|
57782
|
+
return isQuotaSnapshotFresh(facts, quota, policy, now);
|
|
57783
|
+
}
|
|
57784
|
+
const ageMs2 = quotaSnapshotAgeMs(facts, quota, now);
|
|
57785
|
+
if (!Number.isFinite(ageMs2)) return false;
|
|
57786
|
+
const reporterNowMs = Number(quota.updatedAt) + ageMs2;
|
|
57787
|
+
if (!Number.isFinite(reporterNowMs)) return false;
|
|
57788
|
+
return resetsAt > reporterNowMs;
|
|
57789
|
+
}
|
|
57790
|
+
function evaluateProviderQuotaGate(node, providerType, policy, now = Date.now(), context) {
|
|
57791
|
+
const entry = quotaEntryFor(node, providerType, context);
|
|
57748
57792
|
if (!entry) return null;
|
|
57749
57793
|
const { facts, quota } = entry;
|
|
57794
|
+
let sessionTrustworthy = true;
|
|
57795
|
+
let weeklyTrustworthy = true;
|
|
57750
57796
|
if (quota.status !== "ok") {
|
|
57751
57797
|
if (quota.status === "error" && quota.metadata?.failureKind === "quota-exhausted" && isQuotaSnapshotFresh(facts, quota, policy, now)) {
|
|
57752
57798
|
return {
|
|
@@ -57756,12 +57802,15 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57756
57802
|
thresholdPercent: 0
|
|
57757
57803
|
};
|
|
57758
57804
|
}
|
|
57805
|
+
if (quota.metadata?.lastGoodWindows !== true) return null;
|
|
57806
|
+
sessionTrustworthy = isRetainedWindowTrustworthy(quota.session, facts, quota, policy, now);
|
|
57807
|
+
weeklyTrustworthy = isRetainedWindowTrustworthy(quota.weekly, facts, quota, policy, now);
|
|
57808
|
+
} else if (!isQuotaSnapshotFresh(facts, quota, policy, now)) {
|
|
57759
57809
|
return null;
|
|
57760
57810
|
}
|
|
57761
|
-
if (!isQuotaSnapshotFresh(facts, quota, policy, now)) return null;
|
|
57762
57811
|
const resolved = resolveQuotaRoutingPolicy(policy);
|
|
57763
57812
|
const session = remainingPercent(quota.session);
|
|
57764
|
-
if (session !== void 0 && session < resolved.sessionMinRemainingPercent && !isSessionResetImminent(quota.session, facts, quota, resolved.sessionResetImminentMs, now)) {
|
|
57813
|
+
if (sessionTrustworthy && session !== void 0 && session < resolved.sessionMinRemainingPercent && !isSessionResetImminent(quota.session, facts, quota, resolved.sessionResetImminentMs, now)) {
|
|
57765
57814
|
return {
|
|
57766
57815
|
reason: PROVIDER_QUOTA_SESSION_LOW_SKIP_REASON,
|
|
57767
57816
|
window: "session",
|
|
@@ -57770,7 +57819,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57770
57819
|
};
|
|
57771
57820
|
}
|
|
57772
57821
|
const weekly = remainingPercent(quota.weekly);
|
|
57773
|
-
if (weekly !== void 0 && weekly < resolved.weeklyMinRemainingPercent) {
|
|
57822
|
+
if (weeklyTrustworthy && weekly !== void 0 && weekly < resolved.weeklyMinRemainingPercent) {
|
|
57774
57823
|
return {
|
|
57775
57824
|
reason: PROVIDER_QUOTA_WEEKLY_LOW_SKIP_REASON,
|
|
57776
57825
|
window: "weekly",
|
|
@@ -57780,8 +57829,8 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57780
57829
|
}
|
|
57781
57830
|
return null;
|
|
57782
57831
|
}
|
|
57783
|
-
function expiryRiskForRanking(node, providerType, axis, policy, now = Date.now()) {
|
|
57784
|
-
const entry = quotaEntryFor(node, providerType);
|
|
57832
|
+
function expiryRiskForRanking(node, providerType, axis, policy, now = Date.now(), context) {
|
|
57833
|
+
const entry = quotaEntryFor(node, providerType, context);
|
|
57785
57834
|
if (!entry) return void 0;
|
|
57786
57835
|
const { facts, quota } = entry;
|
|
57787
57836
|
if (quota.status !== "ok") return void 0;
|
|
@@ -57800,19 +57849,19 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57800
57849
|
const elapsedFraction = Math.min(1, Math.max(0, 1 - (resetsAt - reporterNowMs) / windowMs));
|
|
57801
57850
|
return { remainingPercent: remaining, risk: remaining * elapsedFraction };
|
|
57802
57851
|
}
|
|
57803
|
-
function rankProvidersByQuotaGate(node, orderedProviderTypes, policy, now = Date.now()) {
|
|
57852
|
+
function rankProvidersByQuotaGate(node, orderedProviderTypes, policy, now = Date.now(), context) {
|
|
57804
57853
|
const clear = [];
|
|
57805
57854
|
const gated = [];
|
|
57806
57855
|
for (const providerType of orderedProviderTypes) {
|
|
57807
|
-
const block2 = evaluateProviderQuotaGate(node, providerType, policy, now);
|
|
57856
|
+
const block2 = evaluateProviderQuotaGate(node, providerType, policy, now, context);
|
|
57808
57857
|
if (block2) gated.push({ providerType, block: block2 });
|
|
57809
57858
|
else clear.push(providerType);
|
|
57810
57859
|
}
|
|
57811
|
-
const weeklyByProvider = new Map(clear.map((p) => [p, expiryRiskForRanking(node, p, "weekly", policy, now)]));
|
|
57860
|
+
const weeklyByProvider = new Map(clear.map((p) => [p, expiryRiskForRanking(node, p, "weekly", policy, now, context)]));
|
|
57812
57861
|
const headroomPercent = resolveQuotaRoutingPolicy(policy).sessionAxisWeeklyHeadroomPercent;
|
|
57813
57862
|
const weeklyMeasured = [...weeklyByProvider.values()].filter((w) => w !== void 0);
|
|
57814
57863
|
const sessionAxisActive = weeklyMeasured.length > 0 && weeklyMeasured.every((w) => w.remainingPercent > headroomPercent);
|
|
57815
|
-
const sessionByProvider = sessionAxisActive ? new Map(clear.map((p) => [p, expiryRiskForRanking(node, p, "session", policy, now)])) : void 0;
|
|
57864
|
+
const sessionByProvider = sessionAxisActive ? new Map(clear.map((p) => [p, expiryRiskForRanking(node, p, "session", policy, now, context)])) : void 0;
|
|
57816
57865
|
clear.sort((a, b) => {
|
|
57817
57866
|
const wa = weeklyByProvider.get(a);
|
|
57818
57867
|
const wb = weeklyByProvider.get(b);
|
|
@@ -57835,13 +57884,13 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57835
57884
|
});
|
|
57836
57885
|
return { clear, gated };
|
|
57837
57886
|
}
|
|
57838
|
-
function resolveRecoveryRelaunchProvider(node, failedProviderType, nodeProviderTypes = [], policy, now = Date.now()) {
|
|
57887
|
+
function resolveRecoveryRelaunchProvider(node, failedProviderType, nodeProviderTypes = [], policy, now = Date.now(), context) {
|
|
57839
57888
|
if (!failedProviderType) return { action: "block" };
|
|
57840
|
-
const block2 = evaluateProviderQuotaGate(node, failedProviderType, policy, now);
|
|
57889
|
+
const block2 = evaluateProviderQuotaGate(node, failedProviderType, policy, now, context);
|
|
57841
57890
|
if (!block2) return { action: "keep", providerType: failedProviderType };
|
|
57842
57891
|
const alternatives = nodeProviderTypes.filter((p) => p && p !== failedProviderType);
|
|
57843
57892
|
if (alternatives.length) {
|
|
57844
|
-
const ranked = rankProvidersByQuotaGate(node, alternatives, policy, now);
|
|
57893
|
+
const ranked = rankProvidersByQuotaGate(node, alternatives, policy, now, context);
|
|
57845
57894
|
if (ranked.clear.length) {
|
|
57846
57895
|
return { action: "fallback", providerType: ranked.clear[0], block: block2 };
|
|
57847
57896
|
}
|
|
@@ -57856,9 +57905,9 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57856
57905
|
}
|
|
57857
57906
|
return `QUOTA GATE: skipping recovery relaunch for node ${nodeId} \u2014 ${cause} and the node has no gate-clear alternative${taskId ? `; task ${taskId}` : ""} stays queued until a quota window resets`;
|
|
57858
57907
|
}
|
|
57859
|
-
function quotaRiskSnapshotForCandidates(node, orderedProviderTypes, policy, now = Date.now()) {
|
|
57908
|
+
function quotaRiskSnapshotForCandidates(node, orderedProviderTypes, policy, now = Date.now(), context) {
|
|
57860
57909
|
return orderedProviderTypes.map((providerType) => {
|
|
57861
|
-
const w = expiryRiskForRanking(node, providerType, "weekly", policy, now);
|
|
57910
|
+
const w = expiryRiskForRanking(node, providerType, "weekly", policy, now, context);
|
|
57862
57911
|
return {
|
|
57863
57912
|
providerType,
|
|
57864
57913
|
...w ? { remainingPercent: w.remainingPercent, risk: w.risk } : {}
|
|
@@ -57902,6 +57951,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57902
57951
|
var init_mesh_quota_routing = __esm2({
|
|
57903
57952
|
"src/mesh/mesh-quota-routing.ts"() {
|
|
57904
57953
|
"use strict";
|
|
57954
|
+
init_dist();
|
|
57905
57955
|
init_repo_mesh_types();
|
|
57906
57956
|
PROVIDER_QUOTA_SESSION_LOW_SKIP_REASON = "provider_quota_session_low";
|
|
57907
57957
|
PROVIDER_QUOTA_WEEKLY_LOW_SKIP_REASON = "provider_quota_weekly_low";
|
|
@@ -61941,7 +61991,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
61941
61991
|
LOG2.info("MeshQueue", `Deferring queue claim for node ${nodeId} (${sessionId}): an auto fast-forward is mutating its workspace \u2014 task left pending, claim re-fires next tick`);
|
|
61942
61992
|
return false;
|
|
61943
61993
|
}
|
|
61944
|
-
const quotaClaimBlock = evaluateProviderQuotaGate(node, providerType, mesh?.policy?.quotaRouting ?? null);
|
|
61994
|
+
const quotaClaimBlock = evaluateProviderQuotaGate(node, providerType, mesh?.policy?.quotaRouting ?? null, Date.now(), mesh);
|
|
61945
61995
|
if (quotaClaimBlock) {
|
|
61946
61996
|
if (quotaClaimBlock.reason === PROVIDER_QUOTA_EXHAUSTED_SKIP_REASON) {
|
|
61947
61997
|
LOG2.info("MeshQueue", `QUOTA GATE: deferring queue claim for node ${nodeId} (${sessionId}): provider '${providerType}' reported its quota EXHAUSTED \u2014 task left pending until the quota resets`);
|
|
@@ -62418,7 +62468,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
62418
62468
|
retractActionableSkipIfPreviouslyNotified(meshId, taskId);
|
|
62419
62469
|
}
|
|
62420
62470
|
}
|
|
62421
|
-
async function resolveUsableProvider(components, nodeId, node, meshId, requiredTags, task, quotaRouting) {
|
|
62471
|
+
async function resolveUsableProvider(components, nodeId, node, meshId, requiredTags, task, quotaRouting, quotaFactsContext) {
|
|
62422
62472
|
const providerLoader = components.providerLoader;
|
|
62423
62473
|
if (!providerLoader) return { reason: "provider_loader_unavailable" };
|
|
62424
62474
|
const slots = resolveNodeCapabilitySlots(node, meshId);
|
|
@@ -62466,8 +62516,8 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
62466
62516
|
if (!candidates.length) {
|
|
62467
62517
|
return { reason: `provider_priority_unusable: ${failed.join("; ") || nodeId}` };
|
|
62468
62518
|
}
|
|
62469
|
-
const ranked = rankProvidersByQuotaGate(node, candidates.map((c) => c.providerType), quotaRouting);
|
|
62470
|
-
const riskSnapshot = quotaRiskSnapshotForCandidates(node, ranked.clear, quotaRouting);
|
|
62519
|
+
const ranked = rankProvidersByQuotaGate(node, candidates.map((c) => c.providerType), quotaRouting, Date.now(), quotaFactsContext);
|
|
62520
|
+
const riskSnapshot = quotaRiskSnapshotForCandidates(node, ranked.clear, quotaRouting, Date.now(), quotaFactsContext);
|
|
62471
62521
|
if (!ranked.clear.length) {
|
|
62472
62522
|
const detail = ranked.gated.map((g) => `${g.providerType}: ${g.block.reason}`).join("; ");
|
|
62473
62523
|
LOG2.info("MeshQueue", `QUOTA GATE: every usable provider on node ${nodeId} is quota-gated (${detail}); leaving the task queued until a quota window resets`);
|
|
@@ -62718,7 +62768,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
62718
62768
|
}
|
|
62719
62769
|
autoLaunchInProgress.add(launchKey);
|
|
62720
62770
|
try {
|
|
62721
|
-
const resolved = await resolveUsableProvider(components, nodeId, node, meshId, task.requiredTags, { difficulty: task.difficulty, requiredTags: task.requiredTags }, mesh?.policy?.quotaRouting ?? null);
|
|
62771
|
+
const resolved = await resolveUsableProvider(components, nodeId, node, meshId, task.requiredTags, { difficulty: task.difficulty, requiredTags: task.requiredTags }, mesh?.policy?.quotaRouting ?? null, mesh);
|
|
62722
62772
|
if (!resolved.providerType) {
|
|
62723
62773
|
markSkip(nodeId, resolved.reason || "provider_unusable");
|
|
62724
62774
|
continue;
|
|
@@ -66393,7 +66443,9 @@ ${cleanBody}`;
|
|
|
66393
66443
|
node,
|
|
66394
66444
|
recoveryContext.failedProviderType,
|
|
66395
66445
|
resolveNodeCapabilitySlots(node, args.meshId).map((s2) => s2.provider),
|
|
66396
|
-
mesh?.policy?.quotaRouting ?? null
|
|
66446
|
+
mesh?.policy?.quotaRouting ?? null,
|
|
66447
|
+
Date.now(),
|
|
66448
|
+
mesh
|
|
66397
66449
|
) : { action: "block" };
|
|
66398
66450
|
const relaunchProviderType = relaunch.action === "block" ? null : relaunch.providerType;
|
|
66399
66451
|
if (node) {
|
|
@@ -68805,6 +68857,17 @@ ${cleanBody}`;
|
|
|
68805
68857
|
return void 0;
|
|
68806
68858
|
}
|
|
68807
68859
|
}
|
|
68860
|
+
function localGeneratingLabelIsContradicted(components, sessionId) {
|
|
68861
|
+
try {
|
|
68862
|
+
const probe = resolveLiveTurnPendingEvidence(components, sessionId);
|
|
68863
|
+
if (!probe) return false;
|
|
68864
|
+
if (probe()) return false;
|
|
68865
|
+
LOG2.info("MeshReconcile", `Session ${sessionId} reports FSM status 'generating' but its adapter has no live turn evidence \u2014 treating the label as stale so the early transcript-evidence rescue may evaluate it (the completion arm was likely orphaned by a continuity cancel)`);
|
|
68866
|
+
return true;
|
|
68867
|
+
} catch {
|
|
68868
|
+
return false;
|
|
68869
|
+
}
|
|
68870
|
+
}
|
|
68808
68871
|
async function evaluateEarlyIdleTranscriptArm(components, mesh, store, row, localDaemonId, selfIds = []) {
|
|
68809
68872
|
const sessionId = readNonEmptyString(row.assignedSessionId);
|
|
68810
68873
|
if (!sessionId) return false;
|
|
@@ -68820,7 +68883,9 @@ ${cleanBody}`;
|
|
|
68820
68883
|
}
|
|
68821
68884
|
}
|
|
68822
68885
|
const verdict = resolveSessionBusyVerdict(components, sessionId);
|
|
68823
|
-
if (verdict === "GENERATING")
|
|
68886
|
+
if (verdict === "GENERATING" && !localGeneratingLabelIsContradicted(components, sessionId)) {
|
|
68887
|
+
return false;
|
|
68888
|
+
}
|
|
68824
68889
|
if (verdict === "UNKNOWN") {
|
|
68825
68890
|
const nodeId = readNonEmptyString(row.assignedNodeId);
|
|
68826
68891
|
const node = (mesh.nodes ?? []).find((n) => n.id === nodeId);
|
|
@@ -93228,6 +93293,45 @@ ${marker}`,
|
|
|
93228
93293
|
init_config();
|
|
93229
93294
|
init_install();
|
|
93230
93295
|
init_logger();
|
|
93296
|
+
var SEMVER_PATTERN = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
93297
|
+
var NUMERIC_IDENTIFIER = /^\d+$/;
|
|
93298
|
+
function parseSemver(version2) {
|
|
93299
|
+
if (typeof version2 !== "string") return null;
|
|
93300
|
+
const match = version2.trim().replace(/^v/, "").match(SEMVER_PATTERN);
|
|
93301
|
+
if (!match) return null;
|
|
93302
|
+
return {
|
|
93303
|
+
major: Number(match[1]),
|
|
93304
|
+
minor: Number(match[2]),
|
|
93305
|
+
patch: Number(match[3]),
|
|
93306
|
+
prerelease: match[4] ? match[4].split(".") : []
|
|
93307
|
+
};
|
|
93308
|
+
}
|
|
93309
|
+
function comparePrerelease(a, b) {
|
|
93310
|
+
if (a.length === 0 && b.length === 0) return 0;
|
|
93311
|
+
if (a.length === 0) return 1;
|
|
93312
|
+
if (b.length === 0) return -1;
|
|
93313
|
+
for (let i = 0; i < Math.min(a.length, b.length); i += 1) {
|
|
93314
|
+
const idA = a[i];
|
|
93315
|
+
const idB = b[i];
|
|
93316
|
+
if (idA === idB) continue;
|
|
93317
|
+
const numA = NUMERIC_IDENTIFIER.test(idA);
|
|
93318
|
+
const numB = NUMERIC_IDENTIFIER.test(idB);
|
|
93319
|
+
if (numA && numB) return Number(idA) < Number(idB) ? -1 : 1;
|
|
93320
|
+
if (numA) return -1;
|
|
93321
|
+
if (numB) return 1;
|
|
93322
|
+
return idA < idB ? -1 : 1;
|
|
93323
|
+
}
|
|
93324
|
+
return a.length === b.length ? 0 : a.length < b.length ? -1 : 1;
|
|
93325
|
+
}
|
|
93326
|
+
function compareSemver(a, b) {
|
|
93327
|
+
const pa = parseSemver(a);
|
|
93328
|
+
const pb = parseSemver(b);
|
|
93329
|
+
if (!pa || !pb) return null;
|
|
93330
|
+
if (pa.major !== pb.major) return pa.major < pb.major ? -1 : 1;
|
|
93331
|
+
if (pa.minor !== pb.minor) return pa.minor < pb.minor ? -1 : 1;
|
|
93332
|
+
if (pa.patch !== pb.patch) return pa.patch < pb.patch ? -1 : 1;
|
|
93333
|
+
return comparePrerelease(pa.prerelease, pb.prerelease);
|
|
93334
|
+
}
|
|
93231
93335
|
init_track_identity();
|
|
93232
93336
|
var daemonLifecycleHandlers = {
|
|
93233
93337
|
daemon_upgrade: async (ctx, args) => {
|
|
@@ -93236,10 +93340,22 @@ ${marker}`,
|
|
|
93236
93340
|
const isStandalone = ctx.deps.packageName === "@adhdev/daemon-standalone" || process.argv[1]?.includes("daemon-standalone");
|
|
93237
93341
|
const pkgName = isStandalone ? "@adhdev/daemon-standalone" : "adhdev";
|
|
93238
93342
|
const npmSurface = resolveCurrentGlobalInstallSurface({ packageName: pkgName });
|
|
93239
|
-
|
|
93240
|
-
|
|
93343
|
+
const requestedChannelRaw = args?.channel ?? args?.updatePolicy?.channel ?? null;
|
|
93344
|
+
const requestedChannel = typeof requestedChannelRaw === "string" && requestedChannelRaw.trim() ? requestedChannelRaw.trim().toLowerCase() : null;
|
|
93345
|
+
const requestedNpmTag = typeof args?.npmTag === "string" && args.npmTag.trim() ? args.npmTag.trim().toLowerCase() : null;
|
|
93346
|
+
if (requestedChannel || requestedNpmTag) {
|
|
93347
|
+
LOG2.info("Upgrade", `Ignoring deprecated channel hint (channel=${requestedChannel ?? "-"}, npmTag=${requestedNpmTag ?? "-"}) \u2014 upgrade target is the build track '${TRACK}'`);
|
|
93241
93348
|
}
|
|
93242
93349
|
const npmTag = IDENTITY.npmTag;
|
|
93350
|
+
const channelOverride = requestedChannel && requestedChannel !== TRACK && !(TRACK === "preview" && requestedChannel === "next") && !(TRACK === "stable" && requestedChannel === "latest") || requestedNpmTag && requestedNpmTag !== npmTag ? {
|
|
93351
|
+
requestedChannel,
|
|
93352
|
+
requestedNpmTag,
|
|
93353
|
+
effectiveChannel: TRACK,
|
|
93354
|
+
effectiveNpmTag: npmTag,
|
|
93355
|
+
ignored: true,
|
|
93356
|
+
reason: `The requested channel/tag was IGNORED. Since Phase 3 the release channel is a build-time identity of the installed binary, so this daemon can only upgrade on its own '${TRACK}' track (${pkgName}@${npmTag}). Switching tracks requires installing the other track's package, not an upgrade argument.`
|
|
93357
|
+
} : null;
|
|
93358
|
+
const withChannelNotice = (payload) => channelOverride ? { ...payload, channelOverride } : payload;
|
|
93243
93359
|
const latest = resolveNpmPublishedVersion(pkgName, npmTag, npmSurface);
|
|
93244
93360
|
LOG2.info("Upgrade", `Latest ${pkgName}@${npmTag}: v${latest}`);
|
|
93245
93361
|
let currentInstalled = null;
|
|
@@ -93256,11 +93372,39 @@ ${marker}`,
|
|
|
93256
93372
|
const runningVersion = typeof ctx.deps.statusVersion === "string" ? ctx.deps.statusVersion.trim().replace(/^v/, "") : null;
|
|
93257
93373
|
if (currentInstalled === latest && runningVersion === latest) {
|
|
93258
93374
|
LOG2.info("Upgrade", `Already on ${TRACK} track version v${latest}; skipping install`);
|
|
93259
|
-
return { success: true, upgraded: false, alreadyLatest: true, outcome: "already_latest", version: latest, targetVersion: latest, channel: TRACK, npmTag };
|
|
93375
|
+
return withChannelNotice({ success: true, upgraded: false, alreadyLatest: true, outcome: "already_latest", version: latest, targetVersion: latest, channel: TRACK, npmTag });
|
|
93260
93376
|
}
|
|
93261
93377
|
if (currentInstalled === latest && runningVersion && runningVersion !== latest) {
|
|
93262
93378
|
LOG2.info("Upgrade", `Installed package is v${latest}, but running daemon is v${runningVersion}; scheduling restart`);
|
|
93263
93379
|
}
|
|
93380
|
+
const direction = runningVersion ? compareSemver(latest, runningVersion) : null;
|
|
93381
|
+
if (direction !== null && direction < 0 && args?.allowDowngrade !== true) {
|
|
93382
|
+
LOG2.warn("Upgrade", `Refusing downgrade: running v${runningVersion} is NEWER than ${TRACK} track target v${latest} (${pkgName}@${npmTag}). Pass allowDowngrade to override.`);
|
|
93383
|
+
return withChannelNotice({
|
|
93384
|
+
success: false,
|
|
93385
|
+
upgraded: false,
|
|
93386
|
+
restarting: false,
|
|
93387
|
+
code: "downgrade_refused",
|
|
93388
|
+
outcome: "downgrade_refused",
|
|
93389
|
+
// Everything the caller needs to see WHY it would go
|
|
93390
|
+
// backwards, without a second round-trip: the incident that
|
|
93391
|
+
// motivated this guard was diagnosable only because someone
|
|
93392
|
+
// noticed the version in the response was lower than the
|
|
93393
|
+
// node's actual version.
|
|
93394
|
+
version: runningVersion,
|
|
93395
|
+
currentVersion: runningVersion,
|
|
93396
|
+
installedVersion: currentInstalled,
|
|
93397
|
+
targetVersion: latest,
|
|
93398
|
+
channel: TRACK,
|
|
93399
|
+
npmTag,
|
|
93400
|
+
packageName: pkgName,
|
|
93401
|
+
reason: `Upgrade refused: it would DOWNGRADE this daemon from v${runningVersion} to v${latest}. The ${TRACK} track dist-tag ${pkgName}@${npmTag} currently resolves to v${latest}, which is older than what is running. This usually means the daemon is resolving the wrong track's package \u2014 check that the npm install surface (global prefix) matches the running build's track. Pass allowDowngrade:true to force the rollback anyway.`,
|
|
93402
|
+
clientHint: "Downgrade refused \u2014 no restart happened and the daemon is untouched. Fix the install surface/track pin, or pass allowDowngrade:true to roll back deliberately."
|
|
93403
|
+
});
|
|
93404
|
+
}
|
|
93405
|
+
if (direction !== null && direction < 0) {
|
|
93406
|
+
LOG2.warn("Upgrade", `allowDowngrade set \u2014 proceeding with DOWNGRADE from v${runningVersion} to v${latest} on the ${TRACK} track`);
|
|
93407
|
+
}
|
|
93264
93408
|
spawnDetachedDaemonUpgradeHelper({
|
|
93265
93409
|
packageName: pkgName,
|
|
93266
93410
|
targetVersion: latest,
|
|
@@ -93274,7 +93418,7 @@ ${marker}`,
|
|
|
93274
93418
|
LOG2.info("Upgrade", "Exiting daemon so detached upgrader can continue...");
|
|
93275
93419
|
process.exit(0);
|
|
93276
93420
|
}, 3e3);
|
|
93277
|
-
return {
|
|
93421
|
+
return withChannelNotice({
|
|
93278
93422
|
success: true,
|
|
93279
93423
|
upgraded: true,
|
|
93280
93424
|
version: latest,
|
|
@@ -93283,9 +93427,16 @@ ${marker}`,
|
|
|
93283
93427
|
npmTag,
|
|
93284
93428
|
outcome: "scheduled",
|
|
93285
93429
|
targetVersion: latest,
|
|
93430
|
+
// No `currentVersion` here on purpose: this response is about a
|
|
93431
|
+
// SCHEDULED move, and daemon-upgrade-scheduled-intent.test.ts
|
|
93432
|
+
// pins that it must not read as "already on the target". The
|
|
93433
|
+
// pre-upgrade version belongs on the refusal payload, where it
|
|
93434
|
+
// is the actual diagnosis. Only the deliberate-override marker
|
|
93435
|
+
// is added, so an intentional rollback stays self-evident.
|
|
93436
|
+
...direction !== null && direction < 0 ? { downgrade: true } : {},
|
|
93286
93437
|
upgradeLogPath: getUpgradeLogPath(),
|
|
93287
93438
|
clientHint: `Upgrade to v${latest} SCHEDULED, not completed \u2014 the detached helper installs and restarts the daemon after this response, and a failure rolls back to the previous version. Check upgradeLogPath (or get_status_metadata.upgradeFailure after the restart) for the actual outcome.`
|
|
93288
|
-
};
|
|
93439
|
+
});
|
|
93289
93440
|
} catch (e) {
|
|
93290
93441
|
LOG2.error("Upgrade", `Failed: ${e.message}`);
|
|
93291
93442
|
return { success: false, error: e.message };
|
|
@@ -97037,6 +97188,8 @@ ${marker}`,
|
|
|
97037
97188
|
var CANON_C_MISSING_ASSISTANT_MIN_ELAPSED_MS = 2e4;
|
|
97038
97189
|
var MISSING_ASSISTANT_TRANSCRIPT_GROWTH_QUIET_MS = 6e4;
|
|
97039
97190
|
var NATIVE_HISTORY_MESH_IDLE_SETTLE_MS = 4e3;
|
|
97191
|
+
var CANCELLED_COMPLETION_RECHECK_MS = 1500;
|
|
97192
|
+
var CANCELLED_COMPLETION_RECHECK_MAX_ATTEMPTS = 4;
|
|
97040
97193
|
var PTY_PARSED_FINAL_ASSISTANT_QUIET_DWELL_MS = 1200;
|
|
97041
97194
|
var ANTIGRAVITY_HOLD_QUIET_DWELL_MS = 3e3;
|
|
97042
97195
|
var ANTIGRAVITY_HOLD_HARD_CAP_MS = 5 * 6e4;
|
|
@@ -98095,7 +98248,7 @@ ${buttons.join("\n")}`;
|
|
|
98095
98248
|
timestamp: Date.now(),
|
|
98096
98249
|
taskId,
|
|
98097
98250
|
finalSummary,
|
|
98098
|
-
evidenceLevel: "
|
|
98251
|
+
evidenceLevel: "reported",
|
|
98099
98252
|
completionDiagnostic: { source: "pre_cleanup_transcript_completion" }
|
|
98100
98253
|
});
|
|
98101
98254
|
return true;
|
|
@@ -98144,7 +98297,7 @@ ${buttons.join("\n")}`;
|
|
|
98144
98297
|
timestamp: Date.now(),
|
|
98145
98298
|
taskId,
|
|
98146
98299
|
finalSummary,
|
|
98147
|
-
evidenceLevel: "
|
|
98300
|
+
evidenceLevel: "reported",
|
|
98148
98301
|
completionDiagnostic: { source: diagnosticSource }
|
|
98149
98302
|
});
|
|
98150
98303
|
return true;
|
|
@@ -98586,6 +98739,64 @@ ${buttons.join("\n")}`;
|
|
|
98586
98739
|
host.pushEvent({ event: me.type, agentKey: me.agentKey, message: me.message, elapsedSec: me.elapsedSec, timestamp: me.timestamp });
|
|
98587
98740
|
}
|
|
98588
98741
|
}
|
|
98742
|
+
init_logger();
|
|
98743
|
+
function armCancelledCompletionRecheck(host, pending, reason) {
|
|
98744
|
+
if (reason === "new_pty_output") return;
|
|
98745
|
+
const now = Date.now();
|
|
98746
|
+
const prior = host.cancelledCompletionRecheck;
|
|
98747
|
+
const carriedPending = prior?.pending ?? pending;
|
|
98748
|
+
const attempts = prior ? prior.attempts : 0;
|
|
98749
|
+
if (attempts >= CANCELLED_COMPLETION_RECHECK_MAX_ATTEMPTS) {
|
|
98750
|
+
clearCancelledCompletionRecheck(host);
|
|
98751
|
+
LOG2.debug("CLI", `[${host.type}] cancelled-completion recheck budget exhausted (${reason}) \u2014 deferring to the next FSM completion edge`);
|
|
98752
|
+
return;
|
|
98753
|
+
}
|
|
98754
|
+
host.cancelledCompletionRecheck = {
|
|
98755
|
+
pending: carriedPending,
|
|
98756
|
+
reason,
|
|
98757
|
+
attempts,
|
|
98758
|
+
firstCancelledAt: prior?.firstCancelledAt ?? now
|
|
98759
|
+
};
|
|
98760
|
+
if (host.cancelledCompletionRecheckTimer) clearTimeout(host.cancelledCompletionRecheckTimer);
|
|
98761
|
+
host.cancelledCompletionRecheckTimer = setTimeout(
|
|
98762
|
+
() => runCancelledCompletionRecheck(host),
|
|
98763
|
+
CANCELLED_COMPLETION_RECHECK_MS
|
|
98764
|
+
);
|
|
98765
|
+
}
|
|
98766
|
+
function clearCancelledCompletionRecheck(host) {
|
|
98767
|
+
if (host.cancelledCompletionRecheckTimer) {
|
|
98768
|
+
clearTimeout(host.cancelledCompletionRecheckTimer);
|
|
98769
|
+
host.cancelledCompletionRecheckTimer = null;
|
|
98770
|
+
}
|
|
98771
|
+
host.cancelledCompletionRecheck = null;
|
|
98772
|
+
}
|
|
98773
|
+
function runCancelledCompletionRecheck(host) {
|
|
98774
|
+
host.cancelledCompletionRecheckTimer = null;
|
|
98775
|
+
const watch3 = host.cancelledCompletionRecheck;
|
|
98776
|
+
if (!watch3) return;
|
|
98777
|
+
if (host.completedDebouncePending) {
|
|
98778
|
+
clearCancelledCompletionRecheck(host);
|
|
98779
|
+
return;
|
|
98780
|
+
}
|
|
98781
|
+
watch3.attempts += 1;
|
|
98782
|
+
LOG2.info("CLI", `[${host.type}] re-checking completion cancelled by ${watch3.reason} (attempt ${watch3.attempts}/${CANCELLED_COMPLETION_RECHECK_MAX_ATTEMPTS}, ${Date.now() - watch3.firstCancelledAt}ms since cancel)`);
|
|
98783
|
+
if (host.completionTraceOn()) host.recordCompletionGateTrace("cancel_recheck", {
|
|
98784
|
+
reason: watch3.reason,
|
|
98785
|
+
attempt: watch3.attempts,
|
|
98786
|
+
sinceCancelMs: Date.now() - watch3.firstCancelledAt,
|
|
98787
|
+
busyEpoch: host.busyEpoch
|
|
98788
|
+
});
|
|
98789
|
+
const lastOutputAt = host.adapter.getStatus({ allowParse: false })?.lastOutputAt;
|
|
98790
|
+
host.completedDebouncePending = {
|
|
98791
|
+
...watch3.pending,
|
|
98792
|
+
busyEpochAtArm: host.busyEpoch,
|
|
98793
|
+
lastOutputAtArm: typeof lastOutputAt === "number" && Number.isFinite(lastOutputAt) ? lastOutputAt : watch3.pending.lastOutputAtArm
|
|
98794
|
+
};
|
|
98795
|
+
host.flushCompletedDebounceIfFinalized();
|
|
98796
|
+
if (host.cancelledCompletionRecheck === watch3 && host.completedDebouncePending) {
|
|
98797
|
+
clearCancelledCompletionRecheck(host);
|
|
98798
|
+
}
|
|
98799
|
+
}
|
|
98589
98800
|
init_contracts2();
|
|
98590
98801
|
var MAX_TRACKED_MESSAGES = 2e3;
|
|
98591
98802
|
function hasUsableTimestamp(message) {
|
|
@@ -99745,11 +99956,20 @@ ${buttons.join("\n")}`;
|
|
|
99745
99956
|
clearTimeout(this.autoApproveBusyTimer);
|
|
99746
99957
|
this.autoApproveBusyTimer = null;
|
|
99747
99958
|
}
|
|
99959
|
+
this.clearCancelledCompletionRecheck();
|
|
99748
99960
|
this.appliedEffectKeys.clear();
|
|
99749
99961
|
closeSqliteProbeCache(this.sqliteProbeCache);
|
|
99750
99962
|
}
|
|
99751
99963
|
completedDebounceTimer = null;
|
|
99752
99964
|
completedDebouncePending = null;
|
|
99965
|
+
/**
|
|
99966
|
+
* (CANCEL-BLIP-ORPHAN) Re-verification watch for an arm the continuity cancel just
|
|
99967
|
+
* deleted — the cancelled arm's snapshot plus a bounded recheck budget, so a
|
|
99968
|
+
* sub-second PTY blip cannot permanently orphan the completion. Full rationale:
|
|
99969
|
+
* completion/cancel-recheck.ts.
|
|
99970
|
+
*/
|
|
99971
|
+
cancelledCompletionRecheck = null;
|
|
99972
|
+
cancelledCompletionRecheckTimer = null;
|
|
99753
99973
|
lastExternalCompletionProbe = null;
|
|
99754
99974
|
// (NATIVE-TURN-SIGNAL) Terminal markers from the last native transcript read. Refreshed
|
|
99755
99975
|
// on every completion probe; null when the provider surfaces none.
|
|
@@ -100196,6 +100416,17 @@ ${buttons.join("\n")}`;
|
|
|
100196
100416
|
if (this.completedDebounceTimer) clearTimeout(this.completedDebounceTimer);
|
|
100197
100417
|
this.completedDebounceTimer = setTimeout(() => this.flushCompletedDebounceIfFinalized(), delayMs);
|
|
100198
100418
|
}
|
|
100419
|
+
/**
|
|
100420
|
+
* (CANCEL-BLIP-ORPHAN) Post-cancel completion re-verification. The judgment and its
|
|
100421
|
+
* full rationale live in completion/cancel-recheck.ts; these are the host-dispatched
|
|
100422
|
+
* seams, matching the status-transition / evidence / stall-rescue moves.
|
|
100423
|
+
*/
|
|
100424
|
+
armCancelledCompletionRecheck(pending, reason) {
|
|
100425
|
+
armCancelledCompletionRecheck(this, pending, reason);
|
|
100426
|
+
}
|
|
100427
|
+
clearCancelledCompletionRecheck() {
|
|
100428
|
+
clearCancelledCompletionRecheck(this);
|
|
100429
|
+
}
|
|
100199
100430
|
// EVTTRACE (observation-only): is this a mesh worker session whose completion
|
|
100200
100431
|
// events must route to a coordinator? Used purely to gate trace logging so a
|
|
100201
100432
|
// non-mesh CLI session's completions don't add EvtTrace noise. No decision logic.
|
|
@@ -100727,6 +100958,7 @@ ${buttons.join("\n")}`;
|
|
|
100727
100958
|
if (this.completionTraceOn()) this.recordCompletionGateTrace("cancel", { blockReason: decision.reason, ...decision.trace });
|
|
100728
100959
|
this.completedDebouncePending = null;
|
|
100729
100960
|
this.completedDebounceTimer = null;
|
|
100961
|
+
this.armCancelledCompletionRecheck(pending, decision.reason);
|
|
100730
100962
|
return;
|
|
100731
100963
|
}
|
|
100732
100964
|
this.applyCompletionArmPatch(pending, decision.armPatch);
|
|
@@ -100784,6 +101016,7 @@ ${buttons.join("\n")}`;
|
|
|
100784
101016
|
});
|
|
100785
101017
|
this.completedDebouncePending = null;
|
|
100786
101018
|
this.completedDebounceTimer = null;
|
|
101019
|
+
this.clearCancelledCompletionRecheck();
|
|
100787
101020
|
this.generatingStartedAt = 0;
|
|
100788
101021
|
this.lastApprovalEventFingerprint = "";
|
|
100789
101022
|
this.markCurrentTurnStartupGraceCollapseSatisfied();
|
|
@@ -100810,7 +101043,7 @@ ${buttons.join("\n")}`;
|
|
|
100810
101043
|
timestamp: pending.timestamp,
|
|
100811
101044
|
taskId: pending.taskId,
|
|
100812
101045
|
finalSummary,
|
|
100813
|
-
evidenceLevel: "
|
|
101046
|
+
evidenceLevel: "reported",
|
|
100814
101047
|
completionDiagnostic: {
|
|
100815
101048
|
source: "clean_final_assistant",
|
|
100816
101049
|
cleanPath: true,
|
|
@@ -100838,6 +101071,7 @@ ${buttons.join("\n")}`;
|
|
|
100838
101071
|
});
|
|
100839
101072
|
this.completedDebouncePending = null;
|
|
100840
101073
|
this.completedDebounceTimer = null;
|
|
101074
|
+
this.clearCancelledCompletionRecheck();
|
|
100841
101075
|
this.generatingStartedAt = 0;
|
|
100842
101076
|
this.lastApprovalEventFingerprint = "";
|
|
100843
101077
|
this.markCurrentTurnStartupGraceCollapseSatisfied();
|
|
@@ -100949,7 +101183,7 @@ ${buttons.join("\n")}`;
|
|
|
100949
101183
|
* • prior emit was WEAK → re-arm ONE-SHOT, but only across a real generating→idle
|
|
100950
101184
|
* transition: require busyEpoch to have advanced past the weak emit's epoch, so a
|
|
100951
101185
|
* static idle screen cannot re-fire the same weak frame. The genuine re-emit passes
|
|
100952
|
-
* evidenceLevel:'
|
|
101186
|
+
* evidenceLevel:'reported' (non-weak), overwriting the latch → any subsequent idle
|
|
100953
101187
|
* tick hits the now-genuine latch and is suppressed. Never a third emit.
|
|
100954
101188
|
*/
|
|
100955
101189
|
shouldSuppressCompletionReEmit(taskId) {
|
|
@@ -110583,7 +110817,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
110583
110817
|
...slots.length ? { slots } : {}
|
|
110584
110818
|
};
|
|
110585
110819
|
if (providerRoles.length) migrateProviderRolesToSlots2(policy);
|
|
110586
|
-
|
|
110820
|
+
syncProviderPriorityFromSlots(policy);
|
|
110587
110821
|
const role = normalizeMeshDaemonRole(args?.role);
|
|
110588
110822
|
const daemonId = typeof args?.daemonId === "string" && args.daemonId.trim() ? args.daemonId.trim() : void 0;
|
|
110589
110823
|
const machineId = typeof args?.machineId === "string" && args.machineId.trim() ? args.machineId.trim() : void 0;
|
|
@@ -110635,10 +110869,8 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
110635
110869
|
else delete policy.providerRoles;
|
|
110636
110870
|
}
|
|
110637
110871
|
migrateProviderRolesToSlots2(policy);
|
|
110638
|
-
|
|
110639
|
-
|
|
110640
|
-
syncProviderPriorityFromSlots(policy, finalSlots);
|
|
110641
|
-
}
|
|
110872
|
+
const finalSlots = Object.prototype.hasOwnProperty.call(policy, "slots") ? policy.slots : getMesh2(meshId)?.nodes.find((n) => n.id === nodeId)?.policy?.slots;
|
|
110873
|
+
syncProviderPriorityFromSlots(policy, finalSlots);
|
|
110642
110874
|
const patch = { policy };
|
|
110643
110875
|
if (typeof args?.systemPrompt === "string") {
|
|
110644
110876
|
const trimmed = args.systemPrompt.trim();
|
|
@@ -110663,9 +110895,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
110663
110895
|
...inlineNode.policy && typeof inlineNode.policy === "object" && !Array.isArray(inlineNode.policy) ? inlineNode.policy : {},
|
|
110664
110896
|
...patch.policy
|
|
110665
110897
|
};
|
|
110666
|
-
|
|
110667
|
-
syncProviderPriorityFromSlots(inlineNode.policy);
|
|
110668
|
-
}
|
|
110898
|
+
syncProviderPriorityFromSlots(inlineNode.policy);
|
|
110669
110899
|
if (Object.prototype.hasOwnProperty.call(patch, "systemPrompt")) {
|
|
110670
110900
|
const sp = patch.systemPrompt;
|
|
110671
110901
|
if (typeof sp === "string" && sp.trim()) inlineNode.systemPrompt = sp;
|
|
@@ -113669,6 +113899,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
113669
113899
|
init_dist();
|
|
113670
113900
|
init_mesh_events();
|
|
113671
113901
|
init_mesh_reconcile_identity();
|
|
113902
|
+
init_mesh_reconcile_acked_hold();
|
|
113672
113903
|
init_mesh_fast_forward();
|
|
113673
113904
|
var import_node_child_process7 = require("child_process");
|
|
113674
113905
|
var import_node_util5 = require("util");
|
|
@@ -115671,11 +115902,20 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
115671
115902
|
LOG2.warn("Mesh", `[Refinery] Failed to append async refine ledger entry: ${e?.message || e}`);
|
|
115672
115903
|
}
|
|
115673
115904
|
}
|
|
115905
|
+
function resolveRefineResumeDispatchGraceMs() {
|
|
115906
|
+
return resolveTunedReconcileMs("MESH_REFINE_RESUME_DISPATCH_GRACE_MS", 6e4, 0, 10 * 6e4);
|
|
115907
|
+
}
|
|
115908
|
+
function resolveRefineResumeZombieCutoffMs() {
|
|
115909
|
+
return resolveTunedReconcileMs("MESH_REFINE_RESUME_ZOMBIE_CUTOFF_MS", 24 * 60 * 6e4, 5 * 6e4, 30 * 24 * 60 * 6e4);
|
|
115910
|
+
}
|
|
115674
115911
|
async function resumePendingRefineJobsOnStartup(self) {
|
|
115675
115912
|
try {
|
|
115676
115913
|
const { listMeshes: listMeshes2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
115677
115914
|
const { readLedgerEntries: readLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
115678
115915
|
const meshIds = listMeshes2().map((m) => m.id).filter(Boolean);
|
|
115916
|
+
const nowMs = Date.now();
|
|
115917
|
+
const dispatchGraceMs = resolveRefineResumeDispatchGraceMs();
|
|
115918
|
+
const zombieCutoffMs = resolveRefineResumeZombieCutoffMs();
|
|
115679
115919
|
for (const meshId of meshIds) {
|
|
115680
115920
|
const entries = readLedgerEntries2(meshId, { kind: ["task_dispatched", "task_completed", "task_failed"] });
|
|
115681
115921
|
const terminal = /* @__PURE__ */ new Set();
|
|
@@ -115693,10 +115933,44 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
115693
115933
|
if (!jobId || terminal.has(`${e.nodeId}:${jobId}`)) continue;
|
|
115694
115934
|
const key2 = buildRefineJobKey(self, meshId, e.nodeId);
|
|
115695
115935
|
if (self.runningRefineJobs.has(key2)) continue;
|
|
115936
|
+
const dispatchedAtMs = new Date(e.timestamp).getTime();
|
|
115937
|
+
const ageMs2 = Number.isFinite(dispatchedAtMs) ? nowMs - dispatchedAtMs : void 0;
|
|
115938
|
+
if (ageMs2 !== void 0 && ageMs2 >= 0 && ageMs2 < dispatchGraceMs) {
|
|
115939
|
+
LOG2.info("Mesh", `[Refinery] Deferring resume of refine job for node ${e.nodeId} (jobId=${jobId}) \u2014 dispatched ${ageMs2}ms ago, within the ${dispatchGraceMs}ms grace window; may still be running.`);
|
|
115940
|
+
continue;
|
|
115941
|
+
}
|
|
115942
|
+
if (ageMs2 !== void 0 && ageMs2 >= zombieCutoffMs) {
|
|
115943
|
+
const node = e.payload?.refineJob;
|
|
115944
|
+
const coordinatorDaemonId2 = node?.targetCoordinatorDaemonId;
|
|
115945
|
+
const coordinatorSessionId2 = node?.targetCoordinatorSessionId;
|
|
115946
|
+
const zombieHandle = buildRefineJobHandle(self, {
|
|
115947
|
+
meshId,
|
|
115948
|
+
nodeId: e.nodeId,
|
|
115949
|
+
jobId,
|
|
115950
|
+
interactionId: typeof node?.interactionId === "string" ? node.interactionId : void 0,
|
|
115951
|
+
status: "failed",
|
|
115952
|
+
startedAt: typeof node?.startedAt === "string" ? node.startedAt : e.timestamp,
|
|
115953
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
115954
|
+
coordinatorDaemonId: coordinatorDaemonId2,
|
|
115955
|
+
coordinatorSessionId: coordinatorSessionId2
|
|
115956
|
+
});
|
|
115957
|
+
LOG2.warn("Mesh", `[Refinery] Closing out stale refine job for node ${e.nodeId} (jobId=${jobId}) as failed \u2014 dispatched ${ageMs2}ms ago, past the ${zombieCutoffMs}ms zombie cutoff with no terminal entry; not resuming.`);
|
|
115958
|
+
const zombieResult = {
|
|
115959
|
+
success: false,
|
|
115960
|
+
code: "resume_abandoned_stale_dispatch",
|
|
115961
|
+
error: `Refine job dispatched at ${e.timestamp} never reached a terminal state and exceeded the ${zombieCutoffMs}ms zombie cutoff on daemon restart; closed out without resuming.`
|
|
115962
|
+
};
|
|
115963
|
+
await appendRefineJobLedger(self, "task_failed", zombieHandle, zombieResult);
|
|
115964
|
+
queueRefineJobEvent(self, "refine:failed", zombieHandle, zombieResult);
|
|
115965
|
+
continue;
|
|
115966
|
+
}
|
|
115696
115967
|
const coordinatorDaemonId = e.payload?.refineJob?.targetCoordinatorDaemonId;
|
|
115968
|
+
const coordinatorSessionId = e.payload?.refineJob?.targetCoordinatorSessionId;
|
|
115697
115969
|
LOG2.info("Mesh", `[Refinery] Auto-resuming interrupted refine job for node ${e.nodeId} (jobId=${jobId})`);
|
|
115698
115970
|
void startMeshRefineJob(self, meshId, e.nodeId, {
|
|
115699
|
-
|
|
115971
|
+
jobId,
|
|
115972
|
+
coordinatorDaemonId,
|
|
115973
|
+
coordinatorSessionId
|
|
115700
115974
|
});
|
|
115701
115975
|
}
|
|
115702
115976
|
}
|
|
@@ -117420,7 +117694,7 @@ ${e?.stderr || ""}`;
|
|
|
117420
117694
|
const terminal = self.terminalRefineJobs.get(key2);
|
|
117421
117695
|
const alreadyRunning = self.runningRefineJobs.get(key2);
|
|
117422
117696
|
if (alreadyRunning) return { ...alreadyRunning, duplicate: true };
|
|
117423
|
-
const jobId = `refine_${createInteractionId()}`;
|
|
117697
|
+
const jobId = typeof args?.jobId === "string" && args.jobId.trim() ? args.jobId.trim() : `refine_${createInteractionId()}`;
|
|
117424
117698
|
const interactionId = createInteractionId();
|
|
117425
117699
|
const placeholder = buildRefineJobHandle(self, { meshId, nodeId, jobId, interactionId, retryOfJobId: terminal?.jobId });
|
|
117426
117700
|
self.runningRefineJobs.set(key2, placeholder);
|