chatroom-cli 1.115.2 → 1.115.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 CHANGED
@@ -27949,7 +27949,7 @@ var init_v_literals_of = __esm(() => {
27949
27949
  });
27950
27950
 
27951
27951
  // ../../services/backend/src/domain/entities/agent.ts
27952
- var AGENT_HARNESSES, AgentHarnessEnum, agentHarnessValidator, AGENT_TYPES, AgentTypeEnum, agentTypeValidator, MACHINE_COMMAND_TYPES, MachineCommandTypeEnum, machineCommandTypeValidator, MACHINE_COMMAND_STATUSES, MachineCommandStatusEnum, machineCommandStatusValidator, AGENT_START_REASONS, AgentStartReasonEnum, agentStartReasonValidator, USER_EXPLICIT_START_REASONS, EXPLICIT_DAEMON_START_REASONS, isExplicitDaemonStart = (reason) => EXPLICIT_DAEMON_START_REASONS.includes(reason), AGENT_STOP_REASONS, agentPostStopDesiredStateValidator, AgentStopReasonEnum, agentStopReasonValidator, isAgentStopReason = (value) => AGENT_STOP_REASONS.includes(value), MODEL_SOURCES, ModelSourceEnum, modelSourceValidator;
27952
+ var AGENT_HARNESSES, AgentHarnessEnum, agentHarnessValidator, AGENT_TYPES, AgentTypeEnum, agentTypeValidator, MACHINE_COMMAND_TYPES, MachineCommandTypeEnum, machineCommandTypeValidator, MACHINE_COMMAND_STATUSES, MachineCommandStatusEnum, machineCommandStatusValidator, AGENT_START_REASONS, AgentStartReasonEnum, agentStartReasonValidator, USER_EXPLICIT_START_REASONS, EXPLICIT_DAEMON_START_REASONS, isExplicitDaemonStart = (reason) => EXPLICIT_DAEMON_START_REASONS.includes(reason), AGENT_STOP_REASONS, agentPostStopDesiredStateValidator, AgentStopReasonEnum, agentStopReasonValidator, MODEL_SOURCES, ModelSourceEnum, modelSourceValidator;
27953
27953
  var init_agent = __esm(() => {
27954
27954
  init_values();
27955
27955
  init_v_literals_of();
@@ -28127,7 +28127,7 @@ function normalizeAgentLifecycleFact(raw) {
28127
28127
  emittedAt: Number(rest.emittedAt)
28128
28128
  };
28129
28129
  }
28130
- if (kind === "spawned" || kind === "exited" || kind === "activity" || kind === "turn_failed") {
28130
+ if (kind === "spawned" || kind === "exited" || kind === "activity" || kind === "turn_failed" || kind === "chatroom_shutdown_complete") {
28131
28131
  return rest;
28132
28132
  }
28133
28133
  throw new Error(`Unknown agent lifecycle fact kind: ${String(kind)}`);
@@ -28147,6 +28147,8 @@ function buildActivityLifecycleFact(params) {
28147
28147
  function agentLifecycleDeliveryKey(machineId, fact) {
28148
28148
  if (fact.kind === "cleared_all_pids")
28149
28149
  return `${machineId}:__machine__`;
28150
+ if (fact.kind === "chatroom_shutdown_complete")
28151
+ return `${machineId}:${fact.chatroomId}:shutdown:${fact.commandId}`;
28150
28152
  return `${machineId}:${fact.chatroomId}:${fact.role.toLowerCase()}`;
28151
28153
  }
28152
28154
  function buildAgentLifecycleRevisionKey(prefix, parts2) {
@@ -28172,7 +28174,7 @@ function isTurnPhaseIdle(phase) {
28172
28174
  var init_check_agent_slot = () => {};
28173
28175
 
28174
28176
  // src/daemon/services/task-service/domain/usecase/native-cold-session-delivery.ts
28175
- function snapshotRequestsNativeColdSession(task) {
28177
+ function taskRequestsNativeColdSession(task) {
28176
28178
  return task.requestsNativeColdSession === true;
28177
28179
  }
28178
28180
  function isColdStartEligibleSlotState(slot) {
@@ -28181,10 +28183,10 @@ function isColdStartEligibleSlotState(slot) {
28181
28183
  return isSlotIdle(slot.state);
28182
28184
  }
28183
28185
  function isNativeColdSessionDeliveryOwnedSpawn(task, slot) {
28184
- return snapshotRequestsNativeColdSession(task) && isColdStartEligibleSlotState(slot);
28186
+ return taskRequestsNativeColdSession(task) && isColdStartEligibleSlotState(slot);
28185
28187
  }
28186
28188
  function explainColdSessionDeliveryBlock(task, slot) {
28187
- if (!snapshotRequestsNativeColdSession(task))
28189
+ if (!taskRequestsNativeColdSession(task))
28188
28190
  return null;
28189
28191
  if (isChatroomStopScopeActive(task.chatroomId)) {
28190
28192
  return "chatroom_stop_scope_active";
@@ -28429,9 +28431,6 @@ var init_assigned_task = __esm(() => {
28429
28431
  });
28430
28432
 
28431
28433
  // src/daemon/services/task-service/domain/usecase/native-ready-invariant.ts
28432
- function isAgentReadyForNativeDelivery(task, slot) {
28433
- return explainAgentReadyForNativeDeliveryBlock(task, slot) === null;
28434
- }
28435
28434
  function explainAgentReadyForNativeDeliveryBlock(task, slot) {
28436
28435
  const runtimeConfig = resolveAgentRuntimeConfig(task, slot);
28437
28436
  if (!runtimeConfig)
@@ -28447,13 +28446,10 @@ function explainAgentReadyForNativeDeliveryBlock(task, slot) {
28447
28446
  return null;
28448
28447
  }
28449
28448
  if (!slot) {
28450
- return task.agentConfig.spawnedAgentPid == null ? "spawned_pid_missing" : `slot_missing (expectedPid=${task.agentConfig.spawnedAgentPid})`;
28449
+ return "slot_missing";
28451
28450
  }
28452
28451
  if (!isSlotRunning(slot.state)) {
28453
- if (task.agentConfig.spawnedAgentPid != null && slot.pid !== task.agentConfig.spawnedAgentPid) {
28454
- return `pid_mismatch (slotPid=${slot.pid ?? "none"}, expectedPid=${task.agentConfig.spawnedAgentPid})`;
28455
- }
28456
- return `slot_not_running (slotState=${slot.state}, expectedPid=${task.agentConfig.spawnedAgentPid ?? "none"})`;
28452
+ return `slot_not_running (slotState=${slot.state})`;
28457
28453
  }
28458
28454
  if (slot.pid == null) {
28459
28455
  return "slot_pid_missing";
@@ -28510,9 +28506,6 @@ var init_native_integration = __esm(() => {
28510
28506
  });
28511
28507
 
28512
28508
  // src/daemon/services/task-service/domain/usecase/native-task-injector-logic.ts
28513
- function shouldDeliverNativeTask(task, opts) {
28514
- return explainNativeDeliveryBlock(task, opts) === null;
28515
- }
28516
28509
  function explainNativeDeliveryBlock(task, opts) {
28517
28510
  if (!isDeliverableNativeTaskStatus(task.status)) {
28518
28511
  return `task_status_not_deliverable (status=${task.status})`;
@@ -28546,8 +28539,8 @@ var init_native_task_injector_logic = __esm(() => {
28546
28539
  // ../../services/backend/src/domain/entities/participant.ts
28547
28540
  var NATIVE_WAITING_ACTION = "native:waiting", NATIVE_TASK_INJECTED_ACTION = "native:task-injected", GET_NEXT_TASK_STARTED_ACTION = "get-next-task:started";
28548
28541
 
28549
- // src/infrastructure/mappers/map-assigned-task.ts
28550
- function mapAssignedTaskSnapshot(row) {
28542
+ // src/infrastructure/mappers/map-assigned-task-view.ts
28543
+ function mapAssignedTask(row) {
28551
28544
  return {
28552
28545
  taskId: row.taskId,
28553
28546
  chatroomId: row.chatroomId,
@@ -28557,11 +28550,7 @@ function mapAssignedTaskSnapshot(row) {
28557
28550
  createdAt: row.createdAt,
28558
28551
  agentConfig: {
28559
28552
  role: row.agentConfig.role,
28560
- machineId: row.agentConfig.machineId,
28561
- spawnedAgentPid: row.agentConfig.spawnedAgentPid,
28562
- desiredState: row.agentConfig.desiredState,
28563
- circuitState: row.agentConfig.circuitState,
28564
- configLifecycleRevision: row.agentConfig.configLifecycleRevision
28553
+ machineId: row.agentConfig.machineId
28565
28554
  },
28566
28555
  assignee: row.assignee,
28567
28556
  participant: row.participant,
@@ -28570,7 +28559,7 @@ function mapAssignedTaskSnapshot(row) {
28570
28559
  }
28571
28560
  function mapAssignedTaskView(row) {
28572
28561
  return {
28573
- ...mapAssignedTaskSnapshot(row),
28562
+ ...mapAssignedTask(row),
28574
28563
  taskContent: row.taskContent,
28575
28564
  taskEnvelope: row.taskEnvelope,
28576
28565
  startInNewSession: row.startInNewSession
@@ -28744,8 +28733,6 @@ function stableBlockReason(reason) {
28744
28733
  "slot_missing",
28745
28734
  "slot_not_running",
28746
28735
  "slot_pid_missing",
28747
- "spawned_pid_missing",
28748
- "pid_mismatch",
28749
28736
  "harness_session_missing",
28750
28737
  "turn_not_idle",
28751
28738
  "working_dir_missing"
@@ -28797,14 +28784,17 @@ function decideNextDelivery(tasks, context5) {
28797
28784
  if (isSlotStopping(context5.slot?.state ?? "idle")) {
28798
28785
  return { kind: "wait", taskId: task.taskId, reason: "slot_stopping" };
28799
28786
  }
28800
- const coldSession = context5.snapshotRequestsNativeColdSession(task);
28801
- const startAllowed = blockReason.startsWith("slot_missing") || blockReason.startsWith("slot_not_running") || blockReason.startsWith("spawned_pid_missing");
28787
+ const coldSession = context5.taskRequestsNativeColdSession(task);
28788
+ const startAllowed = blockReason.startsWith("slot_missing") || blockReason.startsWith("slot_not_running");
28802
28789
  if (startAllowed && !coldSession && task.status === "pending" && isSlotIdle(context5.slot?.state ?? "idle") && runtimeConfig.workingDir) {
28803
28790
  return { kind: "start-agent", taskId: task.taskId };
28804
28791
  }
28805
28792
  if (blockReason.startsWith("harness_session_missing")) {
28806
28793
  return { kind: "wait", taskId: task.taskId, reason: "session_not_ready" };
28807
28794
  }
28795
+ if (blockReason.startsWith("turn_not_idle")) {
28796
+ return { kind: "wait", taskId: task.taskId, reason: "turn_not_idle" };
28797
+ }
28808
28798
  return { kind: "blocked", taskId: task.taskId, reason: stableBlockReason(blockReason) };
28809
28799
  }
28810
28800
  var init_delivery_decision = __esm(() => {
@@ -28930,7 +28920,7 @@ class NativeTaskDeliveryCoordinator {
28930
28920
  deliveryInFlight: false,
28931
28921
  agentLifecycleInFlight: isRestartOrchestratorInFlight(firstTask.chatroomId, role),
28932
28922
  isNativeHarness: taskService.isNativeHarness,
28933
- snapshotRequestsNativeColdSession: taskService.snapshotRequestsNativeColdSession,
28923
+ taskRequestsNativeColdSession: taskService.taskRequestsNativeColdSession,
28934
28924
  explainNativeDeliveryBlock: taskService.explainNativeDeliveryBlock
28935
28925
  });
28936
28926
  const attemptId = `${Date.now()}-${firstTask.taskId}`;
@@ -28970,7 +28960,6 @@ class NativeTaskDeliveryCoordinator {
28970
28960
  workingDir: runtimeConfig.workingDir,
28971
28961
  reason: AgentStartReasonEnum["platform.pending_task_wake"],
28972
28962
  wantResume: false,
28973
- lifecycleRevision: row.agentConfig.configLifecycleRevision,
28974
28963
  taskId: row.taskId
28975
28964
  }, context5.signal));
28976
28965
  console.log(`[NativeDelivery:execution] attempt=${attemptId} role=${role} chatroom=${row.chatroomId} task=${row.taskId} operation=start-agent result=${startResult && typeof startResult === "object" && "success" in startResult ? startResult.success : "completed"}`);
@@ -29043,7 +29032,7 @@ var init_native_task_delivery_coordinator = __esm(() => {
29043
29032
 
29044
29033
  // src/daemon/services/task-service/service/native-delivery/task-delivery-processor.ts
29045
29034
  async function processTasksUpdate(runtime4, effectContext2, agentMgr, runSerializedForAgent, taskService, sessionDeps, machineId, pass, lifecycleOutbox, isTaskActive, options) {
29046
- const first = options.snapshots[0];
29035
+ const first = options.tasks[0];
29047
29036
  if (!first)
29048
29037
  return;
29049
29038
  logNativeDeliveryTrigger(pass, first.agentConfig.role, first.chatroomId, first.taskId);
@@ -29060,7 +29049,6 @@ async function processTasksUpdate(runtime4, effectContext2, agentMgr, runSeriali
29060
29049
  workingDir: runtimeConfig.workingDir,
29061
29050
  reason: AgentStartReasonEnum["platform.pending_task_wake"],
29062
29051
  wantResume: false,
29063
- lifecycleRevision: task.agentConfig.configLifecycleRevision,
29064
29052
  taskId: task.taskId
29065
29053
  }, context5.signal));
29066
29054
  },
@@ -29080,7 +29068,7 @@ async function processTasksUpdate(runtime4, effectContext2, agentMgr, runSeriali
29080
29068
  }
29081
29069
  };
29082
29070
  await getNativeTaskDeliveryCoordinator().reconcileRoleTasks({
29083
- tasks: [...options.snapshots],
29071
+ tasks: [...options.tasks],
29084
29072
  pass,
29085
29073
  runtime: runtime4,
29086
29074
  effectContext: effectContext2,
@@ -29264,7 +29252,7 @@ function resolveSessionAugmentationForTask(task, role) {
29264
29252
  }
29265
29253
  return resolveSessionAugmentationForRole(role);
29266
29254
  }
29267
- function taskRequestsNativeColdSession(task) {
29255
+ function taskRequestsNativeColdSession2(task) {
29268
29256
  if (task.taskEnvelope !== undefined) {
29269
29257
  return normalizeTaskEnvelope({ taskEnvelope: task.taskEnvelope }).sessionPolicy === "new";
29270
29258
  }
@@ -29287,12 +29275,11 @@ var init_parse_session_augmentation = __esm(() => {
29287
29275
  });
29288
29276
 
29289
29277
  // ../../services/backend/config/reliability.ts
29290
- var HARNESS_SESSION_READY_TIMEOUT_MS = 5000, DAEMON_HEARTBEAT_INTERVAL_MS, DAEMON_HEARTBEAT_TTL_MS, AGENT_REQUEST_DEADLINE_MS = 120000, MACHINE_COMMAND_LEASE_RENEWAL_INTERVAL_MS = 20000, MACHINE_COMMAND_DAEMON_ROUTINE_TTL_MS, AGENT_STOP_TERMINAL_RETENTION_MS, SCOPE_TARGET_STOP_TIMEOUT_MS = 1e4, AGENT_LIFECYCLE_OPERATION_TIMEOUT_MS = 120000, CONNECTION_CLOSE_REQUEST_TTL_MS, ENHANCER_TERMINAL_JOB_RETENTION_MS;
29278
+ var HARNESS_SESSION_READY_TIMEOUT_MS = 5000, DAEMON_HEARTBEAT_INTERVAL_MS, DAEMON_HEARTBEAT_TTL_MS, AGENT_REQUEST_DEADLINE_MS = 120000, MACHINE_COMMAND_LEASE_RENEWAL_INTERVAL_MS = 20000, MACHINE_COMMAND_DAEMON_ROUTINE_TTL_MS, SCOPE_TARGET_STOP_TIMEOUT_MS = 1e4, AGENT_LIFECYCLE_OPERATION_TIMEOUT_MS = 120000, CONNECTION_CLOSE_REQUEST_TTL_MS, ENHANCER_TERMINAL_JOB_RETENTION_MS;
29291
29279
  var init_reliability = __esm(() => {
29292
29280
  DAEMON_HEARTBEAT_INTERVAL_MS = 5 * 60000;
29293
29281
  DAEMON_HEARTBEAT_TTL_MS = 6 * DAEMON_HEARTBEAT_INTERVAL_MS;
29294
29282
  MACHINE_COMMAND_DAEMON_ROUTINE_TTL_MS = 5 * 60000;
29295
- AGENT_STOP_TERMINAL_RETENTION_MS = 30 * 24 * 60 * 60 * 1000;
29296
29283
  CONNECTION_CLOSE_REQUEST_TTL_MS = 10 * 60000;
29297
29284
  ENHANCER_TERMINAL_JOB_RETENTION_MS = 30 * 24 * 60 * 60 * 1000;
29298
29285
  });
@@ -29314,7 +29301,7 @@ async function waitForHarnessSessionId(agentMgr, chatroomId, role, signal) {
29314
29301
  return null;
29315
29302
  }
29316
29303
  async function ensureColdSessionBeforeNativeInject(task, deps) {
29317
- if (!taskRequestsNativeColdSession({
29304
+ if (!taskRequestsNativeColdSession2({
29318
29305
  content: task.taskContent ?? "",
29319
29306
  taskEnvelope: task.taskEnvelope,
29320
29307
  startInNewSession: task.startInNewSession
@@ -29460,7 +29447,7 @@ function claimPendingTaskIfNeeded(task, deps) {
29460
29447
  });
29461
29448
  }
29462
29449
  function resolveHarnessSessionPolicy(task, initialHarnessSessionId) {
29463
- if (!taskRequestsNativeColdSession({
29450
+ if (!taskRequestsNativeColdSession2({
29464
29451
  content: task.taskContent ?? "",
29465
29452
  taskEnvelope: task.taskEnvelope,
29466
29453
  startInNewSession: task.startInNewSession
@@ -29674,7 +29661,7 @@ class AgentWorkManager {
29674
29661
  });
29675
29662
  this.deliveryTaskService = {
29676
29663
  isNativeHarness,
29677
- snapshotRequestsNativeColdSession,
29664
+ taskRequestsNativeColdSession,
29678
29665
  explainNativeDeliveryBlock,
29679
29666
  releaseTaskAfterTurnFailure: deps.taskService.releaseTaskAfterTurnFailure,
29680
29667
  loadAssignedTaskForAction: deps.taskService.loadAssignedTaskForAction,
@@ -29777,7 +29764,7 @@ class AgentWorkManager {
29777
29764
  }
29778
29765
  async handleTaskServiceNotification(notification) {
29779
29766
  if (notification.kind === "bootstrap") {
29780
- await this.requestReconcileForSnapshots(notification.snapshots, "bootstrap");
29767
+ await this.requestReconcileForTasks(notification.tasks, "bootstrap");
29781
29768
  return;
29782
29769
  }
29783
29770
  if (notification.event.eventType === "task_deleted" /* TaskDeleted */) {
@@ -29825,14 +29812,14 @@ class AgentWorkManager {
29825
29812
  do {
29826
29813
  const source = state.pendingSource ?? params.source;
29827
29814
  state.pendingSource = undefined;
29828
- const snapshots = this.deps.taskSnapshotState.listForRole(params.chatroomId, params.role);
29829
- if (snapshots.length === 0) {
29815
+ const tasks = this.deps.taskInboxState.listForRole(params.chatroomId, params.role);
29816
+ if (tasks.length === 0) {
29830
29817
  logNativeDeliveryDecision(source, params.role, params.chatroomId, "idle", undefined, {
29831
29818
  reason: "no_deliverable_task",
29832
29819
  attemptId: `${Date.now()}-${params.chatroomId}-${params.role}`
29833
29820
  });
29834
29821
  }
29835
- await this.reconcileRole(source, snapshots, params.onTaskDelivered);
29822
+ await this.reconcileRole(source, tasks, params.onTaskDelivered);
29836
29823
  } while (state.pendingSource !== undefined);
29837
29824
  } finally {
29838
29825
  if (this.reconcileStates.get(key) === state)
@@ -29854,8 +29841,8 @@ class AgentWorkManager {
29854
29841
  });
29855
29842
  return delivered;
29856
29843
  }
29857
- async requestReconcileForSnapshots(snapshots, source) {
29858
- const roles = new Set(snapshots.map((snapshot) => `${snapshot.chatroomId}:${snapshot.agentConfig.role.toLowerCase()}`));
29844
+ async requestReconcileForTasks(tasks, source) {
29845
+ const roles = new Set(tasks.map((snapshot) => `${snapshot.chatroomId}:${snapshot.agentConfig.role.toLowerCase()}`));
29859
29846
  await Promise.all([...roles].map((key) => {
29860
29847
  const separator = key.indexOf(":");
29861
29848
  return this.requestReconcile({
@@ -29865,11 +29852,11 @@ class AgentWorkManager {
29865
29852
  });
29866
29853
  }));
29867
29854
  }
29868
- async reconcileRole(pass, snapshots, onTaskDelivered) {
29869
- if (snapshots.length === 0)
29855
+ async reconcileRole(pass, tasks, onTaskDelivered) {
29856
+ if (tasks.length === 0)
29870
29857
  return;
29871
29858
  await processTasksUpdate(this.deps.runtime, this.deps.effectContext, this.deps.agentMgr, this.deps.runSerializedForAgent, this.deliveryTaskService, this.deps.sessionDeps, this.deps.machineId, pass, this.deps.lifecycleOutbox, ({ chatroomId, role, taskId }) => this.deps.agentTaskState.get({ chatroomId, role })?.taskId === taskId, {
29872
- snapshots,
29859
+ tasks,
29873
29860
  onTaskDelivered: (args2) => {
29874
29861
  this.recordTaskDelivered(args2);
29875
29862
  onTaskDelivered?.(args2);
@@ -30291,11 +30278,6 @@ var init_agent_task_state = () => {};
30291
30278
  function defaultNativeTurnPhase() {
30292
30279
  return "idle";
30293
30280
  }
30294
- function isNativeSlotIdleForDelivery(slot) {
30295
- if (slot?.state !== "running")
30296
- return false;
30297
- return (slot.nativeTurnPhase ?? defaultNativeTurnPhase()) === "idle";
30298
- }
30299
30281
  function setNativeTurnPhase(slot, phase) {
30300
30282
  slot.nativeTurnPhase = phase;
30301
30283
  }
@@ -30441,9 +30423,6 @@ function normalizeAgentStopRole(role) {
30441
30423
  function buildAgentStopTargetKey(args2) {
30442
30424
  return `${args2.machineId}:${normalizeAgentStopRole(args2.role)}:${args2.pid}`;
30443
30425
  }
30444
- function buildAgentStopRevisionKey(args2) {
30445
- return `${args2.stopCommandId}:${args2.targetKey}`;
30446
- }
30447
30426
 
30448
30427
  // src/infrastructure/deps/process.ts
30449
30428
  function isProcessAlive(kill, pid) {
@@ -30675,9 +30654,6 @@ function createChatroomScopeBarrier() {
30675
30654
  }
30676
30655
  };
30677
30656
  }
30678
- function resetChatroomScopeBarrierForTests() {
30679
- activeChatroomScopeDepth.clear();
30680
- }
30681
30657
  function createStopAgentTargetsDeps(args2) {
30682
30658
  const confirmed = createStopAgentConfirmedDeps(args2.confirmedDeps);
30683
30659
  return {
@@ -30707,26 +30683,6 @@ async function runRoleScopedStop(args2) {
30707
30683
  targets
30708
30684
  });
30709
30685
  }
30710
- function createStopAgentTargetsDepsForCommand(args2) {
30711
- const base = createStopAgentTargetsDeps(args2);
30712
- return {
30713
- ...base,
30714
- buildRevisionKey: (target) => buildAgentStopRevisionKey({ stopCommandId: args2.stopCommandId, targetKey: target.targetKey })
30715
- };
30716
- }
30717
- async function runExactTargetsStop(args2) {
30718
- const deps = createStopAgentTargetsDepsForCommand(args2);
30719
- const targets = args2.targets.map((target) => ({
30720
- ...target,
30721
- agentHarness: target.agentHarness
30722
- }));
30723
- return stopAgentTargets(deps, {
30724
- chatroomId: args2.chatroomId,
30725
- scope: { kind: "chatroom" },
30726
- reason: args2.reason,
30727
- targets
30728
- });
30729
- }
30730
30686
  var activeChatroomScopeDepth;
30731
30687
  var init_execute_stop_targets_adapter = __esm(() => {
30732
30688
  init_stop_agent_confirmed_adapter();
@@ -30961,9 +30917,6 @@ var init_agent_lifecycle_service = __esm(() => {
30961
30917
  const key = agentKey(opts.chatroomId, opts.role);
30962
30918
  const currentSlot = yield* getSlotFromRef(key);
30963
30919
  if (currentSlot && currentSlot.state !== "idle") {
30964
- if (opts.lifecycleRevision !== undefined && currentSlot.authorizedLifecycleRevision !== opts.lifecycleRevision) {
30965
- return { success: false, error: "stale_revision" };
30966
- }
30967
30920
  return {
30968
30921
  success: true,
30969
30922
  pid: currentSlot.pid
@@ -31527,9 +31480,6 @@ class AgentProcessManager {
31527
31480
  } else if (slot.stopRequested) {
31528
31481
  return { success: false, error: "stop_requested" };
31529
31482
  }
31530
- if (slot.state !== "idle" && opts.lifecycleRevision !== undefined && slot.authorizedLifecycleRevision !== opts.lifecycleRevision) {
31531
- return { success: false, error: "stale_revision" };
31532
- }
31533
31483
  if (slot.state === "running" && slot.pid && !isProcessAlive(this.deps.processes.kill, slot.pid)) {
31534
31484
  this.clearSlotRuntimeState(slot);
31535
31485
  }
@@ -32242,12 +32192,6 @@ class AgentProcessManager {
32242
32192
  }).catch((err) => {
32243
32193
  console.log(` ⚠️ Failed to record agent.started event: ${err.message}`);
32244
32194
  });
32245
- const lifecycleRevision = slot.authorizedLifecycleRevision ?? opts.lifecycleRevision;
32246
- if (lifecycleRevision === undefined) {
32247
- this.deps.processes.kill(pid, "SIGTERM");
32248
- this.resetSlotIdle(slot);
32249
- return Promise.resolve();
32250
- }
32251
32195
  const emittedAt = this.deps.clock.now();
32252
32196
  return this.deps.lifecycleOutbox.enqueue({
32253
32197
  kind: "spawned",
@@ -32263,14 +32207,9 @@ class AgentProcessManager {
32263
32207
  pid,
32264
32208
  emittedAt
32265
32209
  }),
32266
- emittedAt,
32267
- lifecycleRevision
32268
- }).then((result) => {
32269
- if (result.rejectionReason) {
32270
- console.log(` ⚠️ Spawn rejected by backend: ${result.rejectionReason}`);
32271
- this.deps.processes.kill(pid, "SIGTERM");
32272
- this.resetSlotIdle(slot);
32273
- }
32210
+ emittedAt
32211
+ }).then(() => {
32212
+ return;
32274
32213
  }).catch((err) => console.log(` ⚠️ Failed to enqueue agent spawned lifecycle fact: ${err.message}`));
32275
32214
  }
32276
32215
  registerSpawnCallbacks(slot, opts, spawnResult, pid) {
@@ -32403,14 +32342,12 @@ class AgentProcessManager {
32403
32342
  machineId: this.deps.machineId,
32404
32343
  chatroomId: opts.chatroomId,
32405
32344
  role: opts.role,
32406
- lifecycleRevision: opts.lifecycleRevision,
32407
32345
  taskId: opts.taskId
32408
32346
  });
32409
32347
  if (!authorization.allowed) {
32410
32348
  this.resetSlotIdle(slot);
32411
32349
  return { success: false, error: authorization.reason };
32412
32350
  }
32413
- slot.authorizedLifecycleRevision = authorization.lifecycleRevision;
32414
32351
  const wantResume = opts.wantResume;
32415
32352
  console.log(`[AgentProcessManager] harness start: role=${opts.role} harness=${opts.agentHarness} wantResume=${wantResume} reason=${opts.reason}`);
32416
32353
  try {
@@ -32470,8 +32407,6 @@ class AgentProcessManager {
32470
32407
  async forceClearStuckStoppingSlot(key, slot, chatroomId, role, reason, clearStopIntent = false) {
32471
32408
  const pid = slot.pid;
32472
32409
  const harness = slot.harness;
32473
- const stopCommandId = slot.stopCommandId;
32474
- const stopTargetKey = slot.stopTargetKey;
32475
32410
  const durationMs = slot.stoppingSince ? this.deps.clock.now() - slot.stoppingSince : STOPPING_TIMEOUT_MS;
32476
32411
  this.bumpStopGeneration(slot);
32477
32412
  this.clearSlotRuntimeState(slot);
@@ -32505,32 +32440,6 @@ class AgentProcessManager {
32505
32440
  };
32506
32441
  this.recordAgentExit(role, exitArgs, "Failed to record stop-timeout exit");
32507
32442
  }
32508
- if (pid && stopCommandId && stopTargetKey) {
32509
- try {
32510
- await this.deps.backend.mutation(api.agentStops.reportTargetOutcome, {
32511
- sessionId: this.deps.sessionId,
32512
- stopCommandId,
32513
- chatroomId,
32514
- machineId: this.deps.machineId,
32515
- targetKey: stopTargetKey,
32516
- role,
32517
- pid,
32518
- status: "failed",
32519
- outcome: "failed",
32520
- termination: "forced",
32521
- errorMessage: "Daemon force-cleared a timed-out stop operation"
32522
- });
32523
- await this.deps.backend.mutation(api.agentStops.completeMachineExecution, {
32524
- sessionId: this.deps.sessionId,
32525
- stopCommandId,
32526
- machineId: this.deps.machineId,
32527
- status: "failed",
32528
- errorMessage: "Daemon force-cleared a timed-out stop operation"
32529
- });
32530
- } catch (error) {
32531
- console.log(` ⚠️ Failed to finalize timed-out stop for ${role}@${chatroomId}: ${error.message}`);
32532
- }
32533
- }
32534
32443
  await this.clearAgentPidQuietly(chatroomId, role);
32535
32444
  }
32536
32445
  async doStop(key, slot, pid, opts, stopGeneration) {
@@ -32618,10 +32527,7 @@ function createHarnessActivityEmitter() {
32618
32527
  }
32619
32528
  };
32620
32529
  }
32621
- var HARNESS_ACTIVITY_KINDS;
32622
- var init_harness_activity_emitter = __esm(() => {
32623
- HARNESS_ACTIVITY_KINDS = ["transport", "progress", "waiting", "failure"];
32624
- });
32530
+ var init_harness_activity_emitter = () => {};
32625
32531
 
32626
32532
  // src/daemon/services/agent-process-service/index.ts
32627
32533
  var init_agent_process_service2 = __esm(() => {
@@ -32643,58 +32549,58 @@ var init_agent_process_contracts = __esm(() => {
32643
32549
  init_harness_activity_emitter();
32644
32550
  });
32645
32551
 
32646
- // src/daemon/infrastructure/inbox/task-state-manager.ts
32647
- function snapshotKey(taskId, role) {
32552
+ // src/daemon/infrastructure/inbox/task-inbox-state.ts
32553
+ function taskKey(taskId, role) {
32648
32554
  return `${taskId}:${role.toLowerCase()}`;
32649
32555
  }
32650
- function isStaleStatusPatch(snapshot, status3, updatedAt) {
32651
- if (snapshot.updatedAt > updatedAt)
32556
+ function isStaleStatusPatch(current, status3, updatedAt) {
32557
+ if (current.updatedAt > updatedAt)
32652
32558
  return true;
32653
- return snapshot.updatedAt === updatedAt && snapshot.status === "completed" && status3 !== "completed";
32559
+ return current.updatedAt === updatedAt && current.status === "completed" && status3 !== "completed";
32654
32560
  }
32655
32561
 
32656
- class TaskStateManager {
32657
- snapshots = new Map;
32562
+ class TaskInboxState {
32563
+ tasks = new Map;
32658
32564
  initialized = false;
32659
- replace(snapshots) {
32660
- this.snapshots.clear();
32661
- this.upsert(snapshots);
32565
+ replace(tasks) {
32566
+ this.tasks.clear();
32567
+ this.upsert(tasks);
32662
32568
  this.initialized = true;
32663
32569
  }
32664
32570
  listForRole(chatroomId, role) {
32665
32571
  const roleLower = role.toLowerCase();
32666
- return [...this.snapshots.values()].filter((snapshot) => snapshot.chatroomId === chatroomId && snapshot.agentConfig.role.toLowerCase() === roleLower);
32572
+ return [...this.tasks.values()].filter((task) => task.chatroomId === chatroomId && task.agentConfig.role.toLowerCase() === roleLower);
32667
32573
  }
32668
32574
  isInitialized() {
32669
32575
  return this.initialized;
32670
32576
  }
32671
32577
  getForRole(chatroomId, role, taskId) {
32672
- const snapshot = this.snapshots.get(snapshotKey(taskId, role));
32673
- return snapshot?.chatroomId === chatroomId ? snapshot : null;
32578
+ const task = this.tasks.get(taskKey(taskId, role));
32579
+ return task?.chatroomId === chatroomId ? task : null;
32674
32580
  }
32675
32581
  listAll() {
32676
- return [...this.snapshots.values()];
32582
+ return [...this.tasks.values()];
32677
32583
  }
32678
- upsert(snapshots) {
32679
- for (const snapshot of snapshots) {
32680
- this.snapshots.set(snapshotKey(snapshot.taskId, snapshot.agentConfig.role), snapshot);
32584
+ upsert(tasks) {
32585
+ for (const task of tasks) {
32586
+ this.tasks.set(taskKey(task.taskId, task.agentConfig.role), task);
32681
32587
  }
32682
32588
  }
32683
32589
  remove(chatroomId, role, taskId) {
32684
- const key = snapshotKey(taskId, role);
32685
- const snapshot = this.snapshots.get(key);
32686
- if (!snapshot || snapshot.chatroomId !== chatroomId)
32590
+ const key = taskKey(taskId, role);
32591
+ const task = this.tasks.get(key);
32592
+ if (!task || task.chatroomId !== chatroomId)
32687
32593
  return false;
32688
- return this.snapshots.delete(key);
32594
+ return this.tasks.delete(key);
32689
32595
  }
32690
32596
  markStatus(chatroomId, role, taskId, status3, updatedAt) {
32691
- const key = snapshotKey(taskId, role);
32692
- const snapshot = this.snapshots.get(key);
32693
- if (!snapshot || snapshot.chatroomId !== chatroomId)
32597
+ const key = taskKey(taskId, role);
32598
+ const task = this.tasks.get(key);
32599
+ if (!task || task.chatroomId !== chatroomId)
32694
32600
  return false;
32695
- if (isStaleStatusPatch(snapshot, status3, updatedAt))
32601
+ if (isStaleStatusPatch(task, status3, updatedAt))
32696
32602
  return false;
32697
- this.snapshots.set(key, { ...snapshot, status: status3, updatedAt });
32603
+ this.tasks.set(key, { ...task, status: status3, updatedAt });
32698
32604
  return true;
32699
32605
  }
32700
32606
  }
@@ -32702,7 +32608,7 @@ class TaskStateManager {
32702
32608
  // src/daemon/services/task-service/service/task-service.ts
32703
32609
  function createTaskService(deps) {
32704
32610
  const gateway = createConvexNativeTaskDeliveryGateway(deps.backend);
32705
- const taskSnapshotState = new TaskStateManager;
32611
+ const taskInboxState = new TaskInboxState;
32706
32612
  const listeners = new Set;
32707
32613
  let inboxPollTimer;
32708
32614
  let inboxPollInFlight = false;
@@ -32711,10 +32617,10 @@ function createTaskService(deps) {
32711
32617
  };
32712
32618
  const applyInboxEvent = (event) => {
32713
32619
  if (event.eventType === "task_deleted" /* TaskDeleted */ || event.task.status === "completed") {
32714
- taskSnapshotState.remove(event.chatroomId, event.role, event.taskId);
32620
+ taskInboxState.remove(event.chatroomId, event.role, event.taskId);
32715
32621
  return true;
32716
32622
  }
32717
- taskSnapshotState.upsert([
32623
+ taskInboxState.upsert([
32718
32624
  {
32719
32625
  taskId: event.task.taskId,
32720
32626
  chatroomId: event.task.chatroomId,
@@ -32781,9 +32687,9 @@ function createTaskService(deps) {
32781
32687
  machineId: deps.machineId,
32782
32688
  eventId
32783
32689
  }),
32784
- listTasksForRole: (chatroomId, role) => taskSnapshotState.listForRole(chatroomId, role),
32785
- listAllTasks: () => taskSnapshotState.listAll(),
32786
- taskSnapshotState,
32690
+ listTasksForRole: (chatroomId, role) => taskInboxState.listForRole(chatroomId, role),
32691
+ listAllTasks: () => taskInboxState.listAll(),
32692
+ taskInboxState,
32787
32693
  releaseTaskAfterTurnFailure: async (args2) => {
32788
32694
  const result = await gateway.releaseTaskAfterTurnFailure({
32789
32695
  sessionId: deps.sessionId,
@@ -32791,7 +32697,7 @@ function createTaskService(deps) {
32791
32697
  role: args2.role,
32792
32698
  taskId: args2.taskId
32793
32699
  });
32794
- taskSnapshotState.markStatus(args2.chatroomId, args2.role, args2.taskId, result.status, result.updatedAt);
32700
+ taskInboxState.markStatus(args2.chatroomId, args2.role, args2.taskId, result.status, result.updatedAt);
32795
32701
  return result;
32796
32702
  },
32797
32703
  loadAssignedTaskForAction: async ({ chatroomId, role, taskId }) => {
@@ -32824,55 +32730,6 @@ var init_task_service2 = __esm(() => {
32824
32730
  });
32825
32731
 
32826
32732
  // src/daemon/services/service-interfaces.ts
32827
- var exports_service_interfaces = {};
32828
- __export(exports_service_interfaces, {
32829
- untrackChildPid: () => untrackChildPid,
32830
- trackChildPid: () => trackChildPid,
32831
- snapshotRequestsNativeColdSession: () => snapshotRequestsNativeColdSession,
32832
- shouldDeliverNativeTask: () => shouldDeliverNativeTask,
32833
- setNativeTurnPhase: () => setNativeTurnPhase,
32834
- runRoleScopedStop: () => runRoleScopedStop,
32835
- runNativeInjectionEffect: () => runNativeInjectionEffect,
32836
- runExactTargetsStop: () => runExactTargetsStop,
32837
- runConfirmedStop: () => runConfirmedStop,
32838
- resetRoleDeliveryState: () => resetRoleDeliveryState,
32839
- resetChatroomScopeBarrierForTests: () => resetChatroomScopeBarrierForTests,
32840
- reapOrphanedProcessGroupsEffect: () => reapOrphanedProcessGroupsEffect,
32841
- reapOrphanedProcessGroups: () => reapOrphanedProcessGroups,
32842
- isNativeSlotIdleForDelivery: () => isNativeSlotIdleForDelivery,
32843
- isNativeHarness: () => isNativeHarness,
32844
- isDeliverableNativeTaskStatus: () => isDeliverableNativeTaskStatus,
32845
- isChatroomStopScopeActive: () => isChatroomStopScopeActive,
32846
- isAgentReadyForNativeDelivery: () => isAgentReadyForNativeDelivery,
32847
- getChildPidsFilePath: () => getChildPidsFilePath,
32848
- forceKillAllTrackedProcessGroupsEffect: () => forceKillAllTrackedProcessGroupsEffect,
32849
- forceKillAllTrackedProcessGroups: () => forceKillAllTrackedProcessGroups,
32850
- explainNativeDeliveryBlock: () => explainNativeDeliveryBlock,
32851
- explainAgentReadyForNativeDeliveryBlock: () => explainAgentReadyForNativeDeliveryBlock,
32852
- defaultNativeTurnPhase: () => defaultNativeTurnPhase,
32853
- createTaskService: () => createTaskService,
32854
- createStopAgentTargetsDepsForCommand: () => createStopAgentTargetsDepsForCommand,
32855
- createStopAgentTargetsDeps: () => createStopAgentTargetsDeps,
32856
- createStopAgentConfirmedDeps: () => createStopAgentConfirmedDeps,
32857
- createHarnessActivityEmitter: () => createHarnessActivityEmitter,
32858
- createDaemonAuditPort: () => createDaemonAuditPort,
32859
- createConvexNativeTaskDeliveryGateway: () => createConvexNativeTaskDeliveryGateway,
32860
- createChatroomScopeBarrier: () => createChatroomScopeBarrier,
32861
- createAgentTaskStateService: () => createAgentTaskStateService,
32862
- createAgentProcessService: () => createAgentProcessService,
32863
- createAgentProcessManagerService: () => createAgentProcessManagerService,
32864
- createAgentProcessCommandBus: () => createAgentProcessCommandBus,
32865
- clearTrackedPidsEffect: () => clearTrackedPidsEffect,
32866
- clearTrackedPids: () => clearTrackedPids,
32867
- buildStopTargetDescriptor: () => buildStopTargetDescriptor,
32868
- buildNativeInjectionPrompt: () => buildNativeInjectionPrompt,
32869
- STOPPING_TIMEOUT_MS: () => STOPPING_TIMEOUT_MS,
32870
- InMemoryActiveTaskStateStore: () => InMemoryActiveTaskStateStore,
32871
- HARNESS_ACTIVITY_KINDS: () => HARNESS_ACTIVITY_KINDS,
32872
- DefaultAgentTaskStateService: () => DefaultAgentTaskStateService,
32873
- AgentWorkManager: () => AgentWorkManager,
32874
- AgentProcessManager: () => AgentProcessManager
32875
- });
32876
32733
  var init_service_interfaces = __esm(() => {
32877
32734
  init_task_service2();
32878
32735
  init_agent_process_service2();
@@ -89739,6 +89596,7 @@ function toConvexLifecycleFact(fact) {
89739
89596
  return {
89740
89597
  ...normalized,
89741
89598
  chatroomId: normalized.chatroomId,
89599
+ ...normalized.kind === "chatroom_shutdown_complete" ? { commandId: normalized.commandId } : {},
89742
89600
  ...(normalized.kind === "activity" || normalized.kind === "turn_failed") && normalized.taskId ? { taskId: normalized.taskId } : {}
89743
89601
  };
89744
89602
  }
@@ -89750,10 +89608,7 @@ function createAgentLifecycleSend(session2) {
89750
89608
  fact: toConvexLifecycleFact(fact)
89751
89609
  };
89752
89610
  const result = await session2.backend.mutation(api.machines.projectAgentLifecycleFact, args2);
89753
- return {
89754
- ...result,
89755
- ...result.skipped && result.rejectionReason ? { rejectionReason: result.rejectionReason } : {}
89756
- };
89611
+ return result;
89757
89612
  };
89758
89613
  }
89759
89614
  var init_agent_lifecycle_send = __esm(() => {
@@ -89776,154 +89631,6 @@ var init_agent_lifecycle_outbox_runtime = __esm(() => {
89776
89631
  init_agent_lifecycle_send();
89777
89632
  });
89778
89633
 
89779
- // src/daemon/entry/enhancer/enhancer-spawn-registry.ts
89780
- function registerEnhancerSpawn(handle) {
89781
- const handles = byChatroom.get(handle.chatroomId) ?? new Set;
89782
- handles.add(handle);
89783
- byChatroom.set(handle.chatroomId, handles);
89784
- }
89785
- function unregisterEnhancerSpawn(handle) {
89786
- const handles = byChatroom.get(handle.chatroomId);
89787
- if (!handles)
89788
- return;
89789
- handles.delete(handle);
89790
- if (handles.size === 0)
89791
- byChatroom.delete(handle.chatroomId);
89792
- }
89793
- async function abortEnhancerSpawnsForChatroom(chatroomId) {
89794
- const handles = byChatroom.get(chatroomId);
89795
- if (!handles)
89796
- return;
89797
- await Promise.all([...handles].map(async (handle) => {
89798
- handle.abort();
89799
- await handle.stopProcess().catch(() => {
89800
- return;
89801
- });
89802
- }));
89803
- }
89804
- var byChatroom;
89805
- var init_enhancer_spawn_registry = __esm(() => {
89806
- byChatroom = new Map;
89807
- });
89808
-
89809
- // src/daemon/entry/finalize-scoped-stop-execution.ts
89810
- var exports_finalize_scoped_stop_execution = {};
89811
- __export(exports_finalize_scoped_stop_execution, {
89812
- finalizeScopedStopExecution: () => finalizeScopedStopExecution
89813
- });
89814
- async function finalizeScopedStopExecution(args2) {
89815
- for (const { target, outcome, lifecycleWarning } of args2.result.targets) {
89816
- await args2.backend.mutation(api.agentStops.reportTargetOutcome, {
89817
- sessionId: args2.sessionId,
89818
- stopCommandId: args2.stopCommandId,
89819
- chatroomId: args2.chatroomId,
89820
- machineId: args2.machineId,
89821
- targetKey: target.targetKey,
89822
- role: target.role,
89823
- pid: target.pid,
89824
- status: "completed",
89825
- outcome: outcome.kind === "stopped" ? "stopped" : "already_stopped",
89826
- termination: outcome.termination,
89827
- lifecycleWarning
89828
- });
89829
- }
89830
- for (const failure of args2.result.failures) {
89831
- await args2.backend.mutation(api.agentStops.reportTargetOutcome, {
89832
- sessionId: args2.sessionId,
89833
- stopCommandId: args2.stopCommandId,
89834
- chatroomId: args2.chatroomId,
89835
- machineId: args2.machineId,
89836
- targetKey: failure.target.targetKey,
89837
- role: failure.target.role,
89838
- pid: failure.target.pid,
89839
- status: "failed",
89840
- outcome: "failed",
89841
- errorMessage: String(failure.error)
89842
- });
89843
- }
89844
- const failed = args2.result.failures.length > 0 || args2.executionError != null;
89845
- await args2.backend.mutation(api.agentStops.completeMachineExecution, {
89846
- sessionId: args2.sessionId,
89847
- stopCommandId: args2.stopCommandId,
89848
- machineId: args2.machineId,
89849
- status: failed ? "failed" : "completed",
89850
- errorMessage: failed ? args2.executionError ? String(args2.executionError) : `${args2.result.failures.length} target(s) failed` : undefined
89851
- });
89852
- }
89853
- var init_finalize_scoped_stop_execution = __esm(() => {
89854
- init_api3();
89855
- });
89856
-
89857
- // src/daemon/entry/execute-scoped-stop-command.ts
89858
- async function executeScopedStopForCommand(args2) {
89859
- args2.apm.markChatroomStopIntent(args2.chatroomId, args2.reason);
89860
- if (args2.scope.kind === "chatroom") {
89861
- await abortEnhancerSpawnsForChatroom(args2.chatroomId);
89862
- }
89863
- const { runExactTargetsStop: runExactTargetsStop2 } = await Promise.resolve().then(() => (init_service_interfaces(), exports_service_interfaces));
89864
- const finalize = await Promise.resolve().then(() => (init_finalize_scoped_stop_execution(), exports_finalize_scoped_stop_execution));
89865
- const begun = await args2.backend.mutation(api.agentStops.beginMachineExecution, {
89866
- sessionId: args2.sessionId,
89867
- stopCommandId: args2.stopCommandId,
89868
- machineId: args2.machineId,
89869
- inboxCommandId: args2.inboxCommandId
89870
- });
89871
- if (!begun.shouldExecute)
89872
- return { stoppedCount: 0, failedCount: 0 };
89873
- for (const target of begun.targets) {
89874
- args2.apm.markStopIntent(args2.chatroomId, target.role, args2.reason, target.pid);
89875
- args2.apm.bindStopTarget?.({
89876
- chatroomId: args2.chatroomId,
89877
- role: target.role,
89878
- pid: target.pid,
89879
- stopCommandId: args2.stopCommandId,
89880
- targetKey: target.targetKey
89881
- });
89882
- }
89883
- let result = { targets: [], failures: [] };
89884
- let executionError;
89885
- try {
89886
- const targetsByRole = new Map;
89887
- for (const target of begun.targets) {
89888
- const roleTargets = targetsByRole.get(target.role) ?? [];
89889
- roleTargets.push(target);
89890
- targetsByRole.set(target.role, roleTargets);
89891
- }
89892
- const roleResults = await Promise.all([...targetsByRole.entries()].map(([role, targets]) => args2.runSerializedForAgent({ chatroomId: args2.chatroomId, role }, { timeoutMs: AGENT_LIFECYCLE_OPERATION_TIMEOUT_MS }, async (_ops, context5) => {
89893
- if (context5.signal.aborted)
89894
- throw context5.signal.reason;
89895
- return runExactTargetsStop2({
89896
- apm: args2.apm,
89897
- confirmedDeps: args2.apm.getConfirmedStopAdapterDeps(),
89898
- stopCommandId: args2.stopCommandId,
89899
- chatroomId: args2.chatroomId,
89900
- targets,
89901
- reason: args2.reason
89902
- });
89903
- })));
89904
- result = {
89905
- targets: roleResults.flatMap((roleResult) => roleResult.targets),
89906
- failures: roleResults.flatMap((roleResult) => roleResult.failures)
89907
- };
89908
- } catch (error) {
89909
- executionError = error;
89910
- console.warn("[daemon] scoped stop execution failed", error);
89911
- } finally {
89912
- await finalize.finalizeScopedStopExecution({ ...args2, result, executionError });
89913
- await args2.apm.syncSlotsAfterScopedStop(result);
89914
- }
89915
- return {
89916
- stoppedCount: result.targets.length,
89917
- failedCount: result.failures.length + (executionError != null ? 1 : 0),
89918
- executionError
89919
- };
89920
- }
89921
- var init_execute_scoped_stop_command = __esm(() => {
89922
- init_reliability();
89923
- init_api3();
89924
- init_enhancer_spawn_registry();
89925
- });
89926
-
89927
89634
  // src/daemon/entry/daemon-services.ts
89928
89635
  function DaemonMutableStateServiceLive(init2) {
89929
89636
  return exports_Layer.effect(DaemonMutableStateService, exports_Effect.gen(function* () {
@@ -89946,70 +89653,7 @@ var AgentLifecycleOutboxService, AgentLifecycleOutboxServiceLive = (registry2, m
89946
89653
  loadEventCursor: (machineId) => exports_Effect.promise(() => ops.loadEventCursor(machineId))
89947
89654
  }), DaemonSpawningService, DaemonSpawningServiceLive = (ops) => exports_Layer.succeed(DaemonSpawningService, {
89948
89655
  shouldAllowSpawn: (chatroomId, reason) => ops.shouldAllowSpawn(chatroomId, reason)
89949
- }), DaemonAgentProcessManagerService, DaemonAgentProcessManagerServiceLive = (mgr, processManagerService, sessionDeps) => exports_Layer.succeed(DaemonAgentProcessManagerService, {
89950
- executeScopedStopForCommand: (args2) => exports_Effect.promise(async () => {
89951
- if (!sessionDeps)
89952
- return { stoppedCount: 0, failedCount: 0 };
89953
- return executeScopedStopForCommand({
89954
- ...sessionDeps,
89955
- apm: mgr,
89956
- runSerializedForAgent: processManagerService.runSerializedForAgent,
89957
- ...args2
89958
- });
89959
- }),
89960
- runInboxRoleScopedStop: (event) => exports_Effect.promise(async () => {
89961
- const { runRoleScopedStop: runRoleScopedStop2 } = await Promise.resolve().then(() => (init_service_interfaces(), exports_service_interfaces));
89962
- const legacyReason = {
89963
- "team.switch": "platform.team_switch",
89964
- dedup: "platform.dedup",
89965
- "stale-config": "platform.dedup"
89966
- };
89967
- const reason = isAgentStopReason(event.reason) ? event.reason : legacyReason[event.reason] ?? "user.stop";
89968
- if (Date.now() > event.deadline)
89969
- return;
89970
- const execute = async (stopAgent, signal) => {
89971
- const result = await runRoleScopedStop2({
89972
- apm: mgr,
89973
- confirmedDeps: mgr.getConfirmedStopAdapterDeps(),
89974
- chatroomId: event.chatroomId,
89975
- role: event.role,
89976
- reason
89977
- });
89978
- if (result.targets.length === 0 && result.failures.length === 0 && event.pid) {
89979
- await stopAgent({
89980
- chatroomId: event.chatroomId,
89981
- role: event.role,
89982
- reason,
89983
- pid: event.pid
89984
- }, signal);
89985
- }
89986
- for (const failure of result.failures)
89987
- console.warn(`[daemon] scoped stop failed for ${failure.target.targetKey}`, failure.error);
89988
- };
89989
- await processManagerService.runSerializedForAgent({ chatroomId: event.chatroomId, role: event.role }, { timeoutMs: SCOPE_TARGET_STOP_TIMEOUT_MS }, async (ops, context5) => {
89990
- if (context5.signal.aborted)
89991
- throw context5.signal.reason;
89992
- await execute(ops.stopAgent, context5.signal);
89993
- });
89994
- }),
89995
- runInboxScopedStop: (event) => exports_Effect.promise(async () => {
89996
- if (!sessionDeps)
89997
- return;
89998
- const inboxCommandId = event.commandId ?? event._id;
89999
- const reason = isAgentStopReason(event.reason) ? event.reason : "user.stop";
90000
- await executeScopedStopForCommand({
90001
- sessionId: sessionDeps.sessionId,
90002
- machineId: sessionDeps.machineId,
90003
- backend: sessionDeps.backend,
90004
- apm: mgr,
90005
- stopCommandId: event.stopCommandId,
90006
- chatroomId: event.chatroomId,
90007
- scope: event.scope,
90008
- reason,
90009
- inboxCommandId,
90010
- runSerializedForAgent: processManagerService.runSerializedForAgent
90011
- });
90012
- }),
89656
+ }), DaemonAgentProcessManagerService, DaemonAgentProcessManagerServiceLive = (mgr, processManagerService) => exports_Layer.succeed(DaemonAgentProcessManagerService, {
90013
89657
  ensureRunning: (opts) => exports_Effect.promise(() => mgr.ensureRunning(opts)),
90014
89658
  stop: (opts) => exports_Effect.promise(() => mgr.stop(opts)),
90015
89659
  handleExit: (opts) => exports_Effect.promise(() => mgr.handleExit(opts)),
@@ -90024,10 +89668,7 @@ var AgentLifecycleOutboxService, AgentLifecycleOutboxServiceLive = (registry2, m
90024
89668
  }), DaemonAgentProcessManagerCommandService, DaemonAgentProcessManagerCommandServiceLive = (service4) => exports_Layer.succeed(DaemonAgentProcessManagerCommandService, service4), DaemonSessionService, DaemonMutableStateService;
90025
89669
  var init_daemon_services = __esm(() => {
90026
89670
  init_esm();
90027
- init_reliability();
90028
89671
  init_agent_lifecycle_outbox_runtime();
90029
- init_execute_scoped_stop_command();
90030
- init_agent();
90031
89672
  init_service_interfaces();
90032
89673
  AgentLifecycleOutboxService = class AgentLifecycleOutboxService extends exports_Context.Tag("AgentLifecycleOutboxService")() {
90033
89674
  };
@@ -90055,11 +89696,7 @@ function daemonSessionToLayers(init2) {
90055
89696
  return exports_Layer.mergeAll(BackendServiceLive({
90056
89697
  mutation: (e, a) => init2.backend.mutation(e, a),
90057
89698
  query: (e, a) => init2.backend.query(e, a)
90058
- }), ProcessServiceLive, ClockServiceLive, FsServiceLive, DaemonMachineServiceLive(init2.machine), AgentLifecycleOutboxServiceLive(init2.agentLifecycleOutbox, init2.machineId), DaemonSpawningServiceLive(init2.spawning), DaemonAgentProcessManagerServiceLive(init2.agentProcessManager, init2.agentProcessManagerService, {
90059
- sessionId: init2.sessionId,
90060
- machineId: init2.machineId,
90061
- backend: init2.backend
90062
- }), DaemonAgentProcessManagerCommandServiceLive(init2.agentProcessManagerService), DaemonMutableStateServiceLive({
89699
+ }), ProcessServiceLive, ClockServiceLive, FsServiceLive, DaemonMachineServiceLive(init2.machine), AgentLifecycleOutboxServiceLive(init2.agentLifecycleOutbox, init2.machineId), DaemonSpawningServiceLive(init2.spawning), DaemonAgentProcessManagerServiceLive(init2.agentProcessManager, init2.agentProcessManagerService), DaemonAgentProcessManagerCommandServiceLive(init2.agentProcessManagerService), DaemonMutableStateServiceLive({
90063
89700
  lastPushedGitState: init2.lastPushedGitState,
90064
89701
  lastPushedModels: init2.lastPushedModels,
90065
89702
  lastPushedHarnessFingerprint: init2.lastPushedHarnessFingerprint,
@@ -94519,8 +94156,6 @@ var init_command_event_types = __esm(() => {
94519
94156
  DAEMON_COMMAND_EVENT_TYPES = [
94520
94157
  "agent.requestStart",
94521
94158
  "agent.restart",
94522
- "agent.requestStop",
94523
- "agent.stopScope",
94524
94159
  "daemon.ping",
94525
94160
  "daemon.gitRefresh",
94526
94161
  "daemon.workspaceListChanged",
@@ -96193,8 +95828,7 @@ async function restartAgent(deps, input) {
96193
95828
  model: input.model,
96194
95829
  workingDir: input.workingDir,
96195
95830
  correlationId: input.correlationId,
96196
- wantResume: input.wantResume,
96197
- ...input.lifecycleRevision !== undefined ? { lifecycleRevision: input.lifecycleRevision } : {}
95831
+ wantResume: input.wantResume
96198
95832
  });
96199
95833
  } catch (error) {
96200
95834
  log4(`[daemon] agent.restart failed (correlationId=${input.correlationId}) for role=${input.role}: ${error instanceof Error ? error.message : String(error)}`);
@@ -96434,8 +96068,7 @@ var onRequestRestartAgentEffect = (event, nativeDelivery) => exports_Effect.gen(
96434
96068
  workingDir: event.workingDir,
96435
96069
  correlationId: event.correlationId,
96436
96070
  deadline: event.deadline,
96437
- wantResume: event.wantResume,
96438
- lifecycleRevision: event.lifecycleRevision
96071
+ wantResume: event.wantResume
96439
96072
  }));
96440
96073
  });
96441
96074
  var init_on_request_restart_agent = __esm(() => {
@@ -96461,8 +96094,7 @@ async function startAgent2(deps, input) {
96461
96094
  model: input.model,
96462
96095
  workingDir: input.workingDir,
96463
96096
  reason: input.reason,
96464
- wantResume: input.wantResume,
96465
- ...input.lifecycleRevision !== undefined ? { lifecycleRevision: input.lifecycleRevision } : {}
96097
+ wantResume: input.wantResume
96466
96098
  });
96467
96099
  } catch (error) {
96468
96100
  const message = error instanceof Error ? error.message : typeof error === "object" && error !== null && ("error" in error) ? String(error.error) : "unknown";
@@ -96508,8 +96140,7 @@ var onRequestStartAgentEffect = (event) => exports_Effect.gen(function* () {
96508
96140
  workingDir: event.workingDir,
96509
96141
  reason: event.reason,
96510
96142
  deadline: event.deadline,
96511
- wantResume: event.wantResume,
96512
- lifecycleRevision: event.lifecycleRevision
96143
+ wantResume: event.wantResume
96513
96144
  });
96514
96145
  await drainPendingEnhancerJobsIfRegistered();
96515
96146
  });
@@ -96520,31 +96151,6 @@ var init_on_request_start_agent = __esm(() => {
96520
96151
  init_daemon_services();
96521
96152
  });
96522
96153
 
96523
- // src/daemon/entry/events/agent/on-request-stop-agent.ts
96524
- var onRequestStopAgentEffect = (event) => exports_Effect.gen(function* () {
96525
- const agentMgr = yield* DaemonAgentProcessManagerService;
96526
- if (Date.now() > event.deadline)
96527
- return;
96528
- if (agentMgr.runInboxRoleScopedStop)
96529
- yield* agentMgr.runInboxRoleScopedStop(event);
96530
- });
96531
- var init_on_request_stop_agent = __esm(() => {
96532
- init_esm();
96533
- init_daemon_services();
96534
- });
96535
-
96536
- // src/daemon/entry/events/agent/on-stop-scope-agent.ts
96537
- var onStopScopeAgentEffect = (event) => exports_Effect.gen(function* () {
96538
- const agentMgr = yield* DaemonAgentProcessManagerService;
96539
- const stop4 = agentMgr.runInboxScopedStop;
96540
- if (stop4)
96541
- yield* stop4(event);
96542
- });
96543
- var init_on_stop_scope_agent = __esm(() => {
96544
- init_esm();
96545
- init_daemon_services();
96546
- });
96547
-
96548
96154
  // src/daemon/entry/handlers/ping.ts
96549
96155
  function handlePing() {
96550
96156
  console.log(` ↪ Responding: pong`);
@@ -96722,15 +96328,6 @@ function handleRequestRestartEffect(event, tracker, nativeDelivery) {
96722
96328
  tracker.commandIds.set(eventId, Date.now());
96723
96329
  });
96724
96330
  }
96725
- function handleRequestStopEffect(event, tracker) {
96726
- return exports_Effect.gen(function* () {
96727
- const eventId = event._id.toString();
96728
- if (tracker.commandIds.has(eventId))
96729
- return;
96730
- yield* onRequestStopAgentEffect(event);
96731
- tracker.commandIds.set(eventId, Date.now());
96732
- });
96733
- }
96734
96331
  function handlePingCommandEffect(event, tracker) {
96735
96332
  return exports_Effect.gen(function* () {
96736
96333
  const eventId = event._id.toString();
@@ -96884,8 +96481,6 @@ var init_command_dispatch = __esm(() => {
96884
96481
  init_pick_folder();
96885
96482
  init_on_request_restart_agent();
96886
96483
  init_on_request_start_agent();
96887
- init_on_request_stop_agent();
96888
- init_on_stop_scope_agent();
96889
96484
  init_ping();
96890
96485
  init_manager();
96891
96486
  init_convex_error();
@@ -96893,14 +96488,6 @@ var init_command_dispatch = __esm(() => {
96893
96488
  commandEventHandlers = {
96894
96489
  "agent.requestStart": handleRequestStartEffect,
96895
96490
  "agent.restart": handleRequestRestartEffect,
96896
- "agent.requestStop": handleRequestStopEffect,
96897
- "agent.stopScope": (event, tracker) => exports_Effect.gen(function* () {
96898
- const eventId = String(event.commandId ?? event._id);
96899
- if (tracker.commandIds.has(eventId))
96900
- return;
96901
- yield* onStopScopeAgentEffect(event);
96902
- tracker.commandIds.set(eventId, Date.now());
96903
- }),
96904
96491
  "daemon.ping": handlePingCommandEffect,
96905
96492
  "daemon.gitRefresh": handleGitRefreshCommandEffect,
96906
96493
  "daemon.workspaceListChanged": handleWorkspaceListChangedCommandEffect,
@@ -96956,6 +96543,36 @@ function createEnhancerLogWriter(logSink, context5, clock4 = () => Date.now()) {
96956
96543
  var ENHANCER_LOG_PREFIX = "[enhancer]";
96957
96544
  var init_enhancer_log = () => {};
96958
96545
 
96546
+ // src/daemon/entry/enhancer/enhancer-spawn-registry.ts
96547
+ function registerEnhancerSpawn(handle) {
96548
+ const handles = byChatroom.get(handle.chatroomId) ?? new Set;
96549
+ handles.add(handle);
96550
+ byChatroom.set(handle.chatroomId, handles);
96551
+ }
96552
+ function unregisterEnhancerSpawn(handle) {
96553
+ const handles = byChatroom.get(handle.chatroomId);
96554
+ if (!handles)
96555
+ return;
96556
+ handles.delete(handle);
96557
+ if (handles.size === 0)
96558
+ byChatroom.delete(handle.chatroomId);
96559
+ }
96560
+ async function abortEnhancerSpawnsForChatroom(chatroomId) {
96561
+ const handles = byChatroom.get(chatroomId);
96562
+ if (!handles)
96563
+ return;
96564
+ await Promise.all([...handles].map(async (handle) => {
96565
+ handle.abort();
96566
+ await handle.stopProcess().catch(() => {
96567
+ return;
96568
+ });
96569
+ }));
96570
+ }
96571
+ var byChatroom;
96572
+ var init_enhancer_spawn_registry = __esm(() => {
96573
+ byChatroom = new Map;
96574
+ });
96575
+
96959
96576
  // src/daemon/entry/enhancer/job-outcome-subscription.ts
96960
96577
  function subscribeToEnhancerJobOutcome(args2) {
96961
96578
  let currentState = null;
@@ -103154,7 +102771,7 @@ var startTaskInboxEffect = () => exports_Effect.gen(function* () {
103154
102771
  runSerializedForAgent: commandService.runSerializedForAgent,
103155
102772
  sessionDeps,
103156
102773
  machineId: session2.machineId,
103157
- taskSnapshotState: session2.taskService.taskSnapshotState,
102774
+ taskInboxState: session2.taskService.taskInboxState,
103158
102775
  agentTaskState,
103159
102776
  lifecycleOutbox,
103160
102777
  taskService: session2.taskService
@@ -104151,6 +103768,48 @@ var init_deps = __esm(() => {
104151
103768
  init_publisher_registry();
104152
103769
  });
104153
103770
 
103771
+ // src/daemon/entry/execute-chatroom-stop-command.ts
103772
+ async function executeChatroomStopCommand(args2) {
103773
+ if (args2.role)
103774
+ args2.apm.markStopIntent(args2.chatroomId, args2.role, "user.stop");
103775
+ else {
103776
+ args2.apm.markChatroomStopIntent(args2.chatroomId, "user.stop");
103777
+ await abortEnhancerSpawnsForChatroom(args2.chatroomId);
103778
+ }
103779
+ const confirmedDeps = args2.apm.getConfirmedStopAdapterDeps();
103780
+ const targets = await args2.apm.discoverStopTargets(args2.chatroomId);
103781
+ const roles = [
103782
+ ...new Set(targets.filter((target) => !args2.role || target.role.toLowerCase() === args2.role.toLowerCase()).map((target) => target.role.toLowerCase()))
103783
+ ];
103784
+ const results = await Promise.allSettled(roles.map((role) => args2.runSerializedForAgent({ chatroomId: args2.chatroomId, role }, { timeoutMs: AGENT_LIFECYCLE_OPERATION_TIMEOUT_MS }, async (_ops, context5) => {
103785
+ if (context5.signal.aborted)
103786
+ throw context5.signal.reason;
103787
+ await runRoleScopedStop({
103788
+ apm: args2.apm,
103789
+ confirmedDeps,
103790
+ chatroomId: args2.chatroomId,
103791
+ role,
103792
+ reason: "user.stop"
103793
+ });
103794
+ })));
103795
+ for (const result of results)
103796
+ if (result.status === "rejected")
103797
+ console.warn("[daemon] chatroom stop attempt failed", result.reason);
103798
+ await confirmedDeps.lifecycleOutbox.enqueue({
103799
+ kind: "chatroom_shutdown_complete",
103800
+ chatroomId: args2.chatroomId,
103801
+ commandId: args2.commandId,
103802
+ ...args2.finalizeChatroom === undefined ? {} : { finalizeChatroom: args2.finalizeChatroom },
103803
+ revisionKey: `shutdown:${args2.commandId}`,
103804
+ emittedAt: Date.now()
103805
+ });
103806
+ }
103807
+ var init_execute_chatroom_stop_command = __esm(() => {
103808
+ init_reliability();
103809
+ init_enhancer_spawn_registry();
103810
+ init_agent_process_service2();
103811
+ });
103812
+
104154
103813
  // src/daemon/entry/persistence-path.ts
104155
103814
  import { homedir as homedir10 } from "node:os";
104156
103815
  import { join as join26 } from "node:path";
@@ -104296,6 +103955,45 @@ var init_agentic_query_session = __esm(() => {
104296
103955
  init_api3();
104297
103956
  });
104298
103957
 
103958
+ // src/daemon/infrastructure/convex/subscribers/chatroom-workspace-agent-commands.ts
103959
+ function startChatroomWorkspaceAgentCommandsSubscriber(deps, onClaimed) {
103960
+ let draining = false;
103961
+ let queued = false;
103962
+ let stopped = false;
103963
+ const args2 = { sessionId: deps.sessionId, machineId: deps.machineId };
103964
+ const drain = async () => {
103965
+ if (stopped || draining) {
103966
+ queued = true;
103967
+ return;
103968
+ }
103969
+ draining = true;
103970
+ try {
103971
+ do {
103972
+ queued = false;
103973
+ let claimed;
103974
+ while (claimed = await deps.wsClient.mutation(api.chatroomWorkspaceAgentCommandsInbox.claimNext, args2))
103975
+ await onClaimed(claimed);
103976
+ } while (queued && !stopped);
103977
+ } finally {
103978
+ draining = false;
103979
+ }
103980
+ };
103981
+ const unsub = deps.wsClient.onUpdate(api.chatroomWorkspaceAgentCommandsInbox.watchNext, args2, (commandId) => {
103982
+ if (commandId)
103983
+ drain();
103984
+ }, (err) => console.warn(`[daemon] workspace-agent-command watch error: ${String(err)}`));
103985
+ drain();
103986
+ return {
103987
+ async stop() {
103988
+ stopped = true;
103989
+ unsub();
103990
+ }
103991
+ };
103992
+ }
103993
+ var init_chatroom_workspace_agent_commands = __esm(() => {
103994
+ init_api3();
103995
+ });
103996
+
104299
103997
  // src/daemon/infrastructure/convex/subscribers/command-run.ts
104300
103998
  function runId(run3) {
104301
103999
  return typeof run3._id === "string" ? run3._id : run3._id.toString();
@@ -104688,6 +104386,7 @@ function startAllSubscribers(deps) {
104688
104386
  claimedCommand: claimed
104689
104387
  });
104690
104388
  });
104389
+ const workspaceAgentCommands = deps.onWorkspaceAgentCommand ? startChatroomWorkspaceAgentCommandsSubscriber(deps, deps.onWorkspaceAgentCommand) : undefined;
104691
104390
  const commandRun = startCommandRunSubscriber(deps, onEvent);
104692
104391
  const fileTree = startFileTreeRequestSubscriber(deps, onEvent);
104693
104392
  const fileTreeRelease = startFileTreeReleaseRequestSubscriber(deps, onEvent);
@@ -104699,6 +104398,7 @@ function startAllSubscribers(deps) {
104699
104398
  async stopAll() {
104700
104399
  await Promise.all([
104701
104400
  machineCommands.stop(),
104401
+ workspaceAgentCommands?.stop(),
104702
104402
  commandRun.stop(),
104703
104403
  gitRequest.stop(),
104704
104404
  fileTree.stop(),
@@ -104716,6 +104416,7 @@ var init_subscriber_registry = __esm(() => {
104716
104416
  init_event_router();
104717
104417
  init_agentic_query_prompt();
104718
104418
  init_agentic_query_session();
104419
+ init_chatroom_workspace_agent_commands();
104719
104420
  init_command_run();
104720
104421
  init_enhancer_job();
104721
104422
  init_file_content_request();
@@ -133877,7 +133578,15 @@ async function startDaemon() {
133877
133578
  wsClient: wsClient2,
133878
133579
  sessionId: asConvexSessionId(init2.sessionId),
133879
133580
  machineId: init2.machineId,
133880
- router: createDefaultEventRouterDeps()
133581
+ router: createDefaultEventRouterDeps(),
133582
+ onWorkspaceAgentCommand: (command) => executeChatroomStopCommand({
133583
+ apm: init2.agentProcessManager,
133584
+ chatroomId: command.chatroomId,
133585
+ commandId: command._id,
133586
+ role: command.command.type === "stop_agent" ? command.command.role : undefined,
133587
+ finalizeChatroom: command.command.type === "stop_all_agents" ? command.command.finalizeChatroom : undefined,
133588
+ runSerializedForAgent: init2.agentProcessManagerService.runSerializedForAgent
133589
+ })
133881
133590
  });
133882
133591
  console.log(`[daemon] Local web UI: http://127.0.0.1:${localWeb.port}/`);
133883
133592
  const layers = daemonSessionToLayers(init2);
@@ -133906,6 +133615,7 @@ var init_start_daemon = __esm(() => {
133906
133615
  init_daemon_runtime();
133907
133616
  init_default_router_deps();
133908
133617
  init_deps();
133618
+ init_execute_chatroom_stop_command();
133909
133619
  init_init_daemon();
133910
133620
  init_persistence_path();
133911
133621
  init_resolve_local_web_port();
@@ -135146,4 +134856,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
135146
134856
  });
135147
134857
  program2.parse();
135148
134858
 
135149
- //# debugId=7D04CA8EEEBFA97564756E2164756E21
134859
+ //# debugId=1E9B97C58361134164756E2164756E21