chatroom-cli 1.113.0 → 1.115.0

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
@@ -30221,17 +30221,7 @@ class AgentProcessManager {
30221
30221
  }
30222
30222
  this.maybeEmitProviderUnavailable(opts.chatroomId, opts.role, slot);
30223
30223
  if (slot.harness && getHarnessCapabilities(slot.harness).supportsNativeIntegration) {
30224
- for (const handler of this.agentSessionLostHandlers) {
30225
- try {
30226
- handler({
30227
- chatroomId: opts.chatroomId,
30228
- role: opts.role,
30229
- harnessSessionId: ctx.harnessSessionId
30230
- });
30231
- } catch (error) {
30232
- console.warn(`[AgentProcessManager] native session-loss cleanup failed for ${opts.role}@${opts.chatroomId}: ${error instanceof Error ? error.message : String(error)}`);
30233
- }
30234
- }
30224
+ this.notifyAgentSessionLost(opts.chatroomId, opts.role, ctx.harnessSessionId);
30235
30225
  }
30236
30226
  const lifecyclePromise = this.lifecycle.runPromise(exports_Effect.gen(function* () {
30237
30227
  const svc = yield* AgentLifecycleService;
@@ -30522,12 +30512,22 @@ class AgentProcessManager {
30522
30512
  async syncSlotsAfterScopedStop(result) {
30523
30513
  for (const { target } of result.targets) {
30524
30514
  const slot = this.slots.get(agentKey2(target.chatroomId, target.role));
30515
+ this.notifyAgentSessionLost(target.chatroomId, target.role, slot?.pid === target.pid ? slot.harnessSessionId : undefined);
30525
30516
  if (!slot || slot.pid !== target.pid)
30526
30517
  continue;
30527
30518
  this.resetSlotAfterStop(slot);
30528
30519
  await this.clearAgentPidQuietly(target.chatroomId, target.role);
30529
30520
  }
30530
30521
  }
30522
+ notifyAgentSessionLost(chatroomId, role, harnessSessionId) {
30523
+ for (const handler of this.agentSessionLostHandlers) {
30524
+ try {
30525
+ handler({ chatroomId, role, ...harnessSessionId ? { harnessSessionId } : {} });
30526
+ } catch (error) {
30527
+ console.warn(`[AgentProcessManager] native session-loss cleanup failed for ${role}@${chatroomId}: ${error instanceof Error ? error.message : String(error)}`);
30528
+ }
30529
+ }
30530
+ }
30531
30531
  queueExitRetry(item) {
30532
30532
  this.exitRetryQueue.push(item);
30533
30533
  if (this.exitRetryTimer === null) {
@@ -31820,6 +31820,55 @@ function logNativeDeliveryInjecting(role, chatroomId, taskId) {
31820
31820
  console.log(`[NativeDelivery:inject] ${role}@${chatroomId} task ${taskId} — starting injection`);
31821
31821
  }
31822
31822
 
31823
+ // src/daemon/services/task-service/service/native-delivery/role-delivery-state.ts
31824
+ function roleKey(chatroomId, role) {
31825
+ return `${chatroomId}:${role.toLowerCase()}`;
31826
+ }
31827
+
31828
+ class RoleDeliveryState {
31829
+ generation = new Map;
31830
+ inFlight = new Set;
31831
+ nativeNudgeFailures = new Map;
31832
+ getGeneration(chatroomId, role) {
31833
+ return this.generation.get(roleKey(chatroomId, role)) ?? 0;
31834
+ }
31835
+ resetDeliveryState(chatroomId, role) {
31836
+ const key = roleKey(chatroomId, role);
31837
+ const next4 = (this.generation.get(key) ?? 0) + 1;
31838
+ this.generation.set(key, next4);
31839
+ this.inFlight.delete(key);
31840
+ this.nativeNudgeFailures.delete(key);
31841
+ return next4;
31842
+ }
31843
+ tryAcquireDelivery(chatroomId, role) {
31844
+ const key = roleKey(chatroomId, role);
31845
+ if (this.inFlight.has(key))
31846
+ return false;
31847
+ this.inFlight.add(key);
31848
+ return true;
31849
+ }
31850
+ releaseDelivery(chatroomId, role) {
31851
+ this.inFlight.delete(roleKey(chatroomId, role));
31852
+ }
31853
+ recordNativeNudgeFailure(chatroomId, role) {
31854
+ const key = roleKey(chatroomId, role);
31855
+ const count3 = (this.nativeNudgeFailures.get(key) ?? 0) + 1;
31856
+ this.nativeNudgeFailures.set(key, count3);
31857
+ return count3;
31858
+ }
31859
+ clearNativeNudgeFailures(chatroomId, role) {
31860
+ this.nativeNudgeFailures.delete(roleKey(chatroomId, role));
31861
+ }
31862
+ getNativeNudgeFailures(chatroomId, role) {
31863
+ return this.nativeNudgeFailures.get(roleKey(chatroomId, role)) ?? 0;
31864
+ }
31865
+ }
31866
+ function getRoleDeliveryState() {
31867
+ shared ??= new RoleDeliveryState;
31868
+ return shared;
31869
+ }
31870
+ var shared;
31871
+
31823
31872
  // src/daemon/services/task-service/service/native-delivery/delivery-decision.ts
31824
31873
  function taskSort(a, b) {
31825
31874
  const pendingOrder = Number(b.status === "pending") - Number(a.status === "pending");
@@ -31902,112 +31951,27 @@ var init_delivery_decision = __esm(() => {
31902
31951
  init_check_agent_slot();
31903
31952
  });
31904
31953
 
31905
- // src/infrastructure/mappers/map-assigned-task.ts
31906
- function mapAssignedTaskSnapshot(row) {
31907
- return {
31908
- taskId: row.taskId,
31909
- chatroomId: row.chatroomId,
31910
- status: row.status,
31911
- assignedTo: row.assignedTo,
31912
- updatedAt: row.updatedAt,
31913
- createdAt: row.createdAt,
31914
- agentConfig: {
31915
- role: row.agentConfig.role,
31916
- machineId: row.agentConfig.machineId,
31917
- agentHarness: row.agentConfig.agentHarness,
31918
- model: row.agentConfig.model,
31919
- workingDir: row.agentConfig.workingDir,
31920
- spawnedAgentPid: row.agentConfig.spawnedAgentPid,
31921
- desiredState: row.agentConfig.desiredState,
31922
- circuitState: row.agentConfig.circuitState,
31923
- configLifecycleRevision: row.agentConfig.configLifecycleRevision
31924
- },
31925
- participant: row.participant,
31926
- requestsNativeColdSession: row.requestsNativeColdSession
31927
- };
31928
- }
31929
- function mapAssignedTaskView(row) {
31930
- return {
31931
- ...mapAssignedTaskSnapshot(row),
31932
- taskContent: row.taskContent,
31933
- taskEnvelope: row.taskEnvelope,
31934
- startInNewSession: row.startInNewSession
31935
- };
31936
- }
31937
- function mapAssignedTaskSnapshotList(rows) {
31938
- return rows.map(mapAssignedTaskSnapshot);
31939
- }
31940
-
31941
31954
  // src/daemon/entry/restart-orchestrator-in-flight.ts
31942
- function roleKey(chatroomId, role) {
31955
+ function roleKey2(chatroomId, role) {
31943
31956
  return `${chatroomId}:${role.toLowerCase()}`;
31944
31957
  }
31945
31958
  function markRestartOrchestratorInFlight(chatroomId, role, correlationId) {
31946
- inFlight.set(roleKey(chatroomId, role), correlationId);
31959
+ inFlight.set(roleKey2(chatroomId, role), correlationId);
31947
31960
  }
31948
31961
  function clearRestartOrchestratorInFlight(chatroomId, role, correlationId) {
31949
- const key = roleKey(chatroomId, role);
31962
+ const key = roleKey2(chatroomId, role);
31950
31963
  if (correlationId !== undefined && inFlight.get(key) !== correlationId)
31951
31964
  return;
31952
31965
  inFlight.delete(key);
31953
31966
  }
31954
31967
  function isRestartOrchestratorInFlight(chatroomId, role) {
31955
- return inFlight.has(roleKey(chatroomId, role));
31968
+ return inFlight.has(roleKey2(chatroomId, role));
31956
31969
  }
31957
31970
  var inFlight;
31958
31971
  var init_restart_orchestrator_in_flight = __esm(() => {
31959
31972
  inFlight = new Map;
31960
31973
  });
31961
31974
 
31962
- // src/daemon/entry/role-delivery-state.ts
31963
- function roleKey2(chatroomId, role) {
31964
- return `${chatroomId}:${role.toLowerCase()}`;
31965
- }
31966
-
31967
- class RoleDeliveryState {
31968
- generation = new Map;
31969
- inFlight = new Set;
31970
- nativeNudgeFailures = new Map;
31971
- getGeneration(chatroomId, role) {
31972
- return this.generation.get(roleKey2(chatroomId, role)) ?? 0;
31973
- }
31974
- resetDeliveryState(chatroomId, role) {
31975
- const key = roleKey2(chatroomId, role);
31976
- const next4 = (this.generation.get(key) ?? 0) + 1;
31977
- this.generation.set(key, next4);
31978
- this.inFlight.delete(key);
31979
- this.nativeNudgeFailures.delete(key);
31980
- return next4;
31981
- }
31982
- tryAcquireDelivery(chatroomId, role) {
31983
- const key = roleKey2(chatroomId, role);
31984
- if (this.inFlight.has(key))
31985
- return false;
31986
- this.inFlight.add(key);
31987
- return true;
31988
- }
31989
- releaseDelivery(chatroomId, role) {
31990
- this.inFlight.delete(roleKey2(chatroomId, role));
31991
- }
31992
- recordNativeNudgeFailure(chatroomId, role) {
31993
- const key = roleKey2(chatroomId, role);
31994
- const count3 = (this.nativeNudgeFailures.get(key) ?? 0) + 1;
31995
- this.nativeNudgeFailures.set(key, count3);
31996
- return count3;
31997
- }
31998
- clearNativeNudgeFailures(chatroomId, role) {
31999
- this.nativeNudgeFailures.delete(roleKey2(chatroomId, role));
32000
- }
32001
- getNativeNudgeFailures(chatroomId, role) {
32002
- return this.nativeNudgeFailures.get(roleKey2(chatroomId, role)) ?? 0;
32003
- }
32004
- }
32005
- function getRoleDeliveryState() {
32006
- shared ??= new RoleDeliveryState;
32007
- return shared;
32008
- }
32009
- var shared;
32010
-
32011
31975
  // src/daemon/services/task-service/service/native-delivery/native-task-delivery-coordinator.ts
32012
31976
  class NativeTaskDeliveryCoordinator {
32013
31977
  resetRoleDeliveryState(chatroomId, role) {
@@ -32021,10 +31985,8 @@ class NativeTaskDeliveryCoordinator {
32021
31985
  runtime: runtime4,
32022
31986
  effectContext: effectContext2,
32023
31987
  agentMgr,
32024
- sessionDeps,
32025
31988
  operationalModel,
32026
31989
  isTaskActive,
32027
- machineId,
32028
31990
  onTaskDelivered,
32029
31991
  executors
32030
31992
  } = params;
@@ -32134,17 +32096,15 @@ class NativeTaskDeliveryCoordinator {
32134
32096
  continue;
32135
32097
  }
32136
32098
  await exports_Runtime.runPromise(runtime4)(exports_Effect.gen(function* () {
32137
- const backend2 = yield* exports_Effect.tryPromise(() => sessionDeps.backend.query(api.machines.getAssignedTaskForAction, {
32138
- sessionId: sessionDeps.sessionId,
32139
- machineId,
32140
- taskId: row.taskId,
32141
- role: row.agentConfig.role
32099
+ const full = yield* exports_Effect.tryPromise(() => taskService.loadAssignedTaskForAction({
32100
+ chatroomId: row.chatroomId,
32101
+ role: row.agentConfig.role,
32102
+ taskId: row.taskId
32142
32103
  }));
32143
- if (!backend2) {
32104
+ if (!full) {
32144
32105
  console.warn(`[NativeDelivery:execution] attempt=${attemptId} role=${role} chatroom=${row.chatroomId} task=${row.taskId} operation=inject result=task_hydration_missing`);
32145
32106
  return;
32146
32107
  }
32147
- const full = mapAssignedTaskView(backend2);
32148
32108
  yield* exports_Effect.tryPromise(() => taskService.deliverNativeTask(full, harnessSessionId, (delivered) => {
32149
32109
  onTaskDelivered?.(delivered);
32150
32110
  deliveryState.clearNativeNudgeFailures(delivered.chatroomId, delivered.role);
@@ -32168,7 +32128,6 @@ var init_native_task_delivery_coordinator = __esm(() => {
32168
32128
  init_agent();
32169
32129
  init_esm();
32170
32130
  init_delivery_decision();
32171
- init_api3();
32172
32131
  init_convex_error();
32173
32132
  init_check_agent_slot();
32174
32133
  init_restart_orchestrator_in_flight();
@@ -32193,15 +32152,13 @@ async function processTasksUpdate(runtime4, effectContext2, agentMgr, runSeriali
32193
32152
  taskId: task.taskId
32194
32153
  }, context5.signal)),
32195
32154
  injectTask: async (task, harnessSessionId) => {
32196
- const backend2 = await sessionDeps.backend.query(api.machines.getAssignedTaskForAction, {
32197
- sessionId: sessionDeps.sessionId,
32198
- machineId,
32199
- taskId: task.taskId,
32200
- role: task.agentConfig.role
32155
+ const full = await taskService.loadAssignedTaskForAction({
32156
+ chatroomId: task.chatroomId,
32157
+ role: task.agentConfig.role,
32158
+ taskId: task.taskId
32201
32159
  });
32202
- if (!backend2)
32160
+ if (!full)
32203
32161
  return { kind: "task-unavailable" };
32204
- const full = mapAssignedTaskView(backend2);
32205
32162
  let delivered;
32206
32163
  await taskService.deliverNativeTask(full, harnessSessionId, (result) => {
32207
32164
  delivered = result;
@@ -32229,7 +32186,6 @@ async function processTasksUpdate(runtime4, effectContext2, agentMgr, runSeriali
32229
32186
  var init_task_delivery_processor = __esm(() => {
32230
32187
  init_agent();
32231
32188
  init_native_task_delivery_coordinator();
32232
- init_api3();
32233
32189
  });
32234
32190
 
32235
32191
  // src/daemon/services/task-service/service/native-delivery/native-delivery-service.ts
@@ -32250,6 +32206,7 @@ class NativeDeliveryService {
32250
32206
  this.unsubscribeTaskService = deps.taskService.subscribe?.((notification) => this.handleTaskServiceNotification(notification));
32251
32207
  }
32252
32208
  async handleAgentStarted(event) {
32209
+ this.deps.agentTaskState.clear({ chatroomId: event.chatroomId, role: event.role });
32253
32210
  await this.requestReconcile({
32254
32211
  chatroomId: event.chatroomId,
32255
32212
  role: event.role,
@@ -32276,6 +32233,19 @@ class NativeDeliveryService {
32276
32233
  });
32277
32234
  const errorDetail = completion.error;
32278
32235
  console.error(`[NativeDelivery:turn-failed] chatroom=${event.chatroomId} role=${event.role} task=${activeTask?.taskId ?? "none"} turn=${completion.turnId} status=${completion.status} source=${completion.source} error=${errorDetail ?? "none"}`);
32236
+ if (activeTask) {
32237
+ try {
32238
+ await this.deps.taskService.releaseTaskAfterTurnFailure({
32239
+ chatroomId: event.chatroomId,
32240
+ role: event.role,
32241
+ taskId: activeTask.taskId
32242
+ });
32243
+ } catch (error) {
32244
+ console.error(`[NativeDelivery:turn-failed-recovery-error] chatroom=${event.chatroomId} role=${event.role} task=${activeTask.taskId} turn=${completion.turnId} error=${error instanceof Error ? error.stack ?? error.message : String(error)}`);
32245
+ return { kind: "hold-slot", reason: "task-recovery-failed" };
32246
+ }
32247
+ this.deps.agentTaskState.clear({ chatroomId: event.chatroomId, role: event.role });
32248
+ }
32279
32249
  const fact = {
32280
32250
  kind: "turn_failed",
32281
32251
  chatroomId: event.chatroomId,
@@ -32297,10 +32267,13 @@ class NativeDeliveryService {
32297
32267
  await this.deps.lifecycleOutbox.enqueue(fact);
32298
32268
  } catch (error) {
32299
32269
  console.error(`[NativeDelivery:turn-failed-outbox-error] chatroom=${event.chatroomId} role=${event.role} turn=${completion.turnId} error=${error instanceof Error ? error.stack ?? error.message : String(error)}`);
32270
+ if (activeTask)
32271
+ return { kind: "release-slot" };
32300
32272
  return { kind: "hold-slot", reason: "turn-failed-outbox-enqueue-failed" };
32301
32273
  }
32302
32274
  return { kind: "release-slot" };
32303
32275
  }
32276
+ this.deps.agentTaskState.clear({ chatroomId: event.chatroomId, role: event.role });
32304
32277
  this.scheduleRoleDelivery(event.chatroomId, event.role);
32305
32278
  return { kind: "release-slot" };
32306
32279
  }
@@ -32392,6 +32365,19 @@ class NativeDeliveryService {
32392
32365
  this.reconcileStates.set(key, state);
32393
32366
  await state.promise;
32394
32367
  }
32368
+ async reconcileAfterAgentRestart(args2) {
32369
+ const delivered = [];
32370
+ await this.deps.taskService.syncAssignedTaskSnapshots();
32371
+ await this.requestReconcile({
32372
+ chatroomId: args2.chatroomId,
32373
+ role: args2.role,
32374
+ source: "restart-completed",
32375
+ onTaskDelivered: ({ taskId }) => {
32376
+ delivered.push(taskId);
32377
+ }
32378
+ });
32379
+ return delivered;
32380
+ }
32395
32381
  async requestReconcileForSnapshots(snapshots, source) {
32396
32382
  const roles = new Set(snapshots.map((snapshot) => `${snapshot.chatroomId}:${snapshot.agentConfig.role.toLowerCase()}`));
32397
32383
  await Promise.all([...roles].map((key) => {
@@ -32423,8 +32409,8 @@ var init_native_delivery_service = __esm(() => {
32423
32409
  init_task_delivery_processor();
32424
32410
  });
32425
32411
 
32426
- // src/daemon/services/task-service/service/task-outbox.ts
32427
- class TaskOutbox {
32412
+ // src/daemon/services/task-service/service/native-task-delivery-queue.ts
32413
+ class NativeTaskDeliveryQueue {
32428
32414
  sender;
32429
32415
  tails = new Map;
32430
32416
  constructor(sender) {
@@ -47172,6 +47158,42 @@ var init_assigned_task_snapshot_contract = __esm(() => {
47172
47158
  }));
47173
47159
  });
47174
47160
 
47161
+ // src/infrastructure/mappers/map-assigned-task.ts
47162
+ function mapAssignedTaskSnapshot(row) {
47163
+ return {
47164
+ taskId: row.taskId,
47165
+ chatroomId: row.chatroomId,
47166
+ status: row.status,
47167
+ assignedTo: row.assignedTo,
47168
+ updatedAt: row.updatedAt,
47169
+ createdAt: row.createdAt,
47170
+ agentConfig: {
47171
+ role: row.agentConfig.role,
47172
+ machineId: row.agentConfig.machineId,
47173
+ agentHarness: row.agentConfig.agentHarness,
47174
+ model: row.agentConfig.model,
47175
+ workingDir: row.agentConfig.workingDir,
47176
+ spawnedAgentPid: row.agentConfig.spawnedAgentPid,
47177
+ desiredState: row.agentConfig.desiredState,
47178
+ circuitState: row.agentConfig.circuitState,
47179
+ configLifecycleRevision: row.agentConfig.configLifecycleRevision
47180
+ },
47181
+ participant: row.participant,
47182
+ requestsNativeColdSession: row.requestsNativeColdSession
47183
+ };
47184
+ }
47185
+ function mapAssignedTaskView(row) {
47186
+ return {
47187
+ ...mapAssignedTaskSnapshot(row),
47188
+ taskContent: row.taskContent,
47189
+ taskEnvelope: row.taskEnvelope,
47190
+ startInNewSession: row.startInNewSession
47191
+ };
47192
+ }
47193
+ function mapAssignedTaskSnapshotList(rows) {
47194
+ return rows.map(mapAssignedTaskSnapshot);
47195
+ }
47196
+
47175
47197
  // src/daemon/infrastructure/inbox/fetch-machine-assigned-task-snapshots.ts
47176
47198
  async function fetchMachineAssignedTaskSnapshots(sessionDeps, machineId) {
47177
47199
  const result = await sessionDeps.backend.query(api.machines.listMachineAssignedTaskSnapshots, {
@@ -47339,6 +47361,11 @@ var init_inbox = __esm(() => {
47339
47361
  function snapshotKey(taskId, role) {
47340
47362
  return `${taskId}:${role.toLowerCase()}`;
47341
47363
  }
47364
+ function isStaleStatusPatch(snapshot, status3, updatedAt) {
47365
+ if (snapshot.updatedAt > updatedAt)
47366
+ return true;
47367
+ return snapshot.updatedAt === updatedAt && snapshot.status === "completed" && status3 !== "completed";
47368
+ }
47342
47369
 
47343
47370
  class MachineTaskSnapshotState {
47344
47371
  snapshots = new Map;
@@ -47382,6 +47409,16 @@ class MachineTaskSnapshotState {
47382
47409
  this.snapshots.set(snapshotKey(snapshot.taskId, snapshot.agentConfig.role), snapshot);
47383
47410
  }
47384
47411
  }
47412
+ markStatus(chatroomId, role, taskId, status3, updatedAt) {
47413
+ const key = snapshotKey(taskId, role);
47414
+ const snapshot = this.snapshots.get(key);
47415
+ if (!snapshot || snapshot.chatroomId !== chatroomId)
47416
+ return false;
47417
+ if (isStaleStatusPatch(snapshot, status3, updatedAt))
47418
+ return false;
47419
+ this.snapshots.set(key, { ...snapshot, status: status3, updatedAt });
47420
+ return true;
47421
+ }
47385
47422
  }
47386
47423
 
47387
47424
  // src/daemon/infrastructure/inbox/task-signal-contract.ts
@@ -47521,6 +47558,7 @@ function createConvexNativeTaskDeliveryGateway(backend2) {
47521
47558
  claimPendingTask: async (args2) => {
47522
47559
  await backend2.mutation(api.tasks.claimTask, args2);
47523
47560
  },
47561
+ releaseTaskAfterTurnFailure: (args2) => backend2.mutation(api.tasks.releaseTaskAfterTurnFailure, args2),
47524
47562
  loadDeliveryPrompt: (args2) => backend2.query(api.messages.getTaskDeliveryPrompt, args2),
47525
47563
  recordReceipt: async (args2) => {
47526
47564
  await backend2.mutation(api.taskDeliveryReceipts.record, {
@@ -47536,6 +47574,23 @@ function createConvexNativeTaskDeliveryGateway(backend2) {
47536
47574
  },
47537
47575
  recordSessionAugmentation: async (args2) => {
47538
47576
  await backend2.mutation(api.daemon.agentEvents.sessionAugmented, args2);
47577
+ },
47578
+ loadAssignedTaskForAction: async (args2) => {
47579
+ const row = await backend2.query(api.machines.getAssignedTaskForAction, {
47580
+ sessionId: args2.sessionId,
47581
+ machineId: args2.machineId,
47582
+ taskId: args2.taskId,
47583
+ role: args2.role
47584
+ });
47585
+ if (!row)
47586
+ return null;
47587
+ return mapAssignedTaskView(row);
47588
+ },
47589
+ syncAssignedTaskSnapshots: async ({ sessionId, machineId }) => {
47590
+ await backend2.mutation(api.machines.syncMachineAssignedTaskSnapshotsMutation, {
47591
+ sessionId,
47592
+ machineId
47593
+ });
47539
47594
  }
47540
47595
  };
47541
47596
  }
@@ -47566,7 +47621,7 @@ function createTaskService(deps) {
47566
47621
  let inboxClient;
47567
47622
  let serviceStartedAt = 0;
47568
47623
  let stopped = false;
47569
- const taskOutbox = new TaskOutbox(async (entry) => {
47624
+ const nativeTaskDeliveryQueue = new NativeTaskDeliveryQueue(async (entry) => {
47570
47625
  await exports_Effect.runPromise(runNativeInjectionEffect(entry.task, entry.harnessSessionId, {
47571
47626
  ...deps,
47572
47627
  agentMgr,
@@ -47637,10 +47692,7 @@ function createTaskService(deps) {
47637
47692
  sessionId: deps.sessionId,
47638
47693
  machineId: deps.machineId
47639
47694
  });
47640
- await deps.backend.mutation(api.machines.syncMachineAssignedTaskSnapshotsMutation, {
47641
- sessionId: deps.sessionId,
47642
- machineId: deps.machineId
47643
- });
47695
+ await service4.syncAssignedTaskSnapshots();
47644
47696
  const snapshots = await fetchMachineAssignedTaskSnapshots({ ...deps, convexUrl: deps.convexUrl }, deps.machineId);
47645
47697
  taskSnapshotState.replace(snapshots);
47646
47698
  inboxClient = client2;
@@ -47666,16 +47718,43 @@ function createTaskService(deps) {
47666
47718
  for (const controller of roomControllers.values())
47667
47719
  controller.abort();
47668
47720
  roomControllers.clear();
47669
- taskOutbox.stop();
47721
+ nativeTaskDeliveryQueue.stop();
47670
47722
  inboxStore?.close();
47671
47723
  inboxStore = undefined;
47672
47724
  },
47673
47725
  listTasksForRole: (chatroomId, role) => taskSnapshotState.listForRole(chatroomId, role),
47674
47726
  listAllTasks: () => taskSnapshotState.listAll(),
47675
47727
  taskSnapshotState,
47676
- deliverNativeTask: (task, harnessSessionId, onTaskDelivered) => taskOutbox.enqueue({ task, harnessSessionId, onTaskDelivered }),
47728
+ deliverNativeTask: (task, harnessSessionId, onTaskDelivered) => nativeTaskDeliveryQueue.enqueue({ task, harnessSessionId, onTaskDelivered }),
47677
47729
  isNativeHarness,
47730
+ releaseTaskAfterTurnFailure: async (args2) => {
47731
+ const result = await gateway.releaseTaskAfterTurnFailure({
47732
+ sessionId: deps.sessionId,
47733
+ chatroomId: args2.chatroomId,
47734
+ role: args2.role,
47735
+ taskId: args2.taskId
47736
+ });
47737
+ taskSnapshotState.markStatus(args2.chatroomId, args2.role, args2.taskId, result.status, result.updatedAt);
47738
+ return result;
47739
+ },
47678
47740
  snapshotRequestsNativeColdSession,
47741
+ loadAssignedTaskForAction: async ({ chatroomId, role, taskId }) => {
47742
+ const task = await gateway.loadAssignedTaskForAction({
47743
+ sessionId: deps.sessionId,
47744
+ machineId: deps.machineId,
47745
+ taskId,
47746
+ role
47747
+ });
47748
+ return task?.chatroomId === chatroomId ? task : null;
47749
+ },
47750
+ syncAssignedTaskSnapshots: async () => {
47751
+ await gateway.syncAssignedTaskSnapshots({
47752
+ sessionId: deps.sessionId,
47753
+ machineId: deps.machineId
47754
+ });
47755
+ const snapshots = await fetchMachineAssignedTaskSnapshots({ ...deps, convexUrl: deps.convexUrl }, deps.machineId);
47756
+ taskSnapshotState.replace(snapshots);
47757
+ },
47679
47758
  explainNativeDeliveryBlock: (task, options) => explainNativeDeliveryBlock(task, options),
47680
47759
  createNativeDeliveryService: (deliveryDeps) => {
47681
47760
  const nativeDelivery = new NativeDeliveryService({
@@ -111168,25 +111247,6 @@ async function forceNativeWaiting(deps, event) {
111168
111247
  action: NATIVE_WAITING_ACTION
111169
111248
  });
111170
111249
  }
111171
- async function syncAssignedTaskSnapshots(deps) {
111172
- await deps.session.backend.mutation(api.machines.syncMachineAssignedTaskSnapshotsMutation, {
111173
- sessionId: deps.session.sessionId,
111174
- machineId: deps.session.machineId
111175
- });
111176
- }
111177
- async function deliverPendingTasks(deps, event) {
111178
- const delivered = [];
111179
- await syncAssignedTaskSnapshots(deps);
111180
- await deps.nativeDelivery.requestReconcile({
111181
- chatroomId: event.chatroomId,
111182
- role: event.role,
111183
- source: "restart-completed",
111184
- onTaskDelivered: ({ taskId }) => {
111185
- delivered.push(taskId);
111186
- }
111187
- });
111188
- return delivered;
111189
- }
111190
111250
  async function runRestartOrchestrator(deps, event) {
111191
111251
  const { chatroomId, role } = event;
111192
111252
  markRestartOrchestratorInFlight(chatroomId, role, event.correlationId);
@@ -111220,7 +111280,10 @@ async function runRestartOrchestrator(deps, event) {
111220
111280
  await forceNativeWaiting(deps, event);
111221
111281
  await emitPhase(deps, event, "ready");
111222
111282
  await emitPhase(deps, event, "deliver");
111223
- const deliveredTaskIds = await deliverPendingTasks(deps, event);
111283
+ const deliveredTaskIds = await deps.nativeDelivery.reconcileAfterAgentRestart({
111284
+ chatroomId,
111285
+ role
111286
+ });
111224
111287
  await emitPhase(deps, event, "completed");
111225
111288
  await logDaemonAuditEvent(deps.session.logEvent, buildAgentRestartCompletedEvent({
111226
111289
  chatroomId: event.chatroomId,
@@ -118040,14 +118103,14 @@ var init_command_run_subscription = __esm(() => {
118040
118103
  dispatchedStop = new Set;
118041
118104
  });
118042
118105
 
118043
- // src/daemon/entry/task-inbox-membership-registry.ts
118044
- function registerTaskInboxRoomMembershipRefresh(refresh) {
118106
+ // src/daemon/entry/workspace-membership-refresh-registry.ts
118107
+ function registerWorkspaceMembershipRefresh(refresh) {
118045
118108
  refreshRoomMembership = refresh;
118046
118109
  }
118047
- function unregisterTaskInboxRoomMembershipRefresh() {
118110
+ function unregisterWorkspaceMembershipRefresh() {
118048
118111
  refreshRoomMembership = null;
118049
118112
  }
118050
- async function refreshTaskInboxRoomMembership() {
118113
+ async function refreshWorkspaceMembership() {
118051
118114
  await refreshRoomMembership?.();
118052
118115
  }
118053
118116
  var refreshRoomMembership = null;
@@ -118324,7 +118387,7 @@ var init_operational_inbox = __esm(() => {
118324
118387
  init_operational_signal_feeds();
118325
118388
  });
118326
118389
 
118327
- // src/daemon/entry/task-inbox-runtime.ts
118390
+ // src/daemon/entry/operational-inbox-runtime.ts
118328
118391
  function isAbortError2(error51) {
118329
118392
  return error51 instanceof Error && error51.name === "AbortError";
118330
118393
  }
@@ -118346,7 +118409,7 @@ async function runOperationalInboxLoopWithRestart(options, onUpdate, isStopped)
118346
118409
  }
118347
118410
  }
118348
118411
  }
118349
- var INBOX_RESTART_INITIAL_MS = 1000, INBOX_RESTART_MAX_MS = 30000, startTaskInboxEffect = (wsClient2) => exports_Effect.gen(function* () {
118412
+ var INBOX_RESTART_INITIAL_MS = 1000, INBOX_RESTART_MAX_MS = 30000, startOperationalInboxEffect = (wsClient2) => exports_Effect.gen(function* () {
118350
118413
  const session2 = yield* DaemonSessionService;
118351
118414
  const agentMgr = yield* DaemonAgentProcessManagerService;
118352
118415
  const commandService = yield* DaemonAgentProcessManagerCommandService;
@@ -118366,7 +118429,7 @@ var INBOX_RESTART_INITIAL_MS = 1000, INBOX_RESTART_MAX_MS = 30000, startTaskInbo
118366
118429
  query: (fn2, args2) => session2.backend.query(fn2, args2)
118367
118430
  }
118368
118431
  };
118369
- console.log(`[${formatTimestamp()}] \uD83D\uDCEC Starting task-inbox (chatroom-scoped operational signals)`);
118432
+ console.log(`[${formatTimestamp()}] \uD83D\uDCEC Starting operational-inbox (chatroom-scoped operational signals)`);
118370
118433
  const inboxStore = createInboxStateStore(resolveInboxDbPath(session2.machineId));
118371
118434
  const serviceStartedAt = Date.now();
118372
118435
  const abort = new AbortController;
@@ -118385,7 +118448,7 @@ var INBOX_RESTART_INITIAL_MS = 1000, INBOX_RESTART_MAX_MS = 30000, startTaskInbo
118385
118448
  lifecycleOutbox
118386
118449
  });
118387
118450
  yield* exports_Effect.tryPromise(() => session2.taskService.startTaskInbox(wsClient2)).pipe(exports_Effect.catchAll((error51) => {
118388
- console.warn("[TaskInbox] service bootstrap failed:", error51);
118451
+ console.warn("[TaskService] task inbox bootstrap failed:", error51);
118389
118452
  return exports_Effect.void;
118390
118453
  }));
118391
118454
  const knownRoomIds = new Set;
@@ -118494,10 +118557,10 @@ var INBOX_RESTART_INITIAL_MS = 1000, INBOX_RESTART_MAX_MS = 30000, startTaskInbo
118494
118557
  }
118495
118558
  await Promise.all(chatroomIds.map((chatroomId2) => ensureRoomInboxes(chatroomId2)));
118496
118559
  } catch (error51) {
118497
- console.warn("[TaskInbox] room membership refresh failed:", error51);
118560
+ console.warn("[WorkspaceMembership] room membership refresh failed:", error51);
118498
118561
  }
118499
118562
  };
118500
- registerTaskInboxRoomMembershipRefresh(refreshRoomMembership2);
118563
+ registerWorkspaceMembershipRefresh(refreshRoomMembership2);
118501
118564
  yield* exports_Effect.promise(refreshRoomMembership2);
118502
118565
  yield* exports_Effect.tryPromise(() => Promise.all([...knownRoomIds].map((chatroomId2) => ensureRoomInboxes(chatroomId2)))).pipe(exports_Effect.catchAll((error51) => {
118503
118566
  console.warn("[OperationalInbox] initial watcher start failed:", error51);
@@ -118511,7 +118574,7 @@ var INBOX_RESTART_INITIAL_MS = 1000, INBOX_RESTART_MAX_MS = 30000, startTaskInbo
118511
118574
  for (const watcher of roomWatchers.values()) {
118512
118575
  watcher.controller.abort();
118513
118576
  }
118514
- unregisterTaskInboxRoomMembershipRefresh();
118577
+ unregisterWorkspaceMembershipRefresh();
118515
118578
  session2.taskService.stopTaskInbox();
118516
118579
  nativeDelivery.dispose();
118517
118580
  nativeDelivery.agentTaskState.clearAll();
@@ -118519,7 +118582,7 @@ var INBOX_RESTART_INITIAL_MS = 1000, INBOX_RESTART_MAX_MS = 30000, startTaskInbo
118519
118582
  }
118520
118583
  };
118521
118584
  });
118522
- var init_task_inbox_runtime = __esm(() => {
118585
+ var init_operational_inbox_runtime = __esm(() => {
118523
118586
  init_esm();
118524
118587
  init_daemon_services();
118525
118588
  init_api3();
@@ -119040,7 +119103,7 @@ function createDaemonRuntime(deps) {
119040
119103
  break;
119041
119104
  }
119042
119105
  });
119043
- taskInboxHandle = yield* startTaskInboxEffect(deps.wsClient);
119106
+ taskInboxHandle = yield* startOperationalInboxEffect(deps.wsClient);
119044
119107
  logObserverSubscriptionHandle = startLogObserverSubscription({ sessionId: session2.sessionId, machineId: session2.machineId }, deps.wsClient);
119045
119108
  const commandRunRuntime = yield* exports_Effect.runtime();
119046
119109
  agenticQueryWorkerHandle = startAgenticQuerySubscriptions({
@@ -119095,7 +119158,7 @@ var init_daemon_runtime = __esm(() => {
119095
119158
  init_command_run_subscription();
119096
119159
  init_log_observer_sync();
119097
119160
  init_init_daemon();
119098
- init_task_inbox_runtime();
119161
+ init_operational_inbox_runtime();
119099
119162
  init_git_subscription();
119100
119163
  init_api3();
119101
119164
  init_workspace_list_subscription();
@@ -120026,7 +120089,7 @@ function startAllSubscribers(deps) {
120026
120089
  if (claimed.type === "daemon.workspaceListChanged") {
120027
120090
  enhancerJob.refreshChatrooms();
120028
120091
  gitRequest.refreshWorkspaces();
120029
- refreshTaskInboxRoomMembership();
120092
+ refreshWorkspaceMembership();
120030
120093
  }
120031
120094
  await dispatchCommandInboundEvent({
120032
120095
  type: "command.received",
@@ -135867,4 +135930,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
135867
135930
  });
135868
135931
  program2.parse();
135869
135932
 
135870
- //# debugId=2166B04C5CAC31EC64756E2164756E21
135933
+ //# debugId=A4A4E9F28A3DEB2964756E2164756E21