@opengeni/worker-bundle 1.0.0-canary.0 → 1.0.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.
Files changed (244) hide show
  1. package/dist/activities/agent-run-admission.d.ts +3 -1
  2. package/dist/activities/agent-turn/admission.d.ts +24 -3
  3. package/dist/activities/agent-turn/agent-build.d.ts +4 -0
  4. package/dist/activities/agent-turn/claude-usage-observer.d.ts +58 -0
  5. package/dist/activities/agent-turn/code-search.d.ts +60 -0
  6. package/dist/activities/agent-turn/codex-capacity.d.ts +13 -0
  7. package/dist/activities/agent-turn/codex-plan-entitlement.d.ts +105 -0
  8. package/dist/activities/agent-turn/codex.d.ts +3 -2
  9. package/dist/activities/agent-turn/compaction-prep.d.ts +21 -5
  10. package/dist/activities/agent-turn/credential-leases.d.ts +19 -33
  11. package/dist/activities/agent-turn/credential-restriction.d.ts +3 -0
  12. package/dist/activities/agent-turn/errors.d.ts +82 -11
  13. package/dist/activities/agent-turn/failure-settlement.d.ts +6 -3
  14. package/dist/activities/agent-turn/final-reply.d.ts +18 -0
  15. package/dist/activities/agent-turn/finalization-monitor.d.ts +17 -0
  16. package/dist/activities/agent-turn/finalization.d.ts +4 -2
  17. package/dist/activities/agent-turn/github-repository-bindings.d.ts +2 -0
  18. package/dist/activities/agent-turn/governance-model.d.ts +9 -2
  19. package/dist/activities/agent-turn/history-sink.d.ts +2 -0
  20. package/dist/activities/agent-turn/history.d.ts +2 -0
  21. package/dist/activities/agent-turn/input-wait-reply.d.ts +41 -0
  22. package/dist/activities/agent-turn/media-artifacts.d.ts +5 -3
  23. package/dist/activities/agent-turn/model-call-admission.d.ts +15 -0
  24. package/dist/activities/agent-turn/model-usage.d.ts +6 -0
  25. package/dist/activities/agent-turn/model-wire-dispatch.d.ts +15 -0
  26. package/dist/activities/agent-turn/optional-repositories.d.ts +59 -0
  27. package/dist/activities/agent-turn/provider-dispatch-barrier.d.ts +12 -1
  28. package/dist/activities/agent-turn/quiescence.d.ts +7 -7
  29. package/dist/activities/agent-turn/recovery-warning.d.ts +9 -0
  30. package/dist/activities/agent-turn/refresh-credentials.d.ts +6 -0
  31. package/dist/activities/agent-turn/run-credentials.d.ts +8 -3
  32. package/dist/activities/agent-turn/sandbox-establish.d.ts +2 -1
  33. package/dist/activities/agent-turn/sandbox-provision.d.ts +3 -1
  34. package/dist/activities/agent-turn/sandbox-route.d.ts +3 -20
  35. package/dist/activities/agent-turn/sandbox-runtime.d.ts +2 -2
  36. package/dist/activities/agent-turn/session-title.d.ts +34 -2
  37. package/dist/activities/agent-turn/skill-checkout.d.ts +25 -6
  38. package/dist/activities/agent-turn/skill-read.d.ts +70 -2
  39. package/dist/activities/agent-turn/skill-remove.d.ts +14 -0
  40. package/dist/activities/agent-turn/skill-search.d.ts +3 -1
  41. package/dist/activities/agent-turn/skill-tools.d.ts +15 -2
  42. package/dist/activities/agent-turn/skill-transfer.d.ts +18 -6
  43. package/dist/activities/agent-turn/stream-attempt.d.ts +7 -3
  44. package/dist/activities/agent-turn/subscription-lease.d.ts +38 -0
  45. package/dist/activities/agent-turn/tool-environment.d.ts +56 -6
  46. package/dist/activities/agent-turn/tool-policy.d.ts +43 -0
  47. package/dist/activities/agent-turn/turn-context.d.ts +29 -0
  48. package/dist/activities/agent-turn/turn-sandbox-access.d.ts +3 -0
  49. package/dist/activities/agent-turn/xai-capacity.d.ts +2 -1
  50. package/dist/activities/automations.d.ts +3 -1
  51. package/dist/activities/browser-deadline-checkpoint.d.ts +29 -0
  52. package/dist/activities/codemode-dispatcher.d.ts +9 -2
  53. package/dist/activities/codex-capacity.d.ts +18 -2
  54. package/dist/activities/codex-rotation.d.ts +7 -1
  55. package/dist/activities/context-compaction.d.ts +16 -2
  56. package/dist/activities/gmail-files.d.ts +32 -0
  57. package/dist/activities/goals.d.ts +8 -0
  58. package/dist/activities/knowledge-indexing.d.ts +19 -0
  59. package/dist/activities/mcp-account-routes.d.ts +3 -0
  60. package/dist/activities/mcp-credentials.d.ts +12 -13
  61. package/dist/activities/mcp-operation-authority.d.ts +0 -5
  62. package/dist/activities/model-call-fact-reconciler.d.ts +34 -0
  63. package/dist/activities/open-suffix-resume.d.ts +13 -0
  64. package/dist/activities/parent-wake.d.ts +6 -12
  65. package/dist/activities/retained-screenshots.d.ts +7 -2
  66. package/dist/activities/rig-verification.d.ts +2 -3
  67. package/dist/activities/run-credential-renewal.d.ts +1 -0
  68. package/dist/activities/run-credentials.d.ts +15 -3
  69. package/dist/activities/sandbox-images.d.ts +1 -1
  70. package/dist/activities/sandbox-lease.d.ts +47 -9
  71. package/dist/activities/scheduled-tasks.d.ts +4 -35
  72. package/dist/activities/session-state.d.ts +70 -3
  73. package/dist/activities/types.d.ts +55 -6
  74. package/dist/activities/workspace-capture.d.ts +2 -0
  75. package/dist/activities/workspace-credential-provider.d.ts +46 -0
  76. package/dist/{activities-control-HMFGSKC5.js → activities-control-BNPTRTOE.js} +1896 -418
  77. package/dist/activities-control-BNPTRTOE.js.map +1 -0
  78. package/dist/activities-control.d.ts +182 -4
  79. package/dist/{activities-turn-AP67JADS.js → activities-turn-5LGZOSVU.js} +4476 -1327
  80. package/dist/activities-turn-5LGZOSVU.js.map +1 -0
  81. package/dist/activities.d.ts +182 -4
  82. package/dist/artifact-materializer-entry.js +5 -2
  83. package/dist/artifact-materializer-entry.js.map +1 -1
  84. package/dist/artifact-outbox-entry.js +5 -2
  85. package/dist/artifact-outbox-entry.js.map +1 -1
  86. package/dist/browser-deadline-checkpoint-contract.d.ts +2 -0
  87. package/dist/{chunk-A4XQWVZK.js → chunk-3ZTRWDMN.js} +307 -4
  88. package/dist/chunk-3ZTRWDMN.js.map +1 -0
  89. package/dist/{chunk-RAMNYSAW.js → chunk-4ER3YXOT.js} +22 -4
  90. package/dist/chunk-4ER3YXOT.js.map +1 -0
  91. package/dist/{chunk-CYITU5UH.js → chunk-LJX7Z2KP.js} +1445 -343
  92. package/dist/chunk-LJX7Z2KP.js.map +1 -0
  93. package/dist/editable-artifact-materializer-service.d.ts +2 -2
  94. package/dist/editable-artifact-outbox-service.d.ts +2 -2
  95. package/dist/host-export-pump.d.ts +3 -1
  96. package/dist/host-export.d.ts +1 -1
  97. package/dist/host-export.js +1 -1
  98. package/dist/http.d.ts +1 -1
  99. package/dist/index.d.ts +95 -3
  100. package/dist/index.js +137 -43
  101. package/dist/index.js.map +1 -1
  102. package/dist/observability-metrics.d.ts +118 -8
  103. package/dist/retained-process-diagnostics.d.ts +4 -0
  104. package/dist/retained-process-retry.d.ts +7 -0
  105. package/dist/sandbox-resume.d.ts +55 -13
  106. package/dist/sandbox-routing.d.ts +5 -3
  107. package/dist/sandbox-snapshot-diagnostics.d.ts +20 -0
  108. package/dist/session-event-fanout.d.ts +6 -0
  109. package/dist/warm-capture-holder.d.ts +3 -0
  110. package/dist/worker-service-lifecycle.d.ts +12 -0
  111. package/dist/workflow-bundle.js +273 -41
  112. package/dist/workflows/activities.d.ts +1 -1
  113. package/dist/workflows/browser-deadline-checkpoint.d.ts +9 -0
  114. package/dist/workflows/scheduled-tasks.d.ts +4 -0
  115. package/dist/workflows/session.d.ts +36 -0
  116. package/dist/workflows.d.ts +1 -0
  117. package/package.json +21 -19
  118. package/src/activities/agent-run-admission.ts +17 -1
  119. package/src/activities/agent-turn/admission.ts +66 -3
  120. package/src/activities/agent-turn/agent-build.ts +84 -10
  121. package/src/activities/agent-turn/claim.ts +186 -43
  122. package/src/activities/agent-turn/claude-usage-observer.ts +221 -0
  123. package/src/activities/agent-turn/code-search.ts +275 -0
  124. package/src/activities/agent-turn/codex-capacity.ts +172 -8
  125. package/src/activities/agent-turn/codex-plan-entitlement.ts +254 -0
  126. package/src/activities/agent-turn/codex.ts +13 -5
  127. package/src/activities/agent-turn/compaction-prep.ts +170 -102
  128. package/src/activities/agent-turn/credential-leases.ts +122 -216
  129. package/src/activities/agent-turn/credential-restriction.ts +14 -0
  130. package/src/activities/agent-turn/errors.ts +647 -48
  131. package/src/activities/agent-turn/failure-settlement.ts +682 -130
  132. package/src/activities/agent-turn/final-reply.ts +46 -0
  133. package/src/activities/agent-turn/finalization-monitor.ts +120 -0
  134. package/src/activities/agent-turn/finalization.ts +146 -43
  135. package/src/activities/agent-turn/github-repository-bindings.ts +3 -1
  136. package/src/activities/agent-turn/governance-model.ts +69 -28
  137. package/src/activities/agent-turn/history-sink.ts +16 -2
  138. package/src/activities/agent-turn/history.ts +38 -11
  139. package/src/activities/agent-turn/input-wait-reply.ts +103 -0
  140. package/src/activities/agent-turn/knowledge-source-tools.ts +2 -0
  141. package/src/activities/agent-turn/media-artifacts.ts +2 -1
  142. package/src/activities/agent-turn/model-call-admission.ts +94 -0
  143. package/src/activities/agent-turn/model-usage.ts +64 -3
  144. package/src/activities/agent-turn/model-wire-dispatch.ts +27 -0
  145. package/src/activities/agent-turn/optional-repositories.ts +224 -0
  146. package/src/activities/agent-turn/provider-dispatch-barrier.ts +22 -0
  147. package/src/activities/agent-turn/quiescence.ts +10 -7
  148. package/src/activities/agent-turn/recovery-warning.ts +16 -0
  149. package/src/activities/agent-turn/refresh-credentials.ts +44 -0
  150. package/src/activities/agent-turn/run-credentials.ts +116 -55
  151. package/src/activities/agent-turn/run.ts +320 -93
  152. package/src/activities/agent-turn/sandbox-establish.ts +84 -8
  153. package/src/activities/agent-turn/sandbox-provision.ts +3 -1
  154. package/src/activities/agent-turn/sandbox-route.ts +4 -21
  155. package/src/activities/agent-turn/sandbox-runtime.ts +343 -18
  156. package/src/activities/agent-turn/session-title.ts +81 -5
  157. package/src/activities/agent-turn/skill-checkout.ts +111 -24
  158. package/src/activities/agent-turn/skill-install.ts +1 -1
  159. package/src/activities/agent-turn/skill-read.ts +374 -28
  160. package/src/activities/agent-turn/skill-remove.ts +46 -0
  161. package/src/activities/agent-turn/skill-save.ts +1 -1
  162. package/src/activities/agent-turn/skill-search.ts +10 -1
  163. package/src/activities/agent-turn/skill-selection.ts +4 -0
  164. package/src/activities/agent-turn/skill-tools.ts +112 -18
  165. package/src/activities/agent-turn/skill-transfer.ts +68 -23
  166. package/src/activities/agent-turn/stream-attempt.ts +313 -77
  167. package/src/activities/agent-turn/subscription-lease.ts +115 -0
  168. package/src/activities/agent-turn/tool-environment.ts +316 -167
  169. package/src/activities/agent-turn/tool-policy.ts +80 -1
  170. package/src/activities/agent-turn/turn-context.ts +35 -0
  171. package/src/activities/agent-turn/turn-sandbox-access.ts +7 -1
  172. package/src/activities/agent-turn/xai-capacity.ts +94 -51
  173. package/src/activities/automations.ts +76 -4
  174. package/src/activities/browser-deadline-checkpoint.ts +279 -0
  175. package/src/activities/capabilities.ts +108 -11
  176. package/src/activities/codemode-dispatcher.ts +36 -8
  177. package/src/activities/codex-capacity.ts +60 -25
  178. package/src/activities/codex-rotation.ts +39 -17
  179. package/src/activities/context-compaction.ts +75 -18
  180. package/src/activities/gmail-files.ts +88 -0
  181. package/src/activities/goals.ts +116 -121
  182. package/src/activities/google-drive-publication.ts +1 -3
  183. package/src/activities/image-generation-operation.ts +1 -1
  184. package/src/activities/knowledge-indexing.ts +269 -15
  185. package/src/activities/knowledge-source-sync.ts +10 -0
  186. package/src/activities/mcp-account-routes.ts +17 -0
  187. package/src/activities/mcp-credentials.ts +83 -194
  188. package/src/activities/mcp-operation-authority.ts +16 -41
  189. package/src/activities/model-call-fact-reconciler.ts +112 -0
  190. package/src/activities/open-suffix-resume.ts +15 -2
  191. package/src/activities/parent-wake.ts +46 -21
  192. package/src/activities/retained-screenshots.ts +82 -11
  193. package/src/activities/rig-verification.ts +38 -37
  194. package/src/activities/run-credential-renewal.ts +13 -1
  195. package/src/activities/run-credentials.ts +59 -17
  196. package/src/activities/run-input.ts +25 -16
  197. package/src/activities/sandbox-images.ts +0 -1
  198. package/src/activities/sandbox-lease.ts +798 -82
  199. package/src/activities/scheduled-tasks.ts +550 -178
  200. package/src/activities/session-state.ts +245 -6
  201. package/src/activities/site-auth-maintenance.ts +3 -0
  202. package/src/activities/types.ts +72 -5
  203. package/src/activities/workflow-wake.ts +2 -17
  204. package/src/activities/workspace-capture.ts +13 -2
  205. package/src/activities/workspace-credential-provider.ts +283 -0
  206. package/src/activities-control.ts +4 -0
  207. package/src/activities-turn.ts +5 -0
  208. package/src/activities.ts +13 -0
  209. package/src/activity-services.ts +16 -4
  210. package/src/browser-deadline-checkpoint-contract.ts +5 -0
  211. package/src/editable-artifact-hint-broker.ts +3 -0
  212. package/src/editable-artifact-materializer-service.ts +7 -3
  213. package/src/editable-artifact-outbox-service.ts +4 -4
  214. package/src/github-rest-mcp.ts +1 -2
  215. package/src/host-export-pump.ts +26 -4
  216. package/src/host-export.ts +3 -0
  217. package/src/http.ts +4 -2
  218. package/src/index.ts +99 -37
  219. package/src/observability-metrics.ts +510 -5
  220. package/src/personal-github-git-credentials.ts +2 -1
  221. package/src/pr-review-credentials.ts +1 -3
  222. package/src/retained-process-diagnostics.ts +50 -0
  223. package/src/retained-process-retry.ts +36 -0
  224. package/src/sandbox-resume.ts +388 -101
  225. package/src/sandbox-routing.ts +150 -25
  226. package/src/sandbox-snapshot-diagnostics.ts +112 -0
  227. package/src/session-event-fanout.ts +23 -0
  228. package/src/warm-capture-holder.ts +15 -0
  229. package/src/worker-service-lifecycle.ts +53 -0
  230. package/src/workflows/activities.ts +16 -1
  231. package/src/workflows/browser-deadline-checkpoint.ts +50 -0
  232. package/src/workflows/file-upload-reaper.ts +2 -0
  233. package/src/workflows/scheduled-tasks.ts +26 -13
  234. package/src/workflows/session.ts +242 -22
  235. package/src/workflows.ts +4 -0
  236. package/dist/activities/agent-turn/knowledge-sources.d.ts +0 -20
  237. package/dist/activities/packs.d.ts +0 -55
  238. package/dist/activities-control-HMFGSKC5.js.map +0 -1
  239. package/dist/activities-turn-AP67JADS.js.map +0 -1
  240. package/dist/chunk-A4XQWVZK.js.map +0 -1
  241. package/dist/chunk-CYITU5UH.js.map +0 -1
  242. package/dist/chunk-RAMNYSAW.js.map +0 -1
  243. package/src/activities/agent-turn/knowledge-sources.ts +0 -86
  244. package/src/activities/packs.ts +0 -166
package/src/index.ts CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  } from "@opengeni/config";
10
10
  import {
11
11
  assertRuntimeDatabasePosture,
12
+ isRetryableRuntimeDatabaseStartupError,
12
13
  countSessionRecoveryBacklog,
13
14
  createDb,
14
15
  getContextCompactionPendingSummary,
@@ -60,7 +61,7 @@ import {
60
61
  initializeContextCompactionMetrics,
61
62
  initializeWorkerOutcomeMetrics,
62
63
  normalizeTurnTaskQueueStats,
63
- observabilityEventLogger,
64
+ observabilityEventBusOptions,
64
65
  startContextCompactionPendingMonitor,
65
66
  startSessionRecoveryMonitor,
66
67
  startTurnCapacityMonitor,
@@ -84,6 +85,7 @@ import {
84
85
  combineWorkerRunTargets,
85
86
  constructWithOwnedConnection,
86
87
  createWorkerServiceLifecycle,
88
+ createWorkerCleanupContainment,
87
89
  type WorkerServiceLifecycle,
88
90
  type WorkerRunTarget,
89
91
  } from "./worker-service-lifecycle";
@@ -98,6 +100,10 @@ import {
98
100
  SANDBOX_REAPER_V2_WORKFLOW_ID,
99
101
  sandboxLifecycleTaskQueue,
100
102
  } from "./sandbox-reaper-contract";
103
+ import {
104
+ BROWSER_DEADLINE_CHECKPOINT_SWEEP_ID,
105
+ browserDeadlineCheckpointTaskQueue,
106
+ } from "./browser-deadline-checkpoint-contract";
101
107
 
102
108
  export {
103
109
  createHostExportPump,
@@ -107,6 +113,9 @@ export {
107
113
  type HostEventExport,
108
114
  type HostEventExportBatch,
109
115
  type HostEventSink,
116
+ type HostLifecycleFactExport,
117
+ type HostLifecycleFactExportBatch,
118
+ type HostLifecycleFactSink,
110
119
  type HostUsageExport,
111
120
  type HostUsageExportBatch,
112
121
  type HostUsageSink,
@@ -263,10 +272,20 @@ export async function createOpenGeniWorker(options: WorkerOptions): Promise<{
263
272
  },
264
273
  ),
265
274
  async (connection) => {
275
+ let turnWorker: Worker | undefined;
276
+ let cleanupDrainRequested = false;
266
277
  const activityDependencies = {
267
278
  ...options.activityDependencies,
268
279
  settings,
269
280
  observability,
281
+ requestWorkerDrain:
282
+ options.activityDependencies?.requestWorkerDrain ??
283
+ (() => {
284
+ if (cleanupDrainRequested) return;
285
+ if (!turnWorker) throw new Error("turn worker lifecycle is not initialized");
286
+ turnWorker.shutdown();
287
+ cleanupDrainRequested = true;
288
+ }),
270
289
  };
271
290
  const activities =
272
291
  options.activities ??
@@ -315,32 +334,44 @@ export async function createOpenGeniWorker(options: WorkerOptions): Promise<{
315
334
  : turnConcurrency!.options),
316
335
  });
317
336
  if (options.role !== "control") {
337
+ turnWorker = worker;
318
338
  turnConcurrency?.admission?.finalizeStartupBaseline();
319
339
  return { worker, connection };
320
340
  }
321
341
 
342
+ const ownedWorkers = [worker];
322
343
  try {
323
- const sandboxLifecycleWorker = await Worker.create({
324
- ...sharedWorkerOptions,
325
- ...workflowDefinition,
326
- taskQueue: sandboxLifecycleTaskQueue(settings.temporalTaskQueue),
327
- reuseV8Context: true,
328
- workflowThreadPoolSize: 1,
329
- maxCachedWorkflows: CONTROL_WORKER_MAX_CACHED_WORKFLOWS,
330
- maxConcurrentWorkflowTaskExecutions: CONTROL_WORKER_MAX_CONCURRENT_WORKFLOW_TASKS,
331
- maxConcurrentActivityTaskExecutions: CONTROL_WORKER_MAX_CONCURRENT_ACTIVITIES,
332
- });
344
+ // The new activity type has its own queue. Retain the V1 poller so old
345
+ // drain histories finish; old binaries never receive checkpoint work.
346
+ for (const taskQueue of [
347
+ sandboxLifecycleTaskQueue(settings.temporalTaskQueue),
348
+ browserDeadlineCheckpointTaskQueue(settings.temporalTaskQueue),
349
+ ]) {
350
+ const lifecycleWorker = await Worker.create({
351
+ ...sharedWorkerOptions,
352
+ ...workflowDefinition,
353
+ taskQueue,
354
+ reuseV8Context: true,
355
+ workflowThreadPoolSize: 1,
356
+ maxCachedWorkflows: CONTROL_WORKER_MAX_CACHED_WORKFLOWS,
357
+ maxConcurrentWorkflowTaskExecutions: CONTROL_WORKER_MAX_CONCURRENT_WORKFLOW_TASKS,
358
+ maxConcurrentActivityTaskExecutions: CONTROL_WORKER_MAX_CONCURRENT_ACTIVITIES,
359
+ });
360
+ ownedWorkers.push(lifecycleWorker);
361
+ }
333
362
  return {
334
- worker: combineWorkerRunTargets([worker, sandboxLifecycleWorker]),
363
+ worker: combineWorkerRunTargets(ownedWorkers),
335
364
  connection,
336
365
  };
337
366
  } catch (error) {
338
- try {
339
- worker.shutdown();
340
- } catch {
341
- // Preserve the lifecycle worker construction failure. The base poller
342
- // still received its shutdown request; a secondary synchronous
343
- // shutdown error must not replace the startup root cause.
367
+ for (const ownedWorker of ownedWorkers) {
368
+ try {
369
+ ownedWorker.shutdown();
370
+ } catch {
371
+ // Preserve the lifecycle worker construction failure. The base poller
372
+ // still received its shutdown request; a secondary synchronous
373
+ // shutdown error must not replace the startup root cause.
374
+ }
344
375
  }
345
376
  throw error;
346
377
  }
@@ -474,20 +505,33 @@ export async function createWorkerWorkflowSignaler(
474
505
  return normalizeTurnTaskQueueStats(response.stats);
475
506
  },
476
507
  startSandboxReaperWorkflow: async () => {
477
- try {
478
- await temporal.workflow.start("sandboxReaperWorkflowV2", {
508
+ // Same backend tick, no additional schedule. A bounded independent
509
+ // inventory cannot prevent the existing per-box drain from starting.
510
+ const starts = await Promise.allSettled([
511
+ temporal.workflow.start("sandboxReaperWorkflowV2", {
479
512
  taskQueue: sandboxLifecycleTaskQueue(settings.temporalTaskQueue),
480
513
  workflowId: SANDBOX_REAPER_V2_WORKFLOW_ID,
481
514
  workflowIdReusePolicy: "ALLOW_DUPLICATE",
482
515
  args: [],
483
- });
484
- return "started";
485
- } catch (error) {
486
- if (error instanceof WorkflowExecutionAlreadyStartedError) {
487
- return "already_running";
516
+ }),
517
+ temporal.workflow.start("browserDeadlineCheckpointSweepWorkflow", {
518
+ taskQueue: browserDeadlineCheckpointTaskQueue(settings.temporalTaskQueue),
519
+ workflowId: BROWSER_DEADLINE_CHECKPOINT_SWEEP_ID,
520
+ workflowIdReusePolicy: "ALLOW_DUPLICATE",
521
+ args: [],
522
+ }),
523
+ ]);
524
+ for (const start of starts) {
525
+ if (
526
+ start.status === "rejected" &&
527
+ !(start.reason instanceof WorkflowExecutionAlreadyStartedError)
528
+ ) {
529
+ // The other start already settled. Retry the router without losing
530
+ // ordinary draining or silently omitting the checkpoint sweep.
531
+ throw start.reason;
488
532
  }
489
- throw error;
490
533
  }
534
+ return starts[0].status === "fulfilled" ? "started" : "already_running";
491
535
  },
492
536
  startVideoGenerationWorkflow: async ({ accountId, workspaceId, operationId }) => {
493
537
  try {
@@ -790,6 +834,9 @@ export async function registerSessionWorkflowWakeDispatcherSchedule(
790
834
 
791
835
  export type OpenGeniWorkerServiceOptions = Omit<WorkerOptions, "activityDependencies"> & {
792
836
  activityDependencies: ActivityDependencies & { db: Database; bus: EventBus };
837
+ /** Host-owned final containment after a stalled cleanup has drained peers.
838
+ * The standalone process exits; embedded hosts own their termination policy. */
839
+ terminateWorker?: () => void;
793
840
  /**
794
841
  * Exact catalog posture required by the standalone runtime. Embedded hosts
795
842
  * may omit this when they own an equivalent database isolation contract.
@@ -846,6 +893,7 @@ export async function createOpenGeniWorkerService(
846
893
  const onRetry = (event: Parameters<typeof logStartupDependencyRetry>[1]) =>
847
894
  logStartupDependencyRetry(observability, event);
848
895
  let lifecycle: WorkerServiceLifecycle | undefined;
896
+ let cleanupContainment: ReturnType<typeof createWorkerCleanupContainment> | undefined;
849
897
  let signaler: Awaited<ReturnType<typeof createWorkerWorkflowSignaler>> | undefined;
850
898
  let workerBundle: Awaited<ReturnType<typeof createOpenGeniWorker>> | undefined;
851
899
  let turnCapacityMonitor: ReturnType<typeof startTurnCapacityMonitor> | undefined;
@@ -925,6 +973,10 @@ export async function createOpenGeniWorkerService(
925
973
  signalCodexCapacityWorkflow,
926
974
  startSandboxReaperWorkflow,
927
975
  startVideoGenerationWorkflow,
976
+ requestWorkerDrain: () => {
977
+ if (!cleanupContainment) throw new Error("worker cleanup containment is not initialized");
978
+ cleanupContainment.request();
979
+ },
928
980
  },
929
981
  });
930
982
 
@@ -986,18 +1038,15 @@ export async function createOpenGeniWorkerService(
986
1038
  }
987
1039
 
988
1040
  if (options.http !== false) {
989
- const databaseReady = dbReadyCheck(
990
- options.http?.readinessDb ?? options.activityDependencies.db,
991
- options.databasePosture,
992
- );
1041
+ const readinessDb = options.http?.readinessDb ?? options.activityDependencies.db;
1042
+ const databaseReady = dbReadyCheck(readinessDb, options.databasePosture, async () => {
1043
+ await resolveCatalogSettings(readinessDb, settings);
1044
+ });
993
1045
  httpServer = startWorkerHttpServer({
994
1046
  settings,
995
1047
  observability,
996
1048
  checks: {
997
- db: async () => {
998
- await databaseReady();
999
- await resolveCatalogSettings(options.activityDependencies.db, settings);
1000
- },
1049
+ db: databaseReady,
1001
1050
  nats: natsReadyCheck(options.activityDependencies.bus),
1002
1051
  temporal: temporalReadyCheck(workerBundle.connection),
1003
1052
  },
@@ -1024,9 +1073,21 @@ export async function createOpenGeniWorkerService(
1024
1073
  throw new Error("OpenGeni worker service initialization did not complete");
1025
1074
  }
1026
1075
 
1076
+ cleanupContainment = createWorkerCleanupContainment({
1077
+ drain: () => lifecycle?.drain("stalled turn finalization") ?? false,
1078
+ ...(options.terminateWorker ? { terminate: options.terminateWorker } : {}),
1079
+ observability,
1080
+ });
1081
+ const activeCleanupContainment = cleanupContainment;
1027
1082
  lifecycle = createWorkerServiceLifecycle({
1028
1083
  role: options.role,
1029
- worker: activeWorkerBundle.worker,
1084
+ worker: {
1085
+ shutdown: () => activeWorkerBundle.worker.shutdown(),
1086
+ run: async () => {
1087
+ await activeWorkerBundle.worker.run();
1088
+ activeCleanupContainment.finished();
1089
+ },
1090
+ },
1030
1091
  observability,
1031
1092
  closeOwnedResources: async () => {
1032
1093
  memoryPressureGuard?.close();
@@ -1162,7 +1223,7 @@ export async function startWorker() {
1162
1223
  await retryStartupDependency(
1163
1224
  "PostgreSQL runtime posture",
1164
1225
  () => assertRuntimeDatabasePosture(dbClient.db, databasePosture),
1165
- { ...retryOptions, onRetry },
1226
+ { ...retryOptions, onRetry, shouldRetry: isRetryableRuntimeDatabaseStartupError },
1166
1227
  );
1167
1228
  bus = await retryStartupDependency(
1168
1229
  "NATS",
@@ -1172,12 +1233,13 @@ export async function startWorker() {
1172
1233
  controlPlaneAuth
1173
1234
  ? { user: controlPlaneAuth.user, pass: controlPlaneAuth.password }
1174
1235
  : undefined,
1175
- { logger: observabilityEventLogger(observability) },
1236
+ observabilityEventBusOptions(observability),
1176
1237
  ),
1177
1238
  { ...retryOptions, onRetry },
1178
1239
  );
1179
1240
  await runOpenGeniWorker({
1180
1241
  role,
1242
+ terminateWorker: () => process.exit(1),
1181
1243
  settings,
1182
1244
  databasePosture,
1183
1245
  http: { readinessDb: readinessDbClient.db },