@adhdev/daemon-core 0.9.82-rc.420 → 0.9.82-rc.422
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +149 -41
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +148 -41
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-event-forwarding.d.ts +22 -0
- package/dist/providers/cli-provider-instance.d.ts +11 -0
- package/dist/providers/provider-instance-manager.d.ts +18 -3
- package/package.json +2 -2
- package/src/commands/cli-manager.ts +10 -2
- package/src/index.ts +1 -1
- package/src/mesh/mesh-event-forwarding.ts +95 -1
- package/src/mesh/mesh-queue-assignment.ts +55 -0
- package/src/mesh/mesh-reconcile-loop.ts +11 -3
- package/src/providers/cli-provider-instance.ts +33 -0
- package/src/providers/provider-instance-manager.ts +54 -13
package/dist/index.d.ts
CHANGED
|
@@ -68,7 +68,7 @@ export type { MeshSchedulingRuntime, MeshNodeSchedulingRuntime, MeshNodeProvider
|
|
|
68
68
|
export { buildMeshHostRequiredFailure, createDefaultMeshHostMetadata, isMeshHostOwner, normalizeMeshDaemonRole, requireMeshHostQueueOwner, resolveMeshHostStatus } from './mesh/mesh-host-ownership.js';
|
|
69
69
|
export { triggerMeshQueue, drainPendingMeshCoordinatorEvents, getPendingMeshCoordinatorEvents, clearPendingMeshCoordinatorEvents, queuePendingMeshCoordinatorEvent, reconcileDirectDispatchCompletionFromTranscript } from './mesh/mesh-events.js';
|
|
70
70
|
export type { PendingMeshCoordinatorEvent } from './mesh/mesh-events.js';
|
|
71
|
-
export { resolveMeshSurfacedSessionPreview, readMeshCompletionSummary } from './mesh/mesh-events-utils.js';
|
|
71
|
+
export { resolveMeshSurfacedSessionPreview, readMeshCompletionSummary, isWeakCompletionEvidence } from './mesh/mesh-events-utils.js';
|
|
72
72
|
export { resolveDeliveryDecision, createSessionDelivery, updateSessionDeliveryStatus, getActiveSessionDeliveries, markSessionDeliveriesTerminal, recordCompletionConflict, getRecentCompletionConflicts } from './mesh/mesh-delivery-policy.js';
|
|
73
73
|
export type { MeshSessionDeliveryStatus, MeshSessionDeliveryKind, MeshDeliveryDecision, MeshDeliveryPolicyResult, SessionDeliveryRecord } from './mesh/mesh-delivery-policy.js';
|
|
74
74
|
export { P2pRelayFailureError, buildP2pRelayFailurePayload, classifyP2pRelayFailure, isP2pRelayTransportFailure, } from './mesh/p2p-relay-failure.js';
|
package/dist/index.js
CHANGED
|
@@ -389,10 +389,10 @@ function readInjected(value) {
|
|
|
389
389
|
}
|
|
390
390
|
function getDaemonBuildInfo() {
|
|
391
391
|
if (cached) return cached;
|
|
392
|
-
const commit = readInjected(true ? "
|
|
393
|
-
const commitShort = readInjected(true ? "
|
|
394
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
395
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
392
|
+
const commit = readInjected(true ? "308e099c65d2de2491f3db46913f9ced6aa3992c" : void 0) ?? "unknown";
|
|
393
|
+
const commitShort = readInjected(true ? "308e099c" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
394
|
+
const version = readInjected(true ? "0.9.82-rc.422" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
395
|
+
const builtAt = readInjected(true ? "2026-06-29T05:26:31.350Z" : void 0);
|
|
396
396
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
397
397
|
return cached;
|
|
398
398
|
}
|
|
@@ -3686,21 +3686,6 @@ var init_async_batch_writer = __esm({
|
|
|
3686
3686
|
});
|
|
3687
3687
|
|
|
3688
3688
|
// src/logging/logger.ts
|
|
3689
|
-
var logger_exports = {};
|
|
3690
|
-
__export(logger_exports, {
|
|
3691
|
-
LOG: () => LOG,
|
|
3692
|
-
LOG_DIR_PATH: () => LOG_DIR_PATH,
|
|
3693
|
-
LOG_PATH: () => LOG_PATH,
|
|
3694
|
-
daemonLog: () => daemonLog,
|
|
3695
|
-
getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
|
|
3696
|
-
getDaemonLogDir: () => getDaemonLogDir,
|
|
3697
|
-
getLogBufferSize: () => getLogBufferSize,
|
|
3698
|
-
getLogLevel: () => getLogLevel,
|
|
3699
|
-
getLogPath: () => getLogPath,
|
|
3700
|
-
getRecentLogs: () => getRecentLogs,
|
|
3701
|
-
installGlobalInterceptor: () => installGlobalInterceptor,
|
|
3702
|
-
setLogLevel: () => setLogLevel
|
|
3703
|
-
});
|
|
3704
3689
|
function setLogLevel(level) {
|
|
3705
3690
|
currentLevel = level;
|
|
3706
3691
|
daemonLog("Logger", `Log level set to: ${level}`, "info");
|
|
@@ -3772,9 +3757,6 @@ function getRecentLogs(count = 50, minLevel = "info") {
|
|
|
3772
3757
|
const filtered = ringBuffer.filter((e) => LEVEL_NUM[e.level] >= minNum);
|
|
3773
3758
|
return filtered.slice(-count);
|
|
3774
3759
|
}
|
|
3775
|
-
function getLogBufferSize() {
|
|
3776
|
-
return ringBuffer.length;
|
|
3777
|
-
}
|
|
3778
3760
|
function ts() {
|
|
3779
3761
|
return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
3780
3762
|
}
|
|
@@ -3854,10 +3836,7 @@ function installGlobalInterceptor() {
|
|
|
3854
3836
|
writeToFile(`Log file: ${currentLogFile}`);
|
|
3855
3837
|
writeToFile(`Log level: ${currentLevel}`);
|
|
3856
3838
|
}
|
|
3857
|
-
|
|
3858
|
-
return currentLogFile;
|
|
3859
|
-
}
|
|
3860
|
-
var fs4, path9, os3, LEVEL_NUM, LEVEL_LABEL, currentLevel, ADHDEV_HOME, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH, LOG_DIR_PATH;
|
|
3839
|
+
var fs4, path9, os3, LEVEL_NUM, LEVEL_LABEL, currentLevel, ADHDEV_HOME, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH;
|
|
3861
3840
|
var init_logger = __esm({
|
|
3862
3841
|
"src/logging/logger.ts"() {
|
|
3863
3842
|
"use strict";
|
|
@@ -3919,7 +3898,6 @@ var init_logger = __esm({
|
|
|
3919
3898
|
};
|
|
3920
3899
|
interceptorInstalled = false;
|
|
3921
3900
|
LOG_PATH = path9.join(LOG_DIR, `daemon-${getDateStr()}.log`);
|
|
3922
|
-
LOG_DIR_PATH = LOG_DIR;
|
|
3923
3901
|
}
|
|
3924
3902
|
});
|
|
3925
3903
|
|
|
@@ -12528,6 +12506,23 @@ function liveSessionCountForNode(components, meshId, nodeId) {
|
|
|
12528
12506
|
return !isTerminalSessionStatus(status);
|
|
12529
12507
|
}).length;
|
|
12530
12508
|
}
|
|
12509
|
+
function nodeHasLiveSessionPendingClaim(components, meshId, nodeId) {
|
|
12510
|
+
const busySessionIds = new Set(
|
|
12511
|
+
getQueue(meshId, { status: ["assigned"] }).filter((task) => daemonIdsEquivalent(task.assignedNodeId, nodeId)).map((task) => readNonEmptyString2(task.assignedSessionId)).filter(Boolean)
|
|
12512
|
+
);
|
|
12513
|
+
return components.instanceManager.getByCategory("cli").some((inst) => {
|
|
12514
|
+
const state = inst.getState();
|
|
12515
|
+
const settings = state.settings || {};
|
|
12516
|
+
if (readNonEmptyString2(settings.meshNodeFor) !== meshId) return false;
|
|
12517
|
+
const instNodeId = readNonEmptyString2(settings.meshNodeId) || readNonEmptyString2(settings.nodeId);
|
|
12518
|
+
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
12519
|
+
const status = readNonEmptyString2(state.status).toLowerCase();
|
|
12520
|
+
if (isTerminalSessionStatus(status)) return false;
|
|
12521
|
+
const sessionId = readNonEmptyString2(state.instanceId);
|
|
12522
|
+
if (sessionId && busySessionIds.has(sessionId)) return false;
|
|
12523
|
+
return true;
|
|
12524
|
+
});
|
|
12525
|
+
}
|
|
12531
12526
|
function recordAutoLaunchEvent(meshId, args) {
|
|
12532
12527
|
const dedupKey = `${meshId}:${args.taskId}`;
|
|
12533
12528
|
const currentSig = `${args.phase}|${args.reason || ""}`;
|
|
@@ -12713,6 +12708,10 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
|
|
|
12713
12708
|
sweepExpiredCooldowns();
|
|
12714
12709
|
continue;
|
|
12715
12710
|
}
|
|
12711
|
+
if (nodeHasLiveSessionPendingClaim(components, meshId, nodeId)) {
|
|
12712
|
+
markAutoLaunch(meshId, task.id, { status: "skipped", reason: "node_has_live_session_pending_claim", nodeId });
|
|
12713
|
+
continue;
|
|
12714
|
+
}
|
|
12716
12715
|
if (!isTaskReadonly(task) && nodeHasActiveAssignment(meshId, nodeId)) {
|
|
12717
12716
|
markAutoLaunch(meshId, task.id, { status: "skipped", reason: "node_has_active_assignment", nodeId });
|
|
12718
12717
|
continue;
|
|
@@ -16558,6 +16557,62 @@ function ackUnresolvedDelegateForwardByFingerprint(coordinatorDaemonId, eventNam
|
|
|
16558
16557
|
);
|
|
16559
16558
|
if (match) ackUnresolvedDelegateForward(match.id);
|
|
16560
16559
|
}
|
|
16560
|
+
function flushPendingForMeshIdleCoordinators(components, meshId) {
|
|
16561
|
+
try {
|
|
16562
|
+
const store = MeshRuntimeStore.getInstance();
|
|
16563
|
+
if (store.pendingEventCount(meshId) === 0) return;
|
|
16564
|
+
} catch {
|
|
16565
|
+
}
|
|
16566
|
+
const idleCoordinators = [];
|
|
16567
|
+
try {
|
|
16568
|
+
for (const inst of components.instanceManager.getByCategory("cli")) {
|
|
16569
|
+
const state = inst.getState();
|
|
16570
|
+
const settings = state.settings && typeof state.settings === "object" ? state.settings : {};
|
|
16571
|
+
if (readNonEmptyString2(settings.meshCoordinatorFor) !== meshId) continue;
|
|
16572
|
+
const status = readNonEmptyString2(state.status).toLowerCase();
|
|
16573
|
+
const modalParked = typeof inst.isModalParked === "function" ? inst.isModalParked() === true : status === "waiting_choice" || status === "waiting_approval";
|
|
16574
|
+
if (status === "idle" && !modalParked) {
|
|
16575
|
+
idleCoordinators.push({ instance: inst, sessionId: readNonEmptyString2(state.instanceId) });
|
|
16576
|
+
}
|
|
16577
|
+
}
|
|
16578
|
+
} catch {
|
|
16579
|
+
return;
|
|
16580
|
+
}
|
|
16581
|
+
if (idleCoordinators.length === 0) return;
|
|
16582
|
+
const drainDaemonIds = resolveCoordinatorDrainDaemonIds(components);
|
|
16583
|
+
let pendingEvents;
|
|
16584
|
+
try {
|
|
16585
|
+
pendingEvents = drainPendingMeshCoordinatorEvents(meshId, drainDaemonIds.length > 0 ? drainDaemonIds : void 0);
|
|
16586
|
+
} catch (e) {
|
|
16587
|
+
LOG.warn("MeshEvents", `Event-driven coordinator drain failed for mesh ${meshId}: ${e?.message || e}`);
|
|
16588
|
+
return;
|
|
16589
|
+
}
|
|
16590
|
+
if (pendingEvents.length === 0) return;
|
|
16591
|
+
let delivered = 0;
|
|
16592
|
+
for (const pending of pendingEvents) {
|
|
16593
|
+
const wantSession = readNonEmptyString2(pending.targetCoordinatorSessionId);
|
|
16594
|
+
const targets = wantSession ? idleCoordinators.filter((c) => c.sessionId === wantSession) : idleCoordinators;
|
|
16595
|
+
if (targets.length === 0 || !pending.coordinatorMessage) {
|
|
16596
|
+
try {
|
|
16597
|
+
queuePendingMeshCoordinatorEvent(pending);
|
|
16598
|
+
} catch {
|
|
16599
|
+
}
|
|
16600
|
+
continue;
|
|
16601
|
+
}
|
|
16602
|
+
const message = pending.coordinatorMessage;
|
|
16603
|
+
const force = shouldForceInjectMeshEvent(pending.event);
|
|
16604
|
+
for (const c of targets) {
|
|
16605
|
+
c.instance.onEvent("send_message", {
|
|
16606
|
+
input: { text: message, textFallback: message },
|
|
16607
|
+
...force ? { force: true } : {}
|
|
16608
|
+
});
|
|
16609
|
+
delivered++;
|
|
16610
|
+
}
|
|
16611
|
+
}
|
|
16612
|
+
if (delivered > 0) {
|
|
16613
|
+
LOG.info("MeshEvents", `Event-driven drain delivered ${delivered} pending event(s) to ${idleCoordinators.length} idle coordinator(s) for mesh ${meshId}`);
|
|
16614
|
+
}
|
|
16615
|
+
}
|
|
16561
16616
|
function setupMeshEventForwarding(components) {
|
|
16562
16617
|
components.instanceManager.onEvent((event) => {
|
|
16563
16618
|
if (event.event === "agent:ready" || event.event === "agent:generating_completed") {
|
|
@@ -16629,6 +16684,7 @@ function setupMeshEventForwarding(components) {
|
|
|
16629
16684
|
event: event.event,
|
|
16630
16685
|
metadataEvent: event
|
|
16631
16686
|
});
|
|
16687
|
+
flushPendingForMeshIdleCoordinators(components, routing.meshId);
|
|
16632
16688
|
});
|
|
16633
16689
|
}
|
|
16634
16690
|
var REMOTE_IDLE_SESSION_TTL_MS, meshByWorkspaceCache, MESH_WORKSPACE_CACHE_TTL_MS, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, RECONCILED_COMPLETION_SOURCES, coordinatorForwardLanes;
|
|
@@ -16749,7 +16805,7 @@ function findLiveCoordinators(components) {
|
|
|
16749
16805
|
const meshId = readNonEmptyString2(settings.meshCoordinatorFor);
|
|
16750
16806
|
if (!meshId) continue;
|
|
16751
16807
|
const status = readNonEmptyString2(state.status).toLowerCase();
|
|
16752
|
-
const modalParked = status === "waiting_choice" || status === "waiting_approval";
|
|
16808
|
+
const modalParked = typeof inst.isModalParked === "function" ? inst.isModalParked() === true : status === "waiting_choice" || status === "waiting_approval";
|
|
16753
16809
|
const sessionId = readNonEmptyString2(state.instanceId);
|
|
16754
16810
|
const stateKey = `${meshId}::${sessionId || "?"}`;
|
|
16755
16811
|
const prevParked = coordinatorModalParkState.get(stateKey);
|
|
@@ -23482,6 +23538,7 @@ __export(index_exports, {
|
|
|
23482
23538
|
isSetupComplete: () => isSetupComplete,
|
|
23483
23539
|
isTaskReadonly: () => isTaskReadonly,
|
|
23484
23540
|
isUserFacingChatMessage: () => isUserFacingChatMessage,
|
|
23541
|
+
isWeakCompletionEvidence: () => isWeakCompletionEvidence,
|
|
23485
23542
|
killIdeProcess: () => killIdeProcess,
|
|
23486
23543
|
launchIDE: () => launchIDE,
|
|
23487
23544
|
launchWithCdp: () => launchWithCdp,
|
|
@@ -41032,10 +41089,27 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
41032
41089
|
return null;
|
|
41033
41090
|
}
|
|
41034
41091
|
if (adapterStatus.status === "waiting_approval" && (!this.autoApproveEffectivelyActive(adapterStatus.status) || this.autoApproveMaskStalled())) {
|
|
41092
|
+
if (this.isTransientToolConsent()) {
|
|
41093
|
+
return null;
|
|
41094
|
+
}
|
|
41035
41095
|
return "waiting_approval";
|
|
41036
41096
|
}
|
|
41037
41097
|
return null;
|
|
41038
41098
|
}
|
|
41099
|
+
/**
|
|
41100
|
+
* NOTIF-HELD-DRAIN: true when this `waiting_approval` is a routine, transient tool-consent
|
|
41101
|
+
* of an autonomously-progressing mesh session rather than a genuine human-await modal —
|
|
41102
|
+
* i.e. it is a mesh coordinator/worker session, a turn is actively in flight
|
|
41103
|
+
* (hasAdapterPendingResponse), and no human is attending it by hand. Such a consent is
|
|
41104
|
+
* driven to resolution by the harness/operator as part of the in-flight turn, so holding
|
|
41105
|
+
* the mesh's completion events behind it (modal_parked) is the false-positive that stalls
|
|
41106
|
+
* delivery. Narrow by design: manual attendance or a non-progressing session falls through
|
|
41107
|
+
* to the genuine-modal classification.
|
|
41108
|
+
*/
|
|
41109
|
+
isTransientToolConsent(now = Date.now()) {
|
|
41110
|
+
const isAutonomousMeshSession = this.isMeshWorkerSession() || !!this.settings.meshCoordinatorFor;
|
|
41111
|
+
return isAutonomousMeshSession && this.hasAdapterPendingResponse() && !this.manualAttendance.isAttended(now);
|
|
41112
|
+
}
|
|
41039
41113
|
/** True when this session is parked on a modal awaiting a human answer. */
|
|
41040
41114
|
isModalParked() {
|
|
41041
41115
|
return this.resolveModalParkStatus() !== null;
|
|
@@ -44911,8 +44985,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44911
44985
|
const meshContext = args?.meshContext;
|
|
44912
44986
|
if (meshContext && typeof meshContext === "object" && typeof meshContext.meshId === "string" && meshContext.meshId) {
|
|
44913
44987
|
const targetInstanceId = key2;
|
|
44988
|
+
let stampResult;
|
|
44914
44989
|
try {
|
|
44915
|
-
this.deps.getInstanceManager()?.attachMeshAssignmentToInstance(targetInstanceId, {
|
|
44990
|
+
stampResult = this.deps.getInstanceManager()?.attachMeshAssignmentToInstance(targetInstanceId, {
|
|
44916
44991
|
meshId: meshContext.meshId,
|
|
44917
44992
|
...typeof meshContext.nodeId === "string" && meshContext.nodeId ? { nodeId: meshContext.nodeId } : {},
|
|
44918
44993
|
...typeof meshContext.taskId === "string" && meshContext.taskId ? { taskId: meshContext.taskId } : {},
|
|
@@ -44920,6 +44995,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44920
44995
|
});
|
|
44921
44996
|
} catch {
|
|
44922
44997
|
}
|
|
44998
|
+
if (stampResult && stampResult.stamped === false && stampResult.reason === "task_already_stamped_on_live_instance") {
|
|
44999
|
+
throw new Error(`Refusing duplicate mesh dispatch: task ${meshContext.taskId} is already being worked by a live session on this daemon`);
|
|
45000
|
+
}
|
|
44923
45001
|
}
|
|
44924
45002
|
const input = normalizeInputEnvelope(args?.input ? { input: args.input } : args);
|
|
44925
45003
|
const provider = this.providerLoader.resolve(agentType) || this.providerLoader.getMeta(agentType);
|
|
@@ -58527,25 +58605,54 @@ var ProviderInstanceManager = class {
|
|
|
58527
58605
|
}
|
|
58528
58606
|
/** Stamp a mesh assignment on a single instance (used by mesh_send_task
|
|
58529
58607
|
* --direct so the worker's completion event has a coordinator routing
|
|
58530
|
-
* marker in state.settings). Returns true
|
|
58531
|
-
*
|
|
58608
|
+
* marker in state.settings). Returns `{ stamped: true }` when the stamp was
|
|
58609
|
+
* applied, or `{ stamped: false, reason }` when it was refused — the instance
|
|
58610
|
+
* was missing / has no attach method, or the DOUBLE-DISPATCH idempotence guard
|
|
58611
|
+
* fired (the same task is already running on another live session here). */
|
|
58532
58612
|
attachMeshAssignmentToInstance(instanceId, assignment) {
|
|
58533
58613
|
const inst = this.instances.get(instanceId);
|
|
58534
58614
|
if (!inst || typeof inst.attachMeshAssignment !== "function") {
|
|
58535
|
-
|
|
58536
|
-
|
|
58537
|
-
|
|
58538
|
-
|
|
58615
|
+
LOG.warn("MeshDispatch", `attachMeshAssignment skipped: instance ${instanceId} ${inst ? "has no attach method" : "not found"}`);
|
|
58616
|
+
return { stamped: false, reason: inst ? "instance_has_no_attach_method" : "instance_not_found" };
|
|
58617
|
+
}
|
|
58618
|
+
if (assignment.taskId) {
|
|
58619
|
+
const conflict = this.findLiveWorkingTaskHolder(assignment.meshId, assignment.taskId, instanceId);
|
|
58620
|
+
if (conflict) {
|
|
58621
|
+
LOG.warn("MeshDispatch", `attachMeshAssignment refused: task ${assignment.taskId} (mesh ${assignment.meshId}) is already being worked by live session ${conflict} \u2014 skipping duplicate stamp on ${instanceId}`);
|
|
58622
|
+
return { stamped: false, reason: "task_already_stamped_on_live_instance" };
|
|
58539
58623
|
}
|
|
58540
|
-
return false;
|
|
58541
58624
|
}
|
|
58542
58625
|
inst.attachMeshAssignment(assignment);
|
|
58543
|
-
|
|
58544
|
-
|
|
58545
|
-
|
|
58546
|
-
|
|
58626
|
+
LOG.info("MeshDispatch", `stamped mesh assignment on ${instanceId}: mesh=${assignment.meshId} node=${assignment.nodeId || ""} task=${assignment.taskId || ""} coordinator=${assignment.coordinatorDaemonId || ""}`);
|
|
58627
|
+
return { stamped: true };
|
|
58628
|
+
}
|
|
58629
|
+
/**
|
|
58630
|
+
* DOUBLE-DISPATCH support: the id of another LIVE, actively-working instance that already
|
|
58631
|
+
* holds (meshId, taskId), or null. "Live working" = stamped with this exact mesh+task AND
|
|
58632
|
+
* currently mid-turn / booting toward it (generating / waiting on approval-or-choice /
|
|
58633
|
+
* starting) — NOT idle, stopped, or errored. A stale/dead/idle holder is deliberately
|
|
58634
|
+
* ignored so a legitimate re-dispatch (e.g. after a dispatch failure) is never blocked.
|
|
58635
|
+
* The instance being stamped (excludeInstanceId) is skipped so re-stamping the same
|
|
58636
|
+
* session stays idempotent. O(n) over instances — the count is small.
|
|
58637
|
+
*/
|
|
58638
|
+
findLiveWorkingTaskHolder(meshId, taskId, excludeInstanceId) {
|
|
58639
|
+
const working = /* @__PURE__ */ new Set(["generating", "waiting_approval", "waiting_choice", "starting", "streaming", "working", "no_progress", "long_generating"]);
|
|
58640
|
+
for (const [id, inst] of this.instances) {
|
|
58641
|
+
if (id === excludeInstanceId) continue;
|
|
58642
|
+
let state;
|
|
58643
|
+
try {
|
|
58644
|
+
state = inst.getState();
|
|
58645
|
+
} catch {
|
|
58646
|
+
continue;
|
|
58647
|
+
}
|
|
58648
|
+
const settings = state.settings || {};
|
|
58649
|
+
if (settings.meshNodeFor !== meshId) continue;
|
|
58650
|
+
if (settings.meshActiveTaskId !== taskId) continue;
|
|
58651
|
+
const status = (typeof state.status === "string" ? state.status : "").toLowerCase();
|
|
58652
|
+
const chatStatus = (typeof state.activeChat?.status === "string" ? state.activeChat.status : "").toLowerCase();
|
|
58653
|
+
if (working.has(status) || working.has(chatStatus)) return id;
|
|
58547
58654
|
}
|
|
58548
|
-
return
|
|
58655
|
+
return null;
|
|
58549
58656
|
}
|
|
58550
58657
|
/** Clear a mesh assignment after the dispatched task reaches a terminal
|
|
58551
58658
|
* state (generating_completed / stopped / failed). */
|
|
@@ -65244,6 +65351,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
65244
65351
|
isSetupComplete,
|
|
65245
65352
|
isTaskReadonly,
|
|
65246
65353
|
isUserFacingChatMessage,
|
|
65354
|
+
isWeakCompletionEvidence,
|
|
65247
65355
|
killIdeProcess,
|
|
65248
65356
|
launchIDE,
|
|
65249
65357
|
launchWithCdp,
|