@adhdev/daemon-standalone 1.0.58-rc.41 → 1.0.58-rc.42
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 +1032 -856
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -36911,10 +36911,10 @@ var require_dist3 = __commonJS({
|
|
|
36911
36911
|
}
|
|
36912
36912
|
function getDaemonBuildInfo() {
|
|
36913
36913
|
if (cached2) return cached2;
|
|
36914
|
-
const commit = readInjected(true ? "
|
|
36915
|
-
const commitShort = readInjected(true ? "
|
|
36916
|
-
const version2 = readInjected(true ? "1.0.58-rc.
|
|
36917
|
-
const builtAt = readInjected(true ? "2026-08-
|
|
36914
|
+
const commit = readInjected(true ? "2c1c52a4b48387753bcbd8c0b2d003d18fd5f544" : void 0) ?? "unknown";
|
|
36915
|
+
const commitShort = readInjected(true ? "2c1c52a4" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
36916
|
+
const version2 = readInjected(true ? "1.0.58-rc.42" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
36917
|
+
const builtAt = readInjected(true ? "2026-08-29T14:25:11.174Z" : void 0);
|
|
36918
36918
|
cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
|
|
36919
36919
|
return cached2;
|
|
36920
36920
|
}
|
|
@@ -39067,7 +39067,8 @@ var require_dist3 = __commonJS({
|
|
|
39067
39067
|
env: overrides.env ?? process.env,
|
|
39068
39068
|
spawn: overrides.spawn ?? ((command, args, options) => (0, import_node_child_process2.spawn)(command, args, {
|
|
39069
39069
|
env: options.env,
|
|
39070
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
39070
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
39071
|
+
windowsHide: true
|
|
39071
39072
|
})),
|
|
39072
39073
|
readFile: overrides.readFile ?? ((filePath) => (0, import_promises3.readFile)(filePath, "utf-8")),
|
|
39073
39074
|
setTimeout: overrides.setTimeout ?? ((handler, ms) => setTimeout(handler, ms)),
|
|
@@ -39848,6 +39849,7 @@ const shellArgs = process.platform === 'win32' ? ['/d', '/s', '/c', ORIGINAL_COM
|
|
|
39848
39849
|
|
|
39849
39850
|
const child = spawn(shell, shellArgs, {
|
|
39850
39851
|
stdio: ['pipe', 'inherit', 'inherit'],
|
|
39852
|
+
windowsHide: true,
|
|
39851
39853
|
windowsVerbatimArguments: process.platform === 'win32',
|
|
39852
39854
|
});
|
|
39853
39855
|
|
|
@@ -78793,376 +78795,6 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
78793
78795
|
REMOTE_LAUNCH_READY_POLL_MS = 100;
|
|
78794
78796
|
}
|
|
78795
78797
|
});
|
|
78796
|
-
function isAnthropicProvider(providerType) {
|
|
78797
|
-
const p = typeof providerType === "string" ? providerType.trim().toLowerCase() : "";
|
|
78798
|
-
return p.length > 0 && ANTHROPIC_PROVIDER_TYPES.has(p);
|
|
78799
|
-
}
|
|
78800
|
-
function isAnthropicModel(model) {
|
|
78801
|
-
const m = typeof model === "string" ? model.trim().toLowerCase() : "";
|
|
78802
|
-
if (!m) return false;
|
|
78803
|
-
if (m.startsWith("claude") || m.startsWith("anthropic")) return true;
|
|
78804
|
-
return /^(opus|sonnet|haiku)(\b|[-_])/.test(m);
|
|
78805
|
-
}
|
|
78806
|
-
function isModelCompatibleWithProvider(model, providerType) {
|
|
78807
|
-
if (!isAnthropicModel(model)) return true;
|
|
78808
|
-
if (isAnthropicProvider(providerType)) return true;
|
|
78809
|
-
return false;
|
|
78810
|
-
}
|
|
78811
|
-
var ANTHROPIC_PROVIDER_TYPES;
|
|
78812
|
-
var init_model_provider_compat = __esm2({
|
|
78813
|
-
"src/mesh/model-provider-compat.ts"() {
|
|
78814
|
-
"use strict";
|
|
78815
|
-
ANTHROPIC_PROVIDER_TYPES = /* @__PURE__ */ new Set([
|
|
78816
|
-
"claude-cli"
|
|
78817
|
-
]);
|
|
78818
|
-
}
|
|
78819
|
-
});
|
|
78820
|
-
function encodeDuplicateMeshDispatchCode(holderSessionId) {
|
|
78821
|
-
const holder = typeof holderSessionId === "string" ? holderSessionId.trim() : "";
|
|
78822
|
-
return holder ? `${DUPLICATE_MESH_DISPATCH_CODE}:${holder}` : DUPLICATE_MESH_DISPATCH_CODE;
|
|
78823
|
-
}
|
|
78824
|
-
function classifyDuplicateMeshDispatch(err) {
|
|
78825
|
-
if (!err || typeof err !== "object") return null;
|
|
78826
|
-
const e = err;
|
|
78827
|
-
if (e.code === DUPLICATE_MESH_DISPATCH_CODE) {
|
|
78828
|
-
const holder = typeof e.holderSessionId === "string" ? e.holderSessionId.trim() : "";
|
|
78829
|
-
return holder ? { holderSessionId: holder } : {};
|
|
78830
|
-
}
|
|
78831
|
-
for (const raw of [e.meshCode, e.code]) {
|
|
78832
|
-
if (typeof raw !== "string") continue;
|
|
78833
|
-
if (raw !== DUPLICATE_MESH_DISPATCH_CODE && !raw.startsWith(`${DUPLICATE_MESH_DISPATCH_CODE}:`)) continue;
|
|
78834
|
-
const holder = raw.slice(DUPLICATE_MESH_DISPATCH_CODE.length + 1).trim();
|
|
78835
|
-
return holder ? { holderSessionId: holder } : {};
|
|
78836
|
-
}
|
|
78837
|
-
return null;
|
|
78838
|
-
}
|
|
78839
|
-
var DUPLICATE_MESH_DISPATCH_CODE;
|
|
78840
|
-
var DuplicateMeshDispatchError;
|
|
78841
|
-
var init_mesh_duplicate_dispatch = __esm2({
|
|
78842
|
-
"src/mesh/mesh-duplicate-dispatch.ts"() {
|
|
78843
|
-
"use strict";
|
|
78844
|
-
DUPLICATE_MESH_DISPATCH_CODE = "DUPLICATE_MESH_DISPATCH";
|
|
78845
|
-
DuplicateMeshDispatchError = class extends Error {
|
|
78846
|
-
code = DUPLICATE_MESH_DISPATCH_CODE;
|
|
78847
|
-
holderSessionId;
|
|
78848
|
-
constructor(message, info = {}) {
|
|
78849
|
-
super(message);
|
|
78850
|
-
this.name = "DuplicateMeshDispatchError";
|
|
78851
|
-
this.holderSessionId = info.holderSessionId;
|
|
78852
|
-
}
|
|
78853
|
-
};
|
|
78854
|
-
}
|
|
78855
|
-
});
|
|
78856
|
-
function acquireAutoFastForwardLease(workspace) {
|
|
78857
|
-
const key2 = normalizeMeshWorkspaceForCompare(workspace);
|
|
78858
|
-
if (!key2) return false;
|
|
78859
|
-
if (autoFastForwardWorkspaceLease.has(key2)) return false;
|
|
78860
|
-
autoFastForwardWorkspaceLease.add(key2);
|
|
78861
|
-
return true;
|
|
78862
|
-
}
|
|
78863
|
-
function releaseAutoFastForwardLease(workspace) {
|
|
78864
|
-
const key2 = normalizeMeshWorkspaceForCompare(workspace);
|
|
78865
|
-
if (key2) autoFastForwardWorkspaceLease.delete(key2);
|
|
78866
|
-
}
|
|
78867
|
-
function isWorkspaceAutoFastForwardInFlight(workspace) {
|
|
78868
|
-
const key2 = normalizeMeshWorkspaceForCompare(workspace || "");
|
|
78869
|
-
return !!key2 && autoFastForwardWorkspaceLease.has(key2);
|
|
78870
|
-
}
|
|
78871
|
-
function __resetIdleAutoFastForwardForTests() {
|
|
78872
|
-
idleAutoFastForwardLastAttempt.clear();
|
|
78873
|
-
continuousAutoFastForwardLastScan.clear();
|
|
78874
|
-
autoFastForwardWorkspaceLease.clear();
|
|
78875
|
-
}
|
|
78876
|
-
function isDirtyNode(node) {
|
|
78877
|
-
return node?.health === "dirty" || node?.git?.dirty === true;
|
|
78878
|
-
}
|
|
78879
|
-
function resolveAutoFastForwardPolicy(mesh) {
|
|
78880
|
-
const record2 = mesh?.policy?.autoFastForward && typeof mesh.policy.autoFastForward === "object" && !Array.isArray(mesh.policy.autoFastForward) ? mesh.policy.autoFastForward : {};
|
|
78881
|
-
const maxBehind = Number(record2.maxBehind);
|
|
78882
|
-
return {
|
|
78883
|
-
enabled: record2.enabled !== false,
|
|
78884
|
-
...Number.isFinite(maxBehind) && maxBehind >= 0 ? { maxBehind: Math.floor(maxBehind) } : {},
|
|
78885
|
-
requireCleanSubmodules: record2.requireCleanSubmodules !== false,
|
|
78886
|
-
// Strict opt-in: absent/false → self-only (historical behavior). Only an
|
|
78887
|
-
// explicit `true` extends auto ff to remote owning-daemon nodes.
|
|
78888
|
-
remoteNodes: record2.remoteNodes === true,
|
|
78889
|
-
// Absent/anything-but-continuous → 'idle' (historical idle-edge-only detection).
|
|
78890
|
-
mode: record2.mode === "continuous" ? "continuous" : "idle"
|
|
78891
|
-
};
|
|
78892
|
-
}
|
|
78893
|
-
function dryRunSatisfiesAutoFastForwardPolicy(dryRun, policy) {
|
|
78894
|
-
if (!dryRun || dryRun.code !== "fast_forward_available" || dryRun.allowed !== true) return false;
|
|
78895
|
-
const behind = Number(dryRun.current?.behind);
|
|
78896
|
-
if (!Number.isFinite(behind) || behind <= 0) return false;
|
|
78897
|
-
if (policy.maxBehind !== void 0 && behind > policy.maxBehind) return false;
|
|
78898
|
-
if (policy.requireCleanSubmodules) {
|
|
78899
|
-
const submodules = Array.isArray(dryRun.current?.submodules) ? dryRun.current.submodules : [];
|
|
78900
|
-
if (submodules.some((submodule) => submodule?.dirty || submodule?.error)) return false;
|
|
78901
|
-
}
|
|
78902
|
-
return true;
|
|
78903
|
-
}
|
|
78904
|
-
function readNodeSubmoduleIgnorePaths(node) {
|
|
78905
|
-
return Array.isArray(node?.policy?.submoduleIgnorePaths) ? node.policy.submoduleIgnorePaths.filter((value) => typeof value === "string") : void 0;
|
|
78906
|
-
}
|
|
78907
|
-
function nodeIsAutoFastForwardEligible(components, meshId, nodeId, node, currentSessionId) {
|
|
78908
|
-
if (!node) return false;
|
|
78909
|
-
if (node.status === "disabled" || node.status === "removed") return false;
|
|
78910
|
-
if (node.readOnly === true || node.policy?.readOnly === true) return false;
|
|
78911
|
-
if (isWorktreeBootstrapStaleRunning(node)) return false;
|
|
78912
|
-
if (node.worktreeBootstrap?.status === "running") return false;
|
|
78913
|
-
if (nodeHasActiveMeshWork(components, meshId, nodeId, currentSessionId)) return false;
|
|
78914
|
-
return true;
|
|
78915
|
-
}
|
|
78916
|
-
function remoteNodeIsConnected(components, node) {
|
|
78917
|
-
const daemonId = readMeshNodeDaemonId(node ?? {});
|
|
78918
|
-
if (!daemonId) return false;
|
|
78919
|
-
const getPeerStatus = components.getMeshPeerConnectionStatus;
|
|
78920
|
-
if (getPeerStatus) {
|
|
78921
|
-
const snapshot = getPeerStatus(daemonId);
|
|
78922
|
-
return !!snapshot && String(snapshot.state) === "connected";
|
|
78923
|
-
}
|
|
78924
|
-
return readNonEmptyString(node?.connection?.state).toLowerCase() === "connected";
|
|
78925
|
-
}
|
|
78926
|
-
async function delegateRemoteAutoFastForward(components, args) {
|
|
78927
|
-
const dispatchMeshCommand = components.dispatchMeshCommand;
|
|
78928
|
-
if (!dispatchMeshCommand) return;
|
|
78929
|
-
if (!acquireAutoFastForwardLease(args.workspace)) return;
|
|
78930
|
-
const submoduleIgnorePaths = readNodeSubmoduleIgnorePaths(args.node);
|
|
78931
|
-
const mesh = getMeshWithCache(components, args.meshId);
|
|
78932
|
-
const baseArgs = {
|
|
78933
|
-
meshId: args.meshId,
|
|
78934
|
-
nodeId: args.nodeId,
|
|
78935
|
-
workspace: args.workspace,
|
|
78936
|
-
inlineMesh: mesh,
|
|
78937
|
-
...submoduleIgnorePaths ? { submoduleIgnorePaths } : {},
|
|
78938
|
-
trigger: args.trigger,
|
|
78939
|
-
// Mirror the manual mesh_fast_forward_node update_submodules behavior: if the
|
|
78940
|
-
// ff-only merge moves a submodule gitlink, run `git submodule update --init
|
|
78941
|
-
// --recursive` in the same cycle so the checkout never drifts from the gitlink.
|
|
78942
|
-
// Without this, drift accumulates and self-blocks every subsequent auto-ff
|
|
78943
|
-
// (collectPreflightBlockers treats out-of-sync submodules as a hard blocker).
|
|
78944
|
-
updateSubmodules: true
|
|
78945
|
-
};
|
|
78946
|
-
try {
|
|
78947
|
-
const remoteDry = await dispatchMeshCommand(args.daemonId, "fast_forward_mesh_node", {
|
|
78948
|
-
...baseArgs,
|
|
78949
|
-
execute: false,
|
|
78950
|
-
dryRun: true
|
|
78951
|
-
});
|
|
78952
|
-
if (!dryRunSatisfiesAutoFastForwardPolicy(remoteDry, args.policy)) return;
|
|
78953
|
-
if (nodeHasActiveMeshWork(components, args.meshId, args.nodeId)) return;
|
|
78954
|
-
const executed = await dispatchMeshCommand(args.daemonId, "fast_forward_mesh_node", {
|
|
78955
|
-
...baseArgs,
|
|
78956
|
-
execute: true,
|
|
78957
|
-
dryRun: false
|
|
78958
|
-
});
|
|
78959
|
-
if (executed?.executed === true) {
|
|
78960
|
-
LOG2.info("MeshFastForward", `Remote auto fast-forward executed for node ${args.nodeId} (daemon ${String(args.daemonId).slice(0, 12)}, trigger ${args.trigger})`);
|
|
78961
|
-
}
|
|
78962
|
-
} catch (e) {
|
|
78963
|
-
LOG2.warn("MeshFastForward", `Remote auto fast-forward delegation failed for ${args.nodeId}: ${e?.message || e}`);
|
|
78964
|
-
} finally {
|
|
78965
|
-
releaseAutoFastForwardLease(args.workspace);
|
|
78966
|
-
}
|
|
78967
|
-
}
|
|
78968
|
-
async function executeLocalAutoFastForward(args) {
|
|
78969
|
-
if (!acquireAutoFastForwardLease(args.workspace)) return;
|
|
78970
|
-
const submoduleIgnorePaths = readNodeSubmoduleIgnorePaths(args.node);
|
|
78971
|
-
try {
|
|
78972
|
-
const dryRun = await fastForwardMeshNode({
|
|
78973
|
-
meshId: args.meshId,
|
|
78974
|
-
nodeId: args.nodeId,
|
|
78975
|
-
workspace: args.workspace,
|
|
78976
|
-
execute: false,
|
|
78977
|
-
dryRun: true,
|
|
78978
|
-
// See delegateRemoteAutoFastForward's updateSubmodules comment: mirrors the
|
|
78979
|
-
// manual tool so a gitlink-moving ff cannot leave the submodule drifted.
|
|
78980
|
-
updateSubmodules: true,
|
|
78981
|
-
submoduleIgnorePaths,
|
|
78982
|
-
trigger: args.trigger
|
|
78983
|
-
});
|
|
78984
|
-
if (!dryRunSatisfiesAutoFastForwardPolicy(dryRun, args.policy)) return;
|
|
78985
|
-
await fastForwardMeshNode({
|
|
78986
|
-
meshId: args.meshId,
|
|
78987
|
-
nodeId: args.nodeId,
|
|
78988
|
-
workspace: args.workspace,
|
|
78989
|
-
execute: true,
|
|
78990
|
-
dryRun: false,
|
|
78991
|
-
updateSubmodules: true,
|
|
78992
|
-
submoduleIgnorePaths,
|
|
78993
|
-
trigger: args.trigger
|
|
78994
|
-
});
|
|
78995
|
-
} catch (e) {
|
|
78996
|
-
LOG2.warn("MeshFastForward", `Idle auto fast-forward check failed for ${args.nodeId}: ${e?.message || e}`);
|
|
78997
|
-
} finally {
|
|
78998
|
-
releaseAutoFastForwardLease(args.workspace);
|
|
78999
|
-
}
|
|
79000
|
-
}
|
|
79001
|
-
async function maybeAutoFastForwardIdleNode(components, args) {
|
|
79002
|
-
const mesh = getMeshWithCache(components, args.meshId);
|
|
79003
|
-
const node = mesh?.nodes?.find((candidate) => meshNodeIdMatches(candidate, args.nodeId));
|
|
79004
|
-
const workspace = readNonEmptyString(node?.workspace);
|
|
79005
|
-
if (!workspace) return;
|
|
79006
|
-
const policy = resolveAutoFastForwardPolicy(mesh);
|
|
79007
|
-
if (!policy.enabled) return;
|
|
79008
|
-
if (nodeHasActiveMeshWork(components, args.meshId, args.nodeId, args.sessionId)) return;
|
|
79009
|
-
const throttleKey = `${args.meshId}:${args.nodeId}`;
|
|
79010
|
-
const now = Date.now();
|
|
79011
|
-
const lastAttempt = idleAutoFastForwardLastAttempt.get(throttleKey) || 0;
|
|
79012
|
-
if (now - lastAttempt < IDLE_AUTO_FAST_FORWARD_THROTTLE_MS) return;
|
|
79013
|
-
idleAutoFastForwardLastAttempt.set(throttleKey, now);
|
|
79014
|
-
if (isLocalAutoLaunchNode(node)) {
|
|
79015
|
-
if (!(0, import_fs17.existsSync)(workspace)) return;
|
|
79016
|
-
await executeLocalAutoFastForward({ meshId: args.meshId, nodeId: args.nodeId, node, workspace, policy, trigger: "idle_auto" });
|
|
79017
|
-
return;
|
|
79018
|
-
}
|
|
79019
|
-
if (!policy.remoteNodes) return;
|
|
79020
|
-
const daemonId = readMeshNodeDaemonId(node ?? {});
|
|
79021
|
-
if (!daemonId || !components.dispatchMeshCommand) return;
|
|
79022
|
-
if (!remoteNodeIsConnected(components, node)) return;
|
|
79023
|
-
await delegateRemoteAutoFastForward(components, { meshId: args.meshId, nodeId: args.nodeId, node, daemonId, workspace, policy, trigger: "idle_auto" });
|
|
79024
|
-
}
|
|
79025
|
-
async function runContinuousAutoFastForwardScan(components, mesh) {
|
|
79026
|
-
if (!components.dispatchMeshCommand) return;
|
|
79027
|
-
const policy = resolveAutoFastForwardPolicy(mesh);
|
|
79028
|
-
if (!policy.enabled || !policy.remoteNodes || policy.mode !== "continuous") return;
|
|
79029
|
-
const meshId = readNonEmptyString(mesh?.id);
|
|
79030
|
-
if (!meshId) return;
|
|
79031
|
-
const nodes = Array.isArray(mesh?.nodes) ? mesh.nodes : [];
|
|
79032
|
-
const now = Date.now();
|
|
79033
|
-
for (const node of nodes) {
|
|
79034
|
-
const nodeId = normalizeMeshNodeId(node);
|
|
79035
|
-
if (!nodeId) continue;
|
|
79036
|
-
if (node?.isLocalWorktree === true) continue;
|
|
79037
|
-
if (isLocalAutoLaunchNode(node)) continue;
|
|
79038
|
-
const workspace = readNonEmptyString(node?.workspace);
|
|
79039
|
-
if (!workspace) continue;
|
|
79040
|
-
const daemonId = readMeshNodeDaemonId(node ?? {});
|
|
79041
|
-
if (!daemonId) continue;
|
|
79042
|
-
if (!nodeIsAutoFastForwardEligible(components, meshId, nodeId, node)) continue;
|
|
79043
|
-
if (!remoteNodeIsConnected(components, node)) continue;
|
|
79044
|
-
const cooldownKey = `${meshId}:${nodeId}`;
|
|
79045
|
-
const lastScan = continuousAutoFastForwardLastScan.get(cooldownKey) || 0;
|
|
79046
|
-
if (now - lastScan < CONTINUOUS_AUTO_FAST_FORWARD_SCAN_COOLDOWN_MS) continue;
|
|
79047
|
-
continuousAutoFastForwardLastScan.set(cooldownKey, now);
|
|
79048
|
-
await delegateRemoteAutoFastForward(components, { meshId, nodeId, node, daemonId, workspace, policy, trigger: "reconcile_auto" });
|
|
79049
|
-
}
|
|
79050
|
-
}
|
|
79051
|
-
async function runPendingCoordinatorCatchupScan(components, mesh) {
|
|
79052
|
-
const meshId = readNonEmptyString(mesh?.id);
|
|
79053
|
-
if (!meshId) return;
|
|
79054
|
-
const localIds = expandDaemonIdForms([
|
|
79055
|
-
readNonEmptyString(components.statusInstanceId),
|
|
79056
|
-
readNonEmptyString(loadConfig2().machineId)
|
|
79057
|
-
]);
|
|
79058
|
-
let markers = [];
|
|
79059
|
-
try {
|
|
79060
|
-
markers = drainPendingMeshCoordinatorEvents(
|
|
79061
|
-
meshId,
|
|
79062
|
-
localIds.length > 0 ? localIds : void 0,
|
|
79063
|
-
{ onlyEvents: /* @__PURE__ */ new Set(["coordinator_catchup"]) }
|
|
79064
|
-
);
|
|
79065
|
-
} catch (e) {
|
|
79066
|
-
LOG2.warn("MeshReconcile", `Coordinator-catchup drain failed for mesh ${meshId}: ${e?.message || e}`);
|
|
79067
|
-
return;
|
|
79068
|
-
}
|
|
79069
|
-
if (markers.length === 0) return;
|
|
79070
|
-
const nodes = Array.isArray(mesh?.nodes) ? mesh.nodes : [];
|
|
79071
|
-
for (const marker of markers) {
|
|
79072
|
-
const meta3 = marker.metadataEvent || {};
|
|
79073
|
-
const nodeId = readNonEmptyString(marker.nodeId) || readNonEmptyString(meta3.nodeId);
|
|
79074
|
-
const workspace = readNonEmptyString(marker.workspace) || readNonEmptyString(meta3.workspace);
|
|
79075
|
-
const baseBranch = readNonEmptyString(meta3.baseBranch);
|
|
79076
|
-
if (!workspace) continue;
|
|
79077
|
-
if (nodeId && nodeHasActiveMeshWork(components, meshId, nodeId)) {
|
|
79078
|
-
try {
|
|
79079
|
-
queuePendingMeshCoordinatorEvent(marker);
|
|
79080
|
-
} catch {
|
|
79081
|
-
}
|
|
79082
|
-
continue;
|
|
79083
|
-
}
|
|
79084
|
-
try {
|
|
79085
|
-
const ff = await fastForwardMeshNode({
|
|
79086
|
-
meshId,
|
|
79087
|
-
...nodeId ? { nodeId } : {},
|
|
79088
|
-
workspace,
|
|
79089
|
-
...baseBranch ? { branch: baseBranch } : {},
|
|
79090
|
-
mode: "merge",
|
|
79091
|
-
execute: true,
|
|
79092
|
-
// Same gitlink-drift-prevention rationale as executeLocalAutoFastForward /
|
|
79093
|
-
// delegateRemoteAutoFastForward — this path pushed the base branch itself,
|
|
79094
|
-
// so a submodule gitlink bump here is exactly as likely.
|
|
79095
|
-
updateSubmodules: true,
|
|
79096
|
-
trigger: "refine_post_push_catchup",
|
|
79097
|
-
allowAutoPublishSubmoduleMainCommits: mesh?.policy?.allowAutoPublishSubmoduleMainCommits === true
|
|
79098
|
-
});
|
|
79099
|
-
LOG2.info("MeshReconcile", `Coordinator catch-up ff for ${meshId}/${nodeId || workspace}: ${ff.code} (executed=${ff.executed})`);
|
|
79100
|
-
} catch (e) {
|
|
79101
|
-
LOG2.warn("MeshReconcile", `Coordinator catch-up ff failed for ${meshId}/${nodeId || workspace}: ${e?.message || e}`);
|
|
79102
|
-
}
|
|
79103
|
-
}
|
|
79104
|
-
}
|
|
79105
|
-
var import_fs17;
|
|
79106
|
-
var IDLE_AUTO_FAST_FORWARD_THROTTLE_MS;
|
|
79107
|
-
var idleAutoFastForwardLastAttempt;
|
|
79108
|
-
var CONTINUOUS_AUTO_FAST_FORWARD_SCAN_COOLDOWN_MS;
|
|
79109
|
-
var continuousAutoFastForwardLastScan;
|
|
79110
|
-
var autoFastForwardWorkspaceLease;
|
|
79111
|
-
var init_mesh_auto_fast_forward = __esm2({
|
|
79112
|
-
"src/mesh/mesh-auto-fast-forward.ts"() {
|
|
79113
|
-
"use strict";
|
|
79114
|
-
import_fs17 = require("fs");
|
|
79115
|
-
init_logger();
|
|
79116
|
-
init_config();
|
|
79117
|
-
init_mesh_fast_forward();
|
|
79118
|
-
init_dist();
|
|
79119
|
-
init_mesh_events_utils();
|
|
79120
|
-
init_mesh_node_identity();
|
|
79121
|
-
init_mesh_events_pending();
|
|
79122
|
-
init_worktree_bootstrap_config();
|
|
79123
|
-
init_mesh_queue_assignment();
|
|
79124
|
-
IDLE_AUTO_FAST_FORWARD_THROTTLE_MS = 30 * 60 * 1e3;
|
|
79125
|
-
idleAutoFastForwardLastAttempt = /* @__PURE__ */ new Map();
|
|
79126
|
-
CONTINUOUS_AUTO_FAST_FORWARD_SCAN_COOLDOWN_MS = 45 * 1e3;
|
|
79127
|
-
continuousAutoFastForwardLastScan = /* @__PURE__ */ new Map();
|
|
79128
|
-
autoFastForwardWorkspaceLease = /* @__PURE__ */ new Set();
|
|
79129
|
-
}
|
|
79130
|
-
});
|
|
79131
|
-
function normalizeNodeIdKey(nodeId) {
|
|
79132
|
-
return normalizeMeshNodeId({ id: nodeId ?? void 0 }) ?? "";
|
|
79133
|
-
}
|
|
79134
|
-
function noteRecentlyClonedNode(nodeId, nowMs = Date.now()) {
|
|
79135
|
-
const key2 = normalizeNodeIdKey(nodeId);
|
|
79136
|
-
if (!key2) return;
|
|
79137
|
-
recentlyClonedNodeExpiry.set(key2, nowMs + CLONE_BOOTSTRAP_GRACE_MS);
|
|
79138
|
-
if (recentlyClonedNodeExpiry.size > MAX_TRACKED_CLONED_NODES) {
|
|
79139
|
-
const oldest = recentlyClonedNodeExpiry.keys().next().value;
|
|
79140
|
-
if (oldest !== void 0) recentlyClonedNodeExpiry.delete(oldest);
|
|
79141
|
-
}
|
|
79142
|
-
}
|
|
79143
|
-
function isWithinCloneBootstrapGrace(nodeId, nowMs = Date.now()) {
|
|
79144
|
-
const key2 = normalizeNodeIdKey(nodeId);
|
|
79145
|
-
if (!key2) return false;
|
|
79146
|
-
const expiry = recentlyClonedNodeExpiry.get(key2);
|
|
79147
|
-
if (expiry === void 0) return false;
|
|
79148
|
-
if (nowMs >= expiry) {
|
|
79149
|
-
recentlyClonedNodeExpiry.delete(key2);
|
|
79150
|
-
return false;
|
|
79151
|
-
}
|
|
79152
|
-
return true;
|
|
79153
|
-
}
|
|
79154
|
-
var CLONE_BOOTSTRAP_GRACE_MS;
|
|
79155
|
-
var recentlyClonedNodeExpiry;
|
|
79156
|
-
var MAX_TRACKED_CLONED_NODES;
|
|
79157
|
-
var init_mesh_clone_grace = __esm2({
|
|
79158
|
-
"src/mesh/mesh-clone-grace.ts"() {
|
|
79159
|
-
"use strict";
|
|
79160
|
-
init_dist();
|
|
79161
|
-
CLONE_BOOTSTRAP_GRACE_MS = 10 * 60 * 1e3;
|
|
79162
|
-
recentlyClonedNodeExpiry = /* @__PURE__ */ new Map();
|
|
79163
|
-
MAX_TRACKED_CLONED_NODES = 512;
|
|
79164
|
-
}
|
|
79165
|
-
});
|
|
79166
78798
|
function quotaClaimBlockKey(meshId, observation) {
|
|
79167
78799
|
return `${meshId}:${observation.nodeId}:${observation.sessionId}:${observation.providerType}`;
|
|
79168
78800
|
}
|
|
@@ -79179,30 +78811,41 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
79179
78811
|
if (oldest !== void 0) map3.delete(oldest);
|
|
79180
78812
|
}
|
|
79181
78813
|
}
|
|
79182
|
-
function logQuotaClaimBlockTransition(meshId, observation) {
|
|
78814
|
+
function logQuotaClaimBlockTransition(meshId, observation, phase = "blocked") {
|
|
79183
78815
|
const key2 = quotaClaimBlockKey(meshId, observation);
|
|
79184
|
-
const fingerprint = `${observation.block.reason}:${observation.block.window}:${observation.block.remainingPercent}:${observation.block.thresholdPercent}`;
|
|
78816
|
+
const fingerprint = `${phase}:${observation.block.reason}:${observation.block.window}:${observation.block.remainingPercent}:${observation.block.thresholdPercent}`;
|
|
79185
78817
|
if (lastQuotaClaimBlockLog.get(key2) === fingerprint) return;
|
|
79186
78818
|
const wasBlocked = lastQuotaClaimBlockLog.has(key2);
|
|
79187
78819
|
rememberBounded(lastQuotaClaimBlockLog, key2, fingerprint);
|
|
79188
|
-
|
|
78820
|
+
const overrideNote = phase === "overridden_by_pin" ? " (provider pinned by requiredTags \u2014 gate overridden to honor the pin)" : "";
|
|
78821
|
+
LOG2.info("MeshQueue", `QUOTA GATE: ${phase === "overridden_by_pin" ? "allowing" : "deferring"} queue claim for node ${observation.nodeId} (${observation.sessionId}): ${quotaClaimBlockDescription(observation.providerType, observation.block)}${overrideNote}${phase === "blocked" ? " \u2014 trying remaining provider candidates; the task stays pending only if none can claim" : ""}`);
|
|
79189
78822
|
try {
|
|
78823
|
+
const payload = {
|
|
78824
|
+
phase,
|
|
78825
|
+
nodeId: observation.nodeId,
|
|
78826
|
+
sessionId: observation.sessionId,
|
|
78827
|
+
providerType: observation.providerType,
|
|
78828
|
+
reason: observation.block.reason,
|
|
78829
|
+
window: observation.block.window,
|
|
78830
|
+
remainingPercent: observation.block.remainingPercent,
|
|
78831
|
+
thresholdPercent: observation.block.thresholdPercent,
|
|
78832
|
+
previouslyBlocked: wasBlocked
|
|
78833
|
+
};
|
|
78834
|
+
if (observation.context?.trigger) {
|
|
78835
|
+
payload.trigger = observation.context.trigger;
|
|
78836
|
+
}
|
|
78837
|
+
if (observation.context?.candidateTaskId) {
|
|
78838
|
+
payload.candidateTaskId = observation.context.candidateTaskId;
|
|
78839
|
+
}
|
|
78840
|
+
if (observation.context?.pinOverride) {
|
|
78841
|
+
payload.pinOverride = true;
|
|
78842
|
+
}
|
|
79190
78843
|
appendLedgerEntry(meshId, {
|
|
79191
78844
|
kind: "quota_claim_gate",
|
|
79192
78845
|
nodeId: observation.nodeId,
|
|
79193
78846
|
sessionId: observation.sessionId,
|
|
79194
78847
|
providerType: observation.providerType,
|
|
79195
|
-
payload
|
|
79196
|
-
phase: "blocked",
|
|
79197
|
-
nodeId: observation.nodeId,
|
|
79198
|
-
sessionId: observation.sessionId,
|
|
79199
|
-
providerType: observation.providerType,
|
|
79200
|
-
reason: observation.block.reason,
|
|
79201
|
-
window: observation.block.window,
|
|
79202
|
-
remainingPercent: observation.block.remainingPercent,
|
|
79203
|
-
thresholdPercent: observation.block.thresholdPercent,
|
|
79204
|
-
previouslyBlocked: wasBlocked
|
|
79205
|
-
}
|
|
78848
|
+
payload
|
|
79206
78849
|
});
|
|
79207
78850
|
} catch {
|
|
79208
78851
|
}
|
|
@@ -79336,6 +78979,869 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
79336
78979
|
AUTO_LAUNCH_LEDGER_DEDUP_MAX = 2e3;
|
|
79337
78980
|
}
|
|
79338
78981
|
});
|
|
78982
|
+
function localCoordinatorDaemonId() {
|
|
78983
|
+
return canonicalDaemonId(readNonEmptyString(loadConfig2().machineId));
|
|
78984
|
+
}
|
|
78985
|
+
function isIdleSessionState(state) {
|
|
78986
|
+
const status = readNonEmptyString(state?.status).toLowerCase();
|
|
78987
|
+
if (TERMINAL_SESSION_STATUSES.includes(status)) return false;
|
|
78988
|
+
return status === "idle" || state?.activeChat?.status === "waiting_input";
|
|
78989
|
+
}
|
|
78990
|
+
function sweepAutoLaunchOrphanSessions(components, meshId) {
|
|
78991
|
+
let sessions;
|
|
78992
|
+
try {
|
|
78993
|
+
sessions = components.instanceManager?.getByCategory?.("cli") || [];
|
|
78994
|
+
} catch {
|
|
78995
|
+
return;
|
|
78996
|
+
}
|
|
78997
|
+
if (!sessions.length) return;
|
|
78998
|
+
let queue;
|
|
78999
|
+
try {
|
|
79000
|
+
queue = getQueue(meshId);
|
|
79001
|
+
} catch {
|
|
79002
|
+
return;
|
|
79003
|
+
}
|
|
79004
|
+
const byId = new Map(queue.map((t) => [t.id, t]));
|
|
79005
|
+
for (const inst of sessions) {
|
|
79006
|
+
let state;
|
|
79007
|
+
try {
|
|
79008
|
+
state = inst.getState();
|
|
79009
|
+
} catch {
|
|
79010
|
+
continue;
|
|
79011
|
+
}
|
|
79012
|
+
const settings = state?.settings || {};
|
|
79013
|
+
if (readNonEmptyString(settings.meshNodeFor) !== meshId) continue;
|
|
79014
|
+
const originTaskId = readNonEmptyString(settings.autoLaunchedForQueueTaskId);
|
|
79015
|
+
if (!originTaskId) continue;
|
|
79016
|
+
const sessionId = readNonEmptyString(state?.instanceId);
|
|
79017
|
+
if (!sessionId) continue;
|
|
79018
|
+
if (!isIdleSessionState(state)) continue;
|
|
79019
|
+
if (sessionHasActiveAssignment(meshId, sessionId)) continue;
|
|
79020
|
+
const originTask = byId.get(originTaskId);
|
|
79021
|
+
const assignedElsewhere = !!originTask && originTask.status === "assigned" && !!readNonEmptyString(originTask.assignedSessionId) && !sessionIdsEquivalent(readNonEmptyString(originTask.assignedSessionId), sessionId);
|
|
79022
|
+
const originGone = !originTask || originTask.status !== "pending" && originTask.status !== "assigned";
|
|
79023
|
+
const dedupKey = `${meshId}::${sessionId}`;
|
|
79024
|
+
if (!assignedElsewhere && !originGone) {
|
|
79025
|
+
autoLaunchOrphanFirstSeenAtMs.delete(dedupKey);
|
|
79026
|
+
continue;
|
|
79027
|
+
}
|
|
79028
|
+
const nowMs = Date.now();
|
|
79029
|
+
const firstSeenAtMs = autoLaunchOrphanFirstSeenAtMs.get(dedupKey);
|
|
79030
|
+
if (firstSeenAtMs === void 0) {
|
|
79031
|
+
autoLaunchOrphanFirstSeenAtMs.set(dedupKey, nowMs);
|
|
79032
|
+
if (autoLaunchOrphanFirstSeenAtMs.size > AUTO_LAUNCH_LEDGER_DEDUP_MAX) {
|
|
79033
|
+
const oldest = autoLaunchOrphanFirstSeenAtMs.keys().next().value;
|
|
79034
|
+
if (oldest !== void 0) autoLaunchOrphanFirstSeenAtMs.delete(oldest);
|
|
79035
|
+
}
|
|
79036
|
+
continue;
|
|
79037
|
+
}
|
|
79038
|
+
if (nowMs - firstSeenAtMs < AUTO_LAUNCH_ORPHAN_GRACE_MS) continue;
|
|
79039
|
+
if (autoLaunchOrphanNotified.has(dedupKey)) continue;
|
|
79040
|
+
autoLaunchOrphanNotified.add(dedupKey);
|
|
79041
|
+
if (autoLaunchOrphanNotified.size > AUTO_LAUNCH_LEDGER_DEDUP_MAX) {
|
|
79042
|
+
const oldest = autoLaunchOrphanNotified.values().next().value;
|
|
79043
|
+
if (oldest !== void 0) autoLaunchOrphanNotified.delete(oldest);
|
|
79044
|
+
}
|
|
79045
|
+
const nodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
79046
|
+
const detail = assignedElsewhere ? `task ${originTaskId} is assigned to a different session (${readNonEmptyString(originTask.assignedSessionId)})` : `task ${originTaskId} is no longer active (${originTask ? originTask.status : "absent from the queue"})`;
|
|
79047
|
+
recordAutoLaunchEvent(meshId, {
|
|
79048
|
+
phase: "skipped",
|
|
79049
|
+
taskId: originTaskId,
|
|
79050
|
+
reason: "auto_launch_orphan_session_detected",
|
|
79051
|
+
nodeId,
|
|
79052
|
+
sessionId
|
|
79053
|
+
});
|
|
79054
|
+
LOG2.warn("MeshQueue", `AUTOLAUNCH-ORPHAN-SWEEP: session ${sessionId}${nodeId ? ` on node ${nodeId}` : ""} (mesh ${meshId}) was auto-launched for task ${originTaskId} but ${detail}; it is idle with no work and will not self-recover.`);
|
|
79055
|
+
try {
|
|
79056
|
+
queuePendingMeshCoordinatorEvent({
|
|
79057
|
+
event: "mesh:dispatch_blocked",
|
|
79058
|
+
meshId,
|
|
79059
|
+
nodeLabel: nodeId || meshId,
|
|
79060
|
+
...nodeId ? { nodeId } : {},
|
|
79061
|
+
metadataEvent: {
|
|
79062
|
+
source: "mesh_auto_launch_orphan_session",
|
|
79063
|
+
taskId: originTaskId,
|
|
79064
|
+
sessionId,
|
|
79065
|
+
reason: "auto_launch_orphan_session_detected"
|
|
79066
|
+
},
|
|
79067
|
+
coordinatorMessage: `[System] Mesh session ${sessionId}${nodeId ? ` on node ${nodeId}` : ""} was auto-launched for task ${originTaskId}, but ${detail}. The session is idle with no work assigned and nothing reclaims it on its own. Reuse it for other queued work or stop it.`,
|
|
79068
|
+
queuedAt: Date.now(),
|
|
79069
|
+
...readNonEmptyString(originTask?.sourceCoordinatorSessionId) ? { targetCoordinatorSessionId: readNonEmptyString(originTask.sourceCoordinatorSessionId) } : {},
|
|
79070
|
+
...localCoordinatorDaemonId() ? { targetCoordinatorDaemonId: localCoordinatorDaemonId() } : {}
|
|
79071
|
+
});
|
|
79072
|
+
} catch (e) {
|
|
79073
|
+
LOG2.warn("MeshQueue", `AUTOLAUNCH-ORPHAN-SWEEP: failed to queue the coordinator notification for session ${sessionId}: ${e?.message || e}`);
|
|
79074
|
+
}
|
|
79075
|
+
}
|
|
79076
|
+
}
|
|
79077
|
+
function autoLaunchWriteWouldClobberWinner(meshId, taskId, args, awaitClaimWindowMs3) {
|
|
79078
|
+
if (args.status === "completed" && readNonEmptyString(args.sessionId)) return false;
|
|
79079
|
+
let existing;
|
|
79080
|
+
try {
|
|
79081
|
+
existing = getQueue(meshId).find((t) => t.id === taskId)?.autoLaunch;
|
|
79082
|
+
} catch {
|
|
79083
|
+
return false;
|
|
79084
|
+
}
|
|
79085
|
+
const heldSessionId = existing ? readNonEmptyString(existing.sessionId) : "";
|
|
79086
|
+
if (!existing || existing.status !== "completed" || !heldSessionId) return false;
|
|
79087
|
+
const heldAtMs = Date.parse(existing.updatedAt);
|
|
79088
|
+
if (!Number.isFinite(heldAtMs) || Date.now() - heldAtMs >= awaitClaimWindowMs3) return false;
|
|
79089
|
+
if (sessionIdsEquivalent(readNonEmptyString(args.sessionId), heldSessionId)) return false;
|
|
79090
|
+
LOG2.info("MeshQueue", `AUTOLAUNCH-WINNER-CLOBBER: suppressed a '${args.status}' autoLaunch write for task ${taskId} (mesh ${meshId}) that would have overwritten the in-window launch record for session ${heldSessionId}; the field keeps pointing at the actually-launched session.`);
|
|
79091
|
+
return true;
|
|
79092
|
+
}
|
|
79093
|
+
function awaitClaimWindowMs(cycles) {
|
|
79094
|
+
return AUTO_LAUNCH_AWAIT_CLAIM_MS * Math.pow(2, Math.min(cycles, AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES));
|
|
79095
|
+
}
|
|
79096
|
+
function remoteSessionAppearsLive(meshId, sessionId) {
|
|
79097
|
+
if (!sessionId) return false;
|
|
79098
|
+
try {
|
|
79099
|
+
return MeshRuntimeStore.getInstance().getRemoteIdleSessions(meshId).some((s2) => sessionIdsEquivalent(s2.sessionId, sessionId));
|
|
79100
|
+
} catch {
|
|
79101
|
+
return false;
|
|
79102
|
+
}
|
|
79103
|
+
}
|
|
79104
|
+
function inWindowAutoLaunchSessionIdsForNode(meshId, nodeId) {
|
|
79105
|
+
const nowMs = Date.now();
|
|
79106
|
+
const out = [];
|
|
79107
|
+
for (const task of getQueue(meshId, { status: ["pending"] })) {
|
|
79108
|
+
const al = task.autoLaunch;
|
|
79109
|
+
const sid = al ? readNonEmptyString(al.sessionId) : "";
|
|
79110
|
+
if (!al || al.status !== "started" && al.status !== "completed" || !sid) continue;
|
|
79111
|
+
if (!daemonIdsEquivalent(al.nodeId, nodeId)) continue;
|
|
79112
|
+
const launchedAtMs = Date.parse(al.updatedAt);
|
|
79113
|
+
const inBaseWindow = Number.isFinite(launchedAtMs) && nowMs - launchedAtMs < AUTO_LAUNCH_AWAIT_CLAIM_MS;
|
|
79114
|
+
const inBackoff = autoLaunchAwaitClaimBackoff.has(`${meshId}::${task.id}`);
|
|
79115
|
+
if (inBaseWindow || inBackoff) out.push(sid);
|
|
79116
|
+
}
|
|
79117
|
+
return out;
|
|
79118
|
+
}
|
|
79119
|
+
function driveExpiredAwaitClaim(components, meshId, task, ctx, assignQueueTask) {
|
|
79120
|
+
const { sessionId, nodeId, providerType } = ctx;
|
|
79121
|
+
const backoffKey = `${meshId}::${task.id}`;
|
|
79122
|
+
const nowMs = Date.now();
|
|
79123
|
+
const state = autoLaunchAwaitClaimBackoff.get(backoffKey) || { cycles: 0, nextAttemptAtMs: 0 };
|
|
79124
|
+
if (state.nextAttemptAtMs && nowMs < state.nextAttemptAtMs) return "backoff";
|
|
79125
|
+
const atCap = state.cycles >= AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES;
|
|
79126
|
+
const live = remoteSessionAppearsLive(meshId, sessionId);
|
|
79127
|
+
if ((live || atCap) && nodeId && providerType) {
|
|
79128
|
+
try {
|
|
79129
|
+
MeshRuntimeStore.getInstance().setRemoteIdleSession(meshId, nodeId, sessionId, providerType, nowMs + AUTO_LAUNCH_REMOTE_IDLE_TTL_MS);
|
|
79130
|
+
} catch {
|
|
79131
|
+
}
|
|
79132
|
+
const assigned = assignQueueTask(components, meshId, nodeId, sessionId, providerType);
|
|
79133
|
+
if (assigned) {
|
|
79134
|
+
autoLaunchAwaitClaimBackoff.delete(backoffKey);
|
|
79135
|
+
const isFallback = atCap && !live;
|
|
79136
|
+
recordAutoLaunchEvent(meshId, {
|
|
79137
|
+
phase: "completed",
|
|
79138
|
+
taskId: task.id,
|
|
79139
|
+
reason: isFallback ? "await_claim_direct_dispatch_fallback" : "await_claim_redriven",
|
|
79140
|
+
nodeId,
|
|
79141
|
+
sessionId
|
|
79142
|
+
});
|
|
79143
|
+
LOG2.info("MeshQueue", `Auto-launch await-claim ${isFallback ? "direct-dispatch fallback" : "re-drive"} claimed task ${task.id} into existing session ${sessionId} on node ${nodeId} (mesh ${meshId})`);
|
|
79144
|
+
return isFallback ? "fallback" : "claimed";
|
|
79145
|
+
}
|
|
79146
|
+
if (atCap) {
|
|
79147
|
+
autoLaunchAwaitClaimBackoff.delete(backoffKey);
|
|
79148
|
+
return "respawn";
|
|
79149
|
+
}
|
|
79150
|
+
}
|
|
79151
|
+
const cycles = Math.min(state.cycles + 1, AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES);
|
|
79152
|
+
autoLaunchAwaitClaimBackoff.set(backoffKey, { cycles, nextAttemptAtMs: nowMs + awaitClaimWindowMs(cycles) });
|
|
79153
|
+
recordAutoLaunchEvent(meshId, { phase: "skipped", taskId: task.id, reason: "awaiting_launched_session_claim_backoff", nodeId, sessionId });
|
|
79154
|
+
return "backoff";
|
|
79155
|
+
}
|
|
79156
|
+
var AUTO_LAUNCH_AWAIT_CLAIM_MS;
|
|
79157
|
+
var AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES;
|
|
79158
|
+
var AUTO_LAUNCH_REMOTE_IDLE_TTL_MS;
|
|
79159
|
+
var TERMINAL_SESSION_STATUSES;
|
|
79160
|
+
var autoLaunchOrphanNotified;
|
|
79161
|
+
var autoLaunchOrphanFirstSeenAtMs;
|
|
79162
|
+
var AUTO_LAUNCH_ORPHAN_GRACE_MS;
|
|
79163
|
+
var autoLaunchAwaitClaimBackoff;
|
|
79164
|
+
var init_mesh_autolaunch_integrity = __esm2({
|
|
79165
|
+
"src/mesh/mesh-autolaunch-integrity.ts"() {
|
|
79166
|
+
"use strict";
|
|
79167
|
+
init_config();
|
|
79168
|
+
init_logger();
|
|
79169
|
+
init_dist();
|
|
79170
|
+
init_mesh_work_queue();
|
|
79171
|
+
init_mesh_events_utils();
|
|
79172
|
+
init_mesh_events_pending();
|
|
79173
|
+
init_mesh_queue_observability();
|
|
79174
|
+
init_mesh_scheduling_fitness();
|
|
79175
|
+
init_mesh_runtime_store();
|
|
79176
|
+
AUTO_LAUNCH_AWAIT_CLAIM_MS = 9e4;
|
|
79177
|
+
AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES = 2;
|
|
79178
|
+
AUTO_LAUNCH_REMOTE_IDLE_TTL_MS = 5 * 60 * 1e3;
|
|
79179
|
+
TERMINAL_SESSION_STATUSES = ["stopped", "failed", "terminated", "exited", "closed"];
|
|
79180
|
+
autoLaunchOrphanNotified = /* @__PURE__ */ new Set();
|
|
79181
|
+
autoLaunchOrphanFirstSeenAtMs = /* @__PURE__ */ new Map();
|
|
79182
|
+
AUTO_LAUNCH_ORPHAN_GRACE_MS = 3e4;
|
|
79183
|
+
autoLaunchAwaitClaimBackoff = /* @__PURE__ */ new Map();
|
|
79184
|
+
}
|
|
79185
|
+
});
|
|
79186
|
+
function classifiedDifficultiesForSlot(slot) {
|
|
79187
|
+
const highest = slot.difficulty?.reduce((rank, value) => {
|
|
79188
|
+
const candidate = CLASSIFIED_DIFFICULTIES.indexOf(value);
|
|
79189
|
+
return Math.max(rank, candidate);
|
|
79190
|
+
}, -1) ?? -1;
|
|
79191
|
+
return highest < 0 ? [] : CLASSIFIED_DIFFICULTIES.slice(0, highest + 1);
|
|
79192
|
+
}
|
|
79193
|
+
function allowedClassifiedDifficultiesForSession(node, slots, providerType, model) {
|
|
79194
|
+
if (normalizeNodeCapabilitySlots(node?.policy?.slots).length === 0) return void 0;
|
|
79195
|
+
const providerSlots = slots.filter((slot) => slot.provider?.trim() === providerType);
|
|
79196
|
+
const possibleSlots = model ? providerSlots.filter((slot) => isModelAllowedBySlot(model, slot)) : providerSlots;
|
|
79197
|
+
if (possibleSlots.length === 0) return [];
|
|
79198
|
+
const supported = possibleSlots.map((slot) => new Set(classifiedDifficultiesForSlot(slot)));
|
|
79199
|
+
return CLASSIFIED_DIFFICULTIES.filter((difficulty) => model ? supported.some((grades) => grades.has(difficulty)) : supported.every((grades) => grades.has(difficulty)));
|
|
79200
|
+
}
|
|
79201
|
+
function taskMeetsSessionDifficultyFloor(task, allowed) {
|
|
79202
|
+
if (!allowed || !isMeshTaskDifficulty(task.difficulty) || task.difficulty === "freeform") return true;
|
|
79203
|
+
return allowed.includes(task.difficulty);
|
|
79204
|
+
}
|
|
79205
|
+
function readSessionModel(state) {
|
|
79206
|
+
const controlModel = typeof state?.controlValues?.model === "string" ? state.controlValues.model.trim() : "";
|
|
79207
|
+
if (controlModel) return controlModel;
|
|
79208
|
+
const modelItem = Array.isArray(state?.summaryMetadata?.items) ? state.summaryMetadata.items.find((item) => item?.id === "model") : void 0;
|
|
79209
|
+
const summaryModel = typeof modelItem?.shortValue === "string" && modelItem.shortValue.trim() ? modelItem.shortValue.trim() : typeof modelItem?.value === "string" ? modelItem.value.trim() : "";
|
|
79210
|
+
return summaryModel || void 0;
|
|
79211
|
+
}
|
|
79212
|
+
function isDifficultyFloorWaitReason(reason) {
|
|
79213
|
+
return typeof reason === "string" && (reason.startsWith(TASK_DIFFICULTY_FLOOR_REASON_PREFIX) || reason.startsWith(ALL_PROVIDERS_QUOTA_GATED_SKIP_REASON));
|
|
79214
|
+
}
|
|
79215
|
+
function handleDifficultyFloorSkip(args) {
|
|
79216
|
+
let previousTask;
|
|
79217
|
+
try {
|
|
79218
|
+
previousTask = getQueue(args.meshId).find((task2) => task2.id === args.taskId);
|
|
79219
|
+
} catch {
|
|
79220
|
+
}
|
|
79221
|
+
if (previousTask?.autoLaunch?.reason?.startsWith(TASK_DIFFICULTY_FLOOR_REPORTED_PREFIX)) return;
|
|
79222
|
+
const continuing = previousTask?.autoLaunch?.status === "skipped" && isDifficultyFloorWaitReason(previousTask.autoLaunch.reason);
|
|
79223
|
+
if (!continuing) {
|
|
79224
|
+
recordTaskAutoLaunch(args.meshId, args.taskId, {
|
|
79225
|
+
status: "skipped",
|
|
79226
|
+
reason: args.reason,
|
|
79227
|
+
nodeId: args.nodeId
|
|
79228
|
+
});
|
|
79229
|
+
}
|
|
79230
|
+
const waitStartedAt = Date.parse(previousTask?.autoLaunch?.updatedAt || (/* @__PURE__ */ new Date()).toISOString());
|
|
79231
|
+
const waitedMs = Number.isFinite(waitStartedAt) ? Date.now() - waitStartedAt : 0;
|
|
79232
|
+
const reportKey = `${args.meshId}:${args.taskId}`;
|
|
79233
|
+
if (waitedMs < DIFFICULTY_FLOOR_REPORT_AFTER_MS || difficultyFloorTimeoutReported.has(reportKey)) return;
|
|
79234
|
+
const task = previousTask ?? getQueue(args.meshId).find((candidate) => candidate.id === args.taskId);
|
|
79235
|
+
const difficulty = task?.difficulty || args.reason.split(":")[1] || "classified";
|
|
79236
|
+
const coordinatorMessage = `[System] Queued task ${args.taskId} has waited ${Math.round(waitedMs / 6e4)} minutes because no available slot meets its ${difficulty} difficulty floor. It remains pending and was not downgraded. Ask the user whether to grant an explicit task-scoped downgrade; do not change a mesh-wide policy.`;
|
|
79237
|
+
const queued = queuePendingMeshCoordinatorEvent({
|
|
79238
|
+
event: "mesh:dispatch_blocked",
|
|
79239
|
+
meshId: args.meshId,
|
|
79240
|
+
nodeLabel: args.nodeId || args.meshId,
|
|
79241
|
+
...args.nodeId ? { nodeId: args.nodeId } : {},
|
|
79242
|
+
metadataEvent: {
|
|
79243
|
+
source: "mesh_queue_difficulty_floor_timeout",
|
|
79244
|
+
taskId: args.taskId,
|
|
79245
|
+
reason: "task_difficulty_floor_timeout",
|
|
79246
|
+
difficulty,
|
|
79247
|
+
waitedMs,
|
|
79248
|
+
coordinatorMessage
|
|
79249
|
+
},
|
|
79250
|
+
coordinatorMessage,
|
|
79251
|
+
queuedAt: Date.now(),
|
|
79252
|
+
...args.coordinatorDaemonId ? { targetCoordinatorDaemonId: args.coordinatorDaemonId } : {},
|
|
79253
|
+
...task?.sourceCoordinatorSessionId ? { targetCoordinatorSessionId: task.sourceCoordinatorSessionId } : {}
|
|
79254
|
+
});
|
|
79255
|
+
if (queued) {
|
|
79256
|
+
if (difficultyFloorTimeoutReported.size >= DIFFICULTY_FLOOR_REPORT_DEDUP_MAX) {
|
|
79257
|
+
const oldest = difficultyFloorTimeoutReported.values().next().value;
|
|
79258
|
+
if (oldest) difficultyFloorTimeoutReported.delete(oldest);
|
|
79259
|
+
}
|
|
79260
|
+
difficultyFloorTimeoutReported.add(reportKey);
|
|
79261
|
+
recordTaskAutoLaunch(args.meshId, args.taskId, {
|
|
79262
|
+
status: "skipped",
|
|
79263
|
+
reason: `${TASK_DIFFICULTY_FLOOR_REPORTED_PREFIX}${difficulty}`,
|
|
79264
|
+
nodeId: args.nodeId
|
|
79265
|
+
});
|
|
79266
|
+
}
|
|
79267
|
+
}
|
|
79268
|
+
var DIFFICULTY_FLOOR_REPORT_AFTER_MS;
|
|
79269
|
+
var TASK_DIFFICULTY_FLOOR_REASON_PREFIX;
|
|
79270
|
+
var TASK_DIFFICULTY_FLOOR_REPORTED_PREFIX;
|
|
79271
|
+
var difficultyFloorTimeoutReported;
|
|
79272
|
+
var DIFFICULTY_FLOOR_REPORT_DEDUP_MAX;
|
|
79273
|
+
var CLASSIFIED_DIFFICULTIES;
|
|
79274
|
+
var init_mesh_difficulty_floor = __esm2({
|
|
79275
|
+
"src/mesh/mesh-difficulty-floor.ts"() {
|
|
79276
|
+
"use strict";
|
|
79277
|
+
init_mesh_work_queue();
|
|
79278
|
+
init_mesh_events_pending();
|
|
79279
|
+
init_slot_model_enforcement();
|
|
79280
|
+
init_mesh_quota_routing();
|
|
79281
|
+
init_dist();
|
|
79282
|
+
DIFFICULTY_FLOOR_REPORT_AFTER_MS = 10 * 6e4;
|
|
79283
|
+
TASK_DIFFICULTY_FLOOR_REASON_PREFIX = "task_difficulty_floor_";
|
|
79284
|
+
TASK_DIFFICULTY_FLOOR_REPORTED_PREFIX = "task_difficulty_floor_reported:";
|
|
79285
|
+
difficultyFloorTimeoutReported = /* @__PURE__ */ new Set();
|
|
79286
|
+
DIFFICULTY_FLOOR_REPORT_DEDUP_MAX = 2e3;
|
|
79287
|
+
CLASSIFIED_DIFFICULTIES = ["easy", "medium", "difficult"];
|
|
79288
|
+
}
|
|
79289
|
+
});
|
|
79290
|
+
function normalizeProviderPriority2(policy) {
|
|
79291
|
+
const raw = policy && typeof policy === "object" && !Array.isArray(policy) ? policy.providerPriority : void 0;
|
|
79292
|
+
if (!Array.isArray(raw)) return [];
|
|
79293
|
+
const seen = /* @__PURE__ */ new Set();
|
|
79294
|
+
return raw.map((type2) => typeof type2 === "string" ? type2.trim() : "").filter(Boolean).filter((type2) => {
|
|
79295
|
+
if (seen.has(type2)) return false;
|
|
79296
|
+
seen.add(type2);
|
|
79297
|
+
return true;
|
|
79298
|
+
});
|
|
79299
|
+
}
|
|
79300
|
+
function isTerminalSessionStatus(status) {
|
|
79301
|
+
return ["stopped", "failed", "terminated", "exited", "closed"].includes(status);
|
|
79302
|
+
}
|
|
79303
|
+
function isIdleSessionState2(state) {
|
|
79304
|
+
const status = readNonEmptyString(state?.status).toLowerCase();
|
|
79305
|
+
if (isTerminalSessionStatus(status)) return false;
|
|
79306
|
+
return status === "idle" || state?.activeChat?.status === "waiting_input";
|
|
79307
|
+
}
|
|
79308
|
+
function sessionStateLooksActive(state) {
|
|
79309
|
+
const status = readNonEmptyString(state?.status).toLowerCase();
|
|
79310
|
+
const chatStatus = readNonEmptyString(state?.activeChat?.status).toLowerCase();
|
|
79311
|
+
const active = /* @__PURE__ */ new Set(["generating", "streaming", "no_progress", "long_generating", "working", "starting", "waiting_approval"]);
|
|
79312
|
+
return active.has(status) || active.has(chatStatus);
|
|
79313
|
+
}
|
|
79314
|
+
function nodeHasActiveMeshWork(components, meshId, nodeId, currentSessionId) {
|
|
79315
|
+
if (nodeHasActiveAssignment(meshId, nodeId)) return true;
|
|
79316
|
+
return components.instanceManager.getByCategory("cli").some((inst) => {
|
|
79317
|
+
const state = inst.getState();
|
|
79318
|
+
const settings = state.settings || {};
|
|
79319
|
+
if (readNonEmptyString(settings.meshNodeFor) !== meshId) return false;
|
|
79320
|
+
const instNodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
79321
|
+
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
79322
|
+
const sessionId = readNonEmptyString(state.instanceId);
|
|
79323
|
+
if (currentSessionId && sessionIdsEquivalent(sessionId, currentSessionId) && isIdleSessionState2(state)) return false;
|
|
79324
|
+
return sessionStateLooksActive(state);
|
|
79325
|
+
});
|
|
79326
|
+
}
|
|
79327
|
+
function isLaunchableNode(node) {
|
|
79328
|
+
if (!node || node.status === "disabled" || node.status === "removed") return false;
|
|
79329
|
+
if (shouldDeferDispatchForBootstrap(node)) {
|
|
79330
|
+
return false;
|
|
79331
|
+
}
|
|
79332
|
+
return isMeshNodeHealthLaunchable(node);
|
|
79333
|
+
}
|
|
79334
|
+
function isLocalAutoLaunchNode(node) {
|
|
79335
|
+
const daemonId = readNonEmptyString(node?.daemonId);
|
|
79336
|
+
const machineId = readNonEmptyString(node?.machineId);
|
|
79337
|
+
const appConfig = loadConfig2();
|
|
79338
|
+
const localMachineId = readNonEmptyString(appConfig.machineId) || readNonEmptyString(appConfig.registeredMachineId);
|
|
79339
|
+
const daemonMatchesLocal = !daemonId || daemonIdsEquivalent(daemonId, localMachineId);
|
|
79340
|
+
const machineMatchesLocal = !machineId || daemonIdsEquivalent(machineId, localMachineId);
|
|
79341
|
+
if (node?.isLocalWorktree === true) {
|
|
79342
|
+
return daemonMatchesLocal && machineMatchesLocal;
|
|
79343
|
+
}
|
|
79344
|
+
if (daemonId || machineId) {
|
|
79345
|
+
return daemonMatchesLocal && machineMatchesLocal;
|
|
79346
|
+
}
|
|
79347
|
+
return true;
|
|
79348
|
+
}
|
|
79349
|
+
function isSessionActivelyGenerating(components, sessionId) {
|
|
79350
|
+
if (!sessionId) return false;
|
|
79351
|
+
const state = components.instanceManager?.getInstance?.(sessionId)?.getState?.();
|
|
79352
|
+
if (!state) return false;
|
|
79353
|
+
return sessionStateLooksActive(state);
|
|
79354
|
+
}
|
|
79355
|
+
function resolveSessionBusyVerdict(components, sessionId) {
|
|
79356
|
+
if (!sessionId) return "UNKNOWN";
|
|
79357
|
+
try {
|
|
79358
|
+
const instances = components.instanceManager?.getByCategory?.("cli") || [];
|
|
79359
|
+
const inst = instances.find((i) => {
|
|
79360
|
+
const sid = readNonEmptyString(i?.getState?.().instanceId);
|
|
79361
|
+
return sid && sessionIdsEquivalent(sid, sessionId);
|
|
79362
|
+
});
|
|
79363
|
+
if (!inst) return "UNKNOWN";
|
|
79364
|
+
const state = inst.getState?.();
|
|
79365
|
+
if (!state) return "UNKNOWN";
|
|
79366
|
+
return sessionStateLooksActive(state) ? "GENERATING" : "IDLE_CONFIRMED";
|
|
79367
|
+
} catch {
|
|
79368
|
+
return "UNKNOWN";
|
|
79369
|
+
}
|
|
79370
|
+
}
|
|
79371
|
+
function liveSessionCountForNode(components, meshId, nodeId) {
|
|
79372
|
+
const localInstances = components.instanceManager.getByCategory("cli").filter((inst) => {
|
|
79373
|
+
const state = inst.getState();
|
|
79374
|
+
const settings = state.settings || {};
|
|
79375
|
+
if (readNonEmptyString(settings.meshNodeFor) !== meshId) return false;
|
|
79376
|
+
const instNodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
79377
|
+
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
79378
|
+
const status = readNonEmptyString(state.status).toLowerCase();
|
|
79379
|
+
return !isTerminalSessionStatus(status);
|
|
79380
|
+
});
|
|
79381
|
+
let count = localInstances.length;
|
|
79382
|
+
const localSessionIds = localInstances.map((inst) => readNonEmptyString(inst.getState().instanceId)).filter(Boolean);
|
|
79383
|
+
for (const sid of inWindowAutoLaunchSessionIdsForNode(meshId, nodeId)) {
|
|
79384
|
+
if (!localSessionIds.some((local) => sessionIdsEquivalent(local, sid))) count += 1;
|
|
79385
|
+
}
|
|
79386
|
+
return count;
|
|
79387
|
+
}
|
|
79388
|
+
function nodeHasLiveSessionPendingClaim(components, meshId, nodeId, task, node) {
|
|
79389
|
+
if (inWindowAutoLaunchSessionIdsForNode(meshId, nodeId).length > 0) return true;
|
|
79390
|
+
const busySessionIds = new Set(
|
|
79391
|
+
getQueue(meshId, { status: ["assigned"] }).filter((task2) => daemonIdsEquivalent(task2.assignedNodeId, nodeId)).map((task2) => readNonEmptyString(task2.assignedSessionId)).filter(Boolean)
|
|
79392
|
+
);
|
|
79393
|
+
return components.instanceManager.getByCategory("cli").some((inst) => {
|
|
79394
|
+
const state = inst.getState();
|
|
79395
|
+
const settings = state.settings || {};
|
|
79396
|
+
if (readNonEmptyString(settings.meshNodeFor) !== meshId) return false;
|
|
79397
|
+
if (readNonEmptyString(settings.meshCoordinatorFor) === meshId) return false;
|
|
79398
|
+
const instNodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
79399
|
+
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
79400
|
+
const status = readNonEmptyString(state.status).toLowerCase();
|
|
79401
|
+
if (isTerminalSessionStatus(status)) return false;
|
|
79402
|
+
const sessionId = readNonEmptyString(state.instanceId);
|
|
79403
|
+
if (sessionId && busySessionIds.has(sessionId)) return false;
|
|
79404
|
+
const sessionProviderType = state.type || readNonEmptyString(settings.providerType);
|
|
79405
|
+
if (task.requiredTags?.length) {
|
|
79406
|
+
if (sessionProviderType && !nodeSatisfiesRequiredTags(task.requiredTags, buildMeshNodeCapabilityTags(node, sessionProviderType))) {
|
|
79407
|
+
return false;
|
|
79408
|
+
}
|
|
79409
|
+
}
|
|
79410
|
+
const allowance = allowedClassifiedDifficultiesForSession(node, resolveNodeCapabilitySlots(node, meshId), sessionProviderType, readSessionModel(state));
|
|
79411
|
+
if (!taskMeetsSessionDifficultyFloor(task, allowance)) return false;
|
|
79412
|
+
return true;
|
|
79413
|
+
});
|
|
79414
|
+
}
|
|
79415
|
+
var init_mesh_candidacy_predicates = __esm2({
|
|
79416
|
+
"src/mesh/mesh-candidacy-predicates.ts"() {
|
|
79417
|
+
"use strict";
|
|
79418
|
+
init_config();
|
|
79419
|
+
init_mesh_work_queue();
|
|
79420
|
+
init_dist();
|
|
79421
|
+
init_mesh_events_utils();
|
|
79422
|
+
init_mesh_node_identity();
|
|
79423
|
+
init_worktree_bootstrap_config();
|
|
79424
|
+
init_mesh_autolaunch_integrity();
|
|
79425
|
+
init_mesh_scheduling_fitness();
|
|
79426
|
+
init_mesh_node_slots();
|
|
79427
|
+
init_mesh_difficulty_floor();
|
|
79428
|
+
}
|
|
79429
|
+
});
|
|
79430
|
+
function providerPinOverrideCandidateTaskId(meshId, providerType) {
|
|
79431
|
+
const pending = getQueue(meshId, { status: ["pending"] });
|
|
79432
|
+
for (const task of pending) {
|
|
79433
|
+
const tags = task.requiredTags ?? [];
|
|
79434
|
+
if (tags.includes(`provider=${providerType}`)) {
|
|
79435
|
+
return task.id;
|
|
79436
|
+
}
|
|
79437
|
+
}
|
|
79438
|
+
return void 0;
|
|
79439
|
+
}
|
|
79440
|
+
function evaluateQuotaClaimGateForAssignment(args) {
|
|
79441
|
+
const { meshId, nodeId, sessionId, providerType, trigger, node, mesh, providerLoader, quotaClaimTrace } = args;
|
|
79442
|
+
const pinCandidateTaskId = providerPinOverrideCandidateTaskId(meshId, providerType);
|
|
79443
|
+
const isPinOverride = !!pinCandidateTaskId;
|
|
79444
|
+
const quotaClaimBlock = evaluateProviderQuotaGate(node, providerType, mesh?.policy?.quotaRouting ?? null, Date.now(), quotaFactsContextForLiveRouting(mesh, isLocalAutoLaunchNode, providerLoader));
|
|
79445
|
+
if (quotaClaimTrace) quotaClaimTrace.evaluated += 1;
|
|
79446
|
+
if (quotaClaimBlock) {
|
|
79447
|
+
const observation = {
|
|
79448
|
+
nodeId,
|
|
79449
|
+
sessionId,
|
|
79450
|
+
providerType,
|
|
79451
|
+
block: quotaClaimBlock,
|
|
79452
|
+
context: { trigger, candidateTaskId: pinCandidateTaskId, pinOverride: isPinOverride }
|
|
79453
|
+
};
|
|
79454
|
+
if (isPinOverride) {
|
|
79455
|
+
logQuotaClaimBlockTransition(meshId, observation, "overridden_by_pin");
|
|
79456
|
+
return false;
|
|
79457
|
+
}
|
|
79458
|
+
logQuotaClaimBlockTransition(meshId, observation, "blocked");
|
|
79459
|
+
quotaClaimTrace?.blocked.push(observation);
|
|
79460
|
+
return true;
|
|
79461
|
+
}
|
|
79462
|
+
clearQuotaClaimBlockState(meshId, nodeId, sessionId, providerType);
|
|
79463
|
+
if (quotaClaimTrace) quotaClaimTrace.clear += 1;
|
|
79464
|
+
return false;
|
|
79465
|
+
}
|
|
79466
|
+
var init_mesh_queue_claim_gate = __esm2({
|
|
79467
|
+
"src/mesh/mesh-queue-claim-gate.ts"() {
|
|
79468
|
+
"use strict";
|
|
79469
|
+
init_mesh_quota_routing();
|
|
79470
|
+
init_mesh_queue_observability();
|
|
79471
|
+
init_mesh_work_queue();
|
|
79472
|
+
init_mesh_candidacy_predicates();
|
|
79473
|
+
}
|
|
79474
|
+
});
|
|
79475
|
+
function isAnthropicProvider(providerType) {
|
|
79476
|
+
const p = typeof providerType === "string" ? providerType.trim().toLowerCase() : "";
|
|
79477
|
+
return p.length > 0 && ANTHROPIC_PROVIDER_TYPES.has(p);
|
|
79478
|
+
}
|
|
79479
|
+
function isAnthropicModel(model) {
|
|
79480
|
+
const m = typeof model === "string" ? model.trim().toLowerCase() : "";
|
|
79481
|
+
if (!m) return false;
|
|
79482
|
+
if (m.startsWith("claude") || m.startsWith("anthropic")) return true;
|
|
79483
|
+
return /^(opus|sonnet|haiku)(\b|[-_])/.test(m);
|
|
79484
|
+
}
|
|
79485
|
+
function isModelCompatibleWithProvider(model, providerType) {
|
|
79486
|
+
if (!isAnthropicModel(model)) return true;
|
|
79487
|
+
if (isAnthropicProvider(providerType)) return true;
|
|
79488
|
+
return false;
|
|
79489
|
+
}
|
|
79490
|
+
var ANTHROPIC_PROVIDER_TYPES;
|
|
79491
|
+
var init_model_provider_compat = __esm2({
|
|
79492
|
+
"src/mesh/model-provider-compat.ts"() {
|
|
79493
|
+
"use strict";
|
|
79494
|
+
ANTHROPIC_PROVIDER_TYPES = /* @__PURE__ */ new Set([
|
|
79495
|
+
"claude-cli"
|
|
79496
|
+
]);
|
|
79497
|
+
}
|
|
79498
|
+
});
|
|
79499
|
+
function encodeDuplicateMeshDispatchCode(holderSessionId) {
|
|
79500
|
+
const holder = typeof holderSessionId === "string" ? holderSessionId.trim() : "";
|
|
79501
|
+
return holder ? `${DUPLICATE_MESH_DISPATCH_CODE}:${holder}` : DUPLICATE_MESH_DISPATCH_CODE;
|
|
79502
|
+
}
|
|
79503
|
+
function classifyDuplicateMeshDispatch(err) {
|
|
79504
|
+
if (!err || typeof err !== "object") return null;
|
|
79505
|
+
const e = err;
|
|
79506
|
+
if (e.code === DUPLICATE_MESH_DISPATCH_CODE) {
|
|
79507
|
+
const holder = typeof e.holderSessionId === "string" ? e.holderSessionId.trim() : "";
|
|
79508
|
+
return holder ? { holderSessionId: holder } : {};
|
|
79509
|
+
}
|
|
79510
|
+
for (const raw of [e.meshCode, e.code]) {
|
|
79511
|
+
if (typeof raw !== "string") continue;
|
|
79512
|
+
if (raw !== DUPLICATE_MESH_DISPATCH_CODE && !raw.startsWith(`${DUPLICATE_MESH_DISPATCH_CODE}:`)) continue;
|
|
79513
|
+
const holder = raw.slice(DUPLICATE_MESH_DISPATCH_CODE.length + 1).trim();
|
|
79514
|
+
return holder ? { holderSessionId: holder } : {};
|
|
79515
|
+
}
|
|
79516
|
+
return null;
|
|
79517
|
+
}
|
|
79518
|
+
var DUPLICATE_MESH_DISPATCH_CODE;
|
|
79519
|
+
var DuplicateMeshDispatchError;
|
|
79520
|
+
var init_mesh_duplicate_dispatch = __esm2({
|
|
79521
|
+
"src/mesh/mesh-duplicate-dispatch.ts"() {
|
|
79522
|
+
"use strict";
|
|
79523
|
+
DUPLICATE_MESH_DISPATCH_CODE = "DUPLICATE_MESH_DISPATCH";
|
|
79524
|
+
DuplicateMeshDispatchError = class extends Error {
|
|
79525
|
+
code = DUPLICATE_MESH_DISPATCH_CODE;
|
|
79526
|
+
holderSessionId;
|
|
79527
|
+
constructor(message, info = {}) {
|
|
79528
|
+
super(message);
|
|
79529
|
+
this.name = "DuplicateMeshDispatchError";
|
|
79530
|
+
this.holderSessionId = info.holderSessionId;
|
|
79531
|
+
}
|
|
79532
|
+
};
|
|
79533
|
+
}
|
|
79534
|
+
});
|
|
79535
|
+
function acquireAutoFastForwardLease(workspace) {
|
|
79536
|
+
const key2 = normalizeMeshWorkspaceForCompare(workspace);
|
|
79537
|
+
if (!key2) return false;
|
|
79538
|
+
if (autoFastForwardWorkspaceLease.has(key2)) return false;
|
|
79539
|
+
autoFastForwardWorkspaceLease.add(key2);
|
|
79540
|
+
return true;
|
|
79541
|
+
}
|
|
79542
|
+
function releaseAutoFastForwardLease(workspace) {
|
|
79543
|
+
const key2 = normalizeMeshWorkspaceForCompare(workspace);
|
|
79544
|
+
if (key2) autoFastForwardWorkspaceLease.delete(key2);
|
|
79545
|
+
}
|
|
79546
|
+
function isWorkspaceAutoFastForwardInFlight(workspace) {
|
|
79547
|
+
const key2 = normalizeMeshWorkspaceForCompare(workspace || "");
|
|
79548
|
+
return !!key2 && autoFastForwardWorkspaceLease.has(key2);
|
|
79549
|
+
}
|
|
79550
|
+
function __resetIdleAutoFastForwardForTests() {
|
|
79551
|
+
idleAutoFastForwardLastAttempt.clear();
|
|
79552
|
+
continuousAutoFastForwardLastScan.clear();
|
|
79553
|
+
autoFastForwardWorkspaceLease.clear();
|
|
79554
|
+
}
|
|
79555
|
+
function isDirtyNode(node) {
|
|
79556
|
+
return node?.health === "dirty" || node?.git?.dirty === true;
|
|
79557
|
+
}
|
|
79558
|
+
function resolveAutoFastForwardPolicy(mesh) {
|
|
79559
|
+
const record2 = mesh?.policy?.autoFastForward && typeof mesh.policy.autoFastForward === "object" && !Array.isArray(mesh.policy.autoFastForward) ? mesh.policy.autoFastForward : {};
|
|
79560
|
+
const maxBehind = Number(record2.maxBehind);
|
|
79561
|
+
return {
|
|
79562
|
+
enabled: record2.enabled !== false,
|
|
79563
|
+
...Number.isFinite(maxBehind) && maxBehind >= 0 ? { maxBehind: Math.floor(maxBehind) } : {},
|
|
79564
|
+
requireCleanSubmodules: record2.requireCleanSubmodules !== false,
|
|
79565
|
+
// Strict opt-in: absent/false → self-only (historical behavior). Only an
|
|
79566
|
+
// explicit `true` extends auto ff to remote owning-daemon nodes.
|
|
79567
|
+
remoteNodes: record2.remoteNodes === true,
|
|
79568
|
+
// Absent/anything-but-continuous → 'idle' (historical idle-edge-only detection).
|
|
79569
|
+
mode: record2.mode === "continuous" ? "continuous" : "idle"
|
|
79570
|
+
};
|
|
79571
|
+
}
|
|
79572
|
+
function dryRunSatisfiesAutoFastForwardPolicy(dryRun, policy) {
|
|
79573
|
+
if (!dryRun || dryRun.code !== "fast_forward_available" || dryRun.allowed !== true) return false;
|
|
79574
|
+
const behind = Number(dryRun.current?.behind);
|
|
79575
|
+
if (!Number.isFinite(behind) || behind <= 0) return false;
|
|
79576
|
+
if (policy.maxBehind !== void 0 && behind > policy.maxBehind) return false;
|
|
79577
|
+
if (policy.requireCleanSubmodules) {
|
|
79578
|
+
const submodules = Array.isArray(dryRun.current?.submodules) ? dryRun.current.submodules : [];
|
|
79579
|
+
if (submodules.some((submodule) => submodule?.dirty || submodule?.error)) return false;
|
|
79580
|
+
}
|
|
79581
|
+
return true;
|
|
79582
|
+
}
|
|
79583
|
+
function readNodeSubmoduleIgnorePaths(node) {
|
|
79584
|
+
return Array.isArray(node?.policy?.submoduleIgnorePaths) ? node.policy.submoduleIgnorePaths.filter((value) => typeof value === "string") : void 0;
|
|
79585
|
+
}
|
|
79586
|
+
function nodeIsAutoFastForwardEligible(components, meshId, nodeId, node, currentSessionId) {
|
|
79587
|
+
if (!node) return false;
|
|
79588
|
+
if (node.status === "disabled" || node.status === "removed") return false;
|
|
79589
|
+
if (node.readOnly === true || node.policy?.readOnly === true) return false;
|
|
79590
|
+
if (isWorktreeBootstrapStaleRunning(node)) return false;
|
|
79591
|
+
if (node.worktreeBootstrap?.status === "running") return false;
|
|
79592
|
+
if (nodeHasActiveMeshWork(components, meshId, nodeId, currentSessionId)) return false;
|
|
79593
|
+
return true;
|
|
79594
|
+
}
|
|
79595
|
+
function remoteNodeIsConnected(components, node) {
|
|
79596
|
+
const daemonId = readMeshNodeDaemonId(node ?? {});
|
|
79597
|
+
if (!daemonId) return false;
|
|
79598
|
+
const getPeerStatus = components.getMeshPeerConnectionStatus;
|
|
79599
|
+
if (getPeerStatus) {
|
|
79600
|
+
const snapshot = getPeerStatus(daemonId);
|
|
79601
|
+
return !!snapshot && String(snapshot.state) === "connected";
|
|
79602
|
+
}
|
|
79603
|
+
return readNonEmptyString(node?.connection?.state).toLowerCase() === "connected";
|
|
79604
|
+
}
|
|
79605
|
+
async function delegateRemoteAutoFastForward(components, args) {
|
|
79606
|
+
const dispatchMeshCommand = components.dispatchMeshCommand;
|
|
79607
|
+
if (!dispatchMeshCommand) return;
|
|
79608
|
+
if (!acquireAutoFastForwardLease(args.workspace)) return;
|
|
79609
|
+
const submoduleIgnorePaths = readNodeSubmoduleIgnorePaths(args.node);
|
|
79610
|
+
const mesh = getMeshWithCache(components, args.meshId);
|
|
79611
|
+
const baseArgs = {
|
|
79612
|
+
meshId: args.meshId,
|
|
79613
|
+
nodeId: args.nodeId,
|
|
79614
|
+
workspace: args.workspace,
|
|
79615
|
+
inlineMesh: mesh,
|
|
79616
|
+
...submoduleIgnorePaths ? { submoduleIgnorePaths } : {},
|
|
79617
|
+
trigger: args.trigger,
|
|
79618
|
+
// Mirror the manual mesh_fast_forward_node update_submodules behavior: if the
|
|
79619
|
+
// ff-only merge moves a submodule gitlink, run `git submodule update --init
|
|
79620
|
+
// --recursive` in the same cycle so the checkout never drifts from the gitlink.
|
|
79621
|
+
// Without this, drift accumulates and self-blocks every subsequent auto-ff
|
|
79622
|
+
// (collectPreflightBlockers treats out-of-sync submodules as a hard blocker).
|
|
79623
|
+
updateSubmodules: true
|
|
79624
|
+
};
|
|
79625
|
+
try {
|
|
79626
|
+
const remoteDry = await dispatchMeshCommand(args.daemonId, "fast_forward_mesh_node", {
|
|
79627
|
+
...baseArgs,
|
|
79628
|
+
execute: false,
|
|
79629
|
+
dryRun: true
|
|
79630
|
+
});
|
|
79631
|
+
if (!dryRunSatisfiesAutoFastForwardPolicy(remoteDry, args.policy)) return;
|
|
79632
|
+
if (nodeHasActiveMeshWork(components, args.meshId, args.nodeId)) return;
|
|
79633
|
+
const executed = await dispatchMeshCommand(args.daemonId, "fast_forward_mesh_node", {
|
|
79634
|
+
...baseArgs,
|
|
79635
|
+
execute: true,
|
|
79636
|
+
dryRun: false
|
|
79637
|
+
});
|
|
79638
|
+
if (executed?.executed === true) {
|
|
79639
|
+
LOG2.info("MeshFastForward", `Remote auto fast-forward executed for node ${args.nodeId} (daemon ${String(args.daemonId).slice(0, 12)}, trigger ${args.trigger})`);
|
|
79640
|
+
}
|
|
79641
|
+
} catch (e) {
|
|
79642
|
+
LOG2.warn("MeshFastForward", `Remote auto fast-forward delegation failed for ${args.nodeId}: ${e?.message || e}`);
|
|
79643
|
+
} finally {
|
|
79644
|
+
releaseAutoFastForwardLease(args.workspace);
|
|
79645
|
+
}
|
|
79646
|
+
}
|
|
79647
|
+
async function executeLocalAutoFastForward(args) {
|
|
79648
|
+
if (!acquireAutoFastForwardLease(args.workspace)) return;
|
|
79649
|
+
const submoduleIgnorePaths = readNodeSubmoduleIgnorePaths(args.node);
|
|
79650
|
+
try {
|
|
79651
|
+
const dryRun = await fastForwardMeshNode({
|
|
79652
|
+
meshId: args.meshId,
|
|
79653
|
+
nodeId: args.nodeId,
|
|
79654
|
+
workspace: args.workspace,
|
|
79655
|
+
execute: false,
|
|
79656
|
+
dryRun: true,
|
|
79657
|
+
// See delegateRemoteAutoFastForward's updateSubmodules comment: mirrors the
|
|
79658
|
+
// manual tool so a gitlink-moving ff cannot leave the submodule drifted.
|
|
79659
|
+
updateSubmodules: true,
|
|
79660
|
+
submoduleIgnorePaths,
|
|
79661
|
+
trigger: args.trigger
|
|
79662
|
+
});
|
|
79663
|
+
if (!dryRunSatisfiesAutoFastForwardPolicy(dryRun, args.policy)) return;
|
|
79664
|
+
await fastForwardMeshNode({
|
|
79665
|
+
meshId: args.meshId,
|
|
79666
|
+
nodeId: args.nodeId,
|
|
79667
|
+
workspace: args.workspace,
|
|
79668
|
+
execute: true,
|
|
79669
|
+
dryRun: false,
|
|
79670
|
+
updateSubmodules: true,
|
|
79671
|
+
submoduleIgnorePaths,
|
|
79672
|
+
trigger: args.trigger
|
|
79673
|
+
});
|
|
79674
|
+
} catch (e) {
|
|
79675
|
+
LOG2.warn("MeshFastForward", `Idle auto fast-forward check failed for ${args.nodeId}: ${e?.message || e}`);
|
|
79676
|
+
} finally {
|
|
79677
|
+
releaseAutoFastForwardLease(args.workspace);
|
|
79678
|
+
}
|
|
79679
|
+
}
|
|
79680
|
+
async function maybeAutoFastForwardIdleNode(components, args) {
|
|
79681
|
+
const mesh = getMeshWithCache(components, args.meshId);
|
|
79682
|
+
const node = mesh?.nodes?.find((candidate) => meshNodeIdMatches(candidate, args.nodeId));
|
|
79683
|
+
const workspace = readNonEmptyString(node?.workspace);
|
|
79684
|
+
if (!workspace) return;
|
|
79685
|
+
const policy = resolveAutoFastForwardPolicy(mesh);
|
|
79686
|
+
if (!policy.enabled) return;
|
|
79687
|
+
if (nodeHasActiveMeshWork(components, args.meshId, args.nodeId, args.sessionId)) return;
|
|
79688
|
+
const throttleKey = `${args.meshId}:${args.nodeId}`;
|
|
79689
|
+
const now = Date.now();
|
|
79690
|
+
const lastAttempt = idleAutoFastForwardLastAttempt.get(throttleKey) || 0;
|
|
79691
|
+
if (now - lastAttempt < IDLE_AUTO_FAST_FORWARD_THROTTLE_MS) return;
|
|
79692
|
+
idleAutoFastForwardLastAttempt.set(throttleKey, now);
|
|
79693
|
+
if (isLocalAutoLaunchNode(node)) {
|
|
79694
|
+
if (!(0, import_fs17.existsSync)(workspace)) return;
|
|
79695
|
+
await executeLocalAutoFastForward({ meshId: args.meshId, nodeId: args.nodeId, node, workspace, policy, trigger: "idle_auto" });
|
|
79696
|
+
return;
|
|
79697
|
+
}
|
|
79698
|
+
if (!policy.remoteNodes) return;
|
|
79699
|
+
const daemonId = readMeshNodeDaemonId(node ?? {});
|
|
79700
|
+
if (!daemonId || !components.dispatchMeshCommand) return;
|
|
79701
|
+
if (!remoteNodeIsConnected(components, node)) return;
|
|
79702
|
+
await delegateRemoteAutoFastForward(components, { meshId: args.meshId, nodeId: args.nodeId, node, daemonId, workspace, policy, trigger: "idle_auto" });
|
|
79703
|
+
}
|
|
79704
|
+
async function runContinuousAutoFastForwardScan(components, mesh) {
|
|
79705
|
+
if (!components.dispatchMeshCommand) return;
|
|
79706
|
+
const policy = resolveAutoFastForwardPolicy(mesh);
|
|
79707
|
+
if (!policy.enabled || !policy.remoteNodes || policy.mode !== "continuous") return;
|
|
79708
|
+
const meshId = readNonEmptyString(mesh?.id);
|
|
79709
|
+
if (!meshId) return;
|
|
79710
|
+
const nodes = Array.isArray(mesh?.nodes) ? mesh.nodes : [];
|
|
79711
|
+
const now = Date.now();
|
|
79712
|
+
for (const node of nodes) {
|
|
79713
|
+
const nodeId = normalizeMeshNodeId(node);
|
|
79714
|
+
if (!nodeId) continue;
|
|
79715
|
+
if (node?.isLocalWorktree === true) continue;
|
|
79716
|
+
if (isLocalAutoLaunchNode(node)) continue;
|
|
79717
|
+
const workspace = readNonEmptyString(node?.workspace);
|
|
79718
|
+
if (!workspace) continue;
|
|
79719
|
+
const daemonId = readMeshNodeDaemonId(node ?? {});
|
|
79720
|
+
if (!daemonId) continue;
|
|
79721
|
+
if (!nodeIsAutoFastForwardEligible(components, meshId, nodeId, node)) continue;
|
|
79722
|
+
if (!remoteNodeIsConnected(components, node)) continue;
|
|
79723
|
+
const cooldownKey = `${meshId}:${nodeId}`;
|
|
79724
|
+
const lastScan = continuousAutoFastForwardLastScan.get(cooldownKey) || 0;
|
|
79725
|
+
if (now - lastScan < CONTINUOUS_AUTO_FAST_FORWARD_SCAN_COOLDOWN_MS) continue;
|
|
79726
|
+
continuousAutoFastForwardLastScan.set(cooldownKey, now);
|
|
79727
|
+
await delegateRemoteAutoFastForward(components, { meshId, nodeId, node, daemonId, workspace, policy, trigger: "reconcile_auto" });
|
|
79728
|
+
}
|
|
79729
|
+
}
|
|
79730
|
+
async function runPendingCoordinatorCatchupScan(components, mesh) {
|
|
79731
|
+
const meshId = readNonEmptyString(mesh?.id);
|
|
79732
|
+
if (!meshId) return;
|
|
79733
|
+
const localIds = expandDaemonIdForms([
|
|
79734
|
+
readNonEmptyString(components.statusInstanceId),
|
|
79735
|
+
readNonEmptyString(loadConfig2().machineId)
|
|
79736
|
+
]);
|
|
79737
|
+
let markers = [];
|
|
79738
|
+
try {
|
|
79739
|
+
markers = drainPendingMeshCoordinatorEvents(
|
|
79740
|
+
meshId,
|
|
79741
|
+
localIds.length > 0 ? localIds : void 0,
|
|
79742
|
+
{ onlyEvents: /* @__PURE__ */ new Set(["coordinator_catchup"]) }
|
|
79743
|
+
);
|
|
79744
|
+
} catch (e) {
|
|
79745
|
+
LOG2.warn("MeshReconcile", `Coordinator-catchup drain failed for mesh ${meshId}: ${e?.message || e}`);
|
|
79746
|
+
return;
|
|
79747
|
+
}
|
|
79748
|
+
if (markers.length === 0) return;
|
|
79749
|
+
const nodes = Array.isArray(mesh?.nodes) ? mesh.nodes : [];
|
|
79750
|
+
for (const marker of markers) {
|
|
79751
|
+
const meta3 = marker.metadataEvent || {};
|
|
79752
|
+
const nodeId = readNonEmptyString(marker.nodeId) || readNonEmptyString(meta3.nodeId);
|
|
79753
|
+
const workspace = readNonEmptyString(marker.workspace) || readNonEmptyString(meta3.workspace);
|
|
79754
|
+
const baseBranch = readNonEmptyString(meta3.baseBranch);
|
|
79755
|
+
if (!workspace) continue;
|
|
79756
|
+
if (nodeId && nodeHasActiveMeshWork(components, meshId, nodeId)) {
|
|
79757
|
+
try {
|
|
79758
|
+
queuePendingMeshCoordinatorEvent(marker);
|
|
79759
|
+
} catch {
|
|
79760
|
+
}
|
|
79761
|
+
continue;
|
|
79762
|
+
}
|
|
79763
|
+
try {
|
|
79764
|
+
const ff = await fastForwardMeshNode({
|
|
79765
|
+
meshId,
|
|
79766
|
+
...nodeId ? { nodeId } : {},
|
|
79767
|
+
workspace,
|
|
79768
|
+
...baseBranch ? { branch: baseBranch } : {},
|
|
79769
|
+
mode: "merge",
|
|
79770
|
+
execute: true,
|
|
79771
|
+
// Same gitlink-drift-prevention rationale as executeLocalAutoFastForward /
|
|
79772
|
+
// delegateRemoteAutoFastForward — this path pushed the base branch itself,
|
|
79773
|
+
// so a submodule gitlink bump here is exactly as likely.
|
|
79774
|
+
updateSubmodules: true,
|
|
79775
|
+
trigger: "refine_post_push_catchup",
|
|
79776
|
+
allowAutoPublishSubmoduleMainCommits: mesh?.policy?.allowAutoPublishSubmoduleMainCommits === true
|
|
79777
|
+
});
|
|
79778
|
+
LOG2.info("MeshReconcile", `Coordinator catch-up ff for ${meshId}/${nodeId || workspace}: ${ff.code} (executed=${ff.executed})`);
|
|
79779
|
+
} catch (e) {
|
|
79780
|
+
LOG2.warn("MeshReconcile", `Coordinator catch-up ff failed for ${meshId}/${nodeId || workspace}: ${e?.message || e}`);
|
|
79781
|
+
}
|
|
79782
|
+
}
|
|
79783
|
+
}
|
|
79784
|
+
var import_fs17;
|
|
79785
|
+
var IDLE_AUTO_FAST_FORWARD_THROTTLE_MS;
|
|
79786
|
+
var idleAutoFastForwardLastAttempt;
|
|
79787
|
+
var CONTINUOUS_AUTO_FAST_FORWARD_SCAN_COOLDOWN_MS;
|
|
79788
|
+
var continuousAutoFastForwardLastScan;
|
|
79789
|
+
var autoFastForwardWorkspaceLease;
|
|
79790
|
+
var init_mesh_auto_fast_forward = __esm2({
|
|
79791
|
+
"src/mesh/mesh-auto-fast-forward.ts"() {
|
|
79792
|
+
"use strict";
|
|
79793
|
+
import_fs17 = require("fs");
|
|
79794
|
+
init_logger();
|
|
79795
|
+
init_config();
|
|
79796
|
+
init_mesh_fast_forward();
|
|
79797
|
+
init_dist();
|
|
79798
|
+
init_mesh_events_utils();
|
|
79799
|
+
init_mesh_node_identity();
|
|
79800
|
+
init_mesh_events_pending();
|
|
79801
|
+
init_worktree_bootstrap_config();
|
|
79802
|
+
init_mesh_queue_assignment();
|
|
79803
|
+
IDLE_AUTO_FAST_FORWARD_THROTTLE_MS = 30 * 60 * 1e3;
|
|
79804
|
+
idleAutoFastForwardLastAttempt = /* @__PURE__ */ new Map();
|
|
79805
|
+
CONTINUOUS_AUTO_FAST_FORWARD_SCAN_COOLDOWN_MS = 45 * 1e3;
|
|
79806
|
+
continuousAutoFastForwardLastScan = /* @__PURE__ */ new Map();
|
|
79807
|
+
autoFastForwardWorkspaceLease = /* @__PURE__ */ new Set();
|
|
79808
|
+
}
|
|
79809
|
+
});
|
|
79810
|
+
function normalizeNodeIdKey(nodeId) {
|
|
79811
|
+
return normalizeMeshNodeId({ id: nodeId ?? void 0 }) ?? "";
|
|
79812
|
+
}
|
|
79813
|
+
function noteRecentlyClonedNode(nodeId, nowMs = Date.now()) {
|
|
79814
|
+
const key2 = normalizeNodeIdKey(nodeId);
|
|
79815
|
+
if (!key2) return;
|
|
79816
|
+
recentlyClonedNodeExpiry.set(key2, nowMs + CLONE_BOOTSTRAP_GRACE_MS);
|
|
79817
|
+
if (recentlyClonedNodeExpiry.size > MAX_TRACKED_CLONED_NODES) {
|
|
79818
|
+
const oldest = recentlyClonedNodeExpiry.keys().next().value;
|
|
79819
|
+
if (oldest !== void 0) recentlyClonedNodeExpiry.delete(oldest);
|
|
79820
|
+
}
|
|
79821
|
+
}
|
|
79822
|
+
function isWithinCloneBootstrapGrace(nodeId, nowMs = Date.now()) {
|
|
79823
|
+
const key2 = normalizeNodeIdKey(nodeId);
|
|
79824
|
+
if (!key2) return false;
|
|
79825
|
+
const expiry = recentlyClonedNodeExpiry.get(key2);
|
|
79826
|
+
if (expiry === void 0) return false;
|
|
79827
|
+
if (nowMs >= expiry) {
|
|
79828
|
+
recentlyClonedNodeExpiry.delete(key2);
|
|
79829
|
+
return false;
|
|
79830
|
+
}
|
|
79831
|
+
return true;
|
|
79832
|
+
}
|
|
79833
|
+
var CLONE_BOOTSTRAP_GRACE_MS;
|
|
79834
|
+
var recentlyClonedNodeExpiry;
|
|
79835
|
+
var MAX_TRACKED_CLONED_NODES;
|
|
79836
|
+
var init_mesh_clone_grace = __esm2({
|
|
79837
|
+
"src/mesh/mesh-clone-grace.ts"() {
|
|
79838
|
+
"use strict";
|
|
79839
|
+
init_dist();
|
|
79840
|
+
CLONE_BOOTSTRAP_GRACE_MS = 10 * 60 * 1e3;
|
|
79841
|
+
recentlyClonedNodeExpiry = /* @__PURE__ */ new Map();
|
|
79842
|
+
MAX_TRACKED_CLONED_NODES = 512;
|
|
79843
|
+
}
|
|
79844
|
+
});
|
|
79339
79845
|
function isActionableSkipReason(reason) {
|
|
79340
79846
|
if (!reason) return false;
|
|
79341
79847
|
return ACTIONABLE_SKIP_REASON_PREFIXES.some((prefix) => reason === prefix || reason.startsWith(prefix));
|
|
@@ -79627,454 +80133,6 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
79627
80133
|
targetPinGeneratingCreditMs = /* @__PURE__ */ new Map();
|
|
79628
80134
|
}
|
|
79629
80135
|
});
|
|
79630
|
-
function localCoordinatorDaemonId() {
|
|
79631
|
-
return canonicalDaemonId(readNonEmptyString(loadConfig2().machineId));
|
|
79632
|
-
}
|
|
79633
|
-
function isIdleSessionState2(state) {
|
|
79634
|
-
const status = readNonEmptyString(state?.status).toLowerCase();
|
|
79635
|
-
if (TERMINAL_SESSION_STATUSES.includes(status)) return false;
|
|
79636
|
-
return status === "idle" || state?.activeChat?.status === "waiting_input";
|
|
79637
|
-
}
|
|
79638
|
-
function sweepAutoLaunchOrphanSessions(components, meshId) {
|
|
79639
|
-
let sessions;
|
|
79640
|
-
try {
|
|
79641
|
-
sessions = components.instanceManager?.getByCategory?.("cli") || [];
|
|
79642
|
-
} catch {
|
|
79643
|
-
return;
|
|
79644
|
-
}
|
|
79645
|
-
if (!sessions.length) return;
|
|
79646
|
-
let queue;
|
|
79647
|
-
try {
|
|
79648
|
-
queue = getQueue(meshId);
|
|
79649
|
-
} catch {
|
|
79650
|
-
return;
|
|
79651
|
-
}
|
|
79652
|
-
const byId = new Map(queue.map((t) => [t.id, t]));
|
|
79653
|
-
for (const inst of sessions) {
|
|
79654
|
-
let state;
|
|
79655
|
-
try {
|
|
79656
|
-
state = inst.getState();
|
|
79657
|
-
} catch {
|
|
79658
|
-
continue;
|
|
79659
|
-
}
|
|
79660
|
-
const settings = state?.settings || {};
|
|
79661
|
-
if (readNonEmptyString(settings.meshNodeFor) !== meshId) continue;
|
|
79662
|
-
const originTaskId = readNonEmptyString(settings.autoLaunchedForQueueTaskId);
|
|
79663
|
-
if (!originTaskId) continue;
|
|
79664
|
-
const sessionId = readNonEmptyString(state?.instanceId);
|
|
79665
|
-
if (!sessionId) continue;
|
|
79666
|
-
if (!isIdleSessionState2(state)) continue;
|
|
79667
|
-
if (sessionHasActiveAssignment(meshId, sessionId)) continue;
|
|
79668
|
-
const originTask = byId.get(originTaskId);
|
|
79669
|
-
const assignedElsewhere = !!originTask && originTask.status === "assigned" && !!readNonEmptyString(originTask.assignedSessionId) && !sessionIdsEquivalent(readNonEmptyString(originTask.assignedSessionId), sessionId);
|
|
79670
|
-
const originGone = !originTask || originTask.status !== "pending" && originTask.status !== "assigned";
|
|
79671
|
-
const dedupKey = `${meshId}::${sessionId}`;
|
|
79672
|
-
if (!assignedElsewhere && !originGone) {
|
|
79673
|
-
autoLaunchOrphanFirstSeenAtMs.delete(dedupKey);
|
|
79674
|
-
continue;
|
|
79675
|
-
}
|
|
79676
|
-
const nowMs = Date.now();
|
|
79677
|
-
const firstSeenAtMs = autoLaunchOrphanFirstSeenAtMs.get(dedupKey);
|
|
79678
|
-
if (firstSeenAtMs === void 0) {
|
|
79679
|
-
autoLaunchOrphanFirstSeenAtMs.set(dedupKey, nowMs);
|
|
79680
|
-
if (autoLaunchOrphanFirstSeenAtMs.size > AUTO_LAUNCH_LEDGER_DEDUP_MAX) {
|
|
79681
|
-
const oldest = autoLaunchOrphanFirstSeenAtMs.keys().next().value;
|
|
79682
|
-
if (oldest !== void 0) autoLaunchOrphanFirstSeenAtMs.delete(oldest);
|
|
79683
|
-
}
|
|
79684
|
-
continue;
|
|
79685
|
-
}
|
|
79686
|
-
if (nowMs - firstSeenAtMs < AUTO_LAUNCH_ORPHAN_GRACE_MS) continue;
|
|
79687
|
-
if (autoLaunchOrphanNotified.has(dedupKey)) continue;
|
|
79688
|
-
autoLaunchOrphanNotified.add(dedupKey);
|
|
79689
|
-
if (autoLaunchOrphanNotified.size > AUTO_LAUNCH_LEDGER_DEDUP_MAX) {
|
|
79690
|
-
const oldest = autoLaunchOrphanNotified.values().next().value;
|
|
79691
|
-
if (oldest !== void 0) autoLaunchOrphanNotified.delete(oldest);
|
|
79692
|
-
}
|
|
79693
|
-
const nodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
79694
|
-
const detail = assignedElsewhere ? `task ${originTaskId} is assigned to a different session (${readNonEmptyString(originTask.assignedSessionId)})` : `task ${originTaskId} is no longer active (${originTask ? originTask.status : "absent from the queue"})`;
|
|
79695
|
-
recordAutoLaunchEvent(meshId, {
|
|
79696
|
-
phase: "skipped",
|
|
79697
|
-
taskId: originTaskId,
|
|
79698
|
-
reason: "auto_launch_orphan_session_detected",
|
|
79699
|
-
nodeId,
|
|
79700
|
-
sessionId
|
|
79701
|
-
});
|
|
79702
|
-
LOG2.warn("MeshQueue", `AUTOLAUNCH-ORPHAN-SWEEP: session ${sessionId}${nodeId ? ` on node ${nodeId}` : ""} (mesh ${meshId}) was auto-launched for task ${originTaskId} but ${detail}; it is idle with no work and will not self-recover.`);
|
|
79703
|
-
try {
|
|
79704
|
-
queuePendingMeshCoordinatorEvent({
|
|
79705
|
-
event: "mesh:dispatch_blocked",
|
|
79706
|
-
meshId,
|
|
79707
|
-
nodeLabel: nodeId || meshId,
|
|
79708
|
-
...nodeId ? { nodeId } : {},
|
|
79709
|
-
metadataEvent: {
|
|
79710
|
-
source: "mesh_auto_launch_orphan_session",
|
|
79711
|
-
taskId: originTaskId,
|
|
79712
|
-
sessionId,
|
|
79713
|
-
reason: "auto_launch_orphan_session_detected"
|
|
79714
|
-
},
|
|
79715
|
-
coordinatorMessage: `[System] Mesh session ${sessionId}${nodeId ? ` on node ${nodeId}` : ""} was auto-launched for task ${originTaskId}, but ${detail}. The session is idle with no work assigned and nothing reclaims it on its own. Reuse it for other queued work or stop it.`,
|
|
79716
|
-
queuedAt: Date.now(),
|
|
79717
|
-
...readNonEmptyString(originTask?.sourceCoordinatorSessionId) ? { targetCoordinatorSessionId: readNonEmptyString(originTask.sourceCoordinatorSessionId) } : {},
|
|
79718
|
-
...localCoordinatorDaemonId() ? { targetCoordinatorDaemonId: localCoordinatorDaemonId() } : {}
|
|
79719
|
-
});
|
|
79720
|
-
} catch (e) {
|
|
79721
|
-
LOG2.warn("MeshQueue", `AUTOLAUNCH-ORPHAN-SWEEP: failed to queue the coordinator notification for session ${sessionId}: ${e?.message || e}`);
|
|
79722
|
-
}
|
|
79723
|
-
}
|
|
79724
|
-
}
|
|
79725
|
-
function autoLaunchWriteWouldClobberWinner(meshId, taskId, args, awaitClaimWindowMs3) {
|
|
79726
|
-
if (args.status === "completed" && readNonEmptyString(args.sessionId)) return false;
|
|
79727
|
-
let existing;
|
|
79728
|
-
try {
|
|
79729
|
-
existing = getQueue(meshId).find((t) => t.id === taskId)?.autoLaunch;
|
|
79730
|
-
} catch {
|
|
79731
|
-
return false;
|
|
79732
|
-
}
|
|
79733
|
-
const heldSessionId = existing ? readNonEmptyString(existing.sessionId) : "";
|
|
79734
|
-
if (!existing || existing.status !== "completed" || !heldSessionId) return false;
|
|
79735
|
-
const heldAtMs = Date.parse(existing.updatedAt);
|
|
79736
|
-
if (!Number.isFinite(heldAtMs) || Date.now() - heldAtMs >= awaitClaimWindowMs3) return false;
|
|
79737
|
-
if (sessionIdsEquivalent(readNonEmptyString(args.sessionId), heldSessionId)) return false;
|
|
79738
|
-
LOG2.info("MeshQueue", `AUTOLAUNCH-WINNER-CLOBBER: suppressed a '${args.status}' autoLaunch write for task ${taskId} (mesh ${meshId}) that would have overwritten the in-window launch record for session ${heldSessionId}; the field keeps pointing at the actually-launched session.`);
|
|
79739
|
-
return true;
|
|
79740
|
-
}
|
|
79741
|
-
function awaitClaimWindowMs(cycles) {
|
|
79742
|
-
return AUTO_LAUNCH_AWAIT_CLAIM_MS * Math.pow(2, Math.min(cycles, AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES));
|
|
79743
|
-
}
|
|
79744
|
-
function remoteSessionAppearsLive(meshId, sessionId) {
|
|
79745
|
-
if (!sessionId) return false;
|
|
79746
|
-
try {
|
|
79747
|
-
return MeshRuntimeStore.getInstance().getRemoteIdleSessions(meshId).some((s2) => sessionIdsEquivalent(s2.sessionId, sessionId));
|
|
79748
|
-
} catch {
|
|
79749
|
-
return false;
|
|
79750
|
-
}
|
|
79751
|
-
}
|
|
79752
|
-
function inWindowAutoLaunchSessionIdsForNode(meshId, nodeId) {
|
|
79753
|
-
const nowMs = Date.now();
|
|
79754
|
-
const out = [];
|
|
79755
|
-
for (const task of getQueue(meshId, { status: ["pending"] })) {
|
|
79756
|
-
const al = task.autoLaunch;
|
|
79757
|
-
const sid = al ? readNonEmptyString(al.sessionId) : "";
|
|
79758
|
-
if (!al || al.status !== "started" && al.status !== "completed" || !sid) continue;
|
|
79759
|
-
if (!daemonIdsEquivalent(al.nodeId, nodeId)) continue;
|
|
79760
|
-
const launchedAtMs = Date.parse(al.updatedAt);
|
|
79761
|
-
const inBaseWindow = Number.isFinite(launchedAtMs) && nowMs - launchedAtMs < AUTO_LAUNCH_AWAIT_CLAIM_MS;
|
|
79762
|
-
const inBackoff = autoLaunchAwaitClaimBackoff.has(`${meshId}::${task.id}`);
|
|
79763
|
-
if (inBaseWindow || inBackoff) out.push(sid);
|
|
79764
|
-
}
|
|
79765
|
-
return out;
|
|
79766
|
-
}
|
|
79767
|
-
function driveExpiredAwaitClaim(components, meshId, task, ctx, assignQueueTask) {
|
|
79768
|
-
const { sessionId, nodeId, providerType } = ctx;
|
|
79769
|
-
const backoffKey = `${meshId}::${task.id}`;
|
|
79770
|
-
const nowMs = Date.now();
|
|
79771
|
-
const state = autoLaunchAwaitClaimBackoff.get(backoffKey) || { cycles: 0, nextAttemptAtMs: 0 };
|
|
79772
|
-
if (state.nextAttemptAtMs && nowMs < state.nextAttemptAtMs) return "backoff";
|
|
79773
|
-
const atCap = state.cycles >= AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES;
|
|
79774
|
-
const live = remoteSessionAppearsLive(meshId, sessionId);
|
|
79775
|
-
if ((live || atCap) && nodeId && providerType) {
|
|
79776
|
-
try {
|
|
79777
|
-
MeshRuntimeStore.getInstance().setRemoteIdleSession(meshId, nodeId, sessionId, providerType, nowMs + AUTO_LAUNCH_REMOTE_IDLE_TTL_MS);
|
|
79778
|
-
} catch {
|
|
79779
|
-
}
|
|
79780
|
-
const assigned = assignQueueTask(components, meshId, nodeId, sessionId, providerType);
|
|
79781
|
-
if (assigned) {
|
|
79782
|
-
autoLaunchAwaitClaimBackoff.delete(backoffKey);
|
|
79783
|
-
const isFallback = atCap && !live;
|
|
79784
|
-
recordAutoLaunchEvent(meshId, {
|
|
79785
|
-
phase: "completed",
|
|
79786
|
-
taskId: task.id,
|
|
79787
|
-
reason: isFallback ? "await_claim_direct_dispatch_fallback" : "await_claim_redriven",
|
|
79788
|
-
nodeId,
|
|
79789
|
-
sessionId
|
|
79790
|
-
});
|
|
79791
|
-
LOG2.info("MeshQueue", `Auto-launch await-claim ${isFallback ? "direct-dispatch fallback" : "re-drive"} claimed task ${task.id} into existing session ${sessionId} on node ${nodeId} (mesh ${meshId})`);
|
|
79792
|
-
return isFallback ? "fallback" : "claimed";
|
|
79793
|
-
}
|
|
79794
|
-
if (atCap) {
|
|
79795
|
-
autoLaunchAwaitClaimBackoff.delete(backoffKey);
|
|
79796
|
-
return "respawn";
|
|
79797
|
-
}
|
|
79798
|
-
}
|
|
79799
|
-
const cycles = Math.min(state.cycles + 1, AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES);
|
|
79800
|
-
autoLaunchAwaitClaimBackoff.set(backoffKey, { cycles, nextAttemptAtMs: nowMs + awaitClaimWindowMs(cycles) });
|
|
79801
|
-
recordAutoLaunchEvent(meshId, { phase: "skipped", taskId: task.id, reason: "awaiting_launched_session_claim_backoff", nodeId, sessionId });
|
|
79802
|
-
return "backoff";
|
|
79803
|
-
}
|
|
79804
|
-
var AUTO_LAUNCH_AWAIT_CLAIM_MS;
|
|
79805
|
-
var AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES;
|
|
79806
|
-
var AUTO_LAUNCH_REMOTE_IDLE_TTL_MS;
|
|
79807
|
-
var TERMINAL_SESSION_STATUSES;
|
|
79808
|
-
var autoLaunchOrphanNotified;
|
|
79809
|
-
var autoLaunchOrphanFirstSeenAtMs;
|
|
79810
|
-
var AUTO_LAUNCH_ORPHAN_GRACE_MS;
|
|
79811
|
-
var autoLaunchAwaitClaimBackoff;
|
|
79812
|
-
var init_mesh_autolaunch_integrity = __esm2({
|
|
79813
|
-
"src/mesh/mesh-autolaunch-integrity.ts"() {
|
|
79814
|
-
"use strict";
|
|
79815
|
-
init_config();
|
|
79816
|
-
init_logger();
|
|
79817
|
-
init_dist();
|
|
79818
|
-
init_mesh_work_queue();
|
|
79819
|
-
init_mesh_events_utils();
|
|
79820
|
-
init_mesh_events_pending();
|
|
79821
|
-
init_mesh_queue_observability();
|
|
79822
|
-
init_mesh_scheduling_fitness();
|
|
79823
|
-
init_mesh_runtime_store();
|
|
79824
|
-
AUTO_LAUNCH_AWAIT_CLAIM_MS = 9e4;
|
|
79825
|
-
AUTO_LAUNCH_AWAIT_CLAIM_BACKOFF_CAP_CYCLES = 2;
|
|
79826
|
-
AUTO_LAUNCH_REMOTE_IDLE_TTL_MS = 5 * 60 * 1e3;
|
|
79827
|
-
TERMINAL_SESSION_STATUSES = ["stopped", "failed", "terminated", "exited", "closed"];
|
|
79828
|
-
autoLaunchOrphanNotified = /* @__PURE__ */ new Set();
|
|
79829
|
-
autoLaunchOrphanFirstSeenAtMs = /* @__PURE__ */ new Map();
|
|
79830
|
-
AUTO_LAUNCH_ORPHAN_GRACE_MS = 3e4;
|
|
79831
|
-
autoLaunchAwaitClaimBackoff = /* @__PURE__ */ new Map();
|
|
79832
|
-
}
|
|
79833
|
-
});
|
|
79834
|
-
function classifiedDifficultiesForSlot(slot) {
|
|
79835
|
-
const highest = slot.difficulty?.reduce((rank, value) => {
|
|
79836
|
-
const candidate = CLASSIFIED_DIFFICULTIES.indexOf(value);
|
|
79837
|
-
return Math.max(rank, candidate);
|
|
79838
|
-
}, -1) ?? -1;
|
|
79839
|
-
return highest < 0 ? [] : CLASSIFIED_DIFFICULTIES.slice(0, highest + 1);
|
|
79840
|
-
}
|
|
79841
|
-
function allowedClassifiedDifficultiesForSession(node, slots, providerType, model) {
|
|
79842
|
-
if (normalizeNodeCapabilitySlots(node?.policy?.slots).length === 0) return void 0;
|
|
79843
|
-
const providerSlots = slots.filter((slot) => slot.provider?.trim() === providerType);
|
|
79844
|
-
const possibleSlots = model ? providerSlots.filter((slot) => isModelAllowedBySlot(model, slot)) : providerSlots;
|
|
79845
|
-
if (possibleSlots.length === 0) return [];
|
|
79846
|
-
const supported = possibleSlots.map((slot) => new Set(classifiedDifficultiesForSlot(slot)));
|
|
79847
|
-
return CLASSIFIED_DIFFICULTIES.filter((difficulty) => model ? supported.some((grades) => grades.has(difficulty)) : supported.every((grades) => grades.has(difficulty)));
|
|
79848
|
-
}
|
|
79849
|
-
function taskMeetsSessionDifficultyFloor(task, allowed) {
|
|
79850
|
-
if (!allowed || !isMeshTaskDifficulty(task.difficulty) || task.difficulty === "freeform") return true;
|
|
79851
|
-
return allowed.includes(task.difficulty);
|
|
79852
|
-
}
|
|
79853
|
-
function readSessionModel(state) {
|
|
79854
|
-
const controlModel = typeof state?.controlValues?.model === "string" ? state.controlValues.model.trim() : "";
|
|
79855
|
-
if (controlModel) return controlModel;
|
|
79856
|
-
const modelItem = Array.isArray(state?.summaryMetadata?.items) ? state.summaryMetadata.items.find((item) => item?.id === "model") : void 0;
|
|
79857
|
-
const summaryModel = typeof modelItem?.shortValue === "string" && modelItem.shortValue.trim() ? modelItem.shortValue.trim() : typeof modelItem?.value === "string" ? modelItem.value.trim() : "";
|
|
79858
|
-
return summaryModel || void 0;
|
|
79859
|
-
}
|
|
79860
|
-
function isDifficultyFloorWaitReason(reason) {
|
|
79861
|
-
return typeof reason === "string" && (reason.startsWith(TASK_DIFFICULTY_FLOOR_REASON_PREFIX) || reason.startsWith(ALL_PROVIDERS_QUOTA_GATED_SKIP_REASON));
|
|
79862
|
-
}
|
|
79863
|
-
function handleDifficultyFloorSkip(args) {
|
|
79864
|
-
let previousTask;
|
|
79865
|
-
try {
|
|
79866
|
-
previousTask = getQueue(args.meshId).find((task2) => task2.id === args.taskId);
|
|
79867
|
-
} catch {
|
|
79868
|
-
}
|
|
79869
|
-
if (previousTask?.autoLaunch?.reason?.startsWith(TASK_DIFFICULTY_FLOOR_REPORTED_PREFIX)) return;
|
|
79870
|
-
const continuing = previousTask?.autoLaunch?.status === "skipped" && isDifficultyFloorWaitReason(previousTask.autoLaunch.reason);
|
|
79871
|
-
if (!continuing) {
|
|
79872
|
-
recordTaskAutoLaunch(args.meshId, args.taskId, {
|
|
79873
|
-
status: "skipped",
|
|
79874
|
-
reason: args.reason,
|
|
79875
|
-
nodeId: args.nodeId
|
|
79876
|
-
});
|
|
79877
|
-
}
|
|
79878
|
-
const waitStartedAt = Date.parse(previousTask?.autoLaunch?.updatedAt || (/* @__PURE__ */ new Date()).toISOString());
|
|
79879
|
-
const waitedMs = Number.isFinite(waitStartedAt) ? Date.now() - waitStartedAt : 0;
|
|
79880
|
-
const reportKey = `${args.meshId}:${args.taskId}`;
|
|
79881
|
-
if (waitedMs < DIFFICULTY_FLOOR_REPORT_AFTER_MS || difficultyFloorTimeoutReported.has(reportKey)) return;
|
|
79882
|
-
const task = previousTask ?? getQueue(args.meshId).find((candidate) => candidate.id === args.taskId);
|
|
79883
|
-
const difficulty = task?.difficulty || args.reason.split(":")[1] || "classified";
|
|
79884
|
-
const coordinatorMessage = `[System] Queued task ${args.taskId} has waited ${Math.round(waitedMs / 6e4)} minutes because no available slot meets its ${difficulty} difficulty floor. It remains pending and was not downgraded. Ask the user whether to grant an explicit task-scoped downgrade; do not change a mesh-wide policy.`;
|
|
79885
|
-
const queued = queuePendingMeshCoordinatorEvent({
|
|
79886
|
-
event: "mesh:dispatch_blocked",
|
|
79887
|
-
meshId: args.meshId,
|
|
79888
|
-
nodeLabel: args.nodeId || args.meshId,
|
|
79889
|
-
...args.nodeId ? { nodeId: args.nodeId } : {},
|
|
79890
|
-
metadataEvent: {
|
|
79891
|
-
source: "mesh_queue_difficulty_floor_timeout",
|
|
79892
|
-
taskId: args.taskId,
|
|
79893
|
-
reason: "task_difficulty_floor_timeout",
|
|
79894
|
-
difficulty,
|
|
79895
|
-
waitedMs,
|
|
79896
|
-
coordinatorMessage
|
|
79897
|
-
},
|
|
79898
|
-
coordinatorMessage,
|
|
79899
|
-
queuedAt: Date.now(),
|
|
79900
|
-
...args.coordinatorDaemonId ? { targetCoordinatorDaemonId: args.coordinatorDaemonId } : {},
|
|
79901
|
-
...task?.sourceCoordinatorSessionId ? { targetCoordinatorSessionId: task.sourceCoordinatorSessionId } : {}
|
|
79902
|
-
});
|
|
79903
|
-
if (queued) {
|
|
79904
|
-
if (difficultyFloorTimeoutReported.size >= DIFFICULTY_FLOOR_REPORT_DEDUP_MAX) {
|
|
79905
|
-
const oldest = difficultyFloorTimeoutReported.values().next().value;
|
|
79906
|
-
if (oldest) difficultyFloorTimeoutReported.delete(oldest);
|
|
79907
|
-
}
|
|
79908
|
-
difficultyFloorTimeoutReported.add(reportKey);
|
|
79909
|
-
recordTaskAutoLaunch(args.meshId, args.taskId, {
|
|
79910
|
-
status: "skipped",
|
|
79911
|
-
reason: `${TASK_DIFFICULTY_FLOOR_REPORTED_PREFIX}${difficulty}`,
|
|
79912
|
-
nodeId: args.nodeId
|
|
79913
|
-
});
|
|
79914
|
-
}
|
|
79915
|
-
}
|
|
79916
|
-
var DIFFICULTY_FLOOR_REPORT_AFTER_MS;
|
|
79917
|
-
var TASK_DIFFICULTY_FLOOR_REASON_PREFIX;
|
|
79918
|
-
var TASK_DIFFICULTY_FLOOR_REPORTED_PREFIX;
|
|
79919
|
-
var difficultyFloorTimeoutReported;
|
|
79920
|
-
var DIFFICULTY_FLOOR_REPORT_DEDUP_MAX;
|
|
79921
|
-
var CLASSIFIED_DIFFICULTIES;
|
|
79922
|
-
var init_mesh_difficulty_floor = __esm2({
|
|
79923
|
-
"src/mesh/mesh-difficulty-floor.ts"() {
|
|
79924
|
-
"use strict";
|
|
79925
|
-
init_mesh_work_queue();
|
|
79926
|
-
init_mesh_events_pending();
|
|
79927
|
-
init_slot_model_enforcement();
|
|
79928
|
-
init_mesh_quota_routing();
|
|
79929
|
-
init_dist();
|
|
79930
|
-
DIFFICULTY_FLOOR_REPORT_AFTER_MS = 10 * 6e4;
|
|
79931
|
-
TASK_DIFFICULTY_FLOOR_REASON_PREFIX = "task_difficulty_floor_";
|
|
79932
|
-
TASK_DIFFICULTY_FLOOR_REPORTED_PREFIX = "task_difficulty_floor_reported:";
|
|
79933
|
-
difficultyFloorTimeoutReported = /* @__PURE__ */ new Set();
|
|
79934
|
-
DIFFICULTY_FLOOR_REPORT_DEDUP_MAX = 2e3;
|
|
79935
|
-
CLASSIFIED_DIFFICULTIES = ["easy", "medium", "difficult"];
|
|
79936
|
-
}
|
|
79937
|
-
});
|
|
79938
|
-
function normalizeProviderPriority2(policy) {
|
|
79939
|
-
const raw = policy && typeof policy === "object" && !Array.isArray(policy) ? policy.providerPriority : void 0;
|
|
79940
|
-
if (!Array.isArray(raw)) return [];
|
|
79941
|
-
const seen = /* @__PURE__ */ new Set();
|
|
79942
|
-
return raw.map((type2) => typeof type2 === "string" ? type2.trim() : "").filter(Boolean).filter((type2) => {
|
|
79943
|
-
if (seen.has(type2)) return false;
|
|
79944
|
-
seen.add(type2);
|
|
79945
|
-
return true;
|
|
79946
|
-
});
|
|
79947
|
-
}
|
|
79948
|
-
function isTerminalSessionStatus(status) {
|
|
79949
|
-
return ["stopped", "failed", "terminated", "exited", "closed"].includes(status);
|
|
79950
|
-
}
|
|
79951
|
-
function isIdleSessionState3(state) {
|
|
79952
|
-
const status = readNonEmptyString(state?.status).toLowerCase();
|
|
79953
|
-
if (isTerminalSessionStatus(status)) return false;
|
|
79954
|
-
return status === "idle" || state?.activeChat?.status === "waiting_input";
|
|
79955
|
-
}
|
|
79956
|
-
function sessionStateLooksActive(state) {
|
|
79957
|
-
const status = readNonEmptyString(state?.status).toLowerCase();
|
|
79958
|
-
const chatStatus = readNonEmptyString(state?.activeChat?.status).toLowerCase();
|
|
79959
|
-
const active = /* @__PURE__ */ new Set(["generating", "streaming", "no_progress", "long_generating", "working", "starting", "waiting_approval"]);
|
|
79960
|
-
return active.has(status) || active.has(chatStatus);
|
|
79961
|
-
}
|
|
79962
|
-
function nodeHasActiveMeshWork(components, meshId, nodeId, currentSessionId) {
|
|
79963
|
-
if (nodeHasActiveAssignment(meshId, nodeId)) return true;
|
|
79964
|
-
return components.instanceManager.getByCategory("cli").some((inst) => {
|
|
79965
|
-
const state = inst.getState();
|
|
79966
|
-
const settings = state.settings || {};
|
|
79967
|
-
if (readNonEmptyString(settings.meshNodeFor) !== meshId) return false;
|
|
79968
|
-
const instNodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
79969
|
-
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
79970
|
-
const sessionId = readNonEmptyString(state.instanceId);
|
|
79971
|
-
if (currentSessionId && sessionIdsEquivalent(sessionId, currentSessionId) && isIdleSessionState3(state)) return false;
|
|
79972
|
-
return sessionStateLooksActive(state);
|
|
79973
|
-
});
|
|
79974
|
-
}
|
|
79975
|
-
function isLaunchableNode(node) {
|
|
79976
|
-
if (!node || node.status === "disabled" || node.status === "removed") return false;
|
|
79977
|
-
if (shouldDeferDispatchForBootstrap(node)) {
|
|
79978
|
-
return false;
|
|
79979
|
-
}
|
|
79980
|
-
return isMeshNodeHealthLaunchable(node);
|
|
79981
|
-
}
|
|
79982
|
-
function isLocalAutoLaunchNode(node) {
|
|
79983
|
-
const daemonId = readNonEmptyString(node?.daemonId);
|
|
79984
|
-
const machineId = readNonEmptyString(node?.machineId);
|
|
79985
|
-
const appConfig = loadConfig2();
|
|
79986
|
-
const localMachineId = readNonEmptyString(appConfig.machineId) || readNonEmptyString(appConfig.registeredMachineId);
|
|
79987
|
-
const daemonMatchesLocal = !daemonId || daemonIdsEquivalent(daemonId, localMachineId);
|
|
79988
|
-
const machineMatchesLocal = !machineId || daemonIdsEquivalent(machineId, localMachineId);
|
|
79989
|
-
if (node?.isLocalWorktree === true) {
|
|
79990
|
-
return daemonMatchesLocal && machineMatchesLocal;
|
|
79991
|
-
}
|
|
79992
|
-
if (daemonId || machineId) {
|
|
79993
|
-
return daemonMatchesLocal && machineMatchesLocal;
|
|
79994
|
-
}
|
|
79995
|
-
return true;
|
|
79996
|
-
}
|
|
79997
|
-
function isSessionActivelyGenerating(components, sessionId) {
|
|
79998
|
-
if (!sessionId) return false;
|
|
79999
|
-
const state = components.instanceManager?.getInstance?.(sessionId)?.getState?.();
|
|
80000
|
-
if (!state) return false;
|
|
80001
|
-
return sessionStateLooksActive(state);
|
|
80002
|
-
}
|
|
80003
|
-
function resolveSessionBusyVerdict(components, sessionId) {
|
|
80004
|
-
if (!sessionId) return "UNKNOWN";
|
|
80005
|
-
try {
|
|
80006
|
-
const instances = components.instanceManager?.getByCategory?.("cli") || [];
|
|
80007
|
-
const inst = instances.find((i) => {
|
|
80008
|
-
const sid = readNonEmptyString(i?.getState?.().instanceId);
|
|
80009
|
-
return sid && sessionIdsEquivalent(sid, sessionId);
|
|
80010
|
-
});
|
|
80011
|
-
if (!inst) return "UNKNOWN";
|
|
80012
|
-
const state = inst.getState?.();
|
|
80013
|
-
if (!state) return "UNKNOWN";
|
|
80014
|
-
return sessionStateLooksActive(state) ? "GENERATING" : "IDLE_CONFIRMED";
|
|
80015
|
-
} catch {
|
|
80016
|
-
return "UNKNOWN";
|
|
80017
|
-
}
|
|
80018
|
-
}
|
|
80019
|
-
function liveSessionCountForNode(components, meshId, nodeId) {
|
|
80020
|
-
const localInstances = components.instanceManager.getByCategory("cli").filter((inst) => {
|
|
80021
|
-
const state = inst.getState();
|
|
80022
|
-
const settings = state.settings || {};
|
|
80023
|
-
if (readNonEmptyString(settings.meshNodeFor) !== meshId) return false;
|
|
80024
|
-
const instNodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
80025
|
-
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
80026
|
-
const status = readNonEmptyString(state.status).toLowerCase();
|
|
80027
|
-
return !isTerminalSessionStatus(status);
|
|
80028
|
-
});
|
|
80029
|
-
let count = localInstances.length;
|
|
80030
|
-
const localSessionIds = localInstances.map((inst) => readNonEmptyString(inst.getState().instanceId)).filter(Boolean);
|
|
80031
|
-
for (const sid of inWindowAutoLaunchSessionIdsForNode(meshId, nodeId)) {
|
|
80032
|
-
if (!localSessionIds.some((local) => sessionIdsEquivalent(local, sid))) count += 1;
|
|
80033
|
-
}
|
|
80034
|
-
return count;
|
|
80035
|
-
}
|
|
80036
|
-
function nodeHasLiveSessionPendingClaim(components, meshId, nodeId, task, node) {
|
|
80037
|
-
if (inWindowAutoLaunchSessionIdsForNode(meshId, nodeId).length > 0) return true;
|
|
80038
|
-
const busySessionIds = new Set(
|
|
80039
|
-
getQueue(meshId, { status: ["assigned"] }).filter((task2) => daemonIdsEquivalent(task2.assignedNodeId, nodeId)).map((task2) => readNonEmptyString(task2.assignedSessionId)).filter(Boolean)
|
|
80040
|
-
);
|
|
80041
|
-
return components.instanceManager.getByCategory("cli").some((inst) => {
|
|
80042
|
-
const state = inst.getState();
|
|
80043
|
-
const settings = state.settings || {};
|
|
80044
|
-
if (readNonEmptyString(settings.meshNodeFor) !== meshId) return false;
|
|
80045
|
-
if (readNonEmptyString(settings.meshCoordinatorFor) === meshId) return false;
|
|
80046
|
-
const instNodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
80047
|
-
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
80048
|
-
const status = readNonEmptyString(state.status).toLowerCase();
|
|
80049
|
-
if (isTerminalSessionStatus(status)) return false;
|
|
80050
|
-
const sessionId = readNonEmptyString(state.instanceId);
|
|
80051
|
-
if (sessionId && busySessionIds.has(sessionId)) return false;
|
|
80052
|
-
const sessionProviderType = state.type || readNonEmptyString(settings.providerType);
|
|
80053
|
-
if (task.requiredTags?.length) {
|
|
80054
|
-
if (sessionProviderType && !nodeSatisfiesRequiredTags(task.requiredTags, buildMeshNodeCapabilityTags(node, sessionProviderType))) {
|
|
80055
|
-
return false;
|
|
80056
|
-
}
|
|
80057
|
-
}
|
|
80058
|
-
const allowance = allowedClassifiedDifficultiesForSession(node, resolveNodeCapabilitySlots(node, meshId), sessionProviderType, readSessionModel(state));
|
|
80059
|
-
if (!taskMeetsSessionDifficultyFloor(task, allowance)) return false;
|
|
80060
|
-
return true;
|
|
80061
|
-
});
|
|
80062
|
-
}
|
|
80063
|
-
var init_mesh_candidacy_predicates = __esm2({
|
|
80064
|
-
"src/mesh/mesh-candidacy-predicates.ts"() {
|
|
80065
|
-
"use strict";
|
|
80066
|
-
init_config();
|
|
80067
|
-
init_mesh_work_queue();
|
|
80068
|
-
init_dist();
|
|
80069
|
-
init_mesh_events_utils();
|
|
80070
|
-
init_mesh_node_identity();
|
|
80071
|
-
init_worktree_bootstrap_config();
|
|
80072
|
-
init_mesh_autolaunch_integrity();
|
|
80073
|
-
init_mesh_scheduling_fitness();
|
|
80074
|
-
init_mesh_node_slots();
|
|
80075
|
-
init_mesh_difficulty_floor();
|
|
80076
|
-
}
|
|
80077
|
-
});
|
|
80078
80136
|
function liveSessionsForNode(components, meshId, nodeId) {
|
|
80079
80137
|
try {
|
|
80080
80138
|
const instances = components.instanceManager?.getByCategory?.("cli") || [];
|
|
@@ -81202,7 +81260,7 @@ ${block2.text}`,
|
|
|
81202
81260
|
return void 0;
|
|
81203
81261
|
}
|
|
81204
81262
|
}
|
|
81205
|
-
function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType, routingDecision, quotaClaimTrace) {
|
|
81263
|
+
function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType, routingDecision, quotaClaimTrace, trigger = "queue_claim") {
|
|
81206
81264
|
const mesh = getMeshWithCache(components, meshId);
|
|
81207
81265
|
const node = mesh?.nodes.find((n) => meshNodeIdMatches(n, nodeId));
|
|
81208
81266
|
if (routingDecision?.source !== "autoLaunch") {
|
|
@@ -81213,16 +81271,9 @@ ${block2.text}`,
|
|
|
81213
81271
|
noteClaimDeferredForNode(meshId, nodeId);
|
|
81214
81272
|
return false;
|
|
81215
81273
|
}
|
|
81216
|
-
|
|
81217
|
-
if (quotaClaimTrace) quotaClaimTrace.evaluated += 1;
|
|
81218
|
-
if (quotaClaimBlock) {
|
|
81219
|
-
const observation = { nodeId, sessionId, providerType, block: quotaClaimBlock };
|
|
81220
|
-
logQuotaClaimBlockTransition(meshId, observation);
|
|
81221
|
-
quotaClaimTrace?.blocked.push(observation);
|
|
81274
|
+
if (evaluateQuotaClaimGateForAssignment({ meshId, nodeId, sessionId, providerType, trigger, node, mesh, providerLoader: components.providerLoader, quotaClaimTrace })) {
|
|
81222
81275
|
return false;
|
|
81223
81276
|
}
|
|
81224
|
-
clearQuotaClaimBlockState(meshId, nodeId, sessionId, providerType);
|
|
81225
|
-
if (quotaClaimTrace) quotaClaimTrace.clear += 1;
|
|
81226
81277
|
const inlineBootstrapNode = (() => {
|
|
81227
81278
|
try {
|
|
81228
81279
|
const inlineMesh = components.router?.getCachedInlineMesh?.(meshId);
|
|
@@ -81755,7 +81806,7 @@ ${block2.text}`,
|
|
|
81755
81806
|
if (shouldRedriveDeferredClaim(meshId, alNodeId, alSessionId, () => isWorkspaceAutoFastForwardInFlight(readNonEmptyString(
|
|
81756
81807
|
(Array.isArray(mesh?.nodes) ? mesh.nodes.find((n) => meshNodeIdMatches(n, alNodeId)) : void 0)?.workspace
|
|
81757
81808
|
)))) {
|
|
81758
|
-
if (tryAssignQueueTask(components, meshId, alNodeId, alSessionId, alProvider)) {
|
|
81809
|
+
if (tryAssignQueueTask(components, meshId, alNodeId, alSessionId, alProvider, void 0, void 0, "auto_launch")) {
|
|
81759
81810
|
clearClaimDeferralForNode(meshId, alNodeId);
|
|
81760
81811
|
recordAutoLaunchEvent(meshId, { phase: "completed", taskId: task.id, reason: "fast_forward_deferred_claim_redriven", nodeId: alNodeId, sessionId: alSessionId });
|
|
81761
81812
|
LOG2.info("MeshQueue", `Auto-launch re-drove the auto-fast-forward-deferred claim for task ${task.id} into session ${alSessionId} on node ${alNodeId} (mesh ${meshId})`);
|
|
@@ -82075,7 +82126,7 @@ ${block2.text}`,
|
|
|
82075
82126
|
executedSlot: slotDecision.slot,
|
|
82076
82127
|
demotionReason
|
|
82077
82128
|
});
|
|
82078
|
-
tryAssignQueueTask(components, meshId, nodeId, sessionId, effectiveProviderType, routingDecision);
|
|
82129
|
+
tryAssignQueueTask(components, meshId, nodeId, sessionId, effectiveProviderType, routingDecision, void 0, "auto_launch");
|
|
82079
82130
|
return true;
|
|
82080
82131
|
} catch (e) {
|
|
82081
82132
|
markAutoLaunch(meshId, task.id, { status: "failed", error: e?.message || String(e), nodeId });
|
|
@@ -82133,7 +82184,7 @@ ${block2.text}`,
|
|
|
82133
82184
|
if (instMeshId !== meshId) continue;
|
|
82134
82185
|
const nodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
82135
82186
|
if (!nodeId) continue;
|
|
82136
|
-
if (!
|
|
82187
|
+
if (!isIdleSessionState2(state)) {
|
|
82137
82188
|
const status = readNonEmptyString(state.status).toLowerCase();
|
|
82138
82189
|
skippedSessions.push({
|
|
82139
82190
|
nodeId,
|
|
@@ -82171,7 +82222,7 @@ ${block2.text}`,
|
|
|
82171
82222
|
}
|
|
82172
82223
|
const quotaClaimTrace = { blocked: [], evaluated: 0, clear: 0 };
|
|
82173
82224
|
const assignIdleCandidate = (candidate) => {
|
|
82174
|
-
const assigned = tryAssignQueueTask(components, meshId, candidate.nodeId, candidate.sessionId, candidate.providerType, void 0, quotaClaimTrace);
|
|
82225
|
+
const assigned = tryAssignQueueTask(components, meshId, candidate.nodeId, candidate.sessionId, candidate.providerType, void 0, quotaClaimTrace, "idle_claim_scan");
|
|
82175
82226
|
if (assigned && candidate.origin === "remote") {
|
|
82176
82227
|
try {
|
|
82177
82228
|
MeshRuntimeStore.getInstance().deleteRemoteIdleSession(meshId, candidate.nodeId, candidate.sessionId);
|
|
@@ -82251,7 +82302,7 @@ ${block2.text}`,
|
|
|
82251
82302
|
setImmediate(() => {
|
|
82252
82303
|
maybeAutoFastForwardIdleNode(components, args).finally(() => {
|
|
82253
82304
|
try {
|
|
82254
|
-
tryAssignQueueTask(components, args.meshId, args.nodeId, args.sessionId, args.providerType);
|
|
82305
|
+
tryAssignQueueTask(components, args.meshId, args.nodeId, args.sessionId, args.providerType, void 0, void 0, "idle_maintenance");
|
|
82255
82306
|
} catch (e) {
|
|
82256
82307
|
LOG2.warn("MeshQueue", `Failed to assign idle queue task after maintenance for ${args.nodeId}: ${e?.message || e}`);
|
|
82257
82308
|
}
|
|
@@ -82292,6 +82343,7 @@ ${block2.text}`,
|
|
|
82292
82343
|
init_mesh_node_slots();
|
|
82293
82344
|
init_mesh_daemon_slot_axis();
|
|
82294
82345
|
init_mesh_quota_routing();
|
|
82346
|
+
init_mesh_queue_claim_gate();
|
|
82295
82347
|
init_mesh_events_stale();
|
|
82296
82348
|
init_mesh_events_utils();
|
|
82297
82349
|
init_mesh_node_identity();
|
|
@@ -96335,6 +96387,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
96335
96387
|
const result = await execFileAsync8(spawn7.file, spawn7.args, {
|
|
96336
96388
|
cwd,
|
|
96337
96389
|
encoding: "utf8",
|
|
96390
|
+
windowsHide: true,
|
|
96338
96391
|
timeout,
|
|
96339
96392
|
maxBuffer: candidate.outputLimitBytes || REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
96340
96393
|
env: { ...process.env, CI: process.env.CI || "1", ...refineGateChildEnv(), ...candidate.env || {} },
|
|
@@ -96380,6 +96433,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
96380
96433
|
const result = await execFileAsync8(spawn7.file, spawn7.args, {
|
|
96381
96434
|
cwd,
|
|
96382
96435
|
encoding: "utf8",
|
|
96436
|
+
windowsHide: true,
|
|
96383
96437
|
timeout,
|
|
96384
96438
|
maxBuffer: candidate.outputLimitBytes || REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
96385
96439
|
env: { ...process.env, CI: process.env.CI || "1", ...refineGateChildEnv(), ...candidate.env || {} },
|
|
@@ -121734,6 +121788,100 @@ ${marker}`,
|
|
|
121734
121788
|
}
|
|
121735
121789
|
return out;
|
|
121736
121790
|
}
|
|
121791
|
+
var USER_RE = /^>\s+(\S.*)$/;
|
|
121792
|
+
var EMPTY_COMPOSER_RE = /^>\s*$/;
|
|
121793
|
+
var TOOL_RE = /^●\s+\S+/;
|
|
121794
|
+
var THOUGHT_RE = /^▸\s/;
|
|
121795
|
+
var RULE_RE = /^[─━═\-]{3,}\s*$/;
|
|
121796
|
+
var JSON_START_RE = /^\s*[{\[]/;
|
|
121797
|
+
var CHROME_RES = [
|
|
121798
|
+
RULE_RE,
|
|
121799
|
+
EMPTY_COMPOSER_RE,
|
|
121800
|
+
/^\s*\? for shortcuts/,
|
|
121801
|
+
/esc to cancel/i,
|
|
121802
|
+
/^Resume:\s+agy\b/i,
|
|
121803
|
+
/^Antigravity CLI\b/,
|
|
121804
|
+
/\(Google AI (?:Ultra|Pro|Free)\)/,
|
|
121805
|
+
/^\s*↑\/↓\s+Navigate/,
|
|
121806
|
+
/^Requesting permission for:/,
|
|
121807
|
+
/^Do you want to proceed\?/,
|
|
121808
|
+
/^Accept this file edit\?/,
|
|
121809
|
+
/^Allow (?:access to|creation of) this file\?/,
|
|
121810
|
+
/^Allow sandbox bypass/,
|
|
121811
|
+
/^Command\s*$/
|
|
121812
|
+
];
|
|
121813
|
+
function isChrome(line) {
|
|
121814
|
+
for (const re of CHROME_RES) {
|
|
121815
|
+
if (re.test(line)) return true;
|
|
121816
|
+
}
|
|
121817
|
+
return false;
|
|
121818
|
+
}
|
|
121819
|
+
function isIndented(line) {
|
|
121820
|
+
return /^\s+\S/.test(line);
|
|
121821
|
+
}
|
|
121822
|
+
function assistantMessage(content) {
|
|
121823
|
+
return {
|
|
121824
|
+
role: "assistant",
|
|
121825
|
+
kind: "standard",
|
|
121826
|
+
content,
|
|
121827
|
+
source: "assistant_text",
|
|
121828
|
+
userFacing: true,
|
|
121829
|
+
bubbleState: "final"
|
|
121830
|
+
};
|
|
121831
|
+
}
|
|
121832
|
+
function extractAntigravityScreenAssistantMessages(screenText) {
|
|
121833
|
+
const lines = String(screenText || "").split(/\r?\n/).map((l) => l.replace(/\s+$/, ""));
|
|
121834
|
+
const messages = [];
|
|
121835
|
+
let afterTool = false;
|
|
121836
|
+
let inUser = false;
|
|
121837
|
+
let inThought = false;
|
|
121838
|
+
let seenRole = false;
|
|
121839
|
+
const pushOrAppendAssistant = (text) => {
|
|
121840
|
+
const last = messages[messages.length - 1];
|
|
121841
|
+
if (last && last.role === "assistant" && typeof last.content === "string") {
|
|
121842
|
+
last.content = last.content ? `${last.content}
|
|
121843
|
+
${text}` : text;
|
|
121844
|
+
} else {
|
|
121845
|
+
messages.push(assistantMessage(text));
|
|
121846
|
+
}
|
|
121847
|
+
};
|
|
121848
|
+
for (const line of lines) {
|
|
121849
|
+
if (line.trim() === "") continue;
|
|
121850
|
+
if (isChrome(line)) continue;
|
|
121851
|
+
if (USER_RE.test(line)) {
|
|
121852
|
+
inUser = true;
|
|
121853
|
+
inThought = false;
|
|
121854
|
+
afterTool = false;
|
|
121855
|
+
seenRole = true;
|
|
121856
|
+
continue;
|
|
121857
|
+
}
|
|
121858
|
+
if (TOOL_RE.test(line)) {
|
|
121859
|
+
inUser = false;
|
|
121860
|
+
inThought = false;
|
|
121861
|
+
afterTool = true;
|
|
121862
|
+
seenRole = true;
|
|
121863
|
+
continue;
|
|
121864
|
+
}
|
|
121865
|
+
if (THOUGHT_RE.test(line)) {
|
|
121866
|
+
inUser = false;
|
|
121867
|
+
inThought = true;
|
|
121868
|
+
seenRole = true;
|
|
121869
|
+
continue;
|
|
121870
|
+
}
|
|
121871
|
+
if (!seenRole) continue;
|
|
121872
|
+
if (inUser && isIndented(line)) continue;
|
|
121873
|
+
if (inThought && isIndented(line) && !JSON_START_RE.test(line) && !afterTool) continue;
|
|
121874
|
+
if (afterTool || inThought && JSON_START_RE.test(line)) {
|
|
121875
|
+
const text = line.replace(/^\s+/, "");
|
|
121876
|
+
if (text) {
|
|
121877
|
+
pushOrAppendAssistant(text);
|
|
121878
|
+
inThought = false;
|
|
121879
|
+
inUser = false;
|
|
121880
|
+
}
|
|
121881
|
+
}
|
|
121882
|
+
}
|
|
121883
|
+
return messages.filter((m) => typeof m.content === "string" && m.content.trim().length > 0);
|
|
121884
|
+
}
|
|
121737
121885
|
var fs40 = __toESM2(require("fs"));
|
|
121738
121886
|
var import_node_crypto6 = require("crypto");
|
|
121739
121887
|
init_provider_cli_shared();
|
|
@@ -122189,7 +122337,7 @@ ${marker}`,
|
|
|
122189
122337
|
const bg = this.detectBackgroundTask();
|
|
122190
122338
|
return {
|
|
122191
122339
|
...status,
|
|
122192
|
-
messages: this.
|
|
122340
|
+
messages: this.readScreenAssistantMessages(),
|
|
122193
122341
|
...this.providerSessionId ? { providerSessionId: this.providerSessionId } : {},
|
|
122194
122342
|
backgroundTaskSupport: bg.support ?? "unknown",
|
|
122195
122343
|
...bg.active ? { backgroundTaskActive: true, backgroundTaskCount: bg.count, backgroundTaskIds: bg.ids } : {}
|
|
@@ -122730,7 +122878,7 @@ ${marker}`,
|
|
|
122730
122878
|
} catch {
|
|
122731
122879
|
}
|
|
122732
122880
|
} else {
|
|
122733
|
-
messages = this.
|
|
122881
|
+
messages = this.readScreenAssistantMessages();
|
|
122734
122882
|
}
|
|
122735
122883
|
return {
|
|
122736
122884
|
cliType: this.cliType,
|
|
@@ -122943,6 +123091,29 @@ ${marker}`,
|
|
|
122943
123091
|
const match = clean2.match(/(?:gpt-|o\d|codex-)[^\n·]*·[^\n·]*·\s*([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i);
|
|
122944
123092
|
return match?.[1] || this.providerSessionId;
|
|
122945
123093
|
}
|
|
123094
|
+
/**
|
|
123095
|
+
* PTY-scrape assistant bubbles for the live parse / spec-debug snapshot.
|
|
123096
|
+
*
|
|
123097
|
+
* Native-history remains the completion-path authority
|
|
123098
|
+
* (`chatMessagesOwnedExternally`). This scrape is the fail-closed
|
|
123099
|
+
* fallback the gate already consults via getScriptParsedStatus().messages
|
|
123100
|
+
* when the on-disk transcript has no final standard assistant — which is
|
|
123101
|
+
* the antigravity layout where the JSON report is on screen under
|
|
123102
|
+
* `● Bash(...)` but never lands as a step_type-15 field-20 answer.
|
|
123103
|
+
*/
|
|
123104
|
+
readScreenAssistantMessages() {
|
|
123105
|
+
if (this.cliType === "claude-cli") return this.readClaudeScreenAssistantMessages();
|
|
123106
|
+
if (this.cliType === "antigravity-cli") {
|
|
123107
|
+
let screenText = "";
|
|
123108
|
+
try {
|
|
123109
|
+
screenText = this.driver.snapshot();
|
|
123110
|
+
} catch {
|
|
123111
|
+
return [];
|
|
123112
|
+
}
|
|
123113
|
+
return extractAntigravityScreenAssistantMessages(screenText);
|
|
123114
|
+
}
|
|
123115
|
+
return [];
|
|
123116
|
+
}
|
|
122946
123117
|
readClaudeScreenAssistantMessages() {
|
|
122947
123118
|
if (this.cliType !== "claude-cli") return [];
|
|
122948
123119
|
let screenText = "";
|
|
@@ -123353,7 +123524,7 @@ ${marker}`,
|
|
|
123353
123524
|
} catch (e) {
|
|
123354
123525
|
}
|
|
123355
123526
|
} else {
|
|
123356
|
-
messages = this.
|
|
123527
|
+
messages = this.readScreenAssistantMessages();
|
|
123357
123528
|
}
|
|
123358
123529
|
const latestState = this.latestState;
|
|
123359
123530
|
const latestModal = this.latestModal;
|
|
@@ -131552,7 +131723,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
131552
131723
|
const { shouldDeferDispatchForBootstrap: shouldDeferDispatchForBootstrap2 } = await Promise.resolve().then(() => (init_worktree_bootstrap_config(), worktree_bootstrap_config_exports));
|
|
131553
131724
|
if (shouldDeferDispatchForBootstrap2(nodeObj)) {
|
|
131554
131725
|
const dispatchSessionState = dispatchSessionId ? ctx.deps.instanceManager?.getInstance?.(dispatchSessionId)?.getState?.() : void 0;
|
|
131555
|
-
const sessionConfirmedReady = !!dispatchSessionState &&
|
|
131726
|
+
const sessionConfirmedReady = !!dispatchSessionState && isIdleSessionState2(dispatchSessionState);
|
|
131556
131727
|
if (!sessionConfirmedReady) {
|
|
131557
131728
|
return {
|
|
131558
131729
|
success: false,
|
|
@@ -135003,7 +135174,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
135003
135174
|
}
|
|
135004
135175
|
async function execQuiet(command, options = {}) {
|
|
135005
135176
|
return new Promise((resolve32) => {
|
|
135006
|
-
(0, import_child_process12.exec)(command, options, (error48, stdout) => {
|
|
135177
|
+
(0, import_child_process12.exec)(command, { windowsHide: true, ...options }, (error48, stdout) => {
|
|
135007
135178
|
if (error48) return resolve32("");
|
|
135008
135179
|
resolve32(stdout.toString());
|
|
135009
135180
|
});
|
|
@@ -147045,6 +147216,7 @@ async (params) => {
|
|
|
147045
147216
|
cwd: providerDir,
|
|
147046
147217
|
stdio: ["pipe", "pipe", "pipe"],
|
|
147047
147218
|
shell: spawn7.shell ?? false,
|
|
147219
|
+
windowsHide: true,
|
|
147048
147220
|
env: { ...process.env, ...spawn7.env || {} }
|
|
147049
147221
|
});
|
|
147050
147222
|
ctx.autoImplProcess = child2;
|
|
@@ -147221,6 +147393,7 @@ async (params) => {
|
|
|
147221
147393
|
child = spawnFn(isWin ? "cmd.exe" : "sh", [isWin ? "/c" : "-c", shellCmd], {
|
|
147222
147394
|
cwd: providerDir,
|
|
147223
147395
|
shell: false,
|
|
147396
|
+
windowsHide: true,
|
|
147224
147397
|
timeout: 9e5,
|
|
147225
147398
|
stdio: ["pipe", "pipe", "pipe"],
|
|
147226
147399
|
env: {
|
|
@@ -148373,6 +148546,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
148373
148546
|
try {
|
|
148374
148547
|
const child = spawnFn(spawn7.command, [...spawn7.args || []], {
|
|
148375
148548
|
shell: spawn7.shell ?? false,
|
|
148549
|
+
windowsHide: true,
|
|
148376
148550
|
timeout: 5e3,
|
|
148377
148551
|
stdio: ["pipe", "pipe", "pipe"]
|
|
148378
148552
|
});
|
|
@@ -148888,6 +149062,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
148888
149062
|
const args = [...spawn7.args || [], message];
|
|
148889
149063
|
const child = spawnFn(spawn7.command, args, {
|
|
148890
149064
|
shell: spawn7.shell ?? false,
|
|
149065
|
+
windowsHide: true,
|
|
148891
149066
|
timeout,
|
|
148892
149067
|
stdio: ["pipe", "pipe", "pipe"],
|
|
148893
149068
|
env: { ...process.env, ...spawn7.env || {} }
|
|
@@ -150267,6 +150442,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
150267
150442
|
try {
|
|
150268
150443
|
const { stdout } = await execAsync4(`"${ide.cliCommand}" --list-extensions`, {
|
|
150269
150444
|
encoding: "utf-8",
|
|
150445
|
+
windowsHide: true,
|
|
150270
150446
|
timeout: 15e3
|
|
150271
150447
|
});
|
|
150272
150448
|
const installed = stdout.trim().split("\n").map((e) => e.trim().toLowerCase());
|