@opengeni/worker-bundle 0.28.3 → 0.28.4-canary.1

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 (54) hide show
  1. package/dist/activities/agent-turn/codex-selection-diagnostics.d.ts +1 -0
  2. package/dist/activities/agent-turn/mcp-operation-read-tool.d.ts +16 -0
  3. package/dist/activities/codex-fleet-shadow.d.ts +1 -1
  4. package/dist/activities/mcp-operation-authority.d.ts +16 -0
  5. package/dist/activities/mcp-operation-observer.d.ts +14 -0
  6. package/dist/activities/mcp-operation-reader.d.ts +45 -0
  7. package/dist/activities/mcp-operation-store.d.ts +6 -0
  8. package/dist/activities/sandbox-lease.d.ts +12 -4
  9. package/dist/{activities-control-UXGPMDL3.js → activities-control-MKGEOBXT.js} +90 -71
  10. package/dist/activities-control-MKGEOBXT.js.map +1 -0
  11. package/dist/{activities-turn-NOYDE7PX.js → activities-turn-5MZZ6HQA.js} +15691 -815
  12. package/dist/activities-turn-5MZZ6HQA.js.map +1 -0
  13. package/dist/artifact-materializer-entry.js +2 -0
  14. package/dist/artifact-materializer-entry.js.map +1 -1
  15. package/dist/artifact-outbox-entry.js +2 -0
  16. package/dist/artifact-outbox-entry.js.map +1 -1
  17. package/dist/{chunk-BARTLVBK.js → chunk-A4XQWVZK.js} +25 -25
  18. package/dist/chunk-A4XQWVZK.js.map +1 -0
  19. package/dist/{chunk-NNXLW6V7.js → chunk-OA5CSY5N.js} +147 -112
  20. package/dist/chunk-OA5CSY5N.js.map +1 -0
  21. package/dist/chunk-PZ5AY32C.js +10 -0
  22. package/dist/chunk-PZ5AY32C.js.map +1 -0
  23. package/dist/host-export.js +1 -0
  24. package/dist/index.js +3 -2
  25. package/dist/index.js.map +1 -1
  26. package/dist/observability-metrics.d.ts +12 -4
  27. package/dist/sandbox-archive-storage.d.ts +15 -3
  28. package/dist/sandbox-resume.d.ts +1 -1
  29. package/dist/sandbox-routing.d.ts +6 -1
  30. package/package.json +18 -17
  31. package/src/activities/agent-turn/claim.ts +3 -3
  32. package/src/activities/agent-turn/codex-capacity.ts +31 -53
  33. package/src/activities/agent-turn/codex-selection-diagnostics.ts +1 -0
  34. package/src/activities/agent-turn/finalization.ts +10 -5
  35. package/src/activities/agent-turn/mcp-operation-read-tool.ts +61 -0
  36. package/src/activities/agent-turn/sandbox-establish.ts +2 -0
  37. package/src/activities/agent-turn/skill-search.ts +2 -16
  38. package/src/activities/agent-turn/stream-attempt.ts +1 -1
  39. package/src/activities/agent-turn/tool-environment.ts +65 -0
  40. package/src/activities/codex-fleet-shadow.ts +3 -0
  41. package/src/activities/mcp-credentials.ts +94 -40
  42. package/src/activities/mcp-operation-authority.ts +76 -0
  43. package/src/activities/mcp-operation-observer.ts +86 -0
  44. package/src/activities/mcp-operation-reader.ts +108 -0
  45. package/src/activities/mcp-operation-store.ts +98 -0
  46. package/src/activities/sandbox-lease.ts +111 -73
  47. package/src/observability-metrics.ts +28 -24
  48. package/src/sandbox-archive-storage.ts +82 -18
  49. package/src/sandbox-resume.ts +79 -63
  50. package/src/sandbox-routing.ts +5 -1
  51. package/dist/activities-control-UXGPMDL3.js.map +0 -1
  52. package/dist/activities-turn-NOYDE7PX.js.map +0 -1
  53. package/dist/chunk-BARTLVBK.js.map +0 -1
  54. package/dist/chunk-NNXLW6V7.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  observabilityEventLogger
3
- } from "./chunk-BARTLVBK.js";
3
+ } from "./chunk-A4XQWVZK.js";
4
4
 
5
5
  // src/activity-services.ts
6
6
  import { dbSearchPath, getSettings, resolveNatsControlPlaneAuth } from "@opengeni/config";
@@ -1646,6 +1646,8 @@ async function nextStreamEvent(iterator, context) {
1646
1646
  }
1647
1647
 
1648
1648
  // src/sandbox-archive-storage.ts
1649
+ import { uploadWorkspaceArchiveSpool } from "@opengeni/storage";
1650
+ import { randomUUID as randomUUID2 } from "crypto";
1649
1651
  import {
1650
1652
  parseWorkspaceArchiveObjectRef,
1651
1653
  workspaceArchiveObjectKey
@@ -1657,47 +1659,74 @@ var WorkspaceArchiveObjectStorageRequiredError = class extends Error {
1657
1659
  this.name = "WorkspaceArchiveObjectStorageRequiredError";
1658
1660
  }
1659
1661
  };
1660
- function collectWorkspaceArchiveObjectKeys(resumeState) {
1661
- const sessionState = resumeState?.sessionState && typeof resumeState.sessionState === "object" ? resumeState.sessionState : null;
1662
- const keys = /* @__PURE__ */ new Set();
1663
- for (const value of [sessionState?.workspaceArchiveRef, sessionState?.workspaceArchivePrevRef]) {
1664
- const ref = parseWorkspaceArchiveObjectRef(value);
1665
- if (ref) keys.add(ref.key);
1666
- }
1667
- return keys;
1668
- }
1669
1662
  async function putTarWorkspaceArchiveObject(input) {
1670
- if (input.archive.descriptor.version !== 1) {
1663
+ const descriptor = structuredClone(input.archive.descriptor);
1664
+ if (descriptor.version !== 1) {
1671
1665
  throw new Error("Object-storage workspace archives are portable tar only");
1672
1666
  }
1673
1667
  const key = workspaceArchiveObjectKey({
1674
1668
  accountId: input.accountId,
1675
1669
  workspaceId: input.workspaceId,
1676
1670
  sandboxGroupId: input.sandboxGroupId,
1677
- revision: input.archive.descriptor.revision
1678
- });
1679
- await input.objectStorage.putObject({
1680
- key,
1681
- contentType: "application/x-tar",
1682
- body: input.archive.bytes,
1683
- sha256: input.archive.descriptor.archiveSha256
1671
+ revision: descriptor.revision,
1672
+ uploadId: randomUUID2()
1684
1673
  });
1674
+ const archive = input.archive;
1675
+ if ("spool" in archive) {
1676
+ if (archive.spool.byteSize !== descriptor.archiveBytes || archive.spool.sha256 !== descriptor.archiveSha256) {
1677
+ throw new Error("Workspace archive spool does not match its verified descriptor");
1678
+ }
1679
+ }
1680
+ const source = "spool" in archive ? archive.spool : {
1681
+ path: "",
1682
+ byteSize: archive.bytes.byteLength,
1683
+ sha256: descriptor.archiveSha256,
1684
+ async *open() {
1685
+ for (let offset = 0; offset < archive.bytes.length; offset += 1024 * 1024)
1686
+ yield archive.bytes.subarray(offset, offset + 1024 * 1024);
1687
+ },
1688
+ async dispose() {
1689
+ }
1690
+ };
1691
+ try {
1692
+ await uploadWorkspaceArchiveSpool(input.objectStorage, key, {
1693
+ ...source,
1694
+ byteSize: descriptor.archiveBytes,
1695
+ sha256: descriptor.archiveSha256,
1696
+ open: source.open.bind(source)
1697
+ });
1698
+ } catch (error) {
1699
+ await input.objectStorage.deleteObject(key).catch(() => void 0);
1700
+ throw error;
1701
+ }
1685
1702
  return {
1686
1703
  schema: "sandbox_archive_object_v1",
1687
1704
  key,
1688
- sha256: input.archive.descriptor.archiveSha256,
1689
- bytes: input.archive.descriptor.archiveBytes,
1705
+ sha256: descriptor.archiveSha256,
1706
+ bytes: descriptor.archiveBytes,
1690
1707
  backend: input.objectStorage.backend
1691
1708
  };
1692
1709
  }
1710
+ async function persistWorkspaceArchiveCandidate(input) {
1711
+ const objectStorage = input.objectStorage;
1712
+ const ref = input.ref ? { ...input.ref } : void 0;
1713
+ const result = await input.persist();
1714
+ if (objectStorage && ref && result.candidateDisposition === "unused") {
1715
+ await deleteUnpublishedWorkspaceArchiveObject(objectStorage, ref);
1716
+ }
1717
+ return result;
1718
+ }
1693
1719
  async function putVersion1TarArchiveOrInline(input) {
1694
1720
  if (input.archive.descriptor.version !== 1) {
1721
+ if ("spool" in input.archive) throw new Error("Native snapshots cannot use a portable spool");
1695
1722
  return { workspaceArchive: input.archive.base64 };
1696
1723
  }
1697
1724
  if (input.backend === "opensandbox" && !input.objectStorage) {
1698
1725
  throw new WorkspaceArchiveObjectStorageRequiredError("opensandbox");
1699
1726
  }
1700
1727
  if (!input.objectStorage) {
1728
+ if ("spool" in input.archive)
1729
+ throw new WorkspaceArchiveObjectStorageRequiredError(input.backend);
1701
1730
  return { workspaceArchive: input.archive.base64 };
1702
1731
  }
1703
1732
  try {
@@ -1706,7 +1735,7 @@ async function putVersion1TarArchiveOrInline(input) {
1706
1735
  accountId: input.accountId,
1707
1736
  workspaceId: input.workspaceId,
1708
1737
  sandboxGroupId: input.sandboxGroupId,
1709
- archive: { bytes: input.archive.bytes, descriptor: input.archive.descriptor }
1738
+ archive: input.archive
1710
1739
  });
1711
1740
  try {
1712
1741
  input.metrics?.onWorkspaceArchiveObject?.({
@@ -1747,11 +1776,6 @@ async function deleteUnpublishedWorkspaceArchiveObject(objectStorage, ref, metri
1747
1776
  console.error("unpublished workspace archive object delete failed", { key: ref.key });
1748
1777
  }
1749
1778
  }
1750
- async function deleteWorkspaceArchiveObjectKeys(objectStorage, keys) {
1751
- for (const key of keys) {
1752
- await objectStorage.deleteObject(key);
1753
- }
1754
- }
1755
1779
 
1756
1780
  // src/sandbox-routing.ts
1757
1781
  import { sandboxLifecycleTransitionWaitMs as sandboxLifecycleTransitionWaitMs2 } from "@opengeni/config";
@@ -1806,7 +1830,7 @@ import {
1806
1830
  sandboxArchiveCaptureTimeoutMs,
1807
1831
  sandboxLifecycleTransitionWaitMs
1808
1832
  } from "@opengeni/config";
1809
- import { randomUUID as randomUUID2 } from "crypto";
1833
+ import { randomUUID as randomUUID3 } from "crypto";
1810
1834
  import {
1811
1835
  acquireLease,
1812
1836
  adoptLegacyModalCheckpointArtifact,
@@ -1833,7 +1857,8 @@ import {
1833
1857
  SandboxLeaseTransitionError
1834
1858
  } from "@opengeni/db";
1835
1859
  import {
1836
- captureVerifiedWorkspaceArchive,
1860
+ captureWorkspaceArchiveForStorage,
1861
+ disposeWorkspaceArchive,
1837
1862
  describeLegacyNativeSnapshotArchive,
1838
1863
  inlineWorkspaceArchiveForRestore,
1839
1864
  MODAL_EXEC_READINESS_TIMEOUT_MS,
@@ -1854,6 +1879,10 @@ import {
1854
1879
  verifySandboxExecReadiness,
1855
1880
  withoutSandboxProviderIdentity
1856
1881
  } from "@opengeni/runtime";
1882
+ import {
1883
+ downloadWorkspaceArchiveSpool,
1884
+ WorkspaceArchiveStorageError
1885
+ } from "@opengeni/storage";
1857
1886
  import { parseWorkspaceArchiveObjectRef as parseWorkspaceArchiveObjectRef2 } from "@opengeni/contracts";
1858
1887
  function sandboxLeaseHolderIdForAttempt(attemptId) {
1859
1888
  const normalized = attemptId.trim();
@@ -2109,6 +2138,10 @@ async function materializeSpawnEnvelopeArchive(envelope, objectStorage) {
2109
2138
  "workspace archive object storage is not configured"
2110
2139
  );
2111
2140
  }
2141
+ const descriptor = parseWorkspaceArchiveDescriptor(sessionState.workspaceArchiveMeta);
2142
+ if (process.platform === "linux" && descriptor?.version === 1 && descriptor.workspace.projection === "sdk_local_archive_v1") {
2143
+ return envelope;
2144
+ }
2112
2145
  return {
2113
2146
  ...record,
2114
2147
  sessionState: await inlineWorkspaceArchiveForRestore(
@@ -2206,7 +2239,7 @@ async function persistWarmWorkspaceSnapshot(services, ids, session, leaseEpoch,
2206
2239
  const nativeModalPersistence = workspacePersistence === "snapshot_filesystem" || workspacePersistence === "snapshot_directory";
2207
2240
  const checkpointBinding = nativeModalPersistence ? await resolveModalCheckpointBindingBeforeCapture(settings, persistable, signal) : null;
2208
2241
  if (signal?.aborted) return false;
2209
- const captureId = randomUUID2();
2242
+ const captureId = randomUUID3();
2210
2243
  const captureTimeoutMs = sandboxArchiveCaptureTimeoutMs(settings);
2211
2244
  const claimed = await claimWorkspaceArchiveCapture(db, {
2212
2245
  accountId: ids.accountId,
@@ -2239,7 +2272,7 @@ async function persistWarmWorkspaceSnapshot(services, ids, session, leaseEpoch,
2239
2272
  let timeout;
2240
2273
  const capturedAtMs = Date.now();
2241
2274
  const registerCandidate = async (archive) => {
2242
- if (archive.descriptor.version !== 2 || archive.descriptor.provider !== "modal_snapshot_filesystem" && archive.descriptor.provider !== "modal_snapshot_directory") {
2275
+ if (archive.kind === "host_spool" || archive.descriptor.version !== 2 || archive.descriptor.provider !== "modal_snapshot_filesystem" && archive.descriptor.provider !== "modal_snapshot_directory") {
2243
2276
  return null;
2244
2277
  }
2245
2278
  if (!checkpointBinding) {
@@ -2268,80 +2301,64 @@ async function persistWarmWorkspaceSnapshot(services, ids, session, leaseEpoch,
2268
2301
  }).catch(() => void 0);
2269
2302
  };
2270
2303
  const captureAndPublish = (async () => {
2304
+ let archive;
2271
2305
  let candidate = null;
2272
- let workspaceArchiveRef;
2306
+ let publicationAttempted = false;
2273
2307
  try {
2274
- const archive = await captureVerifiedWorkspaceArchive(session, capturedAtMs, {
2275
- requestId: claimed.claim.providerRequestId,
2276
- strategy: capturePolicy.strategy
2277
- });
2278
- candidate = await registerCandidate(archive);
2279
- const priorLease = await readLease(db, ids.workspaceId, ids.sandboxGroupId);
2280
- const priorKeys = collectWorkspaceArchiveObjectKeys(
2281
- priorLease?.resumeState ?? null
2308
+ archive = await captureWorkspaceArchiveForStorage(
2309
+ session,
2310
+ capturedAtMs,
2311
+ {
2312
+ requestId: claimed.claim.providerRequestId,
2313
+ strategy: capturePolicy.strategy
2314
+ },
2315
+ Boolean(services.objectStorage)
2282
2316
  );
2317
+ candidate = await registerCandidate(archive);
2318
+ const archiveDescriptor = archive.descriptor;
2283
2319
  const published = await putVersion1TarArchiveOrInline({
2284
2320
  backend: lease.backend,
2285
2321
  objectStorage: services.objectStorage,
2286
2322
  accountId: ids.accountId,
2287
2323
  workspaceId: ids.workspaceId,
2288
2324
  sandboxGroupId: ids.sandboxGroupId,
2289
- archive: {
2290
- bytes: archive.bytes,
2291
- descriptor: archive.descriptor,
2292
- base64: archive.base64
2293
- },
2325
+ archive,
2294
2326
  ...services.sandboxMetrics ? { metrics: services.sandboxMetrics } : {}
2295
2327
  });
2296
- workspaceArchiveRef = published.workspaceArchiveRef;
2297
- const { wrote } = await persistWarmSnapshot(db, {
2298
- accountId: ids.accountId,
2299
- workspaceId: ids.workspaceId,
2300
- sessionId: ids.sessionId,
2301
- turnId: ids.turnId,
2302
- attemptId: ids.attemptId,
2303
- sandboxGroupId: ids.sandboxGroupId,
2304
- expectedEpoch: leaseEpoch,
2305
- expectedInstanceId: instanceId,
2306
- expectedWorkspaceGeneration: claimed.claim.workspaceGeneration,
2307
- captureId,
2308
- workspaceArchiveMeta: archive.descriptor,
2309
- ...published,
2310
- checkpointArtifactId: candidate?.id ?? null,
2311
- minIntervalMs: force ? 0 : intervalMs,
2312
- capturedAtMs
2328
+ publicationAttempted = true;
2329
+ const { wrote } = await persistWorkspaceArchiveCandidate({
2330
+ ...services.objectStorage ? { objectStorage: services.objectStorage } : {},
2331
+ ...published.workspaceArchiveRef ? { ref: published.workspaceArchiveRef } : {},
2332
+ persist: () => persistWarmSnapshot(db, {
2333
+ accountId: ids.accountId,
2334
+ workspaceId: ids.workspaceId,
2335
+ sessionId: ids.sessionId,
2336
+ turnId: ids.turnId,
2337
+ attemptId: ids.attemptId,
2338
+ sandboxGroupId: ids.sandboxGroupId,
2339
+ expectedEpoch: leaseEpoch,
2340
+ expectedInstanceId: instanceId,
2341
+ expectedWorkspaceGeneration: claimed.claim.workspaceGeneration,
2342
+ captureId,
2343
+ workspaceArchiveMeta: archiveDescriptor,
2344
+ ...published,
2345
+ checkpointArtifactId: candidate?.id ?? null,
2346
+ minIntervalMs: force ? 0 : intervalMs,
2347
+ capturedAtMs
2348
+ })
2313
2349
  });
2314
- if (published.workspaceArchiveRef && services.objectStorage) {
2315
- if (!wrote) {
2316
- await deleteUnpublishedWorkspaceArchiveObject(
2317
- services.objectStorage,
2318
- published.workspaceArchiveRef,
2319
- services.sandboxMetrics
2320
- );
2321
- } else {
2322
- const afterLease = await readLease(db, ids.workspaceId, ids.sandboxGroupId);
2323
- const afterKeys = collectWorkspaceArchiveObjectKeys(
2324
- afterLease?.resumeState ?? null
2325
- );
2326
- await deleteWorkspaceArchiveObjectKeys(
2327
- services.objectStorage,
2328
- [...priorKeys].filter((key) => !afterKeys.has(key))
2329
- ).catch(() => void 0);
2330
- }
2331
- }
2332
2350
  if (!wrote && candidate) {
2333
2351
  await abandonCandidate(candidate.id, "snapshot_publication_fenced");
2334
2352
  }
2335
2353
  return wrote;
2336
2354
  } catch (error) {
2337
- await deleteUnpublishedWorkspaceArchiveObject(
2338
- services.objectStorage,
2339
- workspaceArchiveRef,
2340
- services.sandboxMetrics
2341
- );
2342
- if (candidate) await abandonCandidate(candidate.id, "snapshot_capture_failed");
2355
+ if (candidate && !publicationAttempted)
2356
+ await abandonCandidate(candidate.id, "snapshot_capture_failed");
2343
2357
  throw error;
2344
2358
  } finally {
2359
+ await disposeWorkspaceArchive(archive).catch(() => {
2360
+ console.warn("workspace archive spool cleanup failed");
2361
+ });
2345
2362
  await releaseWorkspaceArchiveCapture(db, {
2346
2363
  accountId: ids.accountId,
2347
2364
  workspaceId: ids.workspaceId,
@@ -2681,6 +2698,24 @@ async function resumeBoxForTurn(services, ids, kind, holderId) {
2681
2698
  const established = await establishSandboxSessionFromEnvelope(settings, hydrateEnvelope, {
2682
2699
  sessionId: ids.sessionId,
2683
2700
  recovery: "create-or-restore",
2701
+ ...services.objectStorage ? {
2702
+ loadHostWorkspaceArchive: async (ref) => {
2703
+ try {
2704
+ return await downloadWorkspaceArchiveSpool(services.objectStorage, ref.key, {
2705
+ bytes: ref.bytes,
2706
+ sha256: ref.sha256
2707
+ });
2708
+ } catch (error) {
2709
+ if (error instanceof WorkspaceArchiveStorageError) {
2710
+ throw new WorkspaceArchiveIntegrityError(error.code, error.message, {
2711
+ retryable: error.retryable,
2712
+ cause: error
2713
+ });
2714
+ }
2715
+ throw error;
2716
+ }
2717
+ }
2718
+ } : {},
2684
2719
  backendOverride: ids.backend,
2685
2720
  ...ids.environment ? { environment: ids.environment } : {},
2686
2721
  ...services.sandboxMetrics ? { metrics: services.sandboxMetrics } : {},
@@ -3259,11 +3294,11 @@ function afterPersistableHomeMutation(services, ids, home) {
3259
3294
  function beforeRetainedProcessMutation(services, ids) {
3260
3295
  const fence = ids.workspaceMutationFence;
3261
3296
  if (!fence) return void 0;
3262
- return async ({ op, process }) => await advanceWorkspaceGenerationForRetainedProcess(services.db, {
3297
+ return async ({ op, process: process2 }) => await advanceWorkspaceGenerationForRetainedProcess(services.db, {
3263
3298
  accountId: fence.accountId,
3264
3299
  workspaceId: ids.workspaceId,
3265
3300
  sessionId: ids.sessionId,
3266
- processId: process.id,
3301
+ processId: process2.id,
3267
3302
  operation: op,
3268
3303
  captureWaitMs: sandboxLifecycleTransitionWaitMs2(services.settings),
3269
3304
  ...services.waitSignal ? { waitSignal: services.waitSignal } : {}
@@ -3272,7 +3307,7 @@ function beforeRetainedProcessMutation(services, ids) {
3272
3307
  function afterRetainedProcessMutation(services, ids) {
3273
3308
  const fence = ids.workspaceMutationFence;
3274
3309
  if (!fence) return void 0;
3275
- return async ({ op, process, admission, outcome }) => {
3310
+ return async ({ op, process: process2, admission, outcome }) => {
3276
3311
  if (!admission || typeof admission !== "object" || typeof admission.id !== "string" || typeof admission.workspaceGeneration !== "number") {
3277
3312
  throw new Error("Retained-process mutation settlement lacked its exact admission");
3278
3313
  }
@@ -3280,7 +3315,7 @@ function afterRetainedProcessMutation(services, ids) {
3280
3315
  accountId: fence.accountId,
3281
3316
  workspaceId: ids.workspaceId,
3282
3317
  sessionId: ids.sessionId,
3283
- processId: process.id,
3318
+ processId: process2.id,
3284
3319
  admission,
3285
3320
  operation: op,
3286
3321
  outcome
@@ -3306,7 +3341,7 @@ function captureRetainedProcessOutputForTurn(services, ids) {
3306
3341
  const accountId = ids.workspaceMutationFence?.accountId;
3307
3342
  if (!accountId) return void 0;
3308
3343
  return async ({
3309
- process,
3344
+ process: process2,
3310
3345
  chunkId,
3311
3346
  chunk,
3312
3347
  stream,
@@ -3316,7 +3351,7 @@ function captureRetainedProcessOutputForTurn(services, ids) {
3316
3351
  accountId,
3317
3352
  workspaceId: ids.workspaceId,
3318
3353
  sessionId: ids.sessionId,
3319
- commandId: process.id,
3354
+ commandId: process2.id,
3320
3355
  chunkId,
3321
3356
  chunk,
3322
3357
  stream,
@@ -3329,32 +3364,32 @@ function captureRetainedProcessOutputForTurn(services, ids) {
3329
3364
  function observeRetainedProcessTerminalForTurn(services, ids) {
3330
3365
  const fence = ids.workspaceMutationFence;
3331
3366
  if (!fence) return void 0;
3332
- return async ({ process }) => {
3367
+ return async ({ process: process2 }) => {
3333
3368
  await observeSessionBackgroundCommandCompletion(services.db, {
3334
3369
  accountId: fence.accountId,
3335
3370
  workspaceId: ids.workspaceId,
3336
3371
  sessionId: ids.sessionId,
3337
- commandId: process.id
3372
+ commandId: process2.id
3338
3373
  });
3339
3374
  };
3340
3375
  }
3341
3376
  function settleRetainedProcessForTurn(services, ids) {
3342
3377
  const fence = ids.workspaceMutationFence;
3343
3378
  if (!fence) return void 0;
3344
- return async ({ backend, process, proof }) => {
3379
+ return async ({ backend, process: process2, proof }) => {
3345
3380
  const durable = await getRetainedProcess(services.db, {
3346
3381
  workspaceId: ids.workspaceId,
3347
3382
  sessionId: ids.sessionId,
3348
- processId: process.id
3383
+ processId: process2.id
3349
3384
  });
3350
- if (!durable || durable.providerSessionId !== process.providerSessionId || durable.providerBackend !== backend.kind || durable.providerInstanceId !== backend.providerInstanceId || durable.leaseEpoch !== backend.leaseEpoch || durable.routeKind !== (backend.sandboxId === null ? "home" : "active") || durable.routeTargetId !== backend.sandboxId || durable.routeEpoch !== backend.activeEpoch) {
3385
+ if (!durable || durable.providerSessionId !== process2.providerSessionId || durable.providerBackend !== backend.kind || durable.providerInstanceId !== backend.providerInstanceId || durable.leaseEpoch !== backend.leaseEpoch || durable.routeKind !== (backend.sandboxId === null ? "home" : "active") || durable.routeTargetId !== backend.sandboxId || durable.routeEpoch !== backend.activeEpoch) {
3351
3386
  throw new Error("Retained-process settlement lost its exact durable backend identity");
3352
3387
  }
3353
3388
  const settlement = await settleRetainedProcess(services.db, {
3354
3389
  accountId: fence.accountId,
3355
3390
  workspaceId: ids.workspaceId,
3356
3391
  sessionId: ids.sessionId,
3357
- processId: process.id,
3392
+ processId: process2.id,
3358
3393
  expected: retainedProcessSettlementIdentity(durable),
3359
3394
  outcome: proof.outcome,
3360
3395
  exitCode: proof.exitCode,
@@ -3372,13 +3407,13 @@ function settleRetainedProcessForTurn(services, ids) {
3372
3407
  function adoptRetainedProcessAsBackgroundCommandForTurn(services, ids) {
3373
3408
  const fence = ids.workspaceMutationFence;
3374
3409
  if (!fence) return void 0;
3375
- return async ({ backend, process }) => {
3410
+ return async ({ backend, process: process2 }) => {
3376
3411
  const durable = await getRetainedProcess(services.db, {
3377
3412
  workspaceId: ids.workspaceId,
3378
3413
  sessionId: ids.sessionId,
3379
- processId: process.id
3414
+ processId: process2.id
3380
3415
  });
3381
- if (!durable || durable.providerSessionId !== process.providerSessionId || durable.providerBackend !== backend.kind || durable.providerInstanceId !== backend.providerInstanceId || durable.leaseEpoch !== backend.leaseEpoch || durable.routeKind !== (backend.sandboxId === null ? "home" : "active") || durable.routeTargetId !== backend.sandboxId || durable.routeEpoch !== backend.activeEpoch) {
3416
+ if (!durable || durable.providerSessionId !== process2.providerSessionId || durable.providerBackend !== backend.kind || durable.providerInstanceId !== backend.providerInstanceId || durable.leaseEpoch !== backend.leaseEpoch || durable.routeKind !== (backend.sandboxId === null ? "home" : "active") || durable.routeTargetId !== backend.sandboxId || durable.routeEpoch !== backend.activeEpoch) {
3382
3417
  throw new Error("Background command adoption lost its exact retained-process identity");
3383
3418
  }
3384
3419
  await adoptManagedSessionBackgroundCommand(services.db, {
@@ -3388,7 +3423,7 @@ function adoptRetainedProcessAsBackgroundCommandForTurn(services, ids) {
3388
3423
  turnId: fence.turnId,
3389
3424
  executionGeneration: fence.executionGeneration,
3390
3425
  attemptId: fence.attemptId,
3391
- processId: process.id,
3426
+ processId: process2.id,
3392
3427
  expected: retainedProcessSettlementIdentity(durable),
3393
3428
  command: "execCommand"
3394
3429
  });
@@ -3565,11 +3600,11 @@ function wrapTurnBoxWithRouting(services, ids, established) {
3565
3600
  ...services.onSandboxOperation ? { onOperation: services.onSandboxOperation } : {},
3566
3601
  providerCommandHandle: admittedCommandHandle,
3567
3602
  ...ids.workspaceMutationFence ? {
3568
- providerCommandPersistence: (process) => retainedProviderCommandPersistence(db, {
3603
+ providerCommandPersistence: (process2) => retainedProviderCommandPersistence(db, {
3569
3604
  accountId: ids.workspaceMutationFence.accountId,
3570
3605
  workspaceId: ids.workspaceId,
3571
3606
  sessionId: ids.sessionId,
3572
- processId: process.id
3607
+ processId: process2.id
3573
3608
  })
3574
3609
  } : {},
3575
3610
  ...beforeMutation ? { beforeMutation } : {},
@@ -3762,11 +3797,11 @@ function wrapLazyTurnBoxWithRouting(services, ids, args) {
3762
3797
  ...args.onFirstOperation ? { onFirstOperation: args.onFirstOperation } : {},
3763
3798
  providerCommandHandle: admittedCommandHandle,
3764
3799
  ...ids.workspaceMutationFence ? {
3765
- providerCommandPersistence: (process) => retainedProviderCommandPersistence(db, {
3800
+ providerCommandPersistence: (process2) => retainedProviderCommandPersistence(db, {
3766
3801
  accountId: ids.workspaceMutationFence.accountId,
3767
3802
  workspaceId: ids.workspaceId,
3768
3803
  sessionId: ids.sessionId,
3769
- processId: process.id
3804
+ processId: process2.id
3770
3805
  })
3771
3806
  } : {},
3772
3807
  ...beforeMutation ? { beforeMutation } : {},
@@ -3839,7 +3874,8 @@ function connectionBindingFor(services, enrollment) {
3839
3874
  ...opStream !== void 0 ? { opStream } : {},
3840
3875
  operationResourcePolicy: enrollment.operationPolicy,
3841
3876
  operationResourcePolicySupported: enrollment.agentCapabilities.operationResourcePolicy === true,
3842
- operationCpuQuotaSupported: enrollment.agentCapabilities.operationCpuQuota === true
3877
+ operationCpuQuotaSupported: enrollment.agentCapabilities.operationCpuQuota === true,
3878
+ transactionalFsWriteSupported: enrollment.agentCapabilities.transactionalFsWrite === true
3843
3879
  };
3844
3880
  }
3845
3881
  async function resolveRoutedMachineConnection(db, ids, sandbox) {
@@ -3891,6 +3927,7 @@ async function establishSelfhostedTurnSession(services, args) {
3891
3927
  operationResourcePolicy: args.operationResourcePolicy,
3892
3928
  operationResourcePolicySupported: args.operationResourcePolicySupported,
3893
3929
  operationCpuQuotaSupported: args.operationCpuQuotaSupported,
3930
+ transactionalFsWriteSupported: args.transactionalFsWriteSupported === true,
3894
3931
  resolveOperationAdmission: async () => {
3895
3932
  const enrollment = args.personalMachineAttempt ? await resolvePersonalMachineConnectionForAttempt(db, {
3896
3933
  accountId: args.personalMachineAttempt.accountId,
@@ -4785,7 +4822,7 @@ import {
4785
4822
  classifyProviderSandboxFailure
4786
4823
  } from "@opengeni/runtime";
4787
4824
  import { CancelledFailure } from "@temporalio/activity";
4788
- import { randomUUID as randomUUID3 } from "crypto";
4825
+ import { randomUUID as randomUUID4 } from "crypto";
4789
4826
  var TurnOperationCancelledError = class extends Error {
4790
4827
  constructor(reason) {
4791
4828
  super("Turn operation was cancelled with its owning turn", {
@@ -5076,7 +5113,7 @@ function createTurnSandboxProvisioner(establish, options = {}) {
5076
5113
  return {
5077
5114
  get() {
5078
5115
  if (!memo) {
5079
- const provisionId = options.provisionIdFactory?.() ?? randomUUID3();
5116
+ const provisionId = options.provisionIdFactory?.() ?? randomUUID4();
5080
5117
  memo = (async () => {
5081
5118
  const startedAt = performance.now();
5082
5119
  throwIfTurnOperationCancelled(options.signal);
@@ -6641,10 +6678,8 @@ export {
6641
6678
  currentActivityContext,
6642
6679
  startActivityHeartbeat,
6643
6680
  nextStreamEvent,
6644
- collectWorkspaceArchiveObjectKeys,
6681
+ persistWorkspaceArchiveCandidate,
6645
6682
  putVersion1TarArchiveOrInline,
6646
- deleteUnpublishedWorkspaceArchiveObject,
6647
- deleteWorkspaceArchiveObjectKeys,
6648
6683
  sandboxLeaseHolderIdForAttempt,
6649
6684
  waitForWarmSnapshot,
6650
6685
  maybePersistWarmWorkspaceSnapshot,
@@ -6726,4 +6761,4 @@ export {
6726
6761
  codexUsageLimitFailurePayload,
6727
6762
  CODEX_USAGE_LIMIT_MAX_RESUME_MS
6728
6763
  };
6729
- //# sourceMappingURL=chunk-NNXLW6V7.js.map
6764
+ //# sourceMappingURL=chunk-OA5CSY5N.js.map