chatroom-cli 1.116.2 → 1.116.4
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 +195 -118
- package/dist/index.js.map +16 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -27767,7 +27767,8 @@ var init_base_cli_agent_service = __esm(() => {
|
|
|
27767
27767
|
// src/daemon/services/agent-process-service/service/agent-process-manager-service.ts
|
|
27768
27768
|
import { randomUUID } from "node:crypto";
|
|
27769
27769
|
function messageGroupId(input) {
|
|
27770
|
-
|
|
27770
|
+
const base = `${input.chatroomId}:${input.role.toLowerCase()}`;
|
|
27771
|
+
return input.workingDir ? `${base}:${input.workingDir}` : base;
|
|
27771
27772
|
}
|
|
27772
27773
|
function commandMessage(command) {
|
|
27773
27774
|
const input = command.input;
|
|
@@ -27930,7 +27931,7 @@ function createAgentProcessManagerService(deps) {
|
|
|
27930
27931
|
await deps.commandBus.stop();
|
|
27931
27932
|
},
|
|
27932
27933
|
handleExit: (input) => deps.execution.handleExit(input),
|
|
27933
|
-
getSlot: (chatroomId, role) => deps.execution.getSlot(chatroomId, role),
|
|
27934
|
+
getSlot: (chatroomId, role, workingDir) => workingDir === undefined ? deps.execution.getSlot(chatroomId, role) : deps.execution.getSlot(chatroomId, role, workingDir),
|
|
27934
27935
|
listActive: () => deps.execution.listActive(),
|
|
27935
27936
|
clearStuckStoppingSlot: (chatroomId, role, options) => deps.execution.clearStuckStoppingSlot(chatroomId, role, options),
|
|
27936
27937
|
whenTurnEndsIdle: () => deps.execution.whenTurnEndsIdle(),
|
|
@@ -28184,10 +28185,18 @@ function isAgentSlotStartInFlight(slot) {
|
|
|
28184
28185
|
function isAgentSlotActive(slot) {
|
|
28185
28186
|
return isAgentSlotStarted(slot) || isAgentSlotStartInFlight(slot);
|
|
28186
28187
|
}
|
|
28187
|
-
function agentKey(chatroomId, role) {
|
|
28188
|
-
return
|
|
28188
|
+
function agentKey(chatroomId, role, workingDir) {
|
|
28189
|
+
return [chatroomId, role.toLowerCase(), workingDir ?? ""].join(AGENT_KEY_SEPARATOR);
|
|
28190
|
+
}
|
|
28191
|
+
function parseAgentKey(key) {
|
|
28192
|
+
const [chatroomId, role, workingDir] = key.split(AGENT_KEY_SEPARATOR);
|
|
28193
|
+
return {
|
|
28194
|
+
chatroomId,
|
|
28195
|
+
role,
|
|
28196
|
+
...workingDir ? { workingDir } : {}
|
|
28197
|
+
};
|
|
28189
28198
|
}
|
|
28190
|
-
var AGENT_SLOT_STATE, AGENT_START_DISPOSITION, idleSlot = () => ({ state: AGENT_SLOT_STATE.IDLE });
|
|
28199
|
+
var AGENT_SLOT_STATE, AGENT_START_DISPOSITION, idleSlot = () => ({ state: AGENT_SLOT_STATE.IDLE }), AGENT_KEY_SEPARATOR = "\x00";
|
|
28191
28200
|
var init_agent_slot = __esm(() => {
|
|
28192
28201
|
AGENT_SLOT_STATE = {
|
|
28193
28202
|
IDLE: "idle",
|
|
@@ -30740,10 +30749,10 @@ function createStopAgentTargetsDeps(args2) {
|
|
|
30740
30749
|
};
|
|
30741
30750
|
}
|
|
30742
30751
|
async function runRoleScopedStop(args2) {
|
|
30743
|
-
args2.apm.markStopIntent(args2.chatroomId, args2.role, args2.reason);
|
|
30752
|
+
args2.apm.markStopIntent(args2.chatroomId, args2.role, args2.reason, undefined, args2.workingDir);
|
|
30744
30753
|
const deps = createStopAgentTargetsDeps(args2);
|
|
30745
30754
|
const discovered = await args2.apm.discoverStopTargets(args2.chatroomId);
|
|
30746
|
-
const targets = discovered.filter((target) => normalizeAgentStopRole(target.role) === normalizeAgentStopRole(args2.role));
|
|
30755
|
+
const targets = discovered.filter((target) => normalizeAgentStopRole(target.role) === normalizeAgentStopRole(args2.role) && (!args2.workingDir || target.workingDir === args2.workingDir));
|
|
30747
30756
|
return stopAgentTargets(deps, {
|
|
30748
30757
|
chatroomId: args2.chatroomId,
|
|
30749
30758
|
scope: { kind: "agent", role: args2.role },
|
|
@@ -30934,6 +30943,17 @@ var init_agent_lifecycle_service = __esm(() => {
|
|
|
30934
30943
|
const ports = yield* AgentLifecyclePorts;
|
|
30935
30944
|
const slotsRef = yield* exports_Ref.make(new Map);
|
|
30936
30945
|
const getSlotFromRef = (key) => exports_Ref.get(slotsRef).pipe(exports_Effect.map((map18) => map18.get(key)));
|
|
30946
|
+
const findSlotKey = (chatroomId, role, workingDir) => exports_Ref.get(slotsRef).pipe(exports_Effect.map((map18) => {
|
|
30947
|
+
if (workingDir !== undefined) {
|
|
30948
|
+
const key = agentKey(chatroomId, role, workingDir);
|
|
30949
|
+
return map18.has(key) ? key : undefined;
|
|
30950
|
+
}
|
|
30951
|
+
const candidates = [...map18.keys()].filter((key) => {
|
|
30952
|
+
const identity5 = parseAgentKey(key);
|
|
30953
|
+
return identity5.chatroomId === chatroomId && identity5.role === role.toLowerCase();
|
|
30954
|
+
});
|
|
30955
|
+
return candidates.length === 1 ? candidates[0] : undefined;
|
|
30956
|
+
}));
|
|
30937
30957
|
const setSlotInRef = (key, slot) => exports_Ref.update(slotsRef, (map18) => map18.set(key, slot));
|
|
30938
30958
|
const removeSlotFromRef = (key) => exports_Ref.update(slotsRef, (map18) => {
|
|
30939
30959
|
const next4 = new Map(map18);
|
|
@@ -30989,7 +31009,7 @@ var init_agent_lifecycle_service = __esm(() => {
|
|
|
30989
31009
|
return { success: true, pid: slot.pid, disposition: AGENT_START_DISPOSITION.STARTED };
|
|
30990
31010
|
});
|
|
30991
31011
|
const ensureRunning = (opts) => exports_Effect.gen(function* () {
|
|
30992
|
-
const key = agentKey(opts.chatroomId, opts.role);
|
|
31012
|
+
const key = agentKey(opts.chatroomId, opts.role, opts.workingDir);
|
|
30993
31013
|
const currentSlot = yield* getSlotFromRef(key);
|
|
30994
31014
|
if (currentSlot && isAgentSlotActive(currentSlot)) {
|
|
30995
31015
|
return {
|
|
@@ -31010,7 +31030,9 @@ var init_agent_lifecycle_service = __esm(() => {
|
|
|
31010
31030
|
return result;
|
|
31011
31031
|
});
|
|
31012
31032
|
const stop3 = (opts) => exports_Effect.gen(function* () {
|
|
31013
|
-
const key =
|
|
31033
|
+
const key = yield* findSlotKey(opts.chatroomId, opts.role, opts.workingDir);
|
|
31034
|
+
if (!key)
|
|
31035
|
+
return { success: false };
|
|
31014
31036
|
const slot = yield* getSlotFromRef(key);
|
|
31015
31037
|
if (!slot) {
|
|
31016
31038
|
return { success: false };
|
|
@@ -31036,7 +31058,7 @@ var init_agent_lifecycle_service = __esm(() => {
|
|
|
31036
31058
|
return { success: true };
|
|
31037
31059
|
});
|
|
31038
31060
|
const handleExit = (opts) => exports_Effect.gen(function* () {
|
|
31039
|
-
const key = agentKey(opts.chatroomId, opts.role);
|
|
31061
|
+
const key = agentKey(opts.chatroomId, opts.role, opts.workingDir);
|
|
31040
31062
|
const slot = yield* getSlotFromRef(key);
|
|
31041
31063
|
if (!slot) {
|
|
31042
31064
|
return;
|
|
@@ -31064,23 +31086,22 @@ var init_agent_lifecycle_service = __esm(() => {
|
|
|
31064
31086
|
yield* setSlotInRef(key, exitedSlot);
|
|
31065
31087
|
yield* removeSlotFromRef(key);
|
|
31066
31088
|
});
|
|
31067
|
-
const getSlot = (chatroomId, role) =>
|
|
31089
|
+
const getSlot = (chatroomId, role, workingDir) => findSlotKey(chatroomId, role, workingDir).pipe(exports_Effect.flatMap((key) => key ? getSlotFromRef(key) : exports_Effect.succeed(undefined)));
|
|
31068
31090
|
const listActive = () => exports_Ref.get(slotsRef).pipe(exports_Effect.map((map18) => {
|
|
31069
31091
|
const results = [];
|
|
31070
31092
|
for (const [key, slot] of map18) {
|
|
31071
31093
|
if (isAgentSlotActive(slot)) {
|
|
31072
|
-
const
|
|
31073
|
-
results.push({ chatroomId, role, slot });
|
|
31094
|
+
const identity5 = parseAgentKey(key);
|
|
31095
|
+
results.push({ chatroomId: identity5.chatroomId, role: identity5.role, slot });
|
|
31074
31096
|
}
|
|
31075
31097
|
}
|
|
31076
31098
|
return results;
|
|
31077
31099
|
}));
|
|
31078
31100
|
const reset = (input) => exports_Ref.update(slotsRef, (map18) => {
|
|
31079
31101
|
const next4 = new Map(map18);
|
|
31080
|
-
const prefix = `${input.chatroomId}:`;
|
|
31081
|
-
const exactKey = input.scope === "chatroom-role" && input.role ? `${input.chatroomId}:${input.role.toLowerCase()}` : undefined;
|
|
31082
31102
|
for (const key of next4.keys()) {
|
|
31083
|
-
|
|
31103
|
+
const identity5 = parseAgentKey(key);
|
|
31104
|
+
if (identity5.chatroomId === input.chatroomId && (input.scope === "chatroom" || input.role !== undefined && identity5.role === input.role.toLowerCase())) {
|
|
31084
31105
|
next4.delete(key);
|
|
31085
31106
|
}
|
|
31086
31107
|
}
|
|
@@ -31408,8 +31429,15 @@ var init_native_spawn_presence = __esm(() => {
|
|
|
31408
31429
|
});
|
|
31409
31430
|
|
|
31410
31431
|
// src/daemon/services/agent-process-service/infrastructure/agent-process-manager.ts
|
|
31411
|
-
function agentKey2(chatroomId, role) {
|
|
31412
|
-
return
|
|
31432
|
+
function agentKey2(chatroomId, role, workingDir) {
|
|
31433
|
+
return [chatroomId, role.toLowerCase(), workingDir ?? ""].join(AGENT_KEY_SEPARATOR2);
|
|
31434
|
+
}
|
|
31435
|
+
function parseAgentKey2(key) {
|
|
31436
|
+
const [chatroomId, role, workingDir] = key.split(AGENT_KEY_SEPARATOR2);
|
|
31437
|
+
return { chatroomId, role, ...workingDir ? { workingDir } : {} };
|
|
31438
|
+
}
|
|
31439
|
+
function serializedAgentKey(chatroomId, role, workingDir) {
|
|
31440
|
+
return agentKey2(chatroomId, role, workingDir);
|
|
31413
31441
|
}
|
|
31414
31442
|
|
|
31415
31443
|
class AgentProcessManager {
|
|
@@ -31439,7 +31467,7 @@ class AgentProcessManager {
|
|
|
31439
31467
|
this.lifecycle = createAgentLifecycleRuntime(portAdapterDeps);
|
|
31440
31468
|
}
|
|
31441
31469
|
runSerializedForAgent(key, operation) {
|
|
31442
|
-
const serializedKey =
|
|
31470
|
+
const serializedKey = serializedAgentKey(key.chatroomId, key.role, key.workingDir);
|
|
31443
31471
|
const previous = this.serializedOperationTails.get(serializedKey) ?? Promise.resolve();
|
|
31444
31472
|
const current = previous.catch(() => {
|
|
31445
31473
|
return;
|
|
@@ -31458,7 +31486,7 @@ class AgentProcessManager {
|
|
|
31458
31486
|
return current;
|
|
31459
31487
|
}
|
|
31460
31488
|
updateSlotsMirror(chatroomId, role, slot) {
|
|
31461
|
-
const key = agentKey2(chatroomId, role);
|
|
31489
|
+
const key = agentKey2(chatroomId, role, slot.workingDir);
|
|
31462
31490
|
const existing = this.slots.get(key);
|
|
31463
31491
|
if (!existing || existing.state !== slot.state || existing.pid !== slot.pid) {
|
|
31464
31492
|
this.slots.set(key, {
|
|
@@ -31474,8 +31502,17 @@ class AgentProcessManager {
|
|
|
31474
31502
|
});
|
|
31475
31503
|
}
|
|
31476
31504
|
}
|
|
31477
|
-
getSlotFromMirror(chatroomId, role) {
|
|
31478
|
-
|
|
31505
|
+
getSlotFromMirror(chatroomId, role, workingDir) {
|
|
31506
|
+
if (workingDir !== undefined)
|
|
31507
|
+
return this.slots.get(agentKey2(chatroomId, role, workingDir));
|
|
31508
|
+
const legacy = this.slots.get(agentKey2(chatroomId, role));
|
|
31509
|
+
if (legacy)
|
|
31510
|
+
return legacy;
|
|
31511
|
+
const matches = [...this.slots.entries()].filter(([key]) => {
|
|
31512
|
+
const identity5 = parseAgentKey2(key);
|
|
31513
|
+
return identity5.chatroomId === chatroomId && identity5.role === role.toLowerCase();
|
|
31514
|
+
});
|
|
31515
|
+
return matches.length === 1 ? matches[0]?.[1] : undefined;
|
|
31479
31516
|
}
|
|
31480
31517
|
whenTurnEndsIdle() {
|
|
31481
31518
|
return (async () => {
|
|
@@ -31502,7 +31539,6 @@ class AgentProcessManager {
|
|
|
31502
31539
|
slot.harness = undefined;
|
|
31503
31540
|
slot.harnessSessionId = undefined;
|
|
31504
31541
|
slot.model = undefined;
|
|
31505
|
-
slot.workingDir = undefined;
|
|
31506
31542
|
slot.startedAt = undefined;
|
|
31507
31543
|
slot.pendingOperation = undefined;
|
|
31508
31544
|
slot.stoppingSince = undefined;
|
|
@@ -31514,8 +31550,9 @@ class AgentProcessManager {
|
|
|
31514
31550
|
slot.stopGeneration = (slot.stopGeneration ?? 0) + 1;
|
|
31515
31551
|
return slot.stopGeneration;
|
|
31516
31552
|
}
|
|
31517
|
-
markStopIntent(chatroomId, role, reason, pid) {
|
|
31518
|
-
const
|
|
31553
|
+
markStopIntent(chatroomId, role, reason, pid, workingDir) {
|
|
31554
|
+
const resolvedWorkingDir = workingDir ?? [...this.slots.entries()].map(([key]) => ({ identity: parseAgentKey2(key) })).filter(({ identity: identity5 }) => identity5.chatroomId === chatroomId && identity5.role === role.toLowerCase() && identity5.workingDir !== undefined).map(({ identity: identity5 }) => identity5.workingDir).filter((candidate, index, candidates) => candidates.indexOf(candidate) === index)[0];
|
|
31555
|
+
const slot = this.getOrCreateSlot(agentKey2(chatroomId, role, resolvedWorkingDir));
|
|
31519
31556
|
if (slot.stopRequested)
|
|
31520
31557
|
return slot.stopGeneration ?? 0;
|
|
31521
31558
|
const generation = this.bumpStopGeneration(slot);
|
|
@@ -31527,12 +31564,12 @@ class AgentProcessManager {
|
|
|
31527
31564
|
markChatroomStopIntent(chatroomId, reason) {
|
|
31528
31565
|
for (const { chatroomId: cid, role, slot } of this.listAllSlots()) {
|
|
31529
31566
|
if (cid === chatroomId) {
|
|
31530
|
-
this.markStopIntent(chatroomId, role, reason, slot.pid);
|
|
31567
|
+
this.markStopIntent(chatroomId, role, reason, slot.pid, slot.workingDir);
|
|
31531
31568
|
}
|
|
31532
31569
|
}
|
|
31533
31570
|
}
|
|
31534
|
-
isStopRequested(chatroomId, role, generation) {
|
|
31535
|
-
const slot = this.
|
|
31571
|
+
isStopRequested(chatroomId, role, generation, workingDir) {
|
|
31572
|
+
const slot = this.getSlotFromMirror(chatroomId, role, workingDir);
|
|
31536
31573
|
if (!slot)
|
|
31537
31574
|
return false;
|
|
31538
31575
|
if (generation !== undefined && slot.stopGeneration !== generation)
|
|
@@ -31548,7 +31585,7 @@ class AgentProcessManager {
|
|
|
31548
31585
|
if (isChatroomStopScopeActive(opts.chatroomId)) {
|
|
31549
31586
|
return { success: false, error: "stop_in_progress" };
|
|
31550
31587
|
}
|
|
31551
|
-
const key = agentKey2(opts.chatroomId, opts.role);
|
|
31588
|
+
const key = agentKey2(opts.chatroomId, opts.role, opts.workingDir);
|
|
31552
31589
|
const slot = this.getOrCreateSlot(key);
|
|
31553
31590
|
if (isExplicitDaemonStart(opts.reason)) {
|
|
31554
31591
|
this.bumpStopGeneration(slot);
|
|
@@ -31582,8 +31619,7 @@ class AgentProcessManager {
|
|
|
31582
31619
|
return operation;
|
|
31583
31620
|
}
|
|
31584
31621
|
async resumeTurnForSlot(args2) {
|
|
31585
|
-
const
|
|
31586
|
-
const slot = this.slots.get(key);
|
|
31622
|
+
const slot = this.getSlotFromMirror(args2.chatroomId, args2.role, args2.workingDir);
|
|
31587
31623
|
if (!slot?.pid || !slot.harness) {
|
|
31588
31624
|
throw new Error(`No running agent for ${args2.role}@${args2.chatroomId}`);
|
|
31589
31625
|
}
|
|
@@ -31602,10 +31638,14 @@ class AgentProcessManager {
|
|
|
31602
31638
|
}
|
|
31603
31639
|
}
|
|
31604
31640
|
async stop(opts) {
|
|
31605
|
-
const
|
|
31606
|
-
const
|
|
31607
|
-
|
|
31608
|
-
|
|
31641
|
+
const slot = this.getSlotFromMirror(opts.chatroomId, opts.role, opts.workingDir);
|
|
31642
|
+
const resolvedOpts = {
|
|
31643
|
+
...opts,
|
|
31644
|
+
...opts.workingDir === undefined && slot?.workingDir ? { workingDir: slot.workingDir } : {}
|
|
31645
|
+
};
|
|
31646
|
+
const key = agentKey2(opts.chatroomId, opts.role, resolvedOpts.workingDir);
|
|
31647
|
+
this.markStopIntent(resolvedOpts.chatroomId, resolvedOpts.role, resolvedOpts.reason, opts.pid ?? slot?.pid, resolvedOpts.workingDir);
|
|
31648
|
+
const earlyResult = await this.handleStopEarlyReturns(slot, resolvedOpts, key);
|
|
31609
31649
|
if (earlyResult) {
|
|
31610
31650
|
return earlyResult;
|
|
31611
31651
|
}
|
|
@@ -31625,7 +31665,8 @@ class AgentProcessManager {
|
|
|
31625
31665
|
chatroomId: cid,
|
|
31626
31666
|
role,
|
|
31627
31667
|
pid: slot.pid,
|
|
31628
|
-
agentHarness: slot.harness
|
|
31668
|
+
agentHarness: slot.harness,
|
|
31669
|
+
workingDir: slot.workingDir
|
|
31629
31670
|
});
|
|
31630
31671
|
targets.set(target.targetKey, target);
|
|
31631
31672
|
}
|
|
@@ -31638,7 +31679,8 @@ class AgentProcessManager {
|
|
|
31638
31679
|
chatroomId: cid,
|
|
31639
31680
|
role,
|
|
31640
31681
|
pid: entry.pid,
|
|
31641
|
-
agentHarness: entry.harness
|
|
31682
|
+
agentHarness: entry.harness,
|
|
31683
|
+
workingDir: entry.workingDir
|
|
31642
31684
|
});
|
|
31643
31685
|
targets.set(target.targetKey, target);
|
|
31644
31686
|
}
|
|
@@ -31660,26 +31702,26 @@ class AgentProcessManager {
|
|
|
31660
31702
|
};
|
|
31661
31703
|
}
|
|
31662
31704
|
bindStopTarget(args2) {
|
|
31663
|
-
const slot = this.slots.get(agentKey2(args2.chatroomId, args2.role));
|
|
31705
|
+
const slot = this.slots.get(agentKey2(args2.chatroomId, args2.role, args2.workingDir));
|
|
31664
31706
|
if (!slot || slot.pid !== args2.pid || slot.state !== AGENT_SLOT_STATE.STOPPING)
|
|
31665
31707
|
return;
|
|
31666
31708
|
slot.stopCommandId = args2.stopCommandId;
|
|
31667
31709
|
slot.stopTargetKey = args2.targetKey;
|
|
31668
31710
|
}
|
|
31669
31711
|
async withScopedRoleStop(opts, fn2) {
|
|
31670
|
-
const key = agentKey2(opts.chatroomId, opts.role);
|
|
31712
|
+
const key = agentKey2(opts.chatroomId, opts.role, opts.workingDir);
|
|
31671
31713
|
const slot = this.slots.get(key);
|
|
31672
31714
|
if (!slot || !slot.pid || slot.state === AGENT_SLOT_STATE.IDLE)
|
|
31673
31715
|
return { ok: false, reason: "no_slot" };
|
|
31674
31716
|
if (slot.state === AGENT_SLOT_STATE.STOPPING || slot.pendingOperation)
|
|
31675
31717
|
return { ok: false, reason: "concurrent" };
|
|
31676
|
-
this.markStopIntent(opts.chatroomId, opts.role, opts.reason, slot.pid);
|
|
31718
|
+
this.markStopIntent(opts.chatroomId, opts.role, opts.reason, slot.pid, opts.workingDir);
|
|
31677
31719
|
slot.state = AGENT_SLOT_STATE.STOPPING;
|
|
31678
31720
|
slot.stoppingSince = this.deps.clock.now();
|
|
31679
31721
|
try {
|
|
31680
31722
|
const value = await fn2();
|
|
31681
31723
|
this.resetSlotAfterStop(slot);
|
|
31682
|
-
await this.clearAgentPidQuietly(opts.chatroomId, opts.role);
|
|
31724
|
+
await this.clearAgentPidQuietly(opts.chatroomId, opts.role, opts.workingDir);
|
|
31683
31725
|
return { ok: true, value };
|
|
31684
31726
|
} catch (error) {
|
|
31685
31727
|
slot.state = AGENT_SLOT_STATE.RUNNING;
|
|
@@ -31729,7 +31771,7 @@ class AgentProcessManager {
|
|
|
31729
31771
|
this.recordAgentExit(opts.role, exitArgs, "Failed to record agent exit (idle cleanup)");
|
|
31730
31772
|
}
|
|
31731
31773
|
async runHandleAgentEnd(opts) {
|
|
31732
|
-
const slot = this.slots.
|
|
31774
|
+
const slot = [...this.slots.entries()].find(([candidateKey, candidate]) => candidateKey === agentKey2(opts.chatroomId, opts.role, opts.workingDir) && candidate.pid === opts.pid)?.[1];
|
|
31733
31775
|
if (!slot || slot.pid !== opts.pid || slot.harness !== opts.harness || slot.state !== AGENT_SLOT_STATE.RUNNING) {
|
|
31734
31776
|
console.log(`[AgentProcessManager] Ignoring stale agent_end: role=${opts.role} callbackPid=${opts.pid} currentPid=${slot?.pid ?? "none"} currentState=${slot?.state ?? "none"}`);
|
|
31735
31777
|
return;
|
|
@@ -31799,8 +31841,7 @@ class AgentProcessManager {
|
|
|
31799
31841
|
}
|
|
31800
31842
|
}
|
|
31801
31843
|
async handleExit(opts) {
|
|
31802
|
-
const
|
|
31803
|
-
const slot = this.slots.get(key);
|
|
31844
|
+
const slot = this.getSlotFromMirror(opts.chatroomId, opts.role, opts.workingDir);
|
|
31804
31845
|
if (!slot || slot.pid !== opts.pid || slot.state === AGENT_SLOT_STATE.STOPPING) {
|
|
31805
31846
|
return;
|
|
31806
31847
|
}
|
|
@@ -31821,6 +31862,7 @@ class AgentProcessManager {
|
|
|
31821
31862
|
yield* svc.handleExit({
|
|
31822
31863
|
chatroomId: opts.chatroomId,
|
|
31823
31864
|
role: opts.role,
|
|
31865
|
+
workingDir: slot.workingDir,
|
|
31824
31866
|
pid: opts.pid,
|
|
31825
31867
|
code: opts.code,
|
|
31826
31868
|
signal: opts.signal
|
|
@@ -31829,7 +31871,7 @@ class AgentProcessManager {
|
|
|
31829
31871
|
this.resetSlotAfterExit(slot);
|
|
31830
31872
|
this.emitExitEvent(slot, opts, ctx);
|
|
31831
31873
|
try {
|
|
31832
|
-
await this.deps.persistence.clearAgentPid(this.deps.machineId, opts.chatroomId, opts.role);
|
|
31874
|
+
await this.deps.persistence.clearAgentPid(this.deps.machineId, opts.chatroomId, opts.role, slot.workingDir);
|
|
31833
31875
|
} catch {}
|
|
31834
31876
|
this.untrackAllServices(opts.pid);
|
|
31835
31877
|
lifecyclePromise.catch(() => {});
|
|
@@ -31901,15 +31943,15 @@ class AgentProcessManager {
|
|
|
31901
31943
|
emittedAt: this.deps.clock.now()
|
|
31902
31944
|
})).catch(() => {});
|
|
31903
31945
|
}
|
|
31904
|
-
getSlot(chatroomId, role) {
|
|
31905
|
-
return this.getSlotFromMirror(chatroomId, role);
|
|
31946
|
+
getSlot(chatroomId, role, workingDir) {
|
|
31947
|
+
return this.getSlotFromMirror(chatroomId, role, workingDir);
|
|
31906
31948
|
}
|
|
31907
31949
|
listActive() {
|
|
31908
31950
|
const result = [];
|
|
31909
31951
|
for (const [key, slot] of this.slots) {
|
|
31910
31952
|
if (slot.state === AGENT_SLOT_STATE.RUNNING || slot.state === AGENT_SLOT_STATE.SPAWNING) {
|
|
31911
|
-
const
|
|
31912
|
-
result.push({ chatroomId, role, slot });
|
|
31953
|
+
const identity5 = parseAgentKey2(key);
|
|
31954
|
+
result.push({ chatroomId: identity5.chatroomId, role: identity5.role, slot });
|
|
31913
31955
|
}
|
|
31914
31956
|
}
|
|
31915
31957
|
return result;
|
|
@@ -31917,17 +31959,17 @@ class AgentProcessManager {
|
|
|
31917
31959
|
listAllSlots() {
|
|
31918
31960
|
const result = [];
|
|
31919
31961
|
for (const [key, slot] of this.slots) {
|
|
31920
|
-
const
|
|
31921
|
-
result.push({ chatroomId, role, slot });
|
|
31962
|
+
const identity5 = parseAgentKey2(key);
|
|
31963
|
+
result.push({ chatroomId: identity5.chatroomId, role: identity5.role, slot });
|
|
31922
31964
|
}
|
|
31923
31965
|
return result;
|
|
31924
31966
|
}
|
|
31925
31967
|
async clearStuckStoppingSlot(chatroomId, role, options) {
|
|
31926
|
-
const
|
|
31927
|
-
const slot = this.slots.get(key);
|
|
31968
|
+
const slot = this.getSlotFromMirror(chatroomId, role, options?.workingDir);
|
|
31928
31969
|
if (!slot || slot.state !== AGENT_SLOT_STATE.STOPPING) {
|
|
31929
31970
|
return false;
|
|
31930
31971
|
}
|
|
31972
|
+
const key = agentKey2(chatroomId, role, slot.workingDir);
|
|
31931
31973
|
const elapsed3 = slot.stoppingSince ? this.deps.clock.now() - slot.stoppingSince : STOPPING_TIMEOUT_MS;
|
|
31932
31974
|
if (elapsed3 < STOPPING_TIMEOUT_MS) {
|
|
31933
31975
|
return false;
|
|
@@ -31938,8 +31980,8 @@ class AgentProcessManager {
|
|
|
31938
31980
|
}
|
|
31939
31981
|
async clearAllStuckStoppingSlots() {
|
|
31940
31982
|
let cleared = 0;
|
|
31941
|
-
for (const { chatroomId, role } of this.listAllSlots()) {
|
|
31942
|
-
if (await this.clearStuckStoppingSlot(chatroomId, role)) {
|
|
31983
|
+
for (const { chatroomId, role, slot } of this.listAllSlots()) {
|
|
31984
|
+
if (await this.clearStuckStoppingSlot(chatroomId, role, { workingDir: slot.workingDir })) {
|
|
31943
31985
|
cleared++;
|
|
31944
31986
|
}
|
|
31945
31987
|
}
|
|
@@ -31953,11 +31995,12 @@ class AgentProcessManager {
|
|
|
31953
31995
|
if (!matchesScope(slotChatroomId, role))
|
|
31954
31996
|
continue;
|
|
31955
31997
|
if (slot.pid && slot.harness) {
|
|
31956
|
-
knownEntries.set(agentKey2(slotChatroomId, role), {
|
|
31998
|
+
knownEntries.set(agentKey2(slotChatroomId, role, slot.workingDir), {
|
|
31957
31999
|
chatroomId: slotChatroomId,
|
|
31958
32000
|
role,
|
|
31959
32001
|
pid: slot.pid,
|
|
31960
|
-
harness: slot.harness
|
|
32002
|
+
harness: slot.harness,
|
|
32003
|
+
workingDir: slot.workingDir
|
|
31961
32004
|
});
|
|
31962
32005
|
}
|
|
31963
32006
|
}
|
|
@@ -31969,17 +32012,18 @@ class AgentProcessManager {
|
|
|
31969
32012
|
} of await this.deps.persistence.listAgentEntries(this.deps.machineId)) {
|
|
31970
32013
|
if (!matchesScope(entryChatroomId, role))
|
|
31971
32014
|
continue;
|
|
31972
|
-
knownEntries.set(agentKey2(entryChatroomId, role), {
|
|
32015
|
+
knownEntries.set(agentKey2(entryChatroomId, role, entry.workingDir), {
|
|
31973
32016
|
chatroomId: entryChatroomId,
|
|
31974
32017
|
role,
|
|
31975
32018
|
pid: entry.pid,
|
|
31976
|
-
harness: entry.harness
|
|
32019
|
+
harness: entry.harness,
|
|
32020
|
+
workingDir: entry.workingDir
|
|
31977
32021
|
});
|
|
31978
32022
|
}
|
|
31979
32023
|
} catch {}
|
|
31980
|
-
for (const { chatroomId, role, pid, harness } of knownEntries.values()) {
|
|
32024
|
+
for (const { chatroomId, role, pid, harness, workingDir } of knownEntries.values()) {
|
|
31981
32025
|
await this.stopPersistedProcess(pid, harness);
|
|
31982
|
-
await this.clearAgentPidQuietly(chatroomId, role);
|
|
32026
|
+
await this.clearAgentPidQuietly(chatroomId, role, workingDir);
|
|
31983
32027
|
}
|
|
31984
32028
|
for (let i2 = this.exitRetryQueue.length - 1;i2 >= 0; i2--) {
|
|
31985
32029
|
const item = this.exitRetryQueue[i2];
|
|
@@ -31989,8 +32033,8 @@ class AgentProcessManager {
|
|
|
31989
32033
|
if (this.exitRetryQueue.length === 0)
|
|
31990
32034
|
this.stopExitRetryTimer();
|
|
31991
32035
|
for (const key of [...this.slots.keys()]) {
|
|
31992
|
-
const
|
|
31993
|
-
if (matchesScope(
|
|
32036
|
+
const identity5 = parseAgentKey2(key);
|
|
32037
|
+
if (matchesScope(identity5.chatroomId, identity5.role))
|
|
31994
32038
|
this.slots.delete(key);
|
|
31995
32039
|
}
|
|
31996
32040
|
await this.lifecycle.runPromise(exports_Effect.gen(function* () {
|
|
@@ -32023,38 +32067,38 @@ class AgentProcessManager {
|
|
|
32023
32067
|
}
|
|
32024
32068
|
untrackChildPid(pid);
|
|
32025
32069
|
}
|
|
32026
|
-
async killExistingBeforeSpawn(chatroomId, role) {
|
|
32027
|
-
const key = agentKey2(chatroomId, role);
|
|
32028
|
-
await this.killInMemorySlotIfAlive(key, chatroomId, role);
|
|
32029
|
-
await this.killPersistedProcessIfAlive(chatroomId, role);
|
|
32070
|
+
async killExistingBeforeSpawn(chatroomId, role, workingDir) {
|
|
32071
|
+
const key = agentKey2(chatroomId, role, workingDir);
|
|
32072
|
+
await this.killInMemorySlotIfAlive(key, chatroomId, role, workingDir);
|
|
32073
|
+
await this.killPersistedProcessIfAlive(chatroomId, role, workingDir);
|
|
32030
32074
|
}
|
|
32031
|
-
async killInMemorySlotIfAlive(key, chatroomId, role) {
|
|
32075
|
+
async killInMemorySlotIfAlive(key, chatroomId, role, workingDir) {
|
|
32032
32076
|
const slot = this.slots.get(key);
|
|
32033
32077
|
if (slot?.pid && isProcessAlive(this.deps.processes.kill, slot.pid) && (slot.state === AGENT_SLOT_STATE.RUNNING || slot.state === AGENT_SLOT_STATE.SPAWNING)) {
|
|
32034
32078
|
const pid = slot.pid;
|
|
32035
32079
|
slot.state = AGENT_SLOT_STATE.STOPPING;
|
|
32036
32080
|
const stopGeneration = this.bumpStopGeneration(slot);
|
|
32037
32081
|
slot.stoppingSince = this.deps.clock.now();
|
|
32038
|
-
await this.doStop(key, slot, pid, { chatroomId, role, reason: "daemon.respawn" }, stopGeneration);
|
|
32082
|
+
await this.doStop(key, slot, pid, { chatroomId, role, reason: "daemon.respawn", workingDir }, stopGeneration);
|
|
32039
32083
|
}
|
|
32040
32084
|
}
|
|
32041
|
-
async killPersistedProcessIfAlive(chatroomId, role) {
|
|
32085
|
+
async killPersistedProcessIfAlive(chatroomId, role, workingDir) {
|
|
32042
32086
|
let entries2 = [];
|
|
32043
32087
|
try {
|
|
32044
32088
|
entries2 = await this.deps.persistence.listAgentEntries(this.deps.machineId);
|
|
32045
32089
|
} catch {
|
|
32046
32090
|
return;
|
|
32047
32091
|
}
|
|
32048
|
-
const persisted = entries2.find((e) => e.chatroomId === chatroomId && e.role.toLowerCase() === role.toLowerCase());
|
|
32092
|
+
const persisted = entries2.find((e) => e.chatroomId === chatroomId && e.role.toLowerCase() === role.toLowerCase() && (!workingDir || !e.entry.workingDir || e.entry.workingDir === workingDir));
|
|
32049
32093
|
if (!persisted) {
|
|
32050
32094
|
return;
|
|
32051
32095
|
}
|
|
32052
32096
|
const { pid, harness } = persisted.entry;
|
|
32053
32097
|
if (!isProcessAlive(this.deps.processes.kill, pid)) {
|
|
32054
|
-
await this.deps.persistence.clearAgentPid(this.deps.machineId, chatroomId, role).catch(() => {});
|
|
32098
|
+
await this.deps.persistence.clearAgentPid(this.deps.machineId, chatroomId, role, workingDir).catch(() => {});
|
|
32055
32099
|
return;
|
|
32056
32100
|
}
|
|
32057
|
-
const key = agentKey2(chatroomId, role);
|
|
32101
|
+
const key = agentKey2(chatroomId, role, workingDir);
|
|
32058
32102
|
const currentSlot = this.slots.get(key);
|
|
32059
32103
|
if (currentSlot?.pid === pid && currentSlot.state !== AGENT_SLOT_STATE.IDLE) {
|
|
32060
32104
|
return;
|
|
@@ -32072,11 +32116,11 @@ class AgentProcessManager {
|
|
|
32072
32116
|
agentHarness: harness
|
|
32073
32117
|
};
|
|
32074
32118
|
this.recordAgentExit(role, exitArgs, "Failed to record agent exit before respawn");
|
|
32075
|
-
await this.clearAgentPidQuietly(chatroomId, role);
|
|
32119
|
+
await this.clearAgentPidQuietly(chatroomId, role, workingDir);
|
|
32076
32120
|
}
|
|
32077
32121
|
async executeEnsureRunning(key, slot, opts) {
|
|
32078
32122
|
try {
|
|
32079
|
-
await this.killExistingBeforeSpawn(opts.chatroomId, opts.role);
|
|
32123
|
+
await this.killExistingBeforeSpawn(opts.chatroomId, opts.role, opts.workingDir);
|
|
32080
32124
|
const result = await this.doEnsureRunning(key, slot, opts);
|
|
32081
32125
|
return result;
|
|
32082
32126
|
} finally {
|
|
@@ -32097,19 +32141,19 @@ class AgentProcessManager {
|
|
|
32097
32141
|
console.log(` ⚠️ Failed to enqueue agent exited lifecycle fact: ${err.message}`);
|
|
32098
32142
|
});
|
|
32099
32143
|
}
|
|
32100
|
-
async clearAgentPidQuietly(chatroomId, role) {
|
|
32144
|
+
async clearAgentPidQuietly(chatroomId, role, workingDir) {
|
|
32101
32145
|
try {
|
|
32102
|
-
await this.deps.persistence.clearAgentPid(this.deps.machineId, chatroomId, role);
|
|
32146
|
+
await this.deps.persistence.clearAgentPid(this.deps.machineId, chatroomId, role, workingDir);
|
|
32103
32147
|
} catch {}
|
|
32104
32148
|
}
|
|
32105
32149
|
async syncSlotsAfterScopedStop(result) {
|
|
32106
32150
|
for (const { target } of result.targets) {
|
|
32107
|
-
const slot = this.slots.get(agentKey2(target.chatroomId, target.role));
|
|
32151
|
+
const slot = this.slots.get(agentKey2(target.chatroomId, target.role, target.workingDir));
|
|
32108
32152
|
this.notifyAgentSessionLost(target.chatroomId, target.role, slot?.pid === target.pid ? slot.harnessSessionId : undefined);
|
|
32109
32153
|
if (!slot || slot.pid !== target.pid)
|
|
32110
32154
|
continue;
|
|
32111
32155
|
this.resetSlotAfterStop(slot);
|
|
32112
|
-
await this.clearAgentPidQuietly(target.chatroomId, target.role);
|
|
32156
|
+
await this.clearAgentPidQuietly(target.chatroomId, target.role, target.workingDir);
|
|
32113
32157
|
}
|
|
32114
32158
|
}
|
|
32115
32159
|
notifyAgentSessionLost(chatroomId, role, harnessSessionId) {
|
|
@@ -32322,12 +32366,13 @@ class AgentProcessManager {
|
|
|
32322
32366
|
});
|
|
32323
32367
|
spawnResult.onExit(({ code: code2, signal }) => {
|
|
32324
32368
|
const reconcileExit = async () => {
|
|
32325
|
-
const currentSlot = this.slots.
|
|
32369
|
+
const currentSlot = [...this.slots.entries()].find(([candidateKey, candidate]) => candidateKey === agentKey2(opts.chatroomId, opts.role, opts.workingDir) && candidate.pid === pid)?.[1];
|
|
32326
32370
|
const hasUnresolvedNativeTurn = currentSlot?.pid === pid && currentSlot.nativeTurnPhase === "turn_in_flight" && !this.typedCompletionSeenPids.has(pid);
|
|
32327
32371
|
if (hasUnresolvedNativeTurn) {
|
|
32328
|
-
await this.runSerializedForAgent({ chatroomId: opts.chatroomId, role: opts.role }, () => this.runHandleAgentEnd({
|
|
32372
|
+
await this.runSerializedForAgent({ chatroomId: opts.chatroomId, role: opts.role, workingDir: opts.workingDir }, () => this.runHandleAgentEnd({
|
|
32329
32373
|
chatroomId: opts.chatroomId,
|
|
32330
32374
|
role: opts.role,
|
|
32375
|
+
workingDir: opts.workingDir,
|
|
32331
32376
|
pid,
|
|
32332
32377
|
harness: opts.agentHarness,
|
|
32333
32378
|
completion: {
|
|
@@ -32342,6 +32387,7 @@ class AgentProcessManager {
|
|
|
32342
32387
|
await this.handleExit({
|
|
32343
32388
|
chatroomId: opts.chatroomId,
|
|
32344
32389
|
role: opts.role,
|
|
32390
|
+
workingDir: opts.workingDir,
|
|
32345
32391
|
pid,
|
|
32346
32392
|
code: code2,
|
|
32347
32393
|
signal
|
|
@@ -32354,9 +32400,10 @@ class AgentProcessManager {
|
|
|
32354
32400
|
if (spawnResult.onTurnResult) {
|
|
32355
32401
|
spawnResult.onTurnResult((completion) => {
|
|
32356
32402
|
this.typedCompletionSeenPids.add(pid);
|
|
32357
|
-
this.runSerializedForAgent({ chatroomId: opts.chatroomId, role: opts.role }, () => this.runHandleAgentEnd({
|
|
32403
|
+
this.runSerializedForAgent({ chatroomId: opts.chatroomId, role: opts.role, workingDir: opts.workingDir }, () => this.runHandleAgentEnd({
|
|
32358
32404
|
chatroomId: opts.chatroomId,
|
|
32359
32405
|
role: opts.role,
|
|
32406
|
+
workingDir: opts.workingDir,
|
|
32360
32407
|
pid,
|
|
32361
32408
|
harness: opts.agentHarness,
|
|
32362
32409
|
completion
|
|
@@ -32366,9 +32413,10 @@ class AgentProcessManager {
|
|
|
32366
32413
|
});
|
|
32367
32414
|
} else if (spawnResult.onAgentEnd) {
|
|
32368
32415
|
spawnResult.onAgentEnd(() => {
|
|
32369
|
-
this.runSerializedForAgent({ chatroomId: opts.chatroomId, role: opts.role }, () => this.runHandleAgentEnd({
|
|
32416
|
+
this.runSerializedForAgent({ chatroomId: opts.chatroomId, role: opts.role, workingDir: opts.workingDir }, () => this.runHandleAgentEnd({
|
|
32370
32417
|
chatroomId: opts.chatroomId,
|
|
32371
32418
|
role: opts.role,
|
|
32419
|
+
workingDir: opts.workingDir,
|
|
32372
32420
|
pid,
|
|
32373
32421
|
harness: opts.agentHarness
|
|
32374
32422
|
})).catch((error) => {
|
|
@@ -32391,7 +32439,7 @@ class AgentProcessManager {
|
|
|
32391
32439
|
this.assignRunningSlotState(key, slot, opts, spawnResult, wantResume, pid);
|
|
32392
32440
|
await this.emitSpawnedAgentUpdate(slot, opts, spawnResult, pid);
|
|
32393
32441
|
try {
|
|
32394
|
-
await this.deps.persistence.persistAgentPid(this.deps.machineId, opts.chatroomId, opts.role, pid, opts.agentHarness);
|
|
32442
|
+
await this.deps.persistence.persistAgentPid(this.deps.machineId, opts.chatroomId, opts.role, pid, opts.agentHarness, opts.workingDir);
|
|
32395
32443
|
} catch {}
|
|
32396
32444
|
this.registerSpawnCallbacks(slot, opts, spawnResult, pid);
|
|
32397
32445
|
if (getHarnessCapabilities(opts.agentHarness).supportsNativeIntegration) {
|
|
@@ -32524,11 +32572,12 @@ class AgentProcessManager {
|
|
|
32524
32572
|
stopReason: reason,
|
|
32525
32573
|
exitCode: undefined,
|
|
32526
32574
|
signal: "SIGKILL",
|
|
32527
|
-
agentHarness: harness
|
|
32575
|
+
agentHarness: harness,
|
|
32576
|
+
workingDir: slot.workingDir
|
|
32528
32577
|
};
|
|
32529
32578
|
this.recordAgentExit(role, exitArgs, "Failed to record stop-timeout exit");
|
|
32530
32579
|
}
|
|
32531
|
-
await this.clearAgentPidQuietly(chatroomId, role);
|
|
32580
|
+
await this.clearAgentPidQuietly(chatroomId, role, slot.workingDir);
|
|
32532
32581
|
}
|
|
32533
32582
|
async doStop(key, slot, pid, opts, stopGeneration) {
|
|
32534
32583
|
try {
|
|
@@ -32554,7 +32603,8 @@ class AgentProcessManager {
|
|
|
32554
32603
|
chatroomId: opts.chatroomId,
|
|
32555
32604
|
role: opts.role,
|
|
32556
32605
|
pid,
|
|
32557
|
-
agentHarness: harness
|
|
32606
|
+
agentHarness: harness,
|
|
32607
|
+
workingDir: opts.workingDir
|
|
32558
32608
|
}),
|
|
32559
32609
|
reason: opts.reason
|
|
32560
32610
|
});
|
|
@@ -32571,12 +32621,12 @@ class AgentProcessManager {
|
|
|
32571
32621
|
}
|
|
32572
32622
|
this.resetSlotAfterStop(slot);
|
|
32573
32623
|
try {
|
|
32574
|
-
await this.deps.persistence.clearAgentPid(this.deps.machineId, opts.chatroomId, opts.role);
|
|
32624
|
+
await this.deps.persistence.clearAgentPid(this.deps.machineId, opts.chatroomId, opts.role, opts.workingDir);
|
|
32575
32625
|
} catch {}
|
|
32576
32626
|
return { success: true };
|
|
32577
32627
|
}
|
|
32578
32628
|
}
|
|
32579
|
-
var AGENT_EXIT_RETRY_INTERVAL_MS = 1e4, STOPPING_TIMEOUT_MS = 30000;
|
|
32629
|
+
var AGENT_KEY_SEPARATOR2 = "\x00", AGENT_EXIT_RETRY_INTERVAL_MS = 1e4, STOPPING_TIMEOUT_MS = 30000;
|
|
32580
32630
|
var init_agent_process_manager = __esm(() => {
|
|
32581
32631
|
init_agent();
|
|
32582
32632
|
init_types();
|
|
@@ -41534,8 +41584,8 @@ var init_storage2 = __esm(() => {
|
|
|
41534
41584
|
import * as fs5 from "node:fs/promises";
|
|
41535
41585
|
import { homedir as homedir5 } from "node:os";
|
|
41536
41586
|
import { join as join14 } from "node:path";
|
|
41537
|
-
function agentKey3(chatroomId, role) {
|
|
41538
|
-
return `${chatroomId}/${role}`;
|
|
41587
|
+
function agentKey3(chatroomId, role, workingDir) {
|
|
41588
|
+
return workingDir ? `${chatroomId}/${role}/${encodeURIComponent(workingDir)}` : `${chatroomId}/${role}`;
|
|
41539
41589
|
}
|
|
41540
41590
|
async function ensureStateDir() {
|
|
41541
41591
|
await fs5.mkdir(STATE_DIR, { recursive: true, mode: 448 });
|
|
@@ -41571,24 +41621,33 @@ async function loadOrCreate(machineId) {
|
|
|
41571
41621
|
agents: {}
|
|
41572
41622
|
};
|
|
41573
41623
|
}
|
|
41574
|
-
async function persistAgentPid(machineId, chatroomId, role, pid, harness) {
|
|
41624
|
+
async function persistAgentPid(machineId, chatroomId, role, pid, harness, workingDir) {
|
|
41575
41625
|
const state = await loadOrCreate(machineId);
|
|
41576
|
-
state.agents[agentKey3(chatroomId, role)] = {
|
|
41626
|
+
state.agents[agentKey3(chatroomId, role, workingDir)] = {
|
|
41577
41627
|
pid,
|
|
41578
41628
|
harness,
|
|
41579
|
-
startedAt: new Date().toISOString()
|
|
41629
|
+
startedAt: new Date().toISOString(),
|
|
41630
|
+
...workingDir ? { workingDir } : {}
|
|
41580
41631
|
};
|
|
41581
41632
|
state.updatedAt = new Date().toISOString();
|
|
41582
41633
|
await saveDaemonState(state);
|
|
41583
41634
|
}
|
|
41584
|
-
async function clearAgentPid(machineId, chatroomId, role) {
|
|
41635
|
+
async function clearAgentPid(machineId, chatroomId, role, workingDir) {
|
|
41585
41636
|
const state = await loadDaemonState(machineId);
|
|
41586
41637
|
if (!state)
|
|
41587
41638
|
return;
|
|
41588
|
-
const key = agentKey3(chatroomId, role);
|
|
41589
|
-
if (!(key in state.agents))
|
|
41590
|
-
|
|
41591
|
-
|
|
41639
|
+
const key = agentKey3(chatroomId, role, workingDir);
|
|
41640
|
+
if (!(key in state.agents)) {
|
|
41641
|
+
if (workingDir === undefined)
|
|
41642
|
+
return;
|
|
41643
|
+
const legacyKey = agentKey3(chatroomId, role);
|
|
41644
|
+
const legacy = state.agents[legacyKey];
|
|
41645
|
+
if (!legacy || legacy.workingDir !== workingDir)
|
|
41646
|
+
return;
|
|
41647
|
+
delete state.agents[legacyKey];
|
|
41648
|
+
} else {
|
|
41649
|
+
delete state.agents[key];
|
|
41650
|
+
}
|
|
41592
41651
|
state.updatedAt = new Date().toISOString();
|
|
41593
41652
|
await saveDaemonState(state);
|
|
41594
41653
|
}
|
|
@@ -41598,12 +41657,22 @@ async function listAgentEntries(machineId) {
|
|
|
41598
41657
|
return [];
|
|
41599
41658
|
const results = [];
|
|
41600
41659
|
for (const [key, entry] of Object.entries(state.agents)) {
|
|
41601
|
-
const
|
|
41602
|
-
if (
|
|
41660
|
+
const parts2 = key.split("/");
|
|
41661
|
+
if (parts2.length < 2)
|
|
41603
41662
|
continue;
|
|
41604
|
-
const chatroomId =
|
|
41605
|
-
const role =
|
|
41606
|
-
|
|
41663
|
+
const chatroomId = parts2[0];
|
|
41664
|
+
const role = parts2[1];
|
|
41665
|
+
if (parts2.length === 2) {
|
|
41666
|
+
results.push({ chatroomId, role, entry });
|
|
41667
|
+
continue;
|
|
41668
|
+
}
|
|
41669
|
+
try {
|
|
41670
|
+
results.push({
|
|
41671
|
+
chatroomId,
|
|
41672
|
+
role,
|
|
41673
|
+
entry: { ...entry, workingDir: decodeURIComponent(parts2.slice(2).join("/")) }
|
|
41674
|
+
});
|
|
41675
|
+
} catch {}
|
|
41607
41676
|
}
|
|
41608
41677
|
return results;
|
|
41609
41678
|
}
|
|
@@ -89828,8 +89897,8 @@ var AgentLifecycleOutboxService, AgentLifecycleOutboxServiceLive = (registry2, m
|
|
|
89828
89897
|
enqueue: (fact) => exports_Effect.promise(() => enqueueAgentLifecycleFact(registry2, machineId, fact)),
|
|
89829
89898
|
stopAll: () => exports_Effect.promise(() => registry2.stopAll())
|
|
89830
89899
|
}), DaemonMachineService, DaemonMachineServiceLive = (ops) => exports_Layer.succeed(DaemonMachineService, {
|
|
89831
|
-
clearAgentPid: (machineId, chatroomId, role) => exports_Effect.promise(() => ops.clearAgentPid(machineId, chatroomId, role)),
|
|
89832
|
-
persistAgentPid: (machineId, chatroomId, role, pid, harness) => exports_Effect.promise(() => ops.persistAgentPid(machineId, chatroomId, role, pid, harness)),
|
|
89900
|
+
clearAgentPid: (machineId, chatroomId, role, workingDir) => exports_Effect.promise(() => workingDir === undefined ? ops.clearAgentPid(machineId, chatroomId, role) : ops.clearAgentPid(machineId, chatroomId, role, workingDir)),
|
|
89901
|
+
persistAgentPid: (machineId, chatroomId, role, pid, harness, workingDir) => exports_Effect.promise(() => ops.persistAgentPid(machineId, chatroomId, role, pid, harness, workingDir)),
|
|
89833
89902
|
listAgentEntries: (machineId) => exports_Effect.promise(() => ops.listAgentEntries(machineId)),
|
|
89834
89903
|
persistEventCursor: (machineId, lastSeenEventId) => exports_Effect.promise(() => ops.persistEventCursor(machineId, lastSeenEventId)),
|
|
89835
89904
|
loadEventCursor: (machineId) => exports_Effect.promise(() => ops.loadEventCursor(machineId))
|
|
@@ -89839,7 +89908,7 @@ var AgentLifecycleOutboxService, AgentLifecycleOutboxServiceLive = (registry2, m
|
|
|
89839
89908
|
ensureRunning: (opts) => exports_Effect.promise(() => mgr.ensureRunning(opts)),
|
|
89840
89909
|
stop: (opts) => exports_Effect.promise(() => mgr.stop(opts)),
|
|
89841
89910
|
handleExit: (opts) => exports_Effect.promise(() => mgr.handleExit(opts)),
|
|
89842
|
-
getSlot: (chatroomId, role) => mgr.getSlot(chatroomId, role),
|
|
89911
|
+
getSlot: (chatroomId, role, workingDir) => workingDir === undefined ? mgr.getSlot(chatroomId, role) : mgr.getSlot(chatroomId, role, workingDir),
|
|
89843
89912
|
listActive: () => mgr.listActive(),
|
|
89844
89913
|
clearStuckStoppingSlot: (chatroomId, role, options) => exports_Effect.promise(() => mgr.clearStuckStoppingSlot(chatroomId, role, options)),
|
|
89845
89914
|
whenTurnEndsIdle: () => exports_Effect.promise(() => mgr.whenTurnEndsIdle()),
|
|
@@ -96032,13 +96101,13 @@ function sleep6(ms) {
|
|
|
96032
96101
|
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
96033
96102
|
}
|
|
96034
96103
|
async function waitForHarnessSessionId2(deps, event) {
|
|
96035
|
-
const initial = deps.agentMgr.getSlot(event.chatroomId, event.role);
|
|
96104
|
+
const initial = deps.agentMgr.getSlot(event.chatroomId, event.role, event.workingDir);
|
|
96036
96105
|
if (initial?.harnessSessionId) {
|
|
96037
96106
|
return initial.harnessSessionId;
|
|
96038
96107
|
}
|
|
96039
96108
|
const deadline = Date.now() + HARNESS_SESSION_READY_TIMEOUT_MS;
|
|
96040
96109
|
while (Date.now() < deadline) {
|
|
96041
|
-
const slot = deps.agentMgr.getSlot(event.chatroomId, event.role);
|
|
96110
|
+
const slot = deps.agentMgr.getSlot(event.chatroomId, event.role, event.workingDir);
|
|
96042
96111
|
if (slot?.harnessSessionId) {
|
|
96043
96112
|
return slot.harnessSessionId;
|
|
96044
96113
|
}
|
|
@@ -96063,8 +96132,8 @@ async function runRestartOrchestrator(deps, event) {
|
|
|
96063
96132
|
resetRoleDeliveryState(chatroomId, role);
|
|
96064
96133
|
await emitPhase(deps, event, "reset");
|
|
96065
96134
|
await emitPhase(deps, event, "spawn");
|
|
96066
|
-
const spawnResult = await deps.runSerializedForAgent({ chatroomId, role }, { timeoutMs: HARNESS_SESSION_READY_TIMEOUT_MS }, async (ops, context5) => {
|
|
96067
|
-
await ops.stopAgent({ chatroomId, role, reason: "user.restart" }, context5.signal);
|
|
96135
|
+
const spawnResult = await deps.runSerializedForAgent({ chatroomId, role, workingDir: event.workingDir }, { timeoutMs: HARNESS_SESSION_READY_TIMEOUT_MS }, async (ops, context5) => {
|
|
96136
|
+
await ops.stopAgent({ chatroomId, role, reason: "user.restart", workingDir: event.workingDir }, context5.signal);
|
|
96068
96137
|
return ops.startAgent({
|
|
96069
96138
|
chatroomId,
|
|
96070
96139
|
role,
|
|
@@ -96082,7 +96151,13 @@ async function runRestartOrchestrator(deps, event) {
|
|
|
96082
96151
|
await emitPhase(deps, event, "await_session");
|
|
96083
96152
|
const harnessSessionId = await waitForHarnessSessionId2(deps, event);
|
|
96084
96153
|
if (!harnessSessionId) {
|
|
96085
|
-
await deps.runSerializedForAgent({ chatroomId, role }, { timeoutMs: HARNESS_SESSION_READY_TIMEOUT_MS }, (ops, context5) => ops.stopAgent({
|
|
96154
|
+
await deps.runSerializedForAgent({ chatroomId, role, workingDir: event.workingDir }, { timeoutMs: HARNESS_SESSION_READY_TIMEOUT_MS }, (ops, context5) => ops.stopAgent({
|
|
96155
|
+
chatroomId,
|
|
96156
|
+
role,
|
|
96157
|
+
reason: "user.restart",
|
|
96158
|
+
pid: spawnResult.pid,
|
|
96159
|
+
workingDir: event.workingDir
|
|
96160
|
+
}, context5.signal));
|
|
96086
96161
|
await emitPhase(deps, event, "failed", "harnessSessionId timeout");
|
|
96087
96162
|
return;
|
|
96088
96163
|
}
|
|
@@ -103925,17 +104000,17 @@ var init_deps = __esm(() => {
|
|
|
103925
104000
|
// src/daemon/entry/execute-chatroom-stop-command.ts
|
|
103926
104001
|
async function executeChatroomStopCommand(args2) {
|
|
103927
104002
|
if (args2.role)
|
|
103928
|
-
args2.apm.markStopIntent(args2.chatroomId, args2.role, "user.stop");
|
|
103929
|
-
else {
|
|
104003
|
+
args2.apm.markStopIntent(args2.chatroomId, args2.role, "user.stop", undefined, args2.workingDir);
|
|
104004
|
+
else if (!args2.workingDir) {
|
|
103930
104005
|
args2.apm.markChatroomStopIntent(args2.chatroomId, "user.stop");
|
|
103931
104006
|
await abortEnhancerSpawnsForChatroom(args2.chatroomId);
|
|
103932
104007
|
}
|
|
103933
104008
|
const confirmedDeps = args2.apm.getConfirmedStopAdapterDeps();
|
|
103934
104009
|
const targets = await args2.apm.discoverStopTargets(args2.chatroomId);
|
|
103935
104010
|
const roles = [
|
|
103936
|
-
...new Set(targets.filter((target) => !args2.role || target.role.toLowerCase() === args2.role.toLowerCase()).map((target) => target.role.toLowerCase()))
|
|
104011
|
+
...new Set(targets.filter((target) => (!args2.role || target.role.toLowerCase() === args2.role.toLowerCase()) && (!args2.workingDir || target.workingDir === args2.workingDir)).map((target) => target.role.toLowerCase()))
|
|
103937
104012
|
];
|
|
103938
|
-
const results = await Promise.allSettled(roles.map((role) => args2.runSerializedForAgent({ chatroomId: args2.chatroomId, role }, { timeoutMs: AGENT_LIFECYCLE_OPERATION_TIMEOUT_MS }, async (_ops, context5) => {
|
|
104013
|
+
const results = await Promise.allSettled(roles.map((role) => args2.runSerializedForAgent({ chatroomId: args2.chatroomId, role, workingDir: args2.workingDir }, { timeoutMs: AGENT_LIFECYCLE_OPERATION_TIMEOUT_MS }, async (_ops, context5) => {
|
|
103939
104014
|
if (context5.signal.aborted)
|
|
103940
104015
|
throw context5.signal.reason;
|
|
103941
104016
|
await runRoleScopedStop({
|
|
@@ -103943,7 +104018,8 @@ async function executeChatroomStopCommand(args2) {
|
|
|
103943
104018
|
confirmedDeps,
|
|
103944
104019
|
chatroomId: args2.chatroomId,
|
|
103945
104020
|
role,
|
|
103946
|
-
reason: "user.stop"
|
|
104021
|
+
reason: "user.stop",
|
|
104022
|
+
workingDir: args2.workingDir
|
|
103947
104023
|
});
|
|
103948
104024
|
})));
|
|
103949
104025
|
for (const result of results)
|
|
@@ -133735,6 +133811,7 @@ async function startDaemon() {
|
|
|
133735
133811
|
chatroomId: stopCommand.chatroomId,
|
|
133736
133812
|
commandId: stopCommand.commandId,
|
|
133737
133813
|
role: stopCommand.role,
|
|
133814
|
+
workingDir: stopCommand.workingDir,
|
|
133738
133815
|
finalizeChatroom: stopCommand.finalizeChatroom,
|
|
133739
133816
|
runSerializedForAgent: init2.agentProcessManagerService.runSerializedForAgent
|
|
133740
133817
|
});
|
|
@@ -135008,4 +135085,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
135008
135085
|
});
|
|
135009
135086
|
program2.parse();
|
|
135010
135087
|
|
|
135011
|
-
//# debugId=
|
|
135088
|
+
//# debugId=0132031C48F1331264756E2164756E21
|