@opengeni/worker-bundle 1.0.1 → 2.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 (122) hide show
  1. package/dist/activities/agent-turn/codex.d.ts +1 -1
  2. package/dist/activities/agent-turn/compaction-prep.d.ts +1 -5
  3. package/dist/activities/agent-turn/errors.d.ts +31 -5
  4. package/dist/activities/agent-turn/finalization-monitor.d.ts +17 -0
  5. package/dist/activities/agent-turn/finalization.d.ts +1 -1
  6. package/dist/activities/agent-turn/governance-model.d.ts +0 -2
  7. package/dist/activities/agent-turn/quiescence.d.ts +1 -0
  8. package/dist/activities/agent-turn/recovery-warning.d.ts +8 -0
  9. package/dist/activities/agent-turn/run-credentials.d.ts +0 -1
  10. package/dist/activities/agent-turn/sandbox-establish.d.ts +1 -1
  11. package/dist/activities/agent-turn/sandbox-route.d.ts +0 -20
  12. package/dist/activities/agent-turn/sandbox-runtime.d.ts +1 -1
  13. package/dist/activities/agent-turn/skill-remove.d.ts +14 -0
  14. package/dist/activities/agent-turn/skill-search.d.ts +1 -1
  15. package/dist/activities/agent-turn/stream-attempt.d.ts +1 -0
  16. package/dist/activities/agent-turn/tool-environment.d.ts +0 -4
  17. package/dist/activities/agent-turn/turn-context.d.ts +2 -0
  18. package/dist/activities/agent-turn/turn-sandbox-access.d.ts +3 -0
  19. package/dist/activities/codex-capacity.d.ts +6 -1
  20. package/dist/activities/codex-rotation.d.ts +1 -1
  21. package/dist/activities/context-compaction.d.ts +7 -1
  22. package/dist/activities/mcp-account-routes.d.ts +22 -0
  23. package/dist/activities/mcp-credentials.d.ts +12 -13
  24. package/dist/activities/mcp-operation-authority.d.ts +0 -5
  25. package/dist/activities/rig-verification.d.ts +2 -3
  26. package/dist/activities/sandbox-images.d.ts +1 -1
  27. package/dist/activities/sandbox-lease.d.ts +4 -3
  28. package/dist/activities/session-state.d.ts +57 -2
  29. package/dist/activities/types.d.ts +12 -3
  30. package/dist/{activities-control-HMFGSKC5.js → activities-control-BOLIY3H4.js} +366 -187
  31. package/dist/activities-control-BOLIY3H4.js.map +1 -0
  32. package/dist/activities-control.d.ts +110 -2
  33. package/dist/{activities-turn-AP67JADS.js → activities-turn-2B3WMHBB.js} +767 -471
  34. package/dist/activities-turn-2B3WMHBB.js.map +1 -0
  35. package/dist/activities.d.ts +110 -2
  36. package/dist/artifact-materializer-entry.js +5 -2
  37. package/dist/artifact-materializer-entry.js.map +1 -1
  38. package/dist/artifact-outbox-entry.js +2 -2
  39. package/dist/artifact-outbox-entry.js.map +1 -1
  40. package/dist/{chunk-A4XQWVZK.js → chunk-I7HKKMUJ.js} +77 -1
  41. package/dist/chunk-I7HKKMUJ.js.map +1 -0
  42. package/dist/{chunk-CYITU5UH.js → chunk-TVEE2UUC.js} +275 -146
  43. package/dist/chunk-TVEE2UUC.js.map +1 -0
  44. package/dist/editable-artifact-materializer-service.d.ts +2 -2
  45. package/dist/editable-artifact-outbox-service.d.ts +2 -2
  46. package/dist/index.d.ts +55 -1
  47. package/dist/index.js +4 -3
  48. package/dist/index.js.map +1 -1
  49. package/dist/observability-metrics.d.ts +11 -3
  50. package/dist/retained-process-diagnostics.d.ts +4 -0
  51. package/dist/sandbox-resume.d.ts +2 -12
  52. package/dist/sandbox-routing.d.ts +5 -3
  53. package/dist/sandbox-snapshot-diagnostics.d.ts +20 -0
  54. package/dist/warm-capture-holder.d.ts +3 -0
  55. package/dist/workflow-bundle.js +51 -11
  56. package/package.json +15 -15
  57. package/src/activities/agent-turn/agent-build.ts +42 -5
  58. package/src/activities/agent-turn/claim.ts +12 -0
  59. package/src/activities/agent-turn/codex-capacity.ts +26 -4
  60. package/src/activities/agent-turn/codex.ts +6 -2
  61. package/src/activities/agent-turn/compaction-prep.ts +53 -72
  62. package/src/activities/agent-turn/errors.ts +98 -10
  63. package/src/activities/agent-turn/failure-settlement.ts +49 -28
  64. package/src/activities/agent-turn/finalization-monitor.ts +121 -0
  65. package/src/activities/agent-turn/finalization.ts +79 -21
  66. package/src/activities/agent-turn/governance-model.ts +15 -19
  67. package/src/activities/agent-turn/history.ts +24 -10
  68. package/src/activities/agent-turn/quiescence.ts +3 -0
  69. package/src/activities/agent-turn/recovery-warning.ts +18 -0
  70. package/src/activities/agent-turn/run-credentials.ts +3 -7
  71. package/src/activities/agent-turn/run.ts +68 -52
  72. package/src/activities/agent-turn/sandbox-establish.ts +10 -2
  73. package/src/activities/agent-turn/sandbox-route.ts +0 -20
  74. package/src/activities/agent-turn/sandbox-runtime.ts +40 -7
  75. package/src/activities/agent-turn/skill-remove.ts +46 -0
  76. package/src/activities/agent-turn/skill-save.ts +1 -1
  77. package/src/activities/agent-turn/skill-search.ts +1 -1
  78. package/src/activities/agent-turn/skill-selection.ts +2 -0
  79. package/src/activities/agent-turn/skill-tools.ts +10 -5
  80. package/src/activities/agent-turn/stream-attempt.ts +38 -15
  81. package/src/activities/agent-turn/tool-environment.ts +44 -29
  82. package/src/activities/agent-turn/turn-context.ts +3 -0
  83. package/src/activities/agent-turn/turn-sandbox-access.ts +7 -1
  84. package/src/activities/capabilities.ts +17 -2
  85. package/src/activities/codex-capacity.ts +38 -9
  86. package/src/activities/codex-rotation.ts +18 -5
  87. package/src/activities/context-compaction.ts +26 -4
  88. package/src/activities/goals.ts +1 -0
  89. package/src/activities/google-drive-publication.ts +1 -3
  90. package/src/activities/mcp-account-routes.ts +139 -0
  91. package/src/activities/mcp-credentials.ts +83 -194
  92. package/src/activities/mcp-operation-authority.ts +16 -41
  93. package/src/activities/parent-wake.ts +8 -0
  94. package/src/activities/rig-verification.ts +38 -37
  95. package/src/activities/run-input.ts +25 -16
  96. package/src/activities/sandbox-images.ts +0 -1
  97. package/src/activities/sandbox-lease.ts +177 -44
  98. package/src/activities/scheduled-tasks.ts +118 -93
  99. package/src/activities/session-state.ts +83 -3
  100. package/src/activities/types.ts +18 -2
  101. package/src/activities/workflow-wake.ts +2 -17
  102. package/src/editable-artifact-materializer-service.ts +7 -3
  103. package/src/editable-artifact-outbox-service.ts +4 -4
  104. package/src/github-rest-mcp.ts +0 -1
  105. package/src/index.ts +2 -1
  106. package/src/observability-metrics.ts +105 -2
  107. package/src/personal-github-git-credentials.ts +0 -1
  108. package/src/pr-review-credentials.ts +0 -2
  109. package/src/retained-process-diagnostics.ts +50 -0
  110. package/src/sandbox-resume.ts +58 -73
  111. package/src/sandbox-routing.ts +44 -19
  112. package/src/sandbox-snapshot-diagnostics.ts +112 -0
  113. package/src/warm-capture-holder.ts +15 -0
  114. package/src/workflows/session.ts +64 -2
  115. package/dist/activities/agent-turn/knowledge-sources.d.ts +0 -20
  116. package/dist/activities/packs.d.ts +0 -55
  117. package/dist/activities-control-HMFGSKC5.js.map +0 -1
  118. package/dist/activities-turn-AP67JADS.js.map +0 -1
  119. package/dist/chunk-A4XQWVZK.js.map +0 -1
  120. package/dist/chunk-CYITU5UH.js.map +0 -1
  121. package/src/activities/agent-turn/knowledge-sources.ts +0 -86
  122. package/src/activities/packs.ts +0 -166
@@ -28,12 +28,12 @@ import {
28
28
  reconcilePendingParentSystemUpdates,
29
29
  reconcilePendingSessionWorkflowWakes,
30
30
  resolveIncidentTelemetryResponderMetadata,
31
- resolveWorkspacePackRuntime,
32
31
  rigProviderImageSourceImage,
33
32
  scheduledUserMessagePayload,
33
+ warnDrainSnapshotFailure,
34
34
  withFirstPartyTools,
35
35
  workflowIdForSession
36
- } from "./chunk-CYITU5UH.js";
36
+ } from "./chunk-TVEE2UUC.js";
37
37
  import {
38
38
  inspectOpenSandboxKubernetesInventory,
39
39
  recordCreditBalanceGauges,
@@ -53,7 +53,7 @@ import {
53
53
  recordTurnsQueuedGauge,
54
54
  recordWorkerDeathRecoveryMetrics,
55
55
  runtimeMetricsHooksForObservability
56
- } from "./chunk-A4XQWVZK.js";
56
+ } from "./chunk-I7HKKMUJ.js";
57
57
  import "./chunk-PZ5AY32C.js";
58
58
 
59
59
  // src/activities/knowledge-indexing.ts
@@ -978,13 +978,13 @@ var RIG_VERIFICATION_CLEANUP_OPERATION_MAX_MS = 6e4;
978
978
  var RIG_VERIFICATION_HEARTBEAT_MAX_INTERVAL_MS = 1e4;
979
979
  var RIG_VERIFICATION_HEARTBEAT_MIN_INTERVAL_MS = 250;
980
980
  var RIG_VERIFICATION_OWNER_TTL_MS = 20 * 6e4;
981
- var RIG_VERIFICATION_OWNERS_DISABLED_MESSAGE = "Rig verification lease ownership is disabled; refusing to create an unowned verifier sandbox";
981
+ var RIG_VERIFICATION_OWNERS_DISABLED_MESSAGE = "Sandbox Environment verification lease ownership is disabled; refusing to create an unowned verifier sandbox";
982
982
  var RIG_VERIFICATION_HOLDER_TOUCH_INTERVAL_MS = 1e4;
983
983
  var RIG_VERIFICATION_RELEASE_GRACE_MS = 1;
984
984
  var RigVerificationActivityDeadlineError = class extends Error {
985
985
  constructor(startToCloseTimeoutMs, cleanupReserveMs) {
986
986
  super(
987
- `Rig verification activity-local deadline reached with ${cleanupReserveMs}ms reserved for cleanup before the ${startToCloseTimeoutMs}ms Temporal start-to-close timeout`
987
+ `Sandbox Environment verification activity-local deadline reached with ${cleanupReserveMs}ms reserved for cleanup before the ${startToCloseTimeoutMs}ms Temporal start-to-close timeout`
988
988
  );
989
989
  this.startToCloseTimeoutMs = startToCloseTimeoutMs;
990
990
  this.cleanupReserveMs = cleanupReserveMs;
@@ -1003,7 +1003,9 @@ function createRigVerificationActivityLifecycle(context = currentActivityContext
1003
1003
  const temporalSignal = context?.cancellationSignal;
1004
1004
  const forwardTemporalCancellation = () => {
1005
1005
  if (!controller.signal.aborted) {
1006
- controller.abort(temporalSignal?.reason ?? new Error("Rig verification cancelled"));
1006
+ controller.abort(
1007
+ temporalSignal?.reason ?? new Error("Sandbox Environment verification cancelled")
1008
+ );
1007
1009
  }
1008
1010
  };
1009
1011
  if (temporalSignal?.aborted) {
@@ -1065,7 +1067,7 @@ function createRigVerificationActivityLifecycle(context = currentActivityContext
1065
1067
  };
1066
1068
  }
1067
1069
  function abortReason(signal) {
1068
- return signal.reason ?? new Error("Rig verification cancelled");
1070
+ return signal.reason ?? new Error("Sandbox Environment verification cancelled");
1069
1071
  }
1070
1072
  function throwIfAborted(signal) {
1071
1073
  if (signal.aborted) throw abortReason(signal);
@@ -1145,7 +1147,9 @@ var defaultOwnershipDependencies = {
1145
1147
  };
1146
1148
  var RigVerificationLeaseUnavailableError = class extends Error {
1147
1149
  constructor(sandboxGroupId, role) {
1148
- super(`Rig verification requires a new clean sandbox, but lease ${sandboxGroupId} was ${role}`);
1150
+ super(
1151
+ `Sandbox Environment verification requires a new clean sandbox, but lease ${sandboxGroupId} was ${role}`
1152
+ );
1149
1153
  this.sandboxGroupId = sandboxGroupId;
1150
1154
  this.role = role;
1151
1155
  }
@@ -1168,7 +1172,7 @@ async function runWithOwnedRigVerificationSandbox(input, run, dependencies = def
1168
1172
  let establishmentSettled = false;
1169
1173
  let establishmentPromise = null;
1170
1174
  const warnCleanupTimeout = (operation, instanceId) => {
1171
- input.observability.warn("rig verifier: ownership cleanup timed out", {
1175
+ input.observability.warn("sandbox environment verifier: ownership cleanup timed out", {
1172
1176
  holderId,
1173
1177
  instanceId,
1174
1178
  operation,
@@ -1176,7 +1180,7 @@ async function runWithOwnedRigVerificationSandbox(input, run, dependencies = def
1176
1180
  });
1177
1181
  };
1178
1182
  const warnCleanupFailure = (operation, instanceId, error) => {
1179
- input.observability.warn("rig verifier: ownership cleanup failed", {
1183
+ input.observability.warn("sandbox environment verifier: ownership cleanup failed", {
1180
1184
  holderId,
1181
1185
  instanceId,
1182
1186
  operation,
@@ -1302,11 +1306,14 @@ async function runWithOwnedRigVerificationSandbox(input, run, dependencies = def
1302
1306
  );
1303
1307
  } catch (error) {
1304
1308
  if (!signal.aborted) {
1305
- input.observability.warn("rig verifier: Modal ownership tag failed", {
1306
- holderId,
1307
- instanceId: created.instanceId,
1308
- error: error instanceof Error ? error.message : String(error)
1309
- });
1309
+ input.observability.warn(
1310
+ "sandbox environment verifier: Modal ownership tag failed",
1311
+ {
1312
+ holderId,
1313
+ instanceId: created.instanceId,
1314
+ error: error instanceof Error ? error.message : String(error)
1315
+ }
1316
+ );
1310
1317
  }
1311
1318
  }
1312
1319
  }
@@ -1501,10 +1508,12 @@ function rigProviderImageContentMarkerCommand(contentHash, markerRoot = "/var/op
1501
1508
  }
1502
1509
  function rigProviderImageContentMarker(contentHash, markerRoot = "/var/opengeni") {
1503
1510
  if (!/^sha256:[0-9a-f]{64}$/u.test(contentHash)) {
1504
- throw new Error("Rig provider image content marker requires a canonical SHA-256 value");
1511
+ throw new Error(
1512
+ "Sandbox Environment provider image content marker requires a canonical SHA-256 value"
1513
+ );
1505
1514
  }
1506
1515
  if (!/^\/[A-Za-z0-9._/-]+$/u.test(markerRoot)) {
1507
- throw new Error("Rig provider image marker root must be a safe absolute path");
1516
+ throw new Error("Sandbox Environment provider image marker root must be a safe absolute path");
1508
1517
  }
1509
1518
  const normalizedRoot = markerRoot.replace(/\/+$/u, "") || "/";
1510
1519
  const marker = `${normalizedRoot === "/" ? "" : normalizedRoot}/rig-setup-content-${contentHash.slice("sha256:".length)}.done`;
@@ -1542,7 +1551,9 @@ async function verifyRigProviderImageColdBoot(input, dependencies = defaultRigPr
1542
1551
  runContext.commandRunner
1543
1552
  );
1544
1553
  if (markerResult.exitCode !== 0) {
1545
- throw new Error("built provider image is missing its exact rig-content marker");
1554
+ throw new Error(
1555
+ "built provider image is missing its exact sandbox environment-content marker"
1556
+ );
1546
1557
  }
1547
1558
  for (const check of rigPlatformChecksForSettings(input.settings)) {
1548
1559
  const result = await runCommand(
@@ -1627,7 +1638,7 @@ async function buildVerifiedRigProviderImage(input) {
1627
1638
  finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
1628
1639
  error: {
1629
1640
  code: "provider_image_content_conflict",
1630
- message: "this exact rig version already records a provider image for different effective content; mint and verify a new version",
1641
+ message: "this exact sandbox environment version already records a provider image for different effective content; mint and verify a new version",
1631
1642
  retryable: false
1632
1643
  }
1633
1644
  };
@@ -1801,37 +1812,36 @@ async function buildVerifiedRigProviderImage(input) {
1801
1812
  });
1802
1813
  }
1803
1814
  }
1804
- function settingsForRigVerification(settings, packRuntime, rigImage) {
1805
- void packRuntime;
1815
+ function settingsForRigVerification(settings, rigImage) {
1806
1816
  void rigImage;
1807
1817
  return settings;
1808
1818
  }
1809
1819
  async function loadChangeTarget(db, workspaceId, changeId) {
1810
1820
  const change = await getRigChange(db, workspaceId, changeId);
1811
1821
  if (!change) {
1812
- throw new Error(`Rig change not found: ${changeId}`);
1822
+ throw new Error(`Sandbox Environment change not found: ${changeId}`);
1813
1823
  }
1814
1824
  const rig = await getRig(db, workspaceId, change.rigId);
1815
1825
  if (!rig) {
1816
- throw new Error(`Rig not found for change: ${change.rigId}`);
1826
+ throw new Error(`Sandbox Environment not found for change: ${change.rigId}`);
1817
1827
  }
1818
1828
  if (!change.baseVersionId) {
1819
- throw new Error(`Rig change ${change.id} has no base version`);
1829
+ throw new Error(`Sandbox Environment change ${change.id} has no base version`);
1820
1830
  }
1821
1831
  const baseVersion = await getRigVersionById(db, workspaceId, change.baseVersionId);
1822
1832
  if (!baseVersion || baseVersion.rigId !== rig.id) {
1823
- throw new Error(`Base rig version not found: ${change.baseVersionId}`);
1833
+ throw new Error(`Base sandbox environment version not found: ${change.baseVersionId}`);
1824
1834
  }
1825
1835
  return { rig, baseVersion, change };
1826
1836
  }
1827
1837
  async function loadVersionTarget(db, workspaceId, versionId) {
1828
1838
  const version = await getRigVersionById(db, workspaceId, versionId);
1829
1839
  if (!version) {
1830
- throw new Error(`Rig version not found: ${versionId}`);
1840
+ throw new Error(`Sandbox Environment version not found: ${versionId}`);
1831
1841
  }
1832
1842
  const rig = await getRig(db, workspaceId, version.rigId);
1833
1843
  if (!rig) {
1834
- throw new Error(`Rig not found for version: ${version.rigId}`);
1844
+ throw new Error(`Sandbox Environment not found for version: ${version.rigId}`);
1835
1845
  }
1836
1846
  return { rig, version };
1837
1847
  }
@@ -1874,12 +1884,7 @@ function createRigVerificationActivities(services) {
1874
1884
  change,
1875
1885
  candidateVersion
1876
1886
  );
1877
- const packRuntime = await resolveWorkspacePackRuntime(db, input.workspaceId);
1878
- const runSettings = settingsForRigVerification(
1879
- settings,
1880
- packRuntime,
1881
- candidateVersion.image
1882
- );
1887
+ const runSettings = settingsForRigVerification(settings, candidateVersion.image);
1883
1888
  const providerImageContentHash = rigProviderImageContentHash({
1884
1889
  backend: runSettings.sandboxBackend,
1885
1890
  sourceImage: rigProviderImageSourceImage(runSettings, runSettings.sandboxBackend),
@@ -1953,7 +1958,7 @@ function createRigVerificationActivities(services) {
1953
1958
  );
1954
1959
  if (markerResult.exitCode !== 0) {
1955
1960
  throw new Error(
1956
- `Failed to seal rig provider image content marker: ${markerResult.output.slice(-2e3)}`
1961
+ `Failed to seal sandbox environment provider image content marker: ${markerResult.output.slice(-2e3)}`
1957
1962
  );
1958
1963
  }
1959
1964
  const platformCheckResults = await runRigChecks(
@@ -2064,8 +2069,7 @@ function createRigVerificationActivities(services) {
2064
2069
  metadata: { versionId: version.id }
2065
2070
  });
2066
2071
  try {
2067
- const packRuntime = await resolveWorkspacePackRuntime(db, input.workspaceId);
2068
- const runSettings = settingsForRigVerification(settings, packRuntime, version.image);
2072
+ const runSettings = settingsForRigVerification(settings, version.image);
2069
2073
  const providerImageContentHash = rigProviderImageContentHash({
2070
2074
  backend: runSettings.sandboxBackend,
2071
2075
  sourceImage: rigProviderImageSourceImage(runSettings, runSettings.sandboxBackend),
@@ -2107,7 +2111,7 @@ function createRigVerificationActivities(services) {
2107
2111
  );
2108
2112
  if (markerResult.exitCode !== 0) {
2109
2113
  throw new Error(
2110
- `Failed to seal rig provider image content marker: ${markerResult.output.slice(-2e3)}`
2114
+ `Failed to seal sandbox environment provider image content marker: ${markerResult.output.slice(-2e3)}`
2111
2115
  );
2112
2116
  }
2113
2117
  const platformCheckResults = await runRigChecks(
@@ -2180,13 +2184,48 @@ function createRigVerificationActivities(services) {
2180
2184
  };
2181
2185
  }
2182
2186
 
2187
+ // src/retained-process-diagnostics.ts
2188
+ import {
2189
+ databaseFailureCode,
2190
+ nestedPostgresSqlState,
2191
+ safeDatabaseErrorFacts,
2192
+ SandboxWorkspaceMutationFencedError
2193
+ } from "@opengeni/db";
2194
+ function warnRetainedProcessProofFailure(observability, error, process) {
2195
+ let correlationId;
2196
+ try {
2197
+ const sqlState = nestedPostgresSqlState(error);
2198
+ const constraint = safeDatabaseErrorFacts(error).constraint;
2199
+ correlationId = observability.recordFailureDiagnostic({
2200
+ code: error instanceof SandboxWorkspaceMutationFencedError ? "retained_process_fenced" : sqlState ? databaseFailureCode(sqlState) : "retained_process_proof_failed",
2201
+ stage: "sandbox_retained_processes.proof",
2202
+ error,
2203
+ processId: process.id,
2204
+ sessionId: process.sessionId,
2205
+ ...process.ownerAttemptId ? { attemptId: process.ownerAttemptId } : {},
2206
+ ...process.ownerTurnId ? { turnId: process.ownerTurnId } : {},
2207
+ attempts: process.reconcileAttempts,
2208
+ sqlState,
2209
+ ...constraint ? { constraint } : {}
2210
+ });
2211
+ } catch {
2212
+ }
2213
+ try {
2214
+ observability.warn("sandbox reaper: retained-process proof checkpoint failed", {
2215
+ ...correlationId ? { correlationId } : {}
2216
+ });
2217
+ } catch {
2218
+ }
2219
+ }
2220
+
2183
2221
  // src/activities/sandbox-lease.ts
2184
2222
  import { createHash, randomUUID as randomUUID2 } from "crypto";
2185
- import { retainedProviderCommandPersistence } from "@opengeni/db/retained-provider-commands";
2223
+ import { requestRetainedProcessDeadlineCancellation } from "@opengeni/db/retained-provider-commands";
2186
2224
  import { Context } from "@temporalio/activity";
2187
2225
  import { OpLostReason, OpState } from "@opengeni/agent-proto";
2188
2226
  import {
2189
2227
  accrueWarmSeconds,
2228
+ retainedProviderCommandPersistence,
2190
2229
  adoptLegacyModalCheckpointArtifact,
2191
2230
  confirmDrainCold,
2192
2231
  appendSessionEventToSandboxGroup,
@@ -2215,6 +2254,7 @@ import {
2215
2254
  recordRetainedProcessReconciliationProof,
2216
2255
  replaceWorkspaceArchiveCaptureAfterProof,
2217
2256
  readLease,
2257
+ readWorkspaceArchiveCapturePreflight,
2218
2258
  reapExpiredSessionListSnapshots,
2219
2259
  reapStaleLeaseHoldersGlobal,
2220
2260
  requestDueSandboxRotationsGlobal,
@@ -2356,7 +2396,7 @@ function sandboxDrainActivityAttempt() {
2356
2396
  }
2357
2397
  }
2358
2398
  function createSandboxLeaseActivities(services, options = {}) {
2359
- const terminateBox = options.terminateBox ?? (async (settings, lease, observability, persistArchive, providerCaptureRequestId, captureDisposition, capturePolicy, diskBackedArchives, releaseFailedCapture) => await terminateProviderBox(
2399
+ const terminateBox = options.terminateBox ?? (async (settings, lease, observability, persistArchive, providerCaptureRequestId, captureDisposition, capturePolicy, diskBackedArchives, releaseFailedCapture, workspaceId) => await terminateProviderBox(
2360
2400
  settings,
2361
2401
  lease,
2362
2402
  observability,
@@ -2367,7 +2407,8 @@ function createSandboxLeaseActivities(services, options = {}) {
2367
2407
  captureDisposition,
2368
2408
  capturePolicy,
2369
2409
  diskBackedArchives,
2370
- releaseFailedCapture
2410
+ releaseFailedCapture,
2411
+ workspaceId
2371
2412
  ));
2372
2413
  const sweepModalOrphans = options.sweepModalOrphans ?? sweepModalOrphansForConfiguredBackend;
2373
2414
  const inspectOpenSandboxInventory = options.inspectOpenSandboxKubernetesInventory ?? inspectOpenSandboxKubernetesInventory;
@@ -2904,18 +2945,14 @@ async function reconcileConnectedMachineBackgroundCommands(db, settings, observa
2904
2945
  journal: { attachGeneration: () => String(Date.now()), persistSettled: () => {
2905
2946
  } }
2906
2947
  });
2907
- const replay = await client.readExisting(
2948
+ await replayConnectedCommandOutput(
2949
+ client,
2908
2950
  claim.opId,
2909
- proof ? 5e3 : 250,
2951
+ Boolean(proof),
2910
2952
  async (frames) => {
2911
2953
  await captureConnectedCommandOutput(db, claim, bus)(claim.commandId, frames);
2912
2954
  }
2913
2955
  );
2914
- if (proof && replay.status !== "completed" && !replay.terminal) {
2915
- throw new Error(
2916
- "Connected command terminal output replay has not reached its exit frontier"
2917
- );
2918
- }
2919
2956
  }
2920
2957
  if (!proof) {
2921
2958
  await deferConnectedCommandClaim(
@@ -2989,6 +3026,23 @@ async function reconcileConnectedMachineBackgroundCommands(db, settings, observa
2989
3026
  if (claims.length < CONNECTED_COMMAND_RECONCILIATION_LIMIT) break;
2990
3027
  } while (Date.now() < deadline);
2991
3028
  }
3029
+ async function replayConnectedCommandOutput(client, opId, terminalKnown, capture) {
3030
+ let capturedThrough = 0n;
3031
+ while (true) {
3032
+ const before = capturedThrough;
3033
+ const replay = await client.readExisting(opId, terminalKnown ? 5e3 : 250, async (frames) => {
3034
+ await capture(frames);
3035
+ for (const frame of frames) {
3036
+ const sequence = BigInt(frame.sequence);
3037
+ if (sequence > capturedThrough) capturedThrough = sequence;
3038
+ }
3039
+ });
3040
+ if (!terminalKnown || replay.status === "completed" || replay.terminal) return;
3041
+ if (capturedThrough === before) {
3042
+ throw new Error("Connected command terminal output replay has not reached its exit frontier");
3043
+ }
3044
+ }
3045
+ }
2992
3046
  async function probeConnectedMachineBackgroundCommand(claim, controlRpc, controlTimeoutMs, observedAt = /* @__PURE__ */ new Date()) {
2993
3047
  const input = {
2994
3048
  controlRpc,
@@ -3079,6 +3133,40 @@ async function reconcileTerminalRetainedProcesses(db, settings, observability, p
3079
3133
  let process = claim.process;
3080
3134
  const expected = retainedProcessSettlementIdentity(process);
3081
3135
  let proof = retainedProcessReconciliationProof(process);
3136
+ const processScope = {
3137
+ accountId: process.accountId,
3138
+ workspaceId: process.workspaceId,
3139
+ sessionId: process.sessionId,
3140
+ processId: process.id
3141
+ };
3142
+ const storedCommandPersistence = retainedProviderCommandPersistence(
3143
+ db,
3144
+ processScope,
3145
+ bus ? (events) => bus.publish(process.workspaceId, process.sessionId, events) : void 0
3146
+ );
3147
+ const commandPersistence = {
3148
+ ...storedCommandPersistence,
3149
+ requestCancellation: async (reason) => {
3150
+ if (reason === "provider_deadline") {
3151
+ await requestRetainedProcessDeadlineCancellation(db, processScope);
3152
+ if (!await storedCommandPersistence.cancellationRequested())
3153
+ throw new Error(
3154
+ "Supervised deadline cancellation no longer owns its original rotating lease"
3155
+ );
3156
+ } else await storedCommandPersistence.requestCancellation(reason);
3157
+ }
3158
+ };
3159
+ if (proof && process.providerBackend === "modal") {
3160
+ try {
3161
+ const command = await commandPersistence.load();
3162
+ if (command?.kind === "modal-router-v1" && command.supervision && (!await commandPersistence.loadSupervisionReceipt() || ![command.streams.stdout, command.streams.stderr].every(
3163
+ (stream) => stream.eof && stream.exitCode === 0
3164
+ )))
3165
+ proof = null;
3166
+ } catch {
3167
+ proof = null;
3168
+ }
3169
+ }
3082
3170
  if (!proof) {
3083
3171
  let observation = null;
3084
3172
  if (process.providerBackend === "modal" && process.routeTargetId === null && !process.providerBindingKey) {
@@ -3162,6 +3250,19 @@ async function reconcileTerminalRetainedProcesses(db, settings, observability, p
3162
3250
  }
3163
3251
  } else {
3164
3252
  try {
3253
+ const command = await commandPersistence.load();
3254
+ const supervised = command?.kind === "modal-router-v1" && Boolean(command.supervision);
3255
+ const supervisionMetric = (outcome) => observability.incrementCounter({
3256
+ name: "opengeni_command_supervision_total",
3257
+ help: "Native retained command supervision reconciliation outcomes.",
3258
+ labels: { outcome }
3259
+ });
3260
+ if (supervised && (lease.rotationReason === "provider_deadline" || claim.ownerState === "background_stopping")) {
3261
+ await commandPersistence.requestCancellation(
3262
+ lease.rotationReason === "provider_deadline" ? "provider_deadline" : "explicit_stop"
3263
+ );
3264
+ supervisionMetric("cancellation_intent");
3265
+ }
3165
3266
  observation = await probe(
3166
3267
  settings,
3167
3268
  lease,
@@ -3183,13 +3284,17 @@ async function reconcileTerminalRetainedProcesses(db, settings, observability, p
3183
3284
  if (events.length && bus)
3184
3285
  await bus.publish(process.workspaceId, process.sessionId, events).catch(() => void 0);
3185
3286
  },
3186
- retainedProviderCommandPersistence(db, {
3187
- accountId: process.accountId,
3188
- workspaceId: process.workspaceId,
3189
- sessionId: process.sessionId,
3190
- processId: process.id
3191
- })
3287
+ commandPersistence
3192
3288
  );
3289
+ if (supervised) {
3290
+ supervisionMetric(
3291
+ await commandPersistence.loadSupervisionReceipt() ? "proof_retained" : "proof_missing"
3292
+ );
3293
+ if (observation.status === "deferred")
3294
+ supervisionMetric(
3295
+ observation.reason === "provider_running" ? "checkpoint_blocked" : "provider_failure"
3296
+ );
3297
+ }
3193
3298
  } catch (error) {
3194
3299
  observability.warn("sandbox reaper: retained-process provider probe failed", {
3195
3300
  processId: process.id,
@@ -3248,10 +3353,7 @@ async function reconcileTerminalRetainedProcesses(db, settings, observability, p
3248
3353
  recordRetainedProcessReconciliation(observability, `proof_${proof.outcome}`);
3249
3354
  } catch (error) {
3250
3355
  recordRetainedProcessReconciliation(observability, "proof_checkpoint_failed");
3251
- observability.warn("sandbox reaper: retained-process proof checkpoint failed", {
3252
- processId: process.id,
3253
- error: error instanceof Error ? error.message : String(error)
3254
- });
3356
+ warnRetainedProcessProofFailure(observability, error, process);
3255
3357
  continue;
3256
3358
  }
3257
3359
  }
@@ -3377,7 +3479,7 @@ async function captureRetainedProbeOutput(processId, result, capture) {
3377
3479
  pendingRetainedProbeOutput.delete(processId);
3378
3480
  }
3379
3481
  async function probeRetainedProcessAtProvider(settings, lease, process, mode = "observe", captureOutput, providerPersistence) {
3380
- if (lease.id !== process.leaseId || lease.sandboxGroupId !== process.sandboxGroupId || lease.leaseEpoch !== process.leaseEpoch || lease.backend !== process.providerBackend || lease.instanceId !== process.providerInstanceId || lease.resumeBackendId !== process.providerBackend || process.routeTargetId !== null) {
3482
+ if (lease.id !== process.leaseId || lease.sandboxGroupId !== process.sandboxGroupId || lease.leaseEpoch !== process.leaseEpoch || lease.backend !== process.providerBackend || lease.instanceId !== process.providerInstanceId || !lease.resumeBackendId || sandboxBackendForSdkBackendId(lease.resumeBackendId) !== process.providerBackend || process.routeTargetId !== null) {
3381
3483
  return { status: "deferred", reason: "identity_mismatch" };
3382
3484
  }
3383
3485
  if (!lease.resumeState) {
@@ -3390,7 +3492,7 @@ async function probeRetainedProcessAtProvider(settings, lease, process, mode = "
3390
3492
  return classifyRetainedProcessPollResult(pending.result, process.providerSessionId);
3391
3493
  }
3392
3494
  const envelopeBackend = lease.resumeState.backendId;
3393
- if (envelopeBackend !== void 0 && envelopeBackend !== process.providerBackend) {
3495
+ if (envelopeBackend !== void 0 && (typeof envelopeBackend !== "string" || sandboxBackendForSdkBackendId(envelopeBackend) !== process.providerBackend)) {
3394
3496
  return { status: "deferred", reason: "identity_mismatch" };
3395
3497
  }
3396
3498
  if (sandboxProviderInstanceIdFromEnvelope(lease.resumeState) !== process.providerInstanceId) {
@@ -3418,7 +3520,7 @@ async function probeRetainedProcessAtProvider(settings, lease, process, mode = "
3418
3520
  } catch {
3419
3521
  return { status: "deferred", reason: "provider_error" };
3420
3522
  }
3421
- if (!client || client.backendId !== process.providerBackend || !client.resume) {
3523
+ if (!client || sandboxBackendForSdkBackendId(client.backendId) !== process.providerBackend || !client.resume) {
3422
3524
  return { status: "deferred", reason: "backend_unsupported" };
3423
3525
  }
3424
3526
  const envelopeSessionState = lease.resumeState.sessionState ?? lease.resumeState;
@@ -3502,6 +3604,11 @@ async function probeRetainedProcessAtProvider(settings, lease, process, mode = "
3502
3604
  return;
3503
3605
  }
3504
3606
  const page = session.getProviderCommandOutput?.(value);
3607
+ if (page?.command.kind === "modal-router-v1" && typeof value === "string") {
3608
+ if (!session.captureCommandOutput || !await session.captureCommandOutput(value))
3609
+ throw new Error("Byte-offset output requires atomic capture before settlement");
3610
+ return;
3611
+ }
3505
3612
  if (page) {
3506
3613
  for (const chunk of page.chunks)
3507
3614
  if (chunk.text)
@@ -3513,10 +3620,14 @@ async function probeRetainedProcessAtProvider(settings, lease, process, mode = "
3513
3620
  };
3514
3621
  let result;
3515
3622
  try {
3623
+ const supervisedCancelled = mode === "cancel" || lease.rotationReason === "provider_deadline" ? await session.cancelSupervisedCommand?.(
3624
+ process.providerSessionId,
3625
+ lease.rotationReason === "provider_deadline" ? "provider_deadline" : "explicit_stop"
3626
+ ) ?? false : false;
3516
3627
  result = await withRetainedProcessProbeTimeout(
3517
3628
  session.writeStdin({
3518
3629
  sessionId: process.providerSessionId,
3519
- chars: mode === "cancel" ? "" : "",
3630
+ chars: mode === "cancel" && !supervisedCancelled ? "" : "",
3520
3631
  yieldTimeMs: 1e3,
3521
3632
  maxOutputTokens: 2e3
3522
3633
  })
@@ -3542,7 +3653,7 @@ async function probeRetainedProcessAtProvider(settings, lease, process, mode = "
3542
3653
  }
3543
3654
  await capturePage(result);
3544
3655
  const observation = classifyRetainedProcessPollResult(result, process.providerSessionId, session);
3545
- if (observation.status === "deferred" && observation.reason === "provider_running" && lease.rotationRequestedAt !== null) {
3656
+ if (observation.status === "deferred" && observation.reason === "provider_running" && lease.rotationRequestedAt !== null && !await providerPersistence?.load().then((command) => command?.kind === "modal-router-v1" && command.supervision)) {
3546
3657
  try {
3547
3658
  const interrupted = await withRetainedProcessProbeTimeout(
3548
3659
  session.writeStdin({
@@ -4118,6 +4229,16 @@ async function terminateDrainableBox(db, settings, row, observability, terminate
4118
4229
  }
4119
4230
  return result;
4120
4231
  };
4232
+ if (!providerMissingBeforeCapture && backend === "modal" && lease.instanceId && !await readWorkspaceArchiveCapturePreflight(db, {
4233
+ accountId,
4234
+ workspaceId: row.workspaceId,
4235
+ sandboxGroupId: row.sandboxGroupId,
4236
+ expectedEpoch: row.leaseEpoch,
4237
+ expectedInstanceId: lease.instanceId,
4238
+ liveness: "draining"
4239
+ })) {
4240
+ return false;
4241
+ }
4121
4242
  const termination = providerMissingBeforeCapture ? { terminated: true, providerMissingBeforeCapture: true } : await terminateBox(
4122
4243
  settings,
4123
4244
  lease,
@@ -4137,7 +4258,8 @@ async function terminateDrainableBox(db, settings, row, observability, terminate
4137
4258
  expectedEpoch: row.leaseEpoch,
4138
4259
  expectedInstanceId: lease.instanceId
4139
4260
  });
4140
- }
4261
+ },
4262
+ row.workspaceId
4141
4263
  );
4142
4264
  const terminated = typeof termination === "boolean" ? termination : termination.terminated;
4143
4265
  if (!terminated) {
@@ -4193,18 +4315,20 @@ function providerDrainLogIdentity(lease, backend) {
4193
4315
  instanceId: lease.instanceId
4194
4316
  };
4195
4317
  }
4196
- async function terminateProviderBox(settings, lease, observability, persistArchive, createClientForBackend = createSandboxClientForBackend, terminateModalById = terminateModalSandboxById, providerCaptureRequestId, captureDisposition = "capture_required", claimedCapturePolicy, diskBackedArchives = false, releaseFailedCapture) {
4318
+ async function terminateProviderBox(settings, lease, observability, persistArchive, createClientForBackend = createSandboxClientForBackend, terminateModalById = terminateModalSandboxById, providerCaptureRequestId, captureDisposition = "capture_required", claimedCapturePolicy, diskBackedArchives = false, releaseFailedCapture, workspaceId) {
4197
4319
  const durableBackendId = lease.resumeBackendId ?? lease.backend;
4198
4320
  const backend = sandboxBackendForSdkBackendId(durableBackendId) ?? durableBackendId;
4199
4321
  const logIdentity = providerDrainLogIdentity(lease, backend);
4322
+ const warnCaptureFailure = (message, error) => warnDrainSnapshotFailure(observability, message, error, {
4323
+ sandboxGroupId: lease.sandboxGroupId,
4324
+ leaseEpoch: lease.leaseEpoch,
4325
+ ...workspaceId ? { workspaceId } : {}
4326
+ });
4200
4327
  const releaseAfterCaptureFailure = async () => {
4201
4328
  try {
4202
4329
  await releaseFailedCapture?.();
4203
4330
  } catch (error) {
4204
- observability.warn("sandbox reaper: failed capture claim release failed", {
4205
- ...logIdentity,
4206
- error: error instanceof Error ? error.message : String(error)
4207
- });
4331
+ warnCaptureFailure("sandbox reaper: failed capture claim release failed", error);
4208
4332
  }
4209
4333
  };
4210
4334
  if (!backend || backend === "none") {
@@ -4359,26 +4483,17 @@ async function terminateProviderBox(settings, lease, observability, persistArchi
4359
4483
  }
4360
4484
  );
4361
4485
  } catch (error) {
4362
- observability.warn("sandbox reaper: late workspace capture publication failed", {
4363
- ...logIdentity,
4364
- error: error instanceof Error ? error.message : String(error)
4365
- });
4486
+ warnCaptureFailure("sandbox reaper: late workspace capture publication failed", error);
4366
4487
  } finally {
4367
4488
  await disposeWorkspaceArchive(archive);
4368
4489
  }
4369
4490
  },
4370
4491
  observeLatePublicationFailure: (error) => {
4371
- observability.warn("sandbox reaper: late capture publication cleanup failed", {
4372
- ...logIdentity,
4373
- error: error instanceof Error ? error.message : String(error)
4374
- });
4492
+ warnCaptureFailure("sandbox reaper: late capture publication cleanup failed", error);
4375
4493
  },
4376
4494
  observeLateFailure: (error) => {
4377
4495
  void releaseAfterCaptureFailure();
4378
- observability.warn("sandbox reaper: timed-out provider capture later failed", {
4379
- ...logIdentity,
4380
- error: error instanceof Error ? error.message : String(error)
4381
- });
4496
+ warnCaptureFailure("sandbox reaper: timed-out provider capture later failed", error);
4382
4497
  }
4383
4498
  });
4384
4499
  }
@@ -4389,12 +4504,9 @@ async function terminateProviderBox(settings, lease, observability, persistArchi
4389
4504
  });
4390
4505
  return { terminated: true, providerMissingBeforeCapture: true };
4391
4506
  }
4392
- observability.warn(
4507
+ warnCaptureFailure(
4393
4508
  "sandbox reaper: persistWorkspace failed \u2014 leaving box draining (files NOT lost)",
4394
- {
4395
- ...logIdentity,
4396
- error: error instanceof Error ? error.message : String(error)
4397
- }
4509
+ error
4398
4510
  );
4399
4511
  if (!(error instanceof SandboxProviderCaptureTimeoutError)) {
4400
4512
  await releaseAfterCaptureFailure();
@@ -4467,7 +4579,6 @@ import {
4467
4579
  TurnExecutionPolicyV1
4468
4580
  } from "@opengeni/contracts";
4469
4581
  import {
4470
- defaultSessionMcpServerIds,
4471
4582
  openGeniSlackBotMetadata,
4472
4583
  requireOpenGeniSlackBotConnection,
4473
4584
  resolveWorkspaceCatalogSettings as resolveWorkspaceCatalogSettings2,
@@ -4475,6 +4586,12 @@ import {
4475
4586
  workspaceCustomModelReference,
4476
4587
  lockActiveCustomModelForAdmission,
4477
4588
  scheduledSlackBotConnectionId,
4589
+ freezeConnectionAccounts,
4590
+ ConnectionAccountSelectionError,
4591
+ scheduledConnectionSurfaceEligibility,
4592
+ scheduledConnectionTools,
4593
+ settingsWithEnabledCapabilityMcpServers,
4594
+ settingsWithSessionMcpServerMetadata,
4478
4595
  swapActiveSandbox
4479
4596
  } from "@opengeni/core";
4480
4597
  import {
@@ -4489,7 +4606,6 @@ import {
4489
4606
  getScheduledTaskRunAcceptedExecution,
4490
4607
  getScheduledTaskRunByProducerKey,
4491
4608
  getScheduledTargetSessionExecution,
4492
- getScheduledTaskPersonalConnectionDelegations,
4493
4609
  getScheduledTaskRunPersonalResourceAuthority,
4494
4610
  getScheduledTaskPersonalResourceAuthoritySubject,
4495
4611
  getScheduledTaskRevisionAuthority,
@@ -4505,7 +4621,6 @@ import {
4505
4621
  isCodexBilledModel,
4506
4622
  initializeSessionStartAtomically,
4507
4623
  materializeScheduledTaskReusableSessionFromRun,
4508
- listEnabledMcpCapabilityServerIds,
4509
4624
  listInstalledApiIntegrationServerIdsForDelegations,
4510
4625
  markScheduledTaskRunFailedIfQueued,
4511
4626
  markScheduledTaskRunSkippedIfQueued,
@@ -4805,20 +4920,6 @@ function createScheduledTaskActivities(services) {
4805
4920
  if (incidentDeclaration.action === "blocked") {
4806
4921
  return incidentDeclaration;
4807
4922
  }
4808
- const taskPersonalConnectionDelegations = await getScheduledTaskPersonalConnectionDelegations(
4809
- db,
4810
- task.workspaceId,
4811
- task.id
4812
- );
4813
- const taskConnectionAuthoritySubjects = [
4814
- ...new Set(
4815
- taskPersonalConnectionDelegations.map((delegation) => delegation.ownerSubjectId)
4816
- )
4817
- ];
4818
- if (taskConnectionAuthoritySubjects.length > 1) {
4819
- throw new Error("scheduled connection authority has multiple causal humans");
4820
- }
4821
- const taskConnectionAuthoritySubjectId = taskConnectionAuthoritySubjects[0] ?? null;
4822
4923
  const taskPersonalResourceAuthoritySubjectId = await getScheduledTaskPersonalResourceAuthoritySubject(db, {
4823
4924
  accountId: task.accountId,
4824
4925
  workspaceId: task.workspaceId,
@@ -4831,10 +4932,12 @@ function createScheduledTaskActivities(services) {
4831
4932
  taskId: task.id,
4832
4933
  taskAuthorityRevision: task.authorityRevision
4833
4934
  });
4834
- if (taskConnectionAuthoritySubjectId && taskPersonalResourceAuthoritySubjectId && taskConnectionAuthoritySubjectId !== taskPersonalResourceAuthoritySubjectId) {
4835
- throw new Error("scheduled authority classes have different causal humans");
4935
+ const taskAuthoritySubjectId = task.ownerSubjectId;
4936
+ if (task.action.kind === "agent_turn" && ((taskRevisionAuthority?.subjectId ?? null) !== taskAuthoritySubjectId || [taskPersonalResourceAuthoritySubjectId].some(
4937
+ (subject) => subject !== null && subject !== taskAuthoritySubjectId
4938
+ ))) {
4939
+ throw new Error("scheduled authority differs from its immutable execution owner");
4836
4940
  }
4837
- const taskAuthoritySubjectId = taskRevisionAuthority?.subjectId ?? taskPersonalResourceAuthoritySubjectId ?? taskConnectionAuthoritySubjectId;
4838
4941
  const acceptedTargetSessionId = task.runMode === "existing_session" ? task.targetSessionId : task.runMode === "reusable_session" ? task.reusableSessionId : null;
4839
4942
  const targetSessionExecutionBase = acceptedTargetSessionId ? await getScheduledTargetSessionExecution(
4840
4943
  db,
@@ -4851,6 +4954,50 @@ function createScheduledTaskActivities(services) {
4851
4954
  const creatorPolicy = await getScheduledTaskCreatorPolicy(db, task.workspaceId, task.id);
4852
4955
  const firstPartyMcpTools = creatorPolicy?.firstPartyMcpTools ? allowedFirstPartyMcpToolsForSession(settings, creatorPolicy.firstPartyMcpTools) : resolveFirstPartyMcpToolPolicy(settings).default;
4853
4956
  const firstPartyMcpPermissions = creatorPolicy?.firstPartyMcpPermissions ? [...creatorPolicy.firstPartyMcpPermissions] : [...DEFAULT_FIRST_PARTY_MCP_PERMISSIONS];
4957
+ const connectionSettings = await settingsWithEnabledCapabilityMcpServers(
4958
+ db,
4959
+ task.workspaceId,
4960
+ settings,
4961
+ taskAuthoritySubjectId ? { subjectId: taskAuthoritySubjectId } : {}
4962
+ );
4963
+ const connectionTarget = acceptedTargetSessionId && targetSessionExecutionBase ? await requireSession(db, task.workspaceId, acceptedTargetSessionId) : null;
4964
+ const connectionTools = await scheduledConnectionTools(
4965
+ db,
4966
+ task.workspaceId,
4967
+ connectionSettings,
4968
+ connectionTarget,
4969
+ taskTools,
4970
+ taskAuthoritySubjectId ?? void 0
4971
+ );
4972
+ const taskConnections = await freezeConnectionAccounts({
4973
+ db,
4974
+ accountId: task.accountId,
4975
+ workspaceId: task.workspaceId,
4976
+ settings: connectionTarget ? settingsWithSessionMcpServerMetadata(connectionSettings, connectionTarget.mcpServers) : connectionSettings,
4977
+ tools: connectionTools,
4978
+ resources: connectionTarget?.resources ?? task.agentConfig.resources,
4979
+ source: taskAuthoritySubjectId ? { kind: "subject", subjectId: taskAuthoritySubjectId, accountId: task.accountId } : { kind: "none" },
4980
+ authoritySelections: task.agentConfig.connectionAccounts ?? [],
4981
+ authoritySelectionsFrozen: task.agentConfig.connectionAccountsFrozen === true,
4982
+ ...scheduledConnectionSurfaceEligibility(
4983
+ settings,
4984
+ connectionTarget ?? {
4985
+ firstPartyMcpTools,
4986
+ firstPartyMcpPermissions
4987
+ }
4988
+ )
4989
+ }).catch((error) => {
4990
+ if (error instanceof ConnectionAccountSelectionError) return null;
4991
+ throw error;
4992
+ });
4993
+ if (taskConnections === null) {
4994
+ return { action: "blocked", reason: "connection_account_unavailable" };
4995
+ }
4996
+ const {
4997
+ personalConnectionDelegations: taskPersonalConnectionDelegations,
4998
+ mcpAccountBindings: taskMcpAccountBindings
4999
+ } = taskConnections;
5000
+ const taskConnectionAuthoritySubjectId = taskPersonalConnectionDelegations.length > 0 ? taskAuthoritySubjectId : null;
4854
5001
  const creatorSessionPolicy = scheduledCreatorSessionPolicyInput(
4855
5002
  creatorPolicy?.sessionPolicy ?? null
4856
5003
  );
@@ -4898,20 +5045,15 @@ function createScheduledTaskActivities(services) {
4898
5045
  };
4899
5046
  })() : null;
4900
5047
  const targetSessionExecution = targetSessionExecutionBase ? await (async () => {
4901
- const [capabilityServerIds, apiIntegrationServerIds] = await Promise.all([
4902
- listEnabledMcpCapabilityServerIds(db, task.workspaceId),
4903
- listInstalledApiIntegrationServerIdsForDelegations(
4904
- db,
4905
- task.workspaceId,
4906
- taskPersonalConnectionDelegations
4907
- )
4908
- ]);
4909
- const workspaceDefaultMcpServerIds = new Set(
4910
- settings.mcpServers.map((server) => server.id)
5048
+ const apiIntegrationServerIds = await listInstalledApiIntegrationServerIdsForDelegations(
5049
+ db,
5050
+ task.workspaceId,
5051
+ taskPersonalConnectionDelegations
4911
5052
  );
4912
- for (const id of capabilityServerIds) workspaceDefaultMcpServerIds.add(id);
4913
- for (const id of apiIntegrationServerIds) workspaceDefaultMcpServerIds.add(id);
4914
- const availableMcpServerIds = new Set(workspaceDefaultMcpServerIds);
5053
+ const availableMcpServerIds = /* @__PURE__ */ new Set([
5054
+ ...connectionSettings.mcpServers.map((server) => server.id),
5055
+ ...apiIntegrationServerIds
5056
+ ]);
4915
5057
  for (const id of targetSessionExecutionBase.mcpServerIds) {
4916
5058
  availableMcpServerIds.add(id);
4917
5059
  }
@@ -4919,9 +5061,10 @@ function createScheduledTaskActivities(services) {
4919
5061
  toolPolicy: targetSessionExecutionBase.toolPolicy,
4920
5062
  sessionTools: targetSessionExecutionBase.tools,
4921
5063
  availableMcpServerIds,
4922
- defaultMcpServerIds: defaultSessionMcpServerIds(
4923
- [...workspaceDefaultMcpServerIds].map((id) => ({ id }))
4924
- )
5064
+ defaultMcpServerIds: [
5065
+ ...connectionTools.map((tool) => tool.id),
5066
+ ...apiIntegrationServerIds
5067
+ ]
4925
5068
  });
4926
5069
  return {
4927
5070
  ...targetSessionExecutionBase,
@@ -4958,7 +5101,7 @@ function createScheduledTaskActivities(services) {
4958
5101
  task.rigId
4959
5102
  ) : null;
4960
5103
  if (generatedTarget && task.rigId && (!acceptedRig || !acceptedRig.activeVersion)) {
4961
- throw new Error(`rig has no active version to bind: ${task.rigId}`);
5104
+ throw new Error(`sandbox environment has no active version to bind: ${task.rigId}`);
4962
5105
  }
4963
5106
  const acceptedRigDefaultVariableSets = acceptedRig?.activeVersion ? await Promise.all(
4964
5107
  acceptedRig.activeVersion.defaultVariableSetIds.map(async (variableSetId) => {
@@ -4972,7 +5115,9 @@ function createScheduledTaskActivities(services) {
4972
5115
  variableSetId
4973
5116
  );
4974
5117
  if (!variableSet) {
4975
- throw new Error(`rig default Variable Set not found: ${variableSetId}`);
5118
+ throw new Error(
5119
+ `sandbox environment default Variable Set not found: ${variableSetId}`
5120
+ );
4976
5121
  }
4977
5122
  return { id: variableSet.id, generation: variableSet.generation };
4978
5123
  })
@@ -5130,6 +5275,7 @@ function createScheduledTaskActivities(services) {
5130
5275
  targetSessionExecution,
5131
5276
  generatedSessionBinding,
5132
5277
  personalConnectionDelegations: taskPersonalConnectionDelegations,
5278
+ mcpAccountBindings: taskMcpAccountBindings,
5133
5279
  personalResourceAuthoritySubjectId: taskPersonalResourceAuthoritySubjectId,
5134
5280
  causalHumanSubjectId,
5135
5281
  causalHumanAuthority: taskRevisionAuthority,
@@ -5243,13 +5389,7 @@ function createScheduledTaskActivities(services) {
5243
5389
  taskId: task.id
5244
5390
  }
5245
5391
  );
5246
- if (stableJson({
5247
- task: exactAuthority.task,
5248
- personalConnectionDelegations: exactAuthority.personalConnectionDelegations
5249
- }) !== stableJson({
5250
- task,
5251
- personalConnectionDelegations: taskPersonalConnectionDelegations
5252
- })) {
5392
+ if (stableJson(exactAuthority) !== stableJson(task)) {
5253
5393
  throw new IncidentTelemetryPreflightBlockedError(
5254
5394
  "incident_preflight_metadata_missing"
5255
5395
  );
@@ -5270,14 +5410,16 @@ function createScheduledTaskActivities(services) {
5270
5410
  if (task.rigId) {
5271
5411
  const rig = acceptedRig;
5272
5412
  if (!rig || !rig.activeVersion) {
5273
- throw new Error(`rig has no active version to bind: ${task.rigId}`);
5413
+ throw new Error(`sandbox environment has no active version to bind: ${task.rigId}`);
5274
5414
  }
5275
5415
  frozenRigId = rig.id;
5276
5416
  frozenRigVersionId = runPersonalResourceAuthority?.resources.find(
5277
5417
  (resource) => resource.resourceKind === "rig" && resource.resourceId === rig.id
5278
5418
  )?.resourceVersionId ?? rig.activeVersion.id;
5279
5419
  if (frozenRigVersionId !== rig.activeVersion.id) {
5280
- throw new Error("scheduled run rig version changed during admission");
5420
+ throw new Error(
5421
+ "scheduled run sandbox environment version changed during admission"
5422
+ );
5281
5423
  }
5282
5424
  }
5283
5425
  let session;
@@ -5577,6 +5719,7 @@ function createScheduledTaskActivities(services) {
5577
5719
  ...taskXaiProviderAccountAuthoritySnapshot.scope === "user" && task.createdBy.kind === "subject" ? { xaiAuthoritySubjectId: task.createdBy.subjectId } : {}
5578
5720
  },
5579
5721
  personalConnectionDelegations: taskPersonalConnectionDelegations,
5722
+ mcpAccountBindings: taskMcpAccountBindings,
5580
5723
  xaiProviderAccountAuthoritySnapshot: taskXaiProviderAccountAuthoritySnapshot,
5581
5724
  scheduledTaskRunId: run.id
5582
5725
  },
@@ -5686,6 +5829,7 @@ function createScheduledTaskActivities(services) {
5686
5829
  ...taskXaiProviderAccountAuthoritySnapshot.scope === "user" && task.createdBy.kind === "subject" ? { xaiAuthoritySubjectId: task.createdBy.subjectId } : {}
5687
5830
  },
5688
5831
  personalConnectionDelegations: taskPersonalConnectionDelegations,
5832
+ mcpAccountBindings: taskMcpAccountBindings,
5689
5833
  xaiProviderAccountAuthoritySnapshot: taskXaiProviderAccountAuthoritySnapshot,
5690
5834
  scheduledTaskRunId: run.id
5691
5835
  },
@@ -5941,46 +6085,38 @@ function scheduledSessionRejectionError(rejectionReason) {
5941
6085
  }
5942
6086
  async function prepareIncidentTelemetrySource(input) {
5943
6087
  const session = await requireSession(input.tx, input.workspaceId, input.sessionId);
5944
- const { task, personalConnectionDelegations } = input.acceptedExecution ? {
5945
- task: input.acceptedExecution.task,
5946
- personalConnectionDelegations: input.acceptedExecution.personalConnectionDelegations
5947
- } : await requireScheduledTaskIncidentAuthorityInTransaction(input.tx, {
5948
- workspaceId: input.workspaceId,
5949
- taskId: input.taskId
5950
- });
6088
+ const { task, personalConnectionDelegations } = input.acceptedExecution;
5951
6089
  const responder = await resolveIncidentTelemetryResponderMetadata({
5952
6090
  db: input.tx,
5953
6091
  settings: input.settings,
5954
6092
  task,
5955
6093
  session,
5956
6094
  personalConnectionDelegations,
5957
- personalResourceAuthoritySubjectId: input.acceptedExecution?.personalResourceAuthoritySubjectId ?? null,
5958
- ...input.acceptedExecution ? {
5959
- executionPolicy: input.acceptedExecution.targetSessionExecution ? {
5960
- tools: input.acceptedExecution.targetSessionExecution.tools,
5961
- firstPartyMcpTools: input.acceptedExecution.targetSessionExecution.firstPartyMcpTools,
5962
- firstPartyMcpPermissions: input.acceptedExecution.targetSessionExecution.firstPartyMcpPermissions,
5963
- variableSetIds: input.acceptedExecution.targetSessionExecution.variableSets.map(
5964
- (variableSet) => variableSet.id
5965
- ),
5966
- variableSetId: input.acceptedExecution.targetSessionExecution.variableSetId,
5967
- rigId: input.acceptedExecution.targetSessionExecution.rigId,
5968
- rigVersionId: input.acceptedExecution.targetSessionExecution.rigVersionId,
5969
- toolPolicy: input.acceptedExecution.targetSessionExecution.toolPolicy,
5970
- mcpServerIds: input.acceptedExecution.targetSessionExecution.mcpServerIds,
5971
- toolPolicyVersion: input.acceptedExecution.targetSessionExecution.toolPolicyVersion
5972
- } : {
5973
- tools: input.acceptedExecution.resolvedTools,
5974
- firstPartyMcpTools: input.acceptedExecution.resolvedFirstPartyMcpTools,
5975
- firstPartyMcpPermissions: input.acceptedExecution.resolvedFirstPartyMcpPermissions,
5976
- variableSetId: input.acceptedExecution.resolvedVariableSet?.id ?? null,
5977
- rigId: input.acceptedExecution.resolvedRig?.id ?? null,
5978
- rigVersionId: input.acceptedExecution.resolvedRig?.versionId ?? null,
5979
- toolPolicy: session.toolPolicy,
5980
- mcpServerIds: [],
5981
- toolPolicyVersion: session.toolPolicyVersion
5982
- }
5983
- } : {}
6095
+ personalResourceAuthoritySubjectId: input.acceptedExecution.personalResourceAuthoritySubjectId ?? null,
6096
+ executionPolicy: input.acceptedExecution.targetSessionExecution ? {
6097
+ tools: input.acceptedExecution.targetSessionExecution.tools,
6098
+ firstPartyMcpTools: input.acceptedExecution.targetSessionExecution.firstPartyMcpTools,
6099
+ firstPartyMcpPermissions: input.acceptedExecution.targetSessionExecution.firstPartyMcpPermissions,
6100
+ variableSetIds: input.acceptedExecution.targetSessionExecution.variableSets.map(
6101
+ (variableSet) => variableSet.id
6102
+ ),
6103
+ variableSetId: input.acceptedExecution.targetSessionExecution.variableSetId,
6104
+ rigId: input.acceptedExecution.targetSessionExecution.rigId,
6105
+ rigVersionId: input.acceptedExecution.targetSessionExecution.rigVersionId,
6106
+ toolPolicy: input.acceptedExecution.targetSessionExecution.toolPolicy,
6107
+ mcpServerIds: input.acceptedExecution.targetSessionExecution.mcpServerIds,
6108
+ toolPolicyVersion: input.acceptedExecution.targetSessionExecution.toolPolicyVersion
6109
+ } : {
6110
+ tools: input.acceptedExecution.resolvedTools,
6111
+ firstPartyMcpTools: input.acceptedExecution.resolvedFirstPartyMcpTools,
6112
+ firstPartyMcpPermissions: input.acceptedExecution.resolvedFirstPartyMcpPermissions,
6113
+ variableSetId: input.acceptedExecution.resolvedVariableSet?.id ?? null,
6114
+ rigId: input.acceptedExecution.resolvedRig?.id ?? null,
6115
+ rigVersionId: input.acceptedExecution.resolvedRig?.versionId ?? null,
6116
+ toolPolicy: session.toolPolicy,
6117
+ mcpServerIds: [],
6118
+ toolPolicyVersion: session.toolPolicyVersion
6119
+ }
5984
6120
  });
5985
6121
  const preflight = evaluateIncidentTelemetryPreflight({
5986
6122
  agentConfig: task.agentConfig,
@@ -6370,6 +6506,7 @@ async function recoverBoundScheduledTaskDispatch(input) {
6370
6506
  ...input.acceptedExecution.xaiAuthoritySubjectId ? { xaiAuthoritySubjectId: input.acceptedExecution.xaiAuthoritySubjectId } : {}
6371
6507
  },
6372
6508
  personalConnectionDelegations: input.acceptedExecution.personalConnectionDelegations,
6509
+ mcpAccountBindings: input.acceptedExecution.mcpAccountBindings ?? null,
6373
6510
  xaiProviderAccountAuthoritySnapshot: input.acceptedExecution.xaiProviderAccountAuthoritySnapshot,
6374
6511
  scheduledTaskRunId: input.run.id
6375
6512
  },
@@ -6766,6 +6903,7 @@ import {
6766
6903
  applySessionTurnSettlement,
6767
6904
  enqueueSessionWorkflowWake,
6768
6905
  failSessionWorkBeforeAttemptClaim,
6906
+ blockSessionWorkBeforeAttemptClaim,
6769
6907
  requestSessionTurnRecovery,
6770
6908
  recoverSessionDispatch,
6771
6909
  reconcileSessionAttemptQuiescence,
@@ -6782,12 +6920,14 @@ import {
6782
6920
  settleSessionIdleWithParentOutbox
6783
6921
  } from "@opengeni/db";
6784
6922
  import { publishDurableSessionEvents as publishDurableSessionEvents2 } from "@opengeni/events";
6923
+ import { CancelledFailure } from "@temporalio/activity";
6785
6924
  var WORKER_DEATH_MAX_REDISPATCHES = 3;
6786
6925
  function createSessionStateActivities(services, overrides = {}) {
6787
6926
  const settleSessionAttemptInterruptionsFn = overrides.settleSessionAttemptInterruptions ?? settleSessionAttemptInterruptions;
6788
6927
  const applySessionTurnSettlementFn = overrides.applySessionTurnSettlement ?? applySessionTurnSettlement;
6789
6928
  const enqueueSessionWorkflowWakeFn = overrides.enqueueSessionWorkflowWake ?? enqueueSessionWorkflowWake;
6790
6929
  const failSessionWorkBeforeAttemptClaimFn = overrides.failSessionWorkBeforeAttemptClaim ?? failSessionWorkBeforeAttemptClaim;
6930
+ const blockSessionWorkBeforeAttemptClaimFn = overrides.blockSessionWorkBeforeAttemptClaim ?? blockSessionWorkBeforeAttemptClaim;
6791
6931
  const requestSessionTurnRecoveryFn = overrides.requestSessionTurnRecovery ?? requestSessionTurnRecovery;
6792
6932
  const recoverSessionDispatchFn = overrides.recoverSessionDispatch ?? recoverSessionDispatch;
6793
6933
  const reconcileSessionAttemptQuiescenceFn = overrides.reconcileSessionAttemptQuiescence ?? reconcileSessionAttemptQuiescence;
@@ -6830,6 +6970,24 @@ function createSessionStateActivities(services, overrides = {}) {
6830
6970
  });
6831
6971
  if (attempt) return { action: "stale" };
6832
6972
  const preClaimFailureDisposition = input.preClaimFailure?.disposition ?? input.preClaimFailureDisposition;
6973
+ if (preClaimFailureDisposition === "blocked" && input.admissionFence && input.preClaimFailure?.reason) {
6974
+ const blocked = await blockSessionWorkBeforeAttemptClaimFn(db, input.workspaceId, {
6975
+ accountId: input.accountId,
6976
+ sessionId: input.sessionId,
6977
+ workflowId,
6978
+ attemptId: input.attemptId,
6979
+ fence: input.admissionFence,
6980
+ reason: input.preClaimFailure.reason,
6981
+ sqlState: input.preClaimFailure.sqlState ?? null
6982
+ });
6983
+ await publishDurableSessionEventsFn(
6984
+ bus,
6985
+ input.workspaceId,
6986
+ input.sessionId,
6987
+ blocked.events
6988
+ );
6989
+ return { action: blocked.action };
6990
+ }
6833
6991
  if (preClaimFailureDisposition === "permanent" && input.trigger) {
6834
6992
  const failed = await failSessionWorkBeforeAttemptClaimFn(db, input.workspaceId, {
6835
6993
  accountId: input.accountId,
@@ -6837,7 +6995,12 @@ function createSessionStateActivities(services, overrides = {}) {
6837
6995
  workflowId,
6838
6996
  trigger: input.trigger,
6839
6997
  error: input.error ?? "Agent turn admission failed before attempt claim.",
6840
- ...input.preClaimFailure ? { admissionFailure: input.preClaimFailure } : {}
6998
+ ...input.preClaimFailure?.disposition === "permanent" ? {
6999
+ admissionFailure: {
7000
+ disposition: "permanent",
7001
+ code: input.preClaimFailure.code
7002
+ }
7003
+ } : {}
6841
7004
  });
6842
7005
  if (failed.action === "terminal") return { action: "terminal" };
6843
7006
  if (failed.action === "stale") return { action: "stale" };
@@ -7091,8 +7254,39 @@ function createSessionStateActivities(services, overrides = {}) {
7091
7254
  return { action: "recovering" };
7092
7255
  }
7093
7256
  async function peekSessionWork(input) {
7094
- const { db, observability } = await services();
7095
- const peek = await peekSessionWorkFn(db, input.workspaceId, input.sessionId);
7257
+ const { db, observability, inspectSessionAttemptActivity } = await services();
7258
+ const peek = await peekSessionWorkFn(
7259
+ db,
7260
+ input.workspaceId,
7261
+ input.sessionId,
7262
+ input.includeAdmissionFence,
7263
+ input.observerAccountId
7264
+ );
7265
+ if (peek.kind === "unavailable") return peek;
7266
+ if (peek.kind === "attempt-owned") {
7267
+ let ownerActivityState = "unknown";
7268
+ if (inspectSessionAttemptActivity) {
7269
+ try {
7270
+ ownerActivityState = await inspectSessionAttemptActivity(peek.activityRef);
7271
+ } catch (error) {
7272
+ if (error instanceof CancelledFailure) throw error;
7273
+ if (currentActivityContext()?.cancellationSignal.aborted)
7274
+ throw new CancelledFailure("Control observation cancelled");
7275
+ }
7276
+ }
7277
+ if (currentActivityContext()?.cancellationSignal.aborted)
7278
+ throw new CancelledFailure("Control observation cancelled");
7279
+ const current = await peekSessionWorkFn(
7280
+ db,
7281
+ input.workspaceId,
7282
+ input.sessionId,
7283
+ input.includeAdmissionFence,
7284
+ input.observerAccountId
7285
+ );
7286
+ if (current.kind !== "attempt-owned" || current.turnId !== peek.turnId || current.attemptId !== peek.attemptId || current.executionGeneration !== peek.executionGeneration || current.activityRef.workflowId !== peek.activityRef.workflowId || current.activityRef.workflowRunId !== peek.activityRef.workflowRunId || current.activityRef.activityId !== peek.activityRef.activityId)
7287
+ return current;
7288
+ return { ...current, ownerActivityState };
7289
+ }
7096
7290
  await refreshQueuedTurnsGauge(db, observability, countQueuedTurnsFn, recordTurnsQueuedGaugeFn);
7097
7291
  return peek;
7098
7292
  }
@@ -7173,6 +7367,7 @@ import {
7173
7367
  getWorkspaceControlEvent
7174
7368
  } from "@opengeni/db";
7175
7369
  import { publishDurableWorkspaceControlEvent } from "@opengeni/events";
7370
+ import { recordWorkflowWakeReconciliation } from "@opengeni/observability";
7176
7371
  var BATCH_SIZE = 1e3;
7177
7372
  var MAX_DELIVERIES_PER_ACTIVITY = 1e4;
7178
7373
  var MAX_TITLE_FANOUT_PER_ACTIVITY = 1e3;
@@ -7258,23 +7453,7 @@ function createWorkflowWakeActivities(services) {
7258
7453
  pendingAdmissionBlockers,
7259
7454
  exhaustedBatchLimit
7260
7455
  };
7261
- if (claimed > 0) {
7262
- service.observability.info("session workflow wake delivery reconciled", {
7263
- claimed,
7264
- signaled,
7265
- delivered,
7266
- pendingAdmission,
7267
- unconfirmed,
7268
- failed,
7269
- exhaustedBatchLimit,
7270
- ...Object.fromEntries(
7271
- Object.entries(pendingAdmissionBlockers).map(([blocker, count]) => [
7272
- `pendingAdmissionBlockers.${blocker}`,
7273
- count
7274
- ])
7275
- )
7276
- });
7277
- }
7456
+ recordWorkflowWakeReconciliation(service.observability, result);
7278
7457
  return result;
7279
7458
  }
7280
7459
  };
@@ -7319,4 +7498,4 @@ export {
7319
7498
  createControlActivities,
7320
7499
  createControlActivitiesFromServices
7321
7500
  };
7322
- //# sourceMappingURL=activities-control-HMFGSKC5.js.map
7501
+ //# sourceMappingURL=activities-control-BOLIY3H4.js.map