@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
@@ -55,7 +55,9 @@ import {
55
55
  type LeaseHolderKind,
56
56
  } from "@opengeni/db";
57
57
  import {
58
- captureVerifiedWorkspaceArchive,
58
+ captureWorkspaceArchiveForStorage,
59
+ disposeWorkspaceArchive,
60
+ type VerifiedWorkspaceArchivePayload,
59
61
  describeLegacyNativeSnapshotArchive,
60
62
  inlineWorkspaceArchiveForRestore,
61
63
  MODAL_EXEC_READINESS_TIMEOUT_MS,
@@ -79,13 +81,15 @@ import {
79
81
  type RuntimeMetricsHooks,
80
82
  type WorkspaceArchiveDescriptor,
81
83
  } from "@opengeni/runtime";
82
- import type { ObjectStorage } from "@opengeni/storage";
84
+ import {
85
+ downloadWorkspaceArchiveSpool,
86
+ WorkspaceArchiveStorageError,
87
+ type ObjectStorage,
88
+ } from "@opengeni/storage";
83
89
  import type { Observability } from "@opengeni/observability";
84
90
  import { parseWorkspaceArchiveObjectRef } from "@opengeni/contracts";
85
91
  import {
86
- collectWorkspaceArchiveObjectKeys,
87
- deleteUnpublishedWorkspaceArchiveObject,
88
- deleteWorkspaceArchiveObjectKeys,
92
+ persistWorkspaceArchiveCandidate,
89
93
  putVersion1TarArchiveOrInline,
90
94
  } from "./sandbox-archive-storage";
91
95
 
@@ -582,6 +586,14 @@ async function materializeSpawnEnvelopeArchive(
582
586
  "workspace archive object storage is not configured",
583
587
  );
584
588
  }
589
+ const descriptor = parseWorkspaceArchiveDescriptor(sessionState.workspaceArchiveMeta);
590
+ if (
591
+ process.platform === "linux" &&
592
+ descriptor?.version === 1 &&
593
+ descriptor.workspace.projection === "sdk_local_archive_v1"
594
+ ) {
595
+ return envelope;
596
+ }
585
597
  return {
586
598
  ...record,
587
599
  sessionState: await inlineWorkspaceArchiveForRestore(sessionState, (key) =>
@@ -898,9 +910,10 @@ async function persistWarmWorkspaceSnapshot(
898
910
  // first (the bounded-wait race Bugbot flagged).
899
911
  const capturedAtMs = Date.now();
900
912
  const registerCandidate = async (
901
- archive: Awaited<ReturnType<typeof captureVerifiedWorkspaceArchive>>,
913
+ archive: VerifiedWorkspaceArchivePayload,
902
914
  ): Promise<{ id: string } | null> => {
903
915
  if (
916
+ archive.kind === "host_spool" ||
904
917
  archive.descriptor.version !== 2 ||
905
918
  (archive.descriptor.provider !== "modal_snapshot_filesystem" &&
906
919
  archive.descriptor.provider !== "modal_snapshot_directory")
@@ -938,82 +951,65 @@ async function persistWarmWorkspaceSnapshot(
938
951
  // turn signal resolves first. Its finally block is the only normal release
939
952
  // of the exact admission gate; a late callback cannot release a successor.
940
953
  const captureAndPublish = (async (): Promise<boolean> => {
954
+ let archive: VerifiedWorkspaceArchivePayload | undefined;
941
955
  let candidate: { id: string } | null = null;
942
- let workspaceArchiveRef: Awaited<
943
- ReturnType<typeof putVersion1TarArchiveOrInline>
944
- >["workspaceArchiveRef"];
956
+ let publicationAttempted = false;
945
957
  try {
946
- const archive = await captureVerifiedWorkspaceArchive(session, capturedAtMs, {
947
- requestId: claimed.claim.providerRequestId,
948
- strategy: capturePolicy.strategy,
949
- });
950
- candidate = await registerCandidate(archive);
951
- const priorLease = await readLease(db, ids.workspaceId, ids.sandboxGroupId);
952
- const priorKeys = collectWorkspaceArchiveObjectKeys(
953
- (priorLease?.resumeState as Record<string, unknown> | null | undefined) ?? null,
958
+ archive = await captureWorkspaceArchiveForStorage(
959
+ session,
960
+ capturedAtMs,
961
+ {
962
+ requestId: claimed.claim.providerRequestId,
963
+ strategy: capturePolicy.strategy,
964
+ },
965
+ Boolean(services.objectStorage),
954
966
  );
967
+ candidate = await registerCandidate(archive);
968
+ const archiveDescriptor = archive.descriptor;
955
969
  const published = await putVersion1TarArchiveOrInline({
956
970
  backend: lease.backend,
957
971
  objectStorage: services.objectStorage,
958
972
  accountId: ids.accountId,
959
973
  workspaceId: ids.workspaceId,
960
974
  sandboxGroupId: ids.sandboxGroupId,
961
- archive: {
962
- bytes: archive.bytes,
963
- descriptor: archive.descriptor,
964
- base64: archive.base64,
965
- },
975
+ archive,
966
976
  ...(services.sandboxMetrics ? { metrics: services.sandboxMetrics } : {}),
967
977
  });
968
- workspaceArchiveRef = published.workspaceArchiveRef;
969
- const { wrote } = await persistWarmSnapshot(db, {
970
- accountId: ids.accountId,
971
- workspaceId: ids.workspaceId,
972
- sessionId: ids.sessionId,
973
- turnId: ids.turnId,
974
- attemptId: ids.attemptId,
975
- sandboxGroupId: ids.sandboxGroupId,
976
- expectedEpoch: leaseEpoch,
977
- expectedInstanceId: instanceId,
978
- expectedWorkspaceGeneration: claimed.claim.workspaceGeneration,
979
- captureId,
980
- workspaceArchiveMeta: archive.descriptor,
981
- ...published,
982
- checkpointArtifactId: candidate?.id ?? null,
983
- minIntervalMs: force ? 0 : intervalMs,
984
- capturedAtMs,
978
+ publicationAttempted = true;
979
+ const { wrote } = await persistWorkspaceArchiveCandidate({
980
+ ...(services.objectStorage ? { objectStorage: services.objectStorage } : {}),
981
+ ...(published.workspaceArchiveRef ? { ref: published.workspaceArchiveRef } : {}),
982
+ persist: () =>
983
+ persistWarmSnapshot(db, {
984
+ accountId: ids.accountId,
985
+ workspaceId: ids.workspaceId,
986
+ sessionId: ids.sessionId,
987
+ turnId: ids.turnId,
988
+ attemptId: ids.attemptId,
989
+ sandboxGroupId: ids.sandboxGroupId,
990
+ expectedEpoch: leaseEpoch,
991
+ expectedInstanceId: instanceId,
992
+ expectedWorkspaceGeneration: claimed.claim.workspaceGeneration,
993
+ captureId,
994
+ workspaceArchiveMeta: archiveDescriptor,
995
+ ...published,
996
+ checkpointArtifactId: candidate?.id ?? null,
997
+ minIntervalMs: force ? 0 : intervalMs,
998
+ capturedAtMs,
999
+ }),
985
1000
  });
986
- if (published.workspaceArchiveRef && services.objectStorage) {
987
- if (!wrote) {
988
- await deleteUnpublishedWorkspaceArchiveObject(
989
- services.objectStorage,
990
- published.workspaceArchiveRef,
991
- services.sandboxMetrics,
992
- );
993
- } else {
994
- const afterLease = await readLease(db, ids.workspaceId, ids.sandboxGroupId);
995
- const afterKeys = collectWorkspaceArchiveObjectKeys(
996
- (afterLease?.resumeState as Record<string, unknown> | null | undefined) ?? null,
997
- );
998
- await deleteWorkspaceArchiveObjectKeys(
999
- services.objectStorage,
1000
- [...priorKeys].filter((key) => !afterKeys.has(key)),
1001
- ).catch(() => undefined);
1002
- }
1003
- }
1004
1001
  if (!wrote && candidate) {
1005
1002
  await abandonCandidate(candidate.id, "snapshot_publication_fenced");
1006
1003
  }
1007
1004
  return wrote;
1008
1005
  } catch (error) {
1009
- await deleteUnpublishedWorkspaceArchiveObject(
1010
- services.objectStorage,
1011
- workspaceArchiveRef,
1012
- services.sandboxMetrics,
1013
- );
1014
- if (candidate) await abandonCandidate(candidate.id, "snapshot_capture_failed");
1006
+ if (candidate && !publicationAttempted)
1007
+ await abandonCandidate(candidate.id, "snapshot_capture_failed");
1015
1008
  throw error;
1016
1009
  } finally {
1010
+ await disposeWorkspaceArchive(archive).catch(() => {
1011
+ console.warn("workspace archive spool cleanup failed");
1012
+ });
1017
1013
  await releaseWorkspaceArchiveCapture(db, {
1018
1014
  accountId: ids.accountId,
1019
1015
  workspaceId: ids.workspaceId,
@@ -1504,6 +1500,26 @@ export async function resumeBoxForTurn(
1504
1500
  const established = await establishSandboxSessionFromEnvelope(settings, hydrateEnvelope, {
1505
1501
  sessionId: ids.sessionId,
1506
1502
  recovery: "create-or-restore",
1503
+ ...(services.objectStorage
1504
+ ? {
1505
+ loadHostWorkspaceArchive: async (ref) => {
1506
+ try {
1507
+ return await downloadWorkspaceArchiveSpool(services.objectStorage!, ref.key, {
1508
+ bytes: ref.bytes,
1509
+ sha256: ref.sha256,
1510
+ });
1511
+ } catch (error) {
1512
+ if (error instanceof WorkspaceArchiveStorageError) {
1513
+ throw new WorkspaceArchiveIntegrityError(error.code, error.message, {
1514
+ retryable: error.retryable,
1515
+ cause: error,
1516
+ });
1517
+ }
1518
+ throw error;
1519
+ }
1520
+ },
1521
+ }
1522
+ : {}),
1507
1523
  backendOverride: ids.backend as never,
1508
1524
  ...(ids.environment ? { environment: ids.environment } : {}),
1509
1525
  ...(services.sandboxMetrics ? { metrics: services.sandboxMetrics } : {}),
@@ -1383,6 +1383,8 @@ export type SelfhostedTurnSessionArgs = {
1383
1383
  operationResourcePolicy: EnrollmentRecord["operationPolicy"];
1384
1384
  operationResourcePolicySupported: boolean;
1385
1385
  operationCpuQuotaSupported: boolean;
1386
+ /** Feature advertisement only; refreshed by exact live admission for each operation. */
1387
+ transactionalFsWriteSupported?: boolean;
1386
1388
  /** The active pointer's epoch — the control-op fence echoed to the agent. */
1387
1389
  epoch: number;
1388
1390
  /** The run's declared sandbox environment (the SAME object fed to buildAgent +
@@ -1442,7 +1444,7 @@ function opStreamDepsFor(
1442
1444
 
1443
1445
  /** Project one enrollment read into one exact runtime route. Capability and
1444
1446
  * process identity must be taken from the same snapshot. */
1445
- function connectionBindingFor(
1447
+ export function connectionBindingFor(
1446
1448
  services: RoutingWiringServices,
1447
1449
  enrollment: EnrollmentRecord | null,
1448
1450
  ): SelfhostedConnectionBinding | null {
@@ -1456,6 +1458,7 @@ function connectionBindingFor(
1456
1458
  operationResourcePolicy: enrollment.operationPolicy,
1457
1459
  operationResourcePolicySupported: enrollment.agentCapabilities.operationResourcePolicy === true,
1458
1460
  operationCpuQuotaSupported: enrollment.agentCapabilities.operationCpuQuota === true,
1461
+ transactionalFsWriteSupported: enrollment.agentCapabilities.transactionalFsWrite === true,
1459
1462
  };
1460
1463
  }
1461
1464
 
@@ -1526,6 +1529,7 @@ export async function establishSelfhostedTurnSession(
1526
1529
  operationResourcePolicy: args.operationResourcePolicy,
1527
1530
  operationResourcePolicySupported: args.operationResourcePolicySupported,
1528
1531
  operationCpuQuotaSupported: args.operationCpuQuotaSupported,
1532
+ transactionalFsWriteSupported: args.transactionalFsWriteSupported === true,
1529
1533
  resolveOperationAdmission: async () => {
1530
1534
  const enrollment = args.personalMachineAttempt
1531
1535
  ? await resolvePersonalMachineConnectionForAttempt(db, {