@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.
- package/dist/activities/agent-turn/codex-selection-diagnostics.d.ts +1 -0
- package/dist/activities/agent-turn/mcp-operation-read-tool.d.ts +16 -0
- package/dist/activities/codex-fleet-shadow.d.ts +1 -1
- package/dist/activities/mcp-operation-authority.d.ts +16 -0
- package/dist/activities/mcp-operation-observer.d.ts +14 -0
- package/dist/activities/mcp-operation-reader.d.ts +45 -0
- package/dist/activities/mcp-operation-store.d.ts +6 -0
- package/dist/activities/sandbox-lease.d.ts +12 -4
- package/dist/{activities-control-UXGPMDL3.js → activities-control-MKGEOBXT.js} +90 -71
- package/dist/activities-control-MKGEOBXT.js.map +1 -0
- package/dist/{activities-turn-NOYDE7PX.js → activities-turn-5MZZ6HQA.js} +15691 -815
- package/dist/activities-turn-5MZZ6HQA.js.map +1 -0
- package/dist/artifact-materializer-entry.js +2 -0
- package/dist/artifact-materializer-entry.js.map +1 -1
- package/dist/artifact-outbox-entry.js +2 -0
- package/dist/artifact-outbox-entry.js.map +1 -1
- package/dist/{chunk-BARTLVBK.js → chunk-A4XQWVZK.js} +25 -25
- package/dist/chunk-A4XQWVZK.js.map +1 -0
- package/dist/{chunk-NNXLW6V7.js → chunk-OA5CSY5N.js} +147 -112
- package/dist/chunk-OA5CSY5N.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/host-export.js +1 -0
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/observability-metrics.d.ts +12 -4
- package/dist/sandbox-archive-storage.d.ts +15 -3
- package/dist/sandbox-resume.d.ts +1 -1
- package/dist/sandbox-routing.d.ts +6 -1
- package/package.json +18 -17
- package/src/activities/agent-turn/claim.ts +3 -3
- package/src/activities/agent-turn/codex-capacity.ts +31 -53
- package/src/activities/agent-turn/codex-selection-diagnostics.ts +1 -0
- package/src/activities/agent-turn/finalization.ts +10 -5
- package/src/activities/agent-turn/mcp-operation-read-tool.ts +61 -0
- package/src/activities/agent-turn/sandbox-establish.ts +2 -0
- package/src/activities/agent-turn/skill-search.ts +2 -16
- package/src/activities/agent-turn/stream-attempt.ts +1 -1
- package/src/activities/agent-turn/tool-environment.ts +65 -0
- package/src/activities/codex-fleet-shadow.ts +3 -0
- package/src/activities/mcp-credentials.ts +94 -40
- package/src/activities/mcp-operation-authority.ts +76 -0
- package/src/activities/mcp-operation-observer.ts +86 -0
- package/src/activities/mcp-operation-reader.ts +108 -0
- package/src/activities/mcp-operation-store.ts +98 -0
- package/src/activities/sandbox-lease.ts +111 -73
- package/src/observability-metrics.ts +28 -24
- package/src/sandbox-archive-storage.ts +82 -18
- package/src/sandbox-resume.ts +79 -63
- package/src/sandbox-routing.ts +5 -1
- package/dist/activities-control-UXGPMDL3.js.map +0 -1
- package/dist/activities-turn-NOYDE7PX.js.map +0 -1
- package/dist/chunk-BARTLVBK.js.map +0 -1
- package/dist/chunk-NNXLW6V7.js.map +0 -1
package/src/sandbox-resume.ts
CHANGED
|
@@ -55,7 +55,9 @@ import {
|
|
|
55
55
|
type LeaseHolderKind,
|
|
56
56
|
} from "@opengeni/db";
|
|
57
57
|
import {
|
|
58
|
-
|
|
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
|
|
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
|
-
|
|
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:
|
|
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
|
|
943
|
-
ReturnType<typeof putVersion1TarArchiveOrInline>
|
|
944
|
-
>["workspaceArchiveRef"];
|
|
956
|
+
let publicationAttempted = false;
|
|
945
957
|
try {
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
(
|
|
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
|
-
|
|
969
|
-
const { wrote } = await
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
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
|
-
|
|
1010
|
-
|
|
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 } : {}),
|
package/src/sandbox-routing.ts
CHANGED
|
@@ -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, {
|