@adhdev/daemon-standalone 1.0.48 → 1.0.49-rc.10
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 +394 -53
- 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 +75 -5
- package/vendor/mcp-server/index.js.map +1 -1
- package/public/assets/index-CEPCfMWL.css +0 -1
- package/public/assets/index-Wa0peoIh.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.
|
|
37062
|
-
const builtAt = readInjected(true ? "2026-08-
|
|
37059
|
+
const commit = readInjected(true ? "85491e20f327dc51eb20e6b0674af0041e0c5f5e" : void 0) ?? "unknown";
|
|
37060
|
+
const commitShort = readInjected(true ? "85491e20" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
37061
|
+
const version2 = readInjected(true ? "1.0.49-rc.10" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
37062
|
+
const builtAt = readInjected(true ? "2026-08-14T23:22:28.218Z" : void 0);
|
|
37063
37063
|
cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
|
|
37064
37064
|
return cached2;
|
|
37065
37065
|
}
|
|
@@ -38307,7 +38307,7 @@ var require_dist3 = __commonJS({
|
|
|
38307
38307
|
}
|
|
38308
38308
|
});
|
|
38309
38309
|
function resolveBuildTrack(env2 = process.env) {
|
|
38310
|
-
const injected = true ? "
|
|
38310
|
+
const injected = true ? "preview" : void 0;
|
|
38311
38311
|
const stamped = typeof injected === "string" ? injected.trim() : "";
|
|
38312
38312
|
const raw = (stamped || (env2[BUILD_CHANNEL_ENV_VAR] ?? "").trim()).toLowerCase();
|
|
38313
38313
|
return raw === "preview" || raw === "next" ? "preview" : "stable";
|
|
@@ -42270,6 +42270,8 @@ ${error48.message || ""}`;
|
|
|
42270
42270
|
interpolateArgs: () => interpolateArgs,
|
|
42271
42271
|
interpolateString: () => interpolateString,
|
|
42272
42272
|
isMeshTaskDifficulty: () => isMeshTaskDifficulty,
|
|
42273
|
+
isPhantomDaemonEntry: () => isPhantomDaemonEntry,
|
|
42274
|
+
isRawDaemonDoId: () => isRawDaemonDoId,
|
|
42273
42275
|
joinRepoPath: () => joinRepoPath,
|
|
42274
42276
|
machineCoreFromDaemonId: () => machineCoreFromDaemonId,
|
|
42275
42277
|
meshNodeIdMatches: () => meshNodeIdMatches,
|
|
@@ -42565,6 +42567,18 @@ ${error48.message || ""}`;
|
|
|
42565
42567
|
if (!left || !right) return false;
|
|
42566
42568
|
return left === right;
|
|
42567
42569
|
}
|
|
42570
|
+
function isRawDaemonDoId(id) {
|
|
42571
|
+
const trimmed = readString2(id);
|
|
42572
|
+
return !!trimmed && /^[0-9a-f]{64}$/i.test(trimmed);
|
|
42573
|
+
}
|
|
42574
|
+
function isPhantomDaemonEntry(entry) {
|
|
42575
|
+
if (!entry) return false;
|
|
42576
|
+
if (!isRawDaemonDoId(entry.id)) return false;
|
|
42577
|
+
const hasMachineEvidence = Boolean(
|
|
42578
|
+
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
|
|
42579
|
+
);
|
|
42580
|
+
return !hasMachineEvidence;
|
|
42581
|
+
}
|
|
42568
42582
|
function machineCoreFromDaemonId(id) {
|
|
42569
42583
|
const trimmed = readString2(id);
|
|
42570
42584
|
if (!trimmed) return void 0;
|
|
@@ -42990,7 +43004,9 @@ ${error48.message || ""}`;
|
|
|
42990
43004
|
"mesh_magi_kind_panel_list",
|
|
42991
43005
|
"mesh_node_slots_set",
|
|
42992
43006
|
"mesh_node_slots_list",
|
|
42993
|
-
"mesh_node_slots_propose"
|
|
43007
|
+
"mesh_node_slots_propose",
|
|
43008
|
+
"mesh_coordinator_prompt_append_get",
|
|
43009
|
+
"mesh_coordinator_prompt_append_set"
|
|
42994
43010
|
];
|
|
42995
43011
|
CANONICAL_MESH_TOOL_COUNT = CANONICAL_MESH_TOOL_NAMES.length;
|
|
42996
43012
|
STATUS_PROBE_ARG_KEY = "_statusProbe";
|
|
@@ -52711,7 +52727,9 @@ When you compose the task message you dispatch to a node, include this requireme
|
|
|
52711
52727
|
| \`mesh_magi_kind_panel_list\` | List configured task_kind \u2192 MAGI kind-panel slot bindings (machine-local, read-only) |
|
|
52712
52728
|
| \`mesh_node_slots_list\` | List a node's capability slots (its AI-tool profile: provider/model/thinking + difficulty range + capability tags), read-only |
|
|
52713
52729
|
| \`mesh_node_slots_set\` | PROPOSE (dry-run) or APPLY a node's capability slots \u2014 how you autonomously retune a node's tool profile; WHOLESALE replacement, present current-vs-proposed and get user approval before write=true |
|
|
52714
|
-
| \`mesh_node_slots_propose\` | AUTO-DETECT a node's installed CLI agents and DRAFT a slot profile from them (read-only, never writes) \u2014 use when a node has no slots yet or new CLIs were installed; reports droppedSlots (what a wholesale write would destroy), then apply via mesh_node_slots_set write=true after approval
|
|
52730
|
+
| \`mesh_node_slots_propose\` | AUTO-DETECT a node's installed CLI agents and DRAFT a slot profile from them (read-only, never writes) \u2014 use when a node has no slots yet or new CLIs were installed; reports droppedSlots (what a wholesale write would destroy), then apply via mesh_node_slots_set write=true after approval |
|
|
52731
|
+
| \`mesh_coordinator_prompt_append_get\` | Read this daemon's user-level coordinator prompt APPEND text for a CLI type (per-machine file, applies to every mesh this daemon coordinates) |
|
|
52732
|
+
| \`mesh_coordinator_prompt_append_set\` | Write or clear this daemon's user-level coordinator prompt APPEND text for a CLI type \u2014 APPEND ONLY, always stacks after the base prompt; there is no tool to replace the base prompt itself |`;
|
|
52715
52733
|
TOOL_EXPOSURE_PREFLIGHT_SECTION = `## Tool Exposure Preflight
|
|
52716
52734
|
|
|
52717
52735
|
Before doing any coordinator work, confirm that the actual callable tool list includes \`mesh_status\` and the other \`mesh_*\` tools from the table above. If this Repo Mesh coordinator prompt is present but the callable \`mesh_*\` tools are missing, the MCP server/tool manifest is stale or not injected yet. Do not substitute terminal/file/git tools, do not inspect or edit the repository directly, and do not continue as a non-mesh local coding agent. Stop immediately and tell the user to run \`/reload-mcp\` or start a fresh coordinator session so ADHDev can reconnect \`adhdev-mesh\`.`;
|
|
@@ -55440,6 +55458,8 @@ ${rendered}`, "utf-8");
|
|
|
55440
55458
|
});
|
|
55441
55459
|
function readProviderPriorityFromPolicy(policy) {
|
|
55442
55460
|
const record2 = policy && typeof policy === "object" && !Array.isArray(policy) ? policy : {};
|
|
55461
|
+
const derived = deriveProviderPriorityFromSlots(record2.slots);
|
|
55462
|
+
if (derived.length) return derived;
|
|
55443
55463
|
const raw = record2.providerPriority;
|
|
55444
55464
|
if (Array.isArray(raw)) {
|
|
55445
55465
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -55450,7 +55470,7 @@ ${rendered}`, "utf-8");
|
|
|
55450
55470
|
});
|
|
55451
55471
|
if (explicit.length) return explicit;
|
|
55452
55472
|
}
|
|
55453
|
-
return
|
|
55473
|
+
return [];
|
|
55454
55474
|
}
|
|
55455
55475
|
function normalizeProviderRoles(value) {
|
|
55456
55476
|
if (!Array.isArray(value)) return [];
|
|
@@ -55532,7 +55552,7 @@ ${rendered}`, "utf-8");
|
|
|
55532
55552
|
const workspace = readStringValue(node.workspace, node.repoRoot, node.repo_root);
|
|
55533
55553
|
const workspaceName = workspace ? workingDirBasename(workspace) : void 0;
|
|
55534
55554
|
const host = readStringValue(node.machineName, node.machine_name, node.hostname, node.host, node.daemonId, node.daemon_id, node.machineId, node.machine_id);
|
|
55535
|
-
const provider = providerPriority[0] || (Array.isArray(node.providers) ? readStringValue(...node.providers) : void 0);
|
|
55555
|
+
const provider = readProviderPriorityFromPolicy(node.policy)[0] || providerPriority[0] || (Array.isArray(node.providers) ? readStringValue(...node.providers) : void 0);
|
|
55536
55556
|
const parts = [workspaceName, host, provider].filter(Boolean);
|
|
55537
55557
|
if (parts.length > 0) return parts.join(" \xB7 ");
|
|
55538
55558
|
return nodeId || "unidentified mesh node";
|
|
@@ -57708,7 +57728,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57708
57728
|
init_mesh_work_queue();
|
|
57709
57729
|
}
|
|
57710
57730
|
});
|
|
57711
|
-
function
|
|
57731
|
+
function directQuotaEntryFor(node, providerType) {
|
|
57712
57732
|
const facts = node?.nodeFacts;
|
|
57713
57733
|
if (!facts || typeof facts !== "object") return null;
|
|
57714
57734
|
const reportedAt = Number(facts.reportedAt);
|
|
@@ -57717,6 +57737,14 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57717
57737
|
if (!quota || typeof quota !== "object") return null;
|
|
57718
57738
|
return { facts: { reportedAt }, quota };
|
|
57719
57739
|
}
|
|
57740
|
+
function quotaEntryFor(node, providerType, context) {
|
|
57741
|
+
const direct = directQuotaEntryFor(node, providerType);
|
|
57742
|
+
if (direct) return direct;
|
|
57743
|
+
const sourceNodeId = typeof node?.clonedFromNodeId === "string" ? node.clonedFromNodeId.trim() : "";
|
|
57744
|
+
if (!sourceNodeId || !Array.isArray(context?.nodes)) return null;
|
|
57745
|
+
const sourceNode = context.nodes.find((candidate) => candidate !== node && meshNodeIdMatches(candidate, sourceNodeId));
|
|
57746
|
+
return sourceNode ? directQuotaEntryFor(sourceNode, providerType) : null;
|
|
57747
|
+
}
|
|
57720
57748
|
function quotaSnapshotAgeMs(facts, quota, now = Date.now()) {
|
|
57721
57749
|
const updatedAt = Number(quota.updatedAt);
|
|
57722
57750
|
if (!Number.isFinite(updatedAt) || updatedAt <= 0) return Number.POSITIVE_INFINITY;
|
|
@@ -57739,10 +57767,23 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57739
57767
|
const reporterNowMs = Number(quota.updatedAt) + ageMs2;
|
|
57740
57768
|
return resetsAt - reporterNowMs < imminentMs;
|
|
57741
57769
|
}
|
|
57742
|
-
function
|
|
57743
|
-
const
|
|
57770
|
+
function isRetainedWindowTrustworthy(window, facts, quota, policy, now) {
|
|
57771
|
+
const resetsAt = Number(window?.resetsAt);
|
|
57772
|
+
if (!Number.isFinite(resetsAt) || resetsAt <= 0) {
|
|
57773
|
+
return isQuotaSnapshotFresh(facts, quota, policy, now);
|
|
57774
|
+
}
|
|
57775
|
+
const ageMs2 = quotaSnapshotAgeMs(facts, quota, now);
|
|
57776
|
+
if (!Number.isFinite(ageMs2)) return false;
|
|
57777
|
+
const reporterNowMs = Number(quota.updatedAt) + ageMs2;
|
|
57778
|
+
if (!Number.isFinite(reporterNowMs)) return false;
|
|
57779
|
+
return resetsAt > reporterNowMs;
|
|
57780
|
+
}
|
|
57781
|
+
function evaluateProviderQuotaGate(node, providerType, policy, now = Date.now(), context) {
|
|
57782
|
+
const entry = quotaEntryFor(node, providerType, context);
|
|
57744
57783
|
if (!entry) return null;
|
|
57745
57784
|
const { facts, quota } = entry;
|
|
57785
|
+
let sessionTrustworthy = true;
|
|
57786
|
+
let weeklyTrustworthy = true;
|
|
57746
57787
|
if (quota.status !== "ok") {
|
|
57747
57788
|
if (quota.status === "error" && quota.metadata?.failureKind === "quota-exhausted" && isQuotaSnapshotFresh(facts, quota, policy, now)) {
|
|
57748
57789
|
return {
|
|
@@ -57752,12 +57793,15 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57752
57793
|
thresholdPercent: 0
|
|
57753
57794
|
};
|
|
57754
57795
|
}
|
|
57796
|
+
if (quota.metadata?.lastGoodWindows !== true) return null;
|
|
57797
|
+
sessionTrustworthy = isRetainedWindowTrustworthy(quota.session, facts, quota, policy, now);
|
|
57798
|
+
weeklyTrustworthy = isRetainedWindowTrustworthy(quota.weekly, facts, quota, policy, now);
|
|
57799
|
+
} else if (!isQuotaSnapshotFresh(facts, quota, policy, now)) {
|
|
57755
57800
|
return null;
|
|
57756
57801
|
}
|
|
57757
|
-
if (!isQuotaSnapshotFresh(facts, quota, policy, now)) return null;
|
|
57758
57802
|
const resolved = resolveQuotaRoutingPolicy(policy);
|
|
57759
57803
|
const session = remainingPercent(quota.session);
|
|
57760
|
-
if (session !== void 0 && session < resolved.sessionMinRemainingPercent && !isSessionResetImminent(quota.session, facts, quota, resolved.sessionResetImminentMs, now)) {
|
|
57804
|
+
if (sessionTrustworthy && session !== void 0 && session < resolved.sessionMinRemainingPercent && !isSessionResetImminent(quota.session, facts, quota, resolved.sessionResetImminentMs, now)) {
|
|
57761
57805
|
return {
|
|
57762
57806
|
reason: PROVIDER_QUOTA_SESSION_LOW_SKIP_REASON,
|
|
57763
57807
|
window: "session",
|
|
@@ -57766,7 +57810,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57766
57810
|
};
|
|
57767
57811
|
}
|
|
57768
57812
|
const weekly = remainingPercent(quota.weekly);
|
|
57769
|
-
if (weekly !== void 0 && weekly < resolved.weeklyMinRemainingPercent) {
|
|
57813
|
+
if (weeklyTrustworthy && weekly !== void 0 && weekly < resolved.weeklyMinRemainingPercent) {
|
|
57770
57814
|
return {
|
|
57771
57815
|
reason: PROVIDER_QUOTA_WEEKLY_LOW_SKIP_REASON,
|
|
57772
57816
|
window: "weekly",
|
|
@@ -57776,8 +57820,8 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57776
57820
|
}
|
|
57777
57821
|
return null;
|
|
57778
57822
|
}
|
|
57779
|
-
function expiryRiskForRanking(node, providerType, axis, policy, now = Date.now()) {
|
|
57780
|
-
const entry = quotaEntryFor(node, providerType);
|
|
57823
|
+
function expiryRiskForRanking(node, providerType, axis, policy, now = Date.now(), context) {
|
|
57824
|
+
const entry = quotaEntryFor(node, providerType, context);
|
|
57781
57825
|
if (!entry) return void 0;
|
|
57782
57826
|
const { facts, quota } = entry;
|
|
57783
57827
|
if (quota.status !== "ok") return void 0;
|
|
@@ -57796,19 +57840,19 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57796
57840
|
const elapsedFraction = Math.min(1, Math.max(0, 1 - (resetsAt - reporterNowMs) / windowMs));
|
|
57797
57841
|
return { remainingPercent: remaining, risk: remaining * elapsedFraction };
|
|
57798
57842
|
}
|
|
57799
|
-
function rankProvidersByQuotaGate(node, orderedProviderTypes, policy, now = Date.now()) {
|
|
57843
|
+
function rankProvidersByQuotaGate(node, orderedProviderTypes, policy, now = Date.now(), context) {
|
|
57800
57844
|
const clear = [];
|
|
57801
57845
|
const gated = [];
|
|
57802
57846
|
for (const providerType of orderedProviderTypes) {
|
|
57803
|
-
const block2 = evaluateProviderQuotaGate(node, providerType, policy, now);
|
|
57847
|
+
const block2 = evaluateProviderQuotaGate(node, providerType, policy, now, context);
|
|
57804
57848
|
if (block2) gated.push({ providerType, block: block2 });
|
|
57805
57849
|
else clear.push(providerType);
|
|
57806
57850
|
}
|
|
57807
|
-
const weeklyByProvider = new Map(clear.map((p) => [p, expiryRiskForRanking(node, p, "weekly", policy, now)]));
|
|
57851
|
+
const weeklyByProvider = new Map(clear.map((p) => [p, expiryRiskForRanking(node, p, "weekly", policy, now, context)]));
|
|
57808
57852
|
const headroomPercent = resolveQuotaRoutingPolicy(policy).sessionAxisWeeklyHeadroomPercent;
|
|
57809
57853
|
const weeklyMeasured = [...weeklyByProvider.values()].filter((w) => w !== void 0);
|
|
57810
57854
|
const sessionAxisActive = weeklyMeasured.length > 0 && weeklyMeasured.every((w) => w.remainingPercent > headroomPercent);
|
|
57811
|
-
const sessionByProvider = sessionAxisActive ? new Map(clear.map((p) => [p, expiryRiskForRanking(node, p, "session", policy, now)])) : void 0;
|
|
57855
|
+
const sessionByProvider = sessionAxisActive ? new Map(clear.map((p) => [p, expiryRiskForRanking(node, p, "session", policy, now, context)])) : void 0;
|
|
57812
57856
|
clear.sort((a, b) => {
|
|
57813
57857
|
const wa = weeklyByProvider.get(a);
|
|
57814
57858
|
const wb = weeklyByProvider.get(b);
|
|
@@ -57831,13 +57875,13 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57831
57875
|
});
|
|
57832
57876
|
return { clear, gated };
|
|
57833
57877
|
}
|
|
57834
|
-
function resolveRecoveryRelaunchProvider(node, failedProviderType, nodeProviderTypes = [], policy, now = Date.now()) {
|
|
57878
|
+
function resolveRecoveryRelaunchProvider(node, failedProviderType, nodeProviderTypes = [], policy, now = Date.now(), context) {
|
|
57835
57879
|
if (!failedProviderType) return { action: "block" };
|
|
57836
|
-
const block2 = evaluateProviderQuotaGate(node, failedProviderType, policy, now);
|
|
57880
|
+
const block2 = evaluateProviderQuotaGate(node, failedProviderType, policy, now, context);
|
|
57837
57881
|
if (!block2) return { action: "keep", providerType: failedProviderType };
|
|
57838
57882
|
const alternatives = nodeProviderTypes.filter((p) => p && p !== failedProviderType);
|
|
57839
57883
|
if (alternatives.length) {
|
|
57840
|
-
const ranked = rankProvidersByQuotaGate(node, alternatives, policy, now);
|
|
57884
|
+
const ranked = rankProvidersByQuotaGate(node, alternatives, policy, now, context);
|
|
57841
57885
|
if (ranked.clear.length) {
|
|
57842
57886
|
return { action: "fallback", providerType: ranked.clear[0], block: block2 };
|
|
57843
57887
|
}
|
|
@@ -57852,9 +57896,9 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57852
57896
|
}
|
|
57853
57897
|
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`;
|
|
57854
57898
|
}
|
|
57855
|
-
function quotaRiskSnapshotForCandidates(node, orderedProviderTypes, policy, now = Date.now()) {
|
|
57899
|
+
function quotaRiskSnapshotForCandidates(node, orderedProviderTypes, policy, now = Date.now(), context) {
|
|
57856
57900
|
return orderedProviderTypes.map((providerType) => {
|
|
57857
|
-
const w = expiryRiskForRanking(node, providerType, "weekly", policy, now);
|
|
57901
|
+
const w = expiryRiskForRanking(node, providerType, "weekly", policy, now, context);
|
|
57858
57902
|
return {
|
|
57859
57903
|
providerType,
|
|
57860
57904
|
...w ? { remainingPercent: w.remainingPercent, risk: w.risk } : {}
|
|
@@ -57898,6 +57942,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
57898
57942
|
var init_mesh_quota_routing = __esm2({
|
|
57899
57943
|
"src/mesh/mesh-quota-routing.ts"() {
|
|
57900
57944
|
"use strict";
|
|
57945
|
+
init_dist();
|
|
57901
57946
|
init_repo_mesh_types();
|
|
57902
57947
|
PROVIDER_QUOTA_SESSION_LOW_SKIP_REASON = "provider_quota_session_low";
|
|
57903
57948
|
PROVIDER_QUOTA_WEEKLY_LOW_SKIP_REASON = "provider_quota_weekly_low";
|
|
@@ -61937,7 +61982,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
61937
61982
|
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`);
|
|
61938
61983
|
return false;
|
|
61939
61984
|
}
|
|
61940
|
-
const quotaClaimBlock = evaluateProviderQuotaGate(node, providerType, mesh?.policy?.quotaRouting ?? null);
|
|
61985
|
+
const quotaClaimBlock = evaluateProviderQuotaGate(node, providerType, mesh?.policy?.quotaRouting ?? null, Date.now(), mesh);
|
|
61941
61986
|
if (quotaClaimBlock) {
|
|
61942
61987
|
if (quotaClaimBlock.reason === PROVIDER_QUOTA_EXHAUSTED_SKIP_REASON) {
|
|
61943
61988
|
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`);
|
|
@@ -62414,7 +62459,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
62414
62459
|
retractActionableSkipIfPreviouslyNotified(meshId, taskId);
|
|
62415
62460
|
}
|
|
62416
62461
|
}
|
|
62417
|
-
async function resolveUsableProvider(components, nodeId, node, meshId, requiredTags, task, quotaRouting) {
|
|
62462
|
+
async function resolveUsableProvider(components, nodeId, node, meshId, requiredTags, task, quotaRouting, quotaFactsContext) {
|
|
62418
62463
|
const providerLoader = components.providerLoader;
|
|
62419
62464
|
if (!providerLoader) return { reason: "provider_loader_unavailable" };
|
|
62420
62465
|
const slots = resolveNodeCapabilitySlots(node, meshId);
|
|
@@ -62462,8 +62507,8 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
62462
62507
|
if (!candidates.length) {
|
|
62463
62508
|
return { reason: `provider_priority_unusable: ${failed.join("; ") || nodeId}` };
|
|
62464
62509
|
}
|
|
62465
|
-
const ranked = rankProvidersByQuotaGate(node, candidates.map((c) => c.providerType), quotaRouting);
|
|
62466
|
-
const riskSnapshot = quotaRiskSnapshotForCandidates(node, ranked.clear, quotaRouting);
|
|
62510
|
+
const ranked = rankProvidersByQuotaGate(node, candidates.map((c) => c.providerType), quotaRouting, Date.now(), quotaFactsContext);
|
|
62511
|
+
const riskSnapshot = quotaRiskSnapshotForCandidates(node, ranked.clear, quotaRouting, Date.now(), quotaFactsContext);
|
|
62467
62512
|
if (!ranked.clear.length) {
|
|
62468
62513
|
const detail = ranked.gated.map((g) => `${g.providerType}: ${g.block.reason}`).join("; ");
|
|
62469
62514
|
LOG2.info("MeshQueue", `QUOTA GATE: every usable provider on node ${nodeId} is quota-gated (${detail}); leaving the task queued until a quota window resets`);
|
|
@@ -62714,7 +62759,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
62714
62759
|
}
|
|
62715
62760
|
autoLaunchInProgress.add(launchKey);
|
|
62716
62761
|
try {
|
|
62717
|
-
const resolved = await resolveUsableProvider(components, nodeId, node, meshId, task.requiredTags, { difficulty: task.difficulty, requiredTags: task.requiredTags }, mesh?.policy?.quotaRouting ?? null);
|
|
62762
|
+
const resolved = await resolveUsableProvider(components, nodeId, node, meshId, task.requiredTags, { difficulty: task.difficulty, requiredTags: task.requiredTags }, mesh?.policy?.quotaRouting ?? null, mesh);
|
|
62718
62763
|
if (!resolved.providerType) {
|
|
62719
62764
|
markSkip(nodeId, resolved.reason || "provider_unusable");
|
|
62720
62765
|
continue;
|
|
@@ -64955,6 +65000,68 @@ ${cleanBody}`;
|
|
|
64955
65000
|
recentReadDebugSignatureBySession = /* @__PURE__ */ new Map();
|
|
64956
65001
|
}
|
|
64957
65002
|
});
|
|
65003
|
+
function readNonEmptyString3(value) {
|
|
65004
|
+
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
65005
|
+
}
|
|
65006
|
+
function resolveLocalDaemonIds(components) {
|
|
65007
|
+
const statusInstanceId = readNonEmptyString3(components.statusInstanceId);
|
|
65008
|
+
const machineId = readNonEmptyString3(loadConfig2().machineId);
|
|
65009
|
+
return expandDaemonIdForms([statusInstanceId, machineId]);
|
|
65010
|
+
}
|
|
65011
|
+
function scheduleTaskCompletionSideEffectEvidence(components, args) {
|
|
65012
|
+
if (args.taskMode !== "code_change") return;
|
|
65013
|
+
if (!args.taskId) return;
|
|
65014
|
+
const nodeId = args.nodeId;
|
|
65015
|
+
if (!nodeId) return;
|
|
65016
|
+
setImmediate(() => {
|
|
65017
|
+
(async () => {
|
|
65018
|
+
try {
|
|
65019
|
+
const mesh = getMesh(args.meshId);
|
|
65020
|
+
const node = mesh?.nodes.find((n) => meshNodeIdMatches(n, nodeId));
|
|
65021
|
+
const workspace = readNonEmptyString3(node?.workspace);
|
|
65022
|
+
if (!workspace) return;
|
|
65023
|
+
const nodeDaemonId = node ? readMeshNodeDaemonId(node) : void 0;
|
|
65024
|
+
if (nodeDaemonId) {
|
|
65025
|
+
const localDaemonIds = resolveLocalDaemonIds(components);
|
|
65026
|
+
const isLocal = localDaemonIds.some((id) => daemonIdsEquivalent(id, nodeDaemonId));
|
|
65027
|
+
if (!isLocal) return;
|
|
65028
|
+
}
|
|
65029
|
+
const status = await getGitRepoStatus(workspace, { includeSubmodules: false });
|
|
65030
|
+
if (!status.isGitRepo) return;
|
|
65031
|
+
if (status.dirty) return;
|
|
65032
|
+
appendLedgerEntry(args.meshId, {
|
|
65033
|
+
kind: "task_completion_no_side_effects",
|
|
65034
|
+
nodeId,
|
|
65035
|
+
sessionId: args.sessionId,
|
|
65036
|
+
taskId: args.taskId,
|
|
65037
|
+
payload: {
|
|
65038
|
+
taskId: args.taskId,
|
|
65039
|
+
sessionId: args.sessionId,
|
|
65040
|
+
nodeId,
|
|
65041
|
+
workspace,
|
|
65042
|
+
gitDirty: false,
|
|
65043
|
+
changedFiles: 0,
|
|
65044
|
+
reason: "no_side_effects"
|
|
65045
|
+
}
|
|
65046
|
+
});
|
|
65047
|
+
} catch (e) {
|
|
65048
|
+
LOG2.warn("MeshLedger", `Skipped completion side-effect evidence check for task ${args.taskId}: ${e?.message || e}`);
|
|
65049
|
+
}
|
|
65050
|
+
})();
|
|
65051
|
+
});
|
|
65052
|
+
}
|
|
65053
|
+
var init_mesh_completion_side_effect_evidence = __esm2({
|
|
65054
|
+
"src/mesh/mesh-completion-side-effect-evidence.ts"() {
|
|
65055
|
+
"use strict";
|
|
65056
|
+
init_config();
|
|
65057
|
+
init_mesh_config();
|
|
65058
|
+
init_git_status();
|
|
65059
|
+
init_logger();
|
|
65060
|
+
init_dist();
|
|
65061
|
+
init_mesh_ledger();
|
|
65062
|
+
init_mesh_node_identity();
|
|
65063
|
+
}
|
|
65064
|
+
});
|
|
64958
65065
|
function readLiveTurnPendingEvidence(instance) {
|
|
64959
65066
|
const candidate = instance;
|
|
64960
65067
|
try {
|
|
@@ -65968,7 +66075,7 @@ ${cleanBody}`;
|
|
|
65968
66075
|
}
|
|
65969
66076
|
}
|
|
65970
66077
|
setImmediate(() => cleanupTerminalDirectDispatches());
|
|
65971
|
-
return task ? { id: task.id } : null;
|
|
66078
|
+
return task ? { id: task.id, taskMode: task.taskMode } : null;
|
|
65972
66079
|
}
|
|
65973
66080
|
let completedTaskForLedger = null;
|
|
65974
66081
|
let directDispatchTaskIdForLedger;
|
|
@@ -66273,6 +66380,15 @@ ${cleanBody}`;
|
|
|
66273
66380
|
...completionEvidence ? completionEvidence.workerResult.source === "default" ? { evidenceLevel: "insufficient", reviewRecommended: true } : { evidenceLevel: "sufficient" } : {}
|
|
66274
66381
|
}
|
|
66275
66382
|
});
|
|
66383
|
+
if (ledgerKind === "task_completed") {
|
|
66384
|
+
scheduleTaskCompletionSideEffectEvidence(components, {
|
|
66385
|
+
meshId: args.meshId,
|
|
66386
|
+
taskId: completedTaskForLedger?.id || directDispatchTaskIdForLedger || void 0,
|
|
66387
|
+
taskMode: completedTaskForLedger?.taskMode,
|
|
66388
|
+
sessionId: ledgerSessionId,
|
|
66389
|
+
nodeId: ledgerNodeId
|
|
66390
|
+
});
|
|
66391
|
+
}
|
|
66276
66392
|
} catch (e) {
|
|
66277
66393
|
LOG2.warn("MeshLedger", `Failed to record ${ledgerKind}: ${e?.message || e}`);
|
|
66278
66394
|
}
|
|
@@ -66318,7 +66434,9 @@ ${cleanBody}`;
|
|
|
66318
66434
|
node,
|
|
66319
66435
|
recoveryContext.failedProviderType,
|
|
66320
66436
|
resolveNodeCapabilitySlots(node, args.meshId).map((s2) => s2.provider),
|
|
66321
|
-
mesh?.policy?.quotaRouting ?? null
|
|
66437
|
+
mesh?.policy?.quotaRouting ?? null,
|
|
66438
|
+
Date.now(),
|
|
66439
|
+
mesh
|
|
66322
66440
|
) : { action: "block" };
|
|
66323
66441
|
const relaunchProviderType = relaunch.action === "block" ? null : relaunch.providerType;
|
|
66324
66442
|
if (node) {
|
|
@@ -66769,6 +66887,7 @@ ${cleanBody}`;
|
|
|
66769
66887
|
init_mesh_json_config();
|
|
66770
66888
|
init_mesh_quota_routing();
|
|
66771
66889
|
init_mesh_node_slots();
|
|
66890
|
+
init_mesh_completion_side_effect_evidence();
|
|
66772
66891
|
init_dist();
|
|
66773
66892
|
init_mesh_events_stale();
|
|
66774
66893
|
init_mesh_task_inflight();
|
|
@@ -68729,6 +68848,17 @@ ${cleanBody}`;
|
|
|
68729
68848
|
return void 0;
|
|
68730
68849
|
}
|
|
68731
68850
|
}
|
|
68851
|
+
function localGeneratingLabelIsContradicted(components, sessionId) {
|
|
68852
|
+
try {
|
|
68853
|
+
const probe = resolveLiveTurnPendingEvidence(components, sessionId);
|
|
68854
|
+
if (!probe) return false;
|
|
68855
|
+
if (probe()) return false;
|
|
68856
|
+
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)`);
|
|
68857
|
+
return true;
|
|
68858
|
+
} catch {
|
|
68859
|
+
return false;
|
|
68860
|
+
}
|
|
68861
|
+
}
|
|
68732
68862
|
async function evaluateEarlyIdleTranscriptArm(components, mesh, store, row, localDaemonId, selfIds = []) {
|
|
68733
68863
|
const sessionId = readNonEmptyString(row.assignedSessionId);
|
|
68734
68864
|
if (!sessionId) return false;
|
|
@@ -68744,7 +68874,9 @@ ${cleanBody}`;
|
|
|
68744
68874
|
}
|
|
68745
68875
|
}
|
|
68746
68876
|
const verdict = resolveSessionBusyVerdict(components, sessionId);
|
|
68747
|
-
if (verdict === "GENERATING")
|
|
68877
|
+
if (verdict === "GENERATING" && !localGeneratingLabelIsContradicted(components, sessionId)) {
|
|
68878
|
+
return false;
|
|
68879
|
+
}
|
|
68748
68880
|
if (verdict === "UNKNOWN") {
|
|
68749
68881
|
const nodeId = readNonEmptyString(row.assignedNodeId);
|
|
68750
68882
|
const node = (mesh.nodes ?? []).find((n) => n.id === nodeId);
|
|
@@ -93152,6 +93284,45 @@ ${marker}`,
|
|
|
93152
93284
|
init_config();
|
|
93153
93285
|
init_install();
|
|
93154
93286
|
init_logger();
|
|
93287
|
+
var SEMVER_PATTERN = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
93288
|
+
var NUMERIC_IDENTIFIER = /^\d+$/;
|
|
93289
|
+
function parseSemver(version2) {
|
|
93290
|
+
if (typeof version2 !== "string") return null;
|
|
93291
|
+
const match = version2.trim().replace(/^v/, "").match(SEMVER_PATTERN);
|
|
93292
|
+
if (!match) return null;
|
|
93293
|
+
return {
|
|
93294
|
+
major: Number(match[1]),
|
|
93295
|
+
minor: Number(match[2]),
|
|
93296
|
+
patch: Number(match[3]),
|
|
93297
|
+
prerelease: match[4] ? match[4].split(".") : []
|
|
93298
|
+
};
|
|
93299
|
+
}
|
|
93300
|
+
function comparePrerelease(a, b) {
|
|
93301
|
+
if (a.length === 0 && b.length === 0) return 0;
|
|
93302
|
+
if (a.length === 0) return 1;
|
|
93303
|
+
if (b.length === 0) return -1;
|
|
93304
|
+
for (let i = 0; i < Math.min(a.length, b.length); i += 1) {
|
|
93305
|
+
const idA = a[i];
|
|
93306
|
+
const idB = b[i];
|
|
93307
|
+
if (idA === idB) continue;
|
|
93308
|
+
const numA = NUMERIC_IDENTIFIER.test(idA);
|
|
93309
|
+
const numB = NUMERIC_IDENTIFIER.test(idB);
|
|
93310
|
+
if (numA && numB) return Number(idA) < Number(idB) ? -1 : 1;
|
|
93311
|
+
if (numA) return -1;
|
|
93312
|
+
if (numB) return 1;
|
|
93313
|
+
return idA < idB ? -1 : 1;
|
|
93314
|
+
}
|
|
93315
|
+
return a.length === b.length ? 0 : a.length < b.length ? -1 : 1;
|
|
93316
|
+
}
|
|
93317
|
+
function compareSemver(a, b) {
|
|
93318
|
+
const pa = parseSemver(a);
|
|
93319
|
+
const pb = parseSemver(b);
|
|
93320
|
+
if (!pa || !pb) return null;
|
|
93321
|
+
if (pa.major !== pb.major) return pa.major < pb.major ? -1 : 1;
|
|
93322
|
+
if (pa.minor !== pb.minor) return pa.minor < pb.minor ? -1 : 1;
|
|
93323
|
+
if (pa.patch !== pb.patch) return pa.patch < pb.patch ? -1 : 1;
|
|
93324
|
+
return comparePrerelease(pa.prerelease, pb.prerelease);
|
|
93325
|
+
}
|
|
93155
93326
|
init_track_identity();
|
|
93156
93327
|
var daemonLifecycleHandlers = {
|
|
93157
93328
|
daemon_upgrade: async (ctx, args) => {
|
|
@@ -93160,10 +93331,22 @@ ${marker}`,
|
|
|
93160
93331
|
const isStandalone = ctx.deps.packageName === "@adhdev/daemon-standalone" || process.argv[1]?.includes("daemon-standalone");
|
|
93161
93332
|
const pkgName = isStandalone ? "@adhdev/daemon-standalone" : "adhdev";
|
|
93162
93333
|
const npmSurface = resolveCurrentGlobalInstallSurface({ packageName: pkgName });
|
|
93163
|
-
|
|
93164
|
-
|
|
93334
|
+
const requestedChannelRaw = args?.channel ?? args?.updatePolicy?.channel ?? null;
|
|
93335
|
+
const requestedChannel = typeof requestedChannelRaw === "string" && requestedChannelRaw.trim() ? requestedChannelRaw.trim().toLowerCase() : null;
|
|
93336
|
+
const requestedNpmTag = typeof args?.npmTag === "string" && args.npmTag.trim() ? args.npmTag.trim().toLowerCase() : null;
|
|
93337
|
+
if (requestedChannel || requestedNpmTag) {
|
|
93338
|
+
LOG2.info("Upgrade", `Ignoring deprecated channel hint (channel=${requestedChannel ?? "-"}, npmTag=${requestedNpmTag ?? "-"}) \u2014 upgrade target is the build track '${TRACK}'`);
|
|
93165
93339
|
}
|
|
93166
93340
|
const npmTag = IDENTITY.npmTag;
|
|
93341
|
+
const channelOverride = requestedChannel && requestedChannel !== TRACK && !(TRACK === "preview" && requestedChannel === "next") && !(TRACK === "stable" && requestedChannel === "latest") || requestedNpmTag && requestedNpmTag !== npmTag ? {
|
|
93342
|
+
requestedChannel,
|
|
93343
|
+
requestedNpmTag,
|
|
93344
|
+
effectiveChannel: TRACK,
|
|
93345
|
+
effectiveNpmTag: npmTag,
|
|
93346
|
+
ignored: true,
|
|
93347
|
+
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.`
|
|
93348
|
+
} : null;
|
|
93349
|
+
const withChannelNotice = (payload) => channelOverride ? { ...payload, channelOverride } : payload;
|
|
93167
93350
|
const latest = resolveNpmPublishedVersion(pkgName, npmTag, npmSurface);
|
|
93168
93351
|
LOG2.info("Upgrade", `Latest ${pkgName}@${npmTag}: v${latest}`);
|
|
93169
93352
|
let currentInstalled = null;
|
|
@@ -93180,11 +93363,39 @@ ${marker}`,
|
|
|
93180
93363
|
const runningVersion = typeof ctx.deps.statusVersion === "string" ? ctx.deps.statusVersion.trim().replace(/^v/, "") : null;
|
|
93181
93364
|
if (currentInstalled === latest && runningVersion === latest) {
|
|
93182
93365
|
LOG2.info("Upgrade", `Already on ${TRACK} track version v${latest}; skipping install`);
|
|
93183
|
-
return { success: true, upgraded: false, alreadyLatest: true, outcome: "already_latest", version: latest, targetVersion: latest, channel: TRACK, npmTag };
|
|
93366
|
+
return withChannelNotice({ success: true, upgraded: false, alreadyLatest: true, outcome: "already_latest", version: latest, targetVersion: latest, channel: TRACK, npmTag });
|
|
93184
93367
|
}
|
|
93185
93368
|
if (currentInstalled === latest && runningVersion && runningVersion !== latest) {
|
|
93186
93369
|
LOG2.info("Upgrade", `Installed package is v${latest}, but running daemon is v${runningVersion}; scheduling restart`);
|
|
93187
93370
|
}
|
|
93371
|
+
const direction = runningVersion ? compareSemver(latest, runningVersion) : null;
|
|
93372
|
+
if (direction !== null && direction < 0 && args?.allowDowngrade !== true) {
|
|
93373
|
+
LOG2.warn("Upgrade", `Refusing downgrade: running v${runningVersion} is NEWER than ${TRACK} track target v${latest} (${pkgName}@${npmTag}). Pass allowDowngrade to override.`);
|
|
93374
|
+
return withChannelNotice({
|
|
93375
|
+
success: false,
|
|
93376
|
+
upgraded: false,
|
|
93377
|
+
restarting: false,
|
|
93378
|
+
code: "downgrade_refused",
|
|
93379
|
+
outcome: "downgrade_refused",
|
|
93380
|
+
// Everything the caller needs to see WHY it would go
|
|
93381
|
+
// backwards, without a second round-trip: the incident that
|
|
93382
|
+
// motivated this guard was diagnosable only because someone
|
|
93383
|
+
// noticed the version in the response was lower than the
|
|
93384
|
+
// node's actual version.
|
|
93385
|
+
version: runningVersion,
|
|
93386
|
+
currentVersion: runningVersion,
|
|
93387
|
+
installedVersion: currentInstalled,
|
|
93388
|
+
targetVersion: latest,
|
|
93389
|
+
channel: TRACK,
|
|
93390
|
+
npmTag,
|
|
93391
|
+
packageName: pkgName,
|
|
93392
|
+
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.`,
|
|
93393
|
+
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."
|
|
93394
|
+
});
|
|
93395
|
+
}
|
|
93396
|
+
if (direction !== null && direction < 0) {
|
|
93397
|
+
LOG2.warn("Upgrade", `allowDowngrade set \u2014 proceeding with DOWNGRADE from v${runningVersion} to v${latest} on the ${TRACK} track`);
|
|
93398
|
+
}
|
|
93188
93399
|
spawnDetachedDaemonUpgradeHelper({
|
|
93189
93400
|
packageName: pkgName,
|
|
93190
93401
|
targetVersion: latest,
|
|
@@ -93198,7 +93409,7 @@ ${marker}`,
|
|
|
93198
93409
|
LOG2.info("Upgrade", "Exiting daemon so detached upgrader can continue...");
|
|
93199
93410
|
process.exit(0);
|
|
93200
93411
|
}, 3e3);
|
|
93201
|
-
return {
|
|
93412
|
+
return withChannelNotice({
|
|
93202
93413
|
success: true,
|
|
93203
93414
|
upgraded: true,
|
|
93204
93415
|
version: latest,
|
|
@@ -93207,9 +93418,16 @@ ${marker}`,
|
|
|
93207
93418
|
npmTag,
|
|
93208
93419
|
outcome: "scheduled",
|
|
93209
93420
|
targetVersion: latest,
|
|
93421
|
+
// No `currentVersion` here on purpose: this response is about a
|
|
93422
|
+
// SCHEDULED move, and daemon-upgrade-scheduled-intent.test.ts
|
|
93423
|
+
// pins that it must not read as "already on the target". The
|
|
93424
|
+
// pre-upgrade version belongs on the refusal payload, where it
|
|
93425
|
+
// is the actual diagnosis. Only the deliberate-override marker
|
|
93426
|
+
// is added, so an intentional rollback stays self-evident.
|
|
93427
|
+
...direction !== null && direction < 0 ? { downgrade: true } : {},
|
|
93210
93428
|
upgradeLogPath: getUpgradeLogPath(),
|
|
93211
93429
|
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.`
|
|
93212
|
-
};
|
|
93430
|
+
});
|
|
93213
93431
|
} catch (e) {
|
|
93214
93432
|
LOG2.error("Upgrade", `Failed: ${e.message}`);
|
|
93215
93433
|
return { success: false, error: e.message };
|
|
@@ -96961,6 +97179,8 @@ ${marker}`,
|
|
|
96961
97179
|
var CANON_C_MISSING_ASSISTANT_MIN_ELAPSED_MS = 2e4;
|
|
96962
97180
|
var MISSING_ASSISTANT_TRANSCRIPT_GROWTH_QUIET_MS = 6e4;
|
|
96963
97181
|
var NATIVE_HISTORY_MESH_IDLE_SETTLE_MS = 4e3;
|
|
97182
|
+
var CANCELLED_COMPLETION_RECHECK_MS = 1500;
|
|
97183
|
+
var CANCELLED_COMPLETION_RECHECK_MAX_ATTEMPTS = 4;
|
|
96964
97184
|
var PTY_PARSED_FINAL_ASSISTANT_QUIET_DWELL_MS = 1200;
|
|
96965
97185
|
var ANTIGRAVITY_HOLD_QUIET_DWELL_MS = 3e3;
|
|
96966
97186
|
var ANTIGRAVITY_HOLD_HARD_CAP_MS = 5 * 6e4;
|
|
@@ -98019,7 +98239,7 @@ ${buttons.join("\n")}`;
|
|
|
98019
98239
|
timestamp: Date.now(),
|
|
98020
98240
|
taskId,
|
|
98021
98241
|
finalSummary,
|
|
98022
|
-
evidenceLevel: "
|
|
98242
|
+
evidenceLevel: "reported",
|
|
98023
98243
|
completionDiagnostic: { source: "pre_cleanup_transcript_completion" }
|
|
98024
98244
|
});
|
|
98025
98245
|
return true;
|
|
@@ -98068,7 +98288,7 @@ ${buttons.join("\n")}`;
|
|
|
98068
98288
|
timestamp: Date.now(),
|
|
98069
98289
|
taskId,
|
|
98070
98290
|
finalSummary,
|
|
98071
|
-
evidenceLevel: "
|
|
98291
|
+
evidenceLevel: "reported",
|
|
98072
98292
|
completionDiagnostic: { source: diagnosticSource }
|
|
98073
98293
|
});
|
|
98074
98294
|
return true;
|
|
@@ -98510,6 +98730,64 @@ ${buttons.join("\n")}`;
|
|
|
98510
98730
|
host.pushEvent({ event: me.type, agentKey: me.agentKey, message: me.message, elapsedSec: me.elapsedSec, timestamp: me.timestamp });
|
|
98511
98731
|
}
|
|
98512
98732
|
}
|
|
98733
|
+
init_logger();
|
|
98734
|
+
function armCancelledCompletionRecheck(host, pending, reason) {
|
|
98735
|
+
if (reason === "new_pty_output") return;
|
|
98736
|
+
const now = Date.now();
|
|
98737
|
+
const prior = host.cancelledCompletionRecheck;
|
|
98738
|
+
const carriedPending = prior?.pending ?? pending;
|
|
98739
|
+
const attempts = prior ? prior.attempts : 0;
|
|
98740
|
+
if (attempts >= CANCELLED_COMPLETION_RECHECK_MAX_ATTEMPTS) {
|
|
98741
|
+
clearCancelledCompletionRecheck(host);
|
|
98742
|
+
LOG2.debug("CLI", `[${host.type}] cancelled-completion recheck budget exhausted (${reason}) \u2014 deferring to the next FSM completion edge`);
|
|
98743
|
+
return;
|
|
98744
|
+
}
|
|
98745
|
+
host.cancelledCompletionRecheck = {
|
|
98746
|
+
pending: carriedPending,
|
|
98747
|
+
reason,
|
|
98748
|
+
attempts,
|
|
98749
|
+
firstCancelledAt: prior?.firstCancelledAt ?? now
|
|
98750
|
+
};
|
|
98751
|
+
if (host.cancelledCompletionRecheckTimer) clearTimeout(host.cancelledCompletionRecheckTimer);
|
|
98752
|
+
host.cancelledCompletionRecheckTimer = setTimeout(
|
|
98753
|
+
() => runCancelledCompletionRecheck(host),
|
|
98754
|
+
CANCELLED_COMPLETION_RECHECK_MS
|
|
98755
|
+
);
|
|
98756
|
+
}
|
|
98757
|
+
function clearCancelledCompletionRecheck(host) {
|
|
98758
|
+
if (host.cancelledCompletionRecheckTimer) {
|
|
98759
|
+
clearTimeout(host.cancelledCompletionRecheckTimer);
|
|
98760
|
+
host.cancelledCompletionRecheckTimer = null;
|
|
98761
|
+
}
|
|
98762
|
+
host.cancelledCompletionRecheck = null;
|
|
98763
|
+
}
|
|
98764
|
+
function runCancelledCompletionRecheck(host) {
|
|
98765
|
+
host.cancelledCompletionRecheckTimer = null;
|
|
98766
|
+
const watch3 = host.cancelledCompletionRecheck;
|
|
98767
|
+
if (!watch3) return;
|
|
98768
|
+
if (host.completedDebouncePending) {
|
|
98769
|
+
clearCancelledCompletionRecheck(host);
|
|
98770
|
+
return;
|
|
98771
|
+
}
|
|
98772
|
+
watch3.attempts += 1;
|
|
98773
|
+
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)`);
|
|
98774
|
+
if (host.completionTraceOn()) host.recordCompletionGateTrace("cancel_recheck", {
|
|
98775
|
+
reason: watch3.reason,
|
|
98776
|
+
attempt: watch3.attempts,
|
|
98777
|
+
sinceCancelMs: Date.now() - watch3.firstCancelledAt,
|
|
98778
|
+
busyEpoch: host.busyEpoch
|
|
98779
|
+
});
|
|
98780
|
+
const lastOutputAt = host.adapter.getStatus({ allowParse: false })?.lastOutputAt;
|
|
98781
|
+
host.completedDebouncePending = {
|
|
98782
|
+
...watch3.pending,
|
|
98783
|
+
busyEpochAtArm: host.busyEpoch,
|
|
98784
|
+
lastOutputAtArm: typeof lastOutputAt === "number" && Number.isFinite(lastOutputAt) ? lastOutputAt : watch3.pending.lastOutputAtArm
|
|
98785
|
+
};
|
|
98786
|
+
host.flushCompletedDebounceIfFinalized();
|
|
98787
|
+
if (host.cancelledCompletionRecheck === watch3 && host.completedDebouncePending) {
|
|
98788
|
+
clearCancelledCompletionRecheck(host);
|
|
98789
|
+
}
|
|
98790
|
+
}
|
|
98513
98791
|
init_contracts2();
|
|
98514
98792
|
var MAX_TRACKED_MESSAGES = 2e3;
|
|
98515
98793
|
function hasUsableTimestamp(message) {
|
|
@@ -99669,11 +99947,20 @@ ${buttons.join("\n")}`;
|
|
|
99669
99947
|
clearTimeout(this.autoApproveBusyTimer);
|
|
99670
99948
|
this.autoApproveBusyTimer = null;
|
|
99671
99949
|
}
|
|
99950
|
+
this.clearCancelledCompletionRecheck();
|
|
99672
99951
|
this.appliedEffectKeys.clear();
|
|
99673
99952
|
closeSqliteProbeCache(this.sqliteProbeCache);
|
|
99674
99953
|
}
|
|
99675
99954
|
completedDebounceTimer = null;
|
|
99676
99955
|
completedDebouncePending = null;
|
|
99956
|
+
/**
|
|
99957
|
+
* (CANCEL-BLIP-ORPHAN) Re-verification watch for an arm the continuity cancel just
|
|
99958
|
+
* deleted — the cancelled arm's snapshot plus a bounded recheck budget, so a
|
|
99959
|
+
* sub-second PTY blip cannot permanently orphan the completion. Full rationale:
|
|
99960
|
+
* completion/cancel-recheck.ts.
|
|
99961
|
+
*/
|
|
99962
|
+
cancelledCompletionRecheck = null;
|
|
99963
|
+
cancelledCompletionRecheckTimer = null;
|
|
99677
99964
|
lastExternalCompletionProbe = null;
|
|
99678
99965
|
// (NATIVE-TURN-SIGNAL) Terminal markers from the last native transcript read. Refreshed
|
|
99679
99966
|
// on every completion probe; null when the provider surfaces none.
|
|
@@ -100120,6 +100407,17 @@ ${buttons.join("\n")}`;
|
|
|
100120
100407
|
if (this.completedDebounceTimer) clearTimeout(this.completedDebounceTimer);
|
|
100121
100408
|
this.completedDebounceTimer = setTimeout(() => this.flushCompletedDebounceIfFinalized(), delayMs);
|
|
100122
100409
|
}
|
|
100410
|
+
/**
|
|
100411
|
+
* (CANCEL-BLIP-ORPHAN) Post-cancel completion re-verification. The judgment and its
|
|
100412
|
+
* full rationale live in completion/cancel-recheck.ts; these are the host-dispatched
|
|
100413
|
+
* seams, matching the status-transition / evidence / stall-rescue moves.
|
|
100414
|
+
*/
|
|
100415
|
+
armCancelledCompletionRecheck(pending, reason) {
|
|
100416
|
+
armCancelledCompletionRecheck(this, pending, reason);
|
|
100417
|
+
}
|
|
100418
|
+
clearCancelledCompletionRecheck() {
|
|
100419
|
+
clearCancelledCompletionRecheck(this);
|
|
100420
|
+
}
|
|
100123
100421
|
// EVTTRACE (observation-only): is this a mesh worker session whose completion
|
|
100124
100422
|
// events must route to a coordinator? Used purely to gate trace logging so a
|
|
100125
100423
|
// non-mesh CLI session's completions don't add EvtTrace noise. No decision logic.
|
|
@@ -100651,6 +100949,7 @@ ${buttons.join("\n")}`;
|
|
|
100651
100949
|
if (this.completionTraceOn()) this.recordCompletionGateTrace("cancel", { blockReason: decision.reason, ...decision.trace });
|
|
100652
100950
|
this.completedDebouncePending = null;
|
|
100653
100951
|
this.completedDebounceTimer = null;
|
|
100952
|
+
this.armCancelledCompletionRecheck(pending, decision.reason);
|
|
100654
100953
|
return;
|
|
100655
100954
|
}
|
|
100656
100955
|
this.applyCompletionArmPatch(pending, decision.armPatch);
|
|
@@ -100708,6 +101007,7 @@ ${buttons.join("\n")}`;
|
|
|
100708
101007
|
});
|
|
100709
101008
|
this.completedDebouncePending = null;
|
|
100710
101009
|
this.completedDebounceTimer = null;
|
|
101010
|
+
this.clearCancelledCompletionRecheck();
|
|
100711
101011
|
this.generatingStartedAt = 0;
|
|
100712
101012
|
this.lastApprovalEventFingerprint = "";
|
|
100713
101013
|
this.markCurrentTurnStartupGraceCollapseSatisfied();
|
|
@@ -100734,7 +101034,7 @@ ${buttons.join("\n")}`;
|
|
|
100734
101034
|
timestamp: pending.timestamp,
|
|
100735
101035
|
taskId: pending.taskId,
|
|
100736
101036
|
finalSummary,
|
|
100737
|
-
evidenceLevel: "
|
|
101037
|
+
evidenceLevel: "reported",
|
|
100738
101038
|
completionDiagnostic: {
|
|
100739
101039
|
source: "clean_final_assistant",
|
|
100740
101040
|
cleanPath: true,
|
|
@@ -100762,6 +101062,7 @@ ${buttons.join("\n")}`;
|
|
|
100762
101062
|
});
|
|
100763
101063
|
this.completedDebouncePending = null;
|
|
100764
101064
|
this.completedDebounceTimer = null;
|
|
101065
|
+
this.clearCancelledCompletionRecheck();
|
|
100765
101066
|
this.generatingStartedAt = 0;
|
|
100766
101067
|
this.lastApprovalEventFingerprint = "";
|
|
100767
101068
|
this.markCurrentTurnStartupGraceCollapseSatisfied();
|
|
@@ -100873,7 +101174,7 @@ ${buttons.join("\n")}`;
|
|
|
100873
101174
|
* • prior emit was WEAK → re-arm ONE-SHOT, but only across a real generating→idle
|
|
100874
101175
|
* transition: require busyEpoch to have advanced past the weak emit's epoch, so a
|
|
100875
101176
|
* static idle screen cannot re-fire the same weak frame. The genuine re-emit passes
|
|
100876
|
-
* evidenceLevel:'
|
|
101177
|
+
* evidenceLevel:'reported' (non-weak), overwriting the latch → any subsequent idle
|
|
100877
101178
|
* tick hits the now-genuine latch and is suppressed. Never a third emit.
|
|
100878
101179
|
*/
|
|
100879
101180
|
shouldSuppressCompletionReEmit(taskId) {
|
|
@@ -110507,7 +110808,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
110507
110808
|
...slots.length ? { slots } : {}
|
|
110508
110809
|
};
|
|
110509
110810
|
if (providerRoles.length) migrateProviderRolesToSlots2(policy);
|
|
110510
|
-
|
|
110811
|
+
syncProviderPriorityFromSlots(policy);
|
|
110511
110812
|
const role = normalizeMeshDaemonRole(args?.role);
|
|
110512
110813
|
const daemonId = typeof args?.daemonId === "string" && args.daemonId.trim() ? args.daemonId.trim() : void 0;
|
|
110513
110814
|
const machineId = typeof args?.machineId === "string" && args.machineId.trim() ? args.machineId.trim() : void 0;
|
|
@@ -110559,10 +110860,8 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
110559
110860
|
else delete policy.providerRoles;
|
|
110560
110861
|
}
|
|
110561
110862
|
migrateProviderRolesToSlots2(policy);
|
|
110562
|
-
|
|
110563
|
-
|
|
110564
|
-
syncProviderPriorityFromSlots(policy, finalSlots);
|
|
110565
|
-
}
|
|
110863
|
+
const finalSlots = Object.prototype.hasOwnProperty.call(policy, "slots") ? policy.slots : getMesh2(meshId)?.nodes.find((n) => n.id === nodeId)?.policy?.slots;
|
|
110864
|
+
syncProviderPriorityFromSlots(policy, finalSlots);
|
|
110566
110865
|
const patch = { policy };
|
|
110567
110866
|
if (typeof args?.systemPrompt === "string") {
|
|
110568
110867
|
const trimmed = args.systemPrompt.trim();
|
|
@@ -110587,9 +110886,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
110587
110886
|
...inlineNode.policy && typeof inlineNode.policy === "object" && !Array.isArray(inlineNode.policy) ? inlineNode.policy : {},
|
|
110588
110887
|
...patch.policy
|
|
110589
110888
|
};
|
|
110590
|
-
|
|
110591
|
-
syncProviderPriorityFromSlots(inlineNode.policy);
|
|
110592
|
-
}
|
|
110889
|
+
syncProviderPriorityFromSlots(inlineNode.policy);
|
|
110593
110890
|
if (Object.prototype.hasOwnProperty.call(patch, "systemPrompt")) {
|
|
110594
110891
|
const sp = patch.systemPrompt;
|
|
110595
110892
|
if (typeof sp === "string" && sp.trim()) inlineNode.systemPrompt = sp;
|
|
@@ -113593,6 +113890,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
113593
113890
|
init_dist();
|
|
113594
113891
|
init_mesh_events();
|
|
113595
113892
|
init_mesh_reconcile_identity();
|
|
113893
|
+
init_mesh_reconcile_acked_hold();
|
|
113596
113894
|
init_mesh_fast_forward();
|
|
113597
113895
|
var import_node_child_process7 = require("child_process");
|
|
113598
113896
|
var import_node_util5 = require("util");
|
|
@@ -115595,11 +115893,20 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
115595
115893
|
LOG2.warn("Mesh", `[Refinery] Failed to append async refine ledger entry: ${e?.message || e}`);
|
|
115596
115894
|
}
|
|
115597
115895
|
}
|
|
115896
|
+
function resolveRefineResumeDispatchGraceMs() {
|
|
115897
|
+
return resolveTunedReconcileMs("MESH_REFINE_RESUME_DISPATCH_GRACE_MS", 6e4, 0, 10 * 6e4);
|
|
115898
|
+
}
|
|
115899
|
+
function resolveRefineResumeZombieCutoffMs() {
|
|
115900
|
+
return resolveTunedReconcileMs("MESH_REFINE_RESUME_ZOMBIE_CUTOFF_MS", 24 * 60 * 6e4, 5 * 6e4, 30 * 24 * 60 * 6e4);
|
|
115901
|
+
}
|
|
115598
115902
|
async function resumePendingRefineJobsOnStartup(self) {
|
|
115599
115903
|
try {
|
|
115600
115904
|
const { listMeshes: listMeshes2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
115601
115905
|
const { readLedgerEntries: readLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
115602
115906
|
const meshIds = listMeshes2().map((m) => m.id).filter(Boolean);
|
|
115907
|
+
const nowMs = Date.now();
|
|
115908
|
+
const dispatchGraceMs = resolveRefineResumeDispatchGraceMs();
|
|
115909
|
+
const zombieCutoffMs = resolveRefineResumeZombieCutoffMs();
|
|
115603
115910
|
for (const meshId of meshIds) {
|
|
115604
115911
|
const entries = readLedgerEntries2(meshId, { kind: ["task_dispatched", "task_completed", "task_failed"] });
|
|
115605
115912
|
const terminal = /* @__PURE__ */ new Set();
|
|
@@ -115617,10 +115924,44 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
115617
115924
|
if (!jobId || terminal.has(`${e.nodeId}:${jobId}`)) continue;
|
|
115618
115925
|
const key2 = buildRefineJobKey(self, meshId, e.nodeId);
|
|
115619
115926
|
if (self.runningRefineJobs.has(key2)) continue;
|
|
115927
|
+
const dispatchedAtMs = new Date(e.timestamp).getTime();
|
|
115928
|
+
const ageMs2 = Number.isFinite(dispatchedAtMs) ? nowMs - dispatchedAtMs : void 0;
|
|
115929
|
+
if (ageMs2 !== void 0 && ageMs2 >= 0 && ageMs2 < dispatchGraceMs) {
|
|
115930
|
+
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.`);
|
|
115931
|
+
continue;
|
|
115932
|
+
}
|
|
115933
|
+
if (ageMs2 !== void 0 && ageMs2 >= zombieCutoffMs) {
|
|
115934
|
+
const node = e.payload?.refineJob;
|
|
115935
|
+
const coordinatorDaemonId2 = node?.targetCoordinatorDaemonId;
|
|
115936
|
+
const coordinatorSessionId2 = node?.targetCoordinatorSessionId;
|
|
115937
|
+
const zombieHandle = buildRefineJobHandle(self, {
|
|
115938
|
+
meshId,
|
|
115939
|
+
nodeId: e.nodeId,
|
|
115940
|
+
jobId,
|
|
115941
|
+
interactionId: typeof node?.interactionId === "string" ? node.interactionId : void 0,
|
|
115942
|
+
status: "failed",
|
|
115943
|
+
startedAt: typeof node?.startedAt === "string" ? node.startedAt : e.timestamp,
|
|
115944
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
115945
|
+
coordinatorDaemonId: coordinatorDaemonId2,
|
|
115946
|
+
coordinatorSessionId: coordinatorSessionId2
|
|
115947
|
+
});
|
|
115948
|
+
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.`);
|
|
115949
|
+
const zombieResult = {
|
|
115950
|
+
success: false,
|
|
115951
|
+
code: "resume_abandoned_stale_dispatch",
|
|
115952
|
+
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.`
|
|
115953
|
+
};
|
|
115954
|
+
await appendRefineJobLedger(self, "task_failed", zombieHandle, zombieResult);
|
|
115955
|
+
queueRefineJobEvent(self, "refine:failed", zombieHandle, zombieResult);
|
|
115956
|
+
continue;
|
|
115957
|
+
}
|
|
115620
115958
|
const coordinatorDaemonId = e.payload?.refineJob?.targetCoordinatorDaemonId;
|
|
115959
|
+
const coordinatorSessionId = e.payload?.refineJob?.targetCoordinatorSessionId;
|
|
115621
115960
|
LOG2.info("Mesh", `[Refinery] Auto-resuming interrupted refine job for node ${e.nodeId} (jobId=${jobId})`);
|
|
115622
115961
|
void startMeshRefineJob(self, meshId, e.nodeId, {
|
|
115623
|
-
|
|
115962
|
+
jobId,
|
|
115963
|
+
coordinatorDaemonId,
|
|
115964
|
+
coordinatorSessionId
|
|
115624
115965
|
});
|
|
115625
115966
|
}
|
|
115626
115967
|
}
|
|
@@ -117344,7 +117685,7 @@ ${e?.stderr || ""}`;
|
|
|
117344
117685
|
const terminal = self.terminalRefineJobs.get(key2);
|
|
117345
117686
|
const alreadyRunning = self.runningRefineJobs.get(key2);
|
|
117346
117687
|
if (alreadyRunning) return { ...alreadyRunning, duplicate: true };
|
|
117347
|
-
const jobId = `refine_${createInteractionId()}`;
|
|
117688
|
+
const jobId = typeof args?.jobId === "string" && args.jobId.trim() ? args.jobId.trim() : `refine_${createInteractionId()}`;
|
|
117348
117689
|
const interactionId = createInteractionId();
|
|
117349
117690
|
const placeholder = buildRefineJobHandle(self, { meshId, nodeId, jobId, interactionId, retryOfJobId: terminal?.jobId });
|
|
117350
117691
|
self.runningRefineJobs.set(key2, placeholder);
|