@workbench-ai/workbench-core 0.0.46
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/adapter-auth.d.ts +63 -0
- package/dist/adapter-auth.d.ts.map +1 -0
- package/dist/adapter-auth.js +244 -0
- package/dist/execution-events.d.ts +53 -0
- package/dist/execution-events.d.ts.map +1 -0
- package/dist/execution-events.js +195 -0
- package/dist/execution-graph.d.ts +27 -0
- package/dist/execution-graph.d.ts.map +1 -0
- package/dist/execution-graph.js +126 -0
- package/dist/execution-jobs.d.ts +70 -0
- package/dist/execution-jobs.d.ts.map +1 -0
- package/dist/execution-jobs.js +229 -0
- package/dist/execution-outputs.d.ts +9 -0
- package/dist/execution-outputs.d.ts.map +1 -0
- package/dist/execution-outputs.js +393 -0
- package/dist/execution-phases.d.ts +21 -0
- package/dist/execution-phases.d.ts.map +1 -0
- package/dist/execution-phases.js +262 -0
- package/dist/execution-runtime-types.d.ts +35 -0
- package/dist/execution-runtime-types.d.ts.map +1 -0
- package/dist/execution-runtime-types.js +1 -0
- package/dist/execution-scheduler.d.ts +31 -0
- package/dist/execution-scheduler.d.ts.map +1 -0
- package/dist/execution-scheduler.js +241 -0
- package/dist/execution-traces.d.ts +16 -0
- package/dist/execution-traces.d.ts.map +1 -0
- package/dist/execution-traces.js +164 -0
- package/dist/execution-usage.d.ts +12 -0
- package/dist/execution-usage.d.ts.map +1 -0
- package/dist/execution-usage.js +433 -0
- package/dist/generic-spec.d.ts +113 -0
- package/dist/generic-spec.d.ts.map +1 -0
- package/dist/generic-spec.js +656 -0
- package/dist/index.d.ts +160 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2858 -0
- package/dist/model-prices-litellm.d.ts +9674 -0
- package/dist/model-prices-litellm.d.ts.map +1 -0
- package/dist/model-prices-litellm.js +9668 -0
- package/dist/runtime-utils.d.ts +18 -0
- package/dist/runtime-utils.d.ts.map +1 -0
- package/dist/runtime-utils.js +108 -0
- package/dist/sandbox-backends/docker.d.ts +5 -0
- package/dist/sandbox-backends/docker.d.ts.map +1 -0
- package/dist/sandbox-backends/docker.js +568 -0
- package/dist/sandbox-backends/index.d.ts +37 -0
- package/dist/sandbox-backends/index.d.ts.map +1 -0
- package/dist/sandbox-backends/index.js +79 -0
- package/dist/sandbox-backends/names.d.ts +6 -0
- package/dist/sandbox-backends/names.d.ts.map +1 -0
- package/dist/sandbox-backends/names.js +14 -0
- package/dist/sandbox-backends/template-images.d.ts +4 -0
- package/dist/sandbox-backends/template-images.d.ts.map +1 -0
- package/dist/sandbox-backends/template-images.js +48 -0
- package/dist/sandbox-inputs.d.ts +27 -0
- package/dist/sandbox-inputs.d.ts.map +1 -0
- package/dist/sandbox-inputs.js +220 -0
- package/dist/sandbox-plane.d.ts +89 -0
- package/dist/sandbox-plane.d.ts.map +1 -0
- package/dist/sandbox-plane.js +327 -0
- package/dist/subject-patch.d.ts +8 -0
- package/dist/subject-patch.d.ts.map +1 -0
- package/dist/subject-patch.js +63 -0
- package/dist/trace-files.d.ts +18 -0
- package/dist/trace-files.d.ts.map +1 -0
- package/dist/trace-files.js +94 -0
- package/environments/libreoffice-agent/Dockerfile +13 -0
- package/environments/libreoffice-python/Dockerfile +11 -0
- package/environments/node-22/Dockerfile +3 -0
- package/environments/python-3.12/Dockerfile +8 -0
- package/package.json +42 -0
- package/worker/sandbox-adapter-runner.cjs +275 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { createDockerSandboxBackendDescriptor, createDockerSandboxPlane, } from "./docker.js";
|
|
2
|
+
import { DOCKER_SANDBOX_BACKEND, resolveWorkbenchSandboxProviderName, } from "./names.js";
|
|
3
|
+
export { DOCKER_SANDBOX_BACKEND, resolveWorkbenchSandboxProviderName, } from "./names.js";
|
|
4
|
+
export { createDockerSandboxBackendDescriptor, createDockerSandboxPlane, } from "./docker.js";
|
|
5
|
+
export function createSandboxBackendPlaneForProvider(provider, args, startedAt, fileStore) {
|
|
6
|
+
const resolved = resolveWorkbenchSandboxProviderName(provider);
|
|
7
|
+
if (resolved !== DOCKER_SANDBOX_BACKEND) {
|
|
8
|
+
throw new Error(`Unsupported local sandbox provider ${provider}.`);
|
|
9
|
+
}
|
|
10
|
+
return createDockerSandboxPlane(args, startedAt, fileStore);
|
|
11
|
+
}
|
|
12
|
+
export function sandboxHostHealthExpectationForProvider(provider) {
|
|
13
|
+
if (provider !== DOCKER_SANDBOX_BACKEND) {
|
|
14
|
+
resolveWorkbenchSandboxProviderName(provider);
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
provider,
|
|
18
|
+
backend: provider,
|
|
19
|
+
capabilities: createDockerSandboxBackendDescriptor().capabilities,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function assertSandboxHostHealthForProvider(value, provider) {
|
|
23
|
+
const expected = sandboxHostHealthExpectationForProvider(provider);
|
|
24
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
25
|
+
throw new Error("sandbox host health response must be an object.");
|
|
26
|
+
}
|
|
27
|
+
const record = value;
|
|
28
|
+
if (record.provider !== expected.provider) {
|
|
29
|
+
throw new Error(`sandbox host provider ${String(record.provider ?? "missing")} does not match expected ${expected.provider}.`);
|
|
30
|
+
}
|
|
31
|
+
if (record.backend !== expected.backend) {
|
|
32
|
+
throw new Error(`sandbox host backend ${String(record.backend ?? "missing")} does not match expected ${expected.backend}.`);
|
|
33
|
+
}
|
|
34
|
+
if (!isSandboxBackendCapabilities(record.capabilities)) {
|
|
35
|
+
throw new Error(`sandbox host capabilities are invalid for backend ${expected.backend}.`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function sandboxProviderDefaultMaxConcurrentJobs(_provider) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
export function sandboxProviderAdmissionForResources(provider, resources) {
|
|
42
|
+
if (provider !== DOCKER_SANDBOX_BACKEND) {
|
|
43
|
+
resolveWorkbenchSandboxProviderName(provider);
|
|
44
|
+
}
|
|
45
|
+
assertPositiveResource(resources.cpu, "resources.cpu");
|
|
46
|
+
assertPositiveResource(resources.memoryGb, "resources.memoryGb");
|
|
47
|
+
if (resources.diskGb !== undefined) {
|
|
48
|
+
assertPositiveResource(resources.diskGb, "resources.diskGb");
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
provider,
|
|
52
|
+
hostCost: {
|
|
53
|
+
cpu: resources.cpu,
|
|
54
|
+
memoryGb: resources.memoryGb,
|
|
55
|
+
diskGb: resources.diskGb ?? 1,
|
|
56
|
+
},
|
|
57
|
+
providerLeases: [],
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export function sandboxProviderLeaseScope(provider) {
|
|
61
|
+
throw new Error(`Local sandbox provider ${provider} does not use provider leases.`);
|
|
62
|
+
}
|
|
63
|
+
function isSandboxBackendCapabilities(value) {
|
|
64
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
const record = value;
|
|
68
|
+
return typeof record.snapshots === "boolean" &&
|
|
69
|
+
typeof record.interactiveExec === "boolean" &&
|
|
70
|
+
typeof record.filesystemDiff === "boolean" &&
|
|
71
|
+
typeof record.fileCapabilities === "boolean" &&
|
|
72
|
+
Array.isArray(record.networkPolicy) &&
|
|
73
|
+
record.networkPolicy.every((policy) => policy === "none" || policy === "open" || policy === "allowlist");
|
|
74
|
+
}
|
|
75
|
+
function assertPositiveResource(value, label) {
|
|
76
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
77
|
+
throw new Error(`${label} must be a positive number.`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const DOCKER_SANDBOX_BACKEND = "docker";
|
|
2
|
+
export type WorkbenchSandboxBackendName = typeof DOCKER_SANDBOX_BACKEND;
|
|
3
|
+
export type WorkbenchSandboxProviderName = WorkbenchSandboxBackendName;
|
|
4
|
+
export declare function isWorkbenchSandboxProviderName(value: string): value is WorkbenchSandboxProviderName;
|
|
5
|
+
export declare function resolveWorkbenchSandboxProviderName(value: string | null | undefined): WorkbenchSandboxProviderName;
|
|
6
|
+
//# sourceMappingURL=names.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../src/sandbox-backends/names.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,WAAW,CAAC;AAE/C,MAAM,MAAM,2BAA2B,GAAG,OAAO,sBAAsB,CAAC;AAExE,MAAM,MAAM,4BAA4B,GAAG,2BAA2B,CAAC;AAEvE,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,4BAA4B,CAEnG;AAED,wBAAgB,mCAAmC,CACjD,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,4BAA4B,CAS9B"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const DOCKER_SANDBOX_BACKEND = "docker";
|
|
2
|
+
export function isWorkbenchSandboxProviderName(value) {
|
|
3
|
+
return value === DOCKER_SANDBOX_BACKEND;
|
|
4
|
+
}
|
|
5
|
+
export function resolveWorkbenchSandboxProviderName(value) {
|
|
6
|
+
const normalized = value?.trim();
|
|
7
|
+
if (!normalized) {
|
|
8
|
+
throw new Error("Sandbox provider is required.");
|
|
9
|
+
}
|
|
10
|
+
if (isWorkbenchSandboxProviderName(normalized)) {
|
|
11
|
+
return normalized;
|
|
12
|
+
}
|
|
13
|
+
throw new Error(`Unsupported local sandbox provider ${normalized}. Supported providers: docker.`);
|
|
14
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { WorkbenchExecutionSpec } from "@workbench-ai/workbench-contract";
|
|
2
|
+
import type { WorkbenchExecutionRuntimeInput } from "../execution-runtime-types.ts";
|
|
3
|
+
export declare function resolveSandboxTemplateImage(execution: WorkbenchExecutionSpec, args: WorkbenchExecutionRuntimeInput): string;
|
|
4
|
+
//# sourceMappingURL=template-images.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-images.d.ts","sourceRoot":"","sources":["../../src/sandbox-backends/template-images.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACvB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EACV,8BAA8B,EAC/B,MAAM,+BAA+B,CAAC;AAMvC,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,sBAAsB,EACjC,IAAI,EAAE,8BAA8B,GACnC,MAAM,CAiBR"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { normalizeRuntimeRegistry, resolveDockerRuntimeImageRef, } from "../runtime-utils.js";
|
|
2
|
+
export function resolveSandboxTemplateImage(execution, args) {
|
|
3
|
+
if (execution.sandbox.kind === "oci") {
|
|
4
|
+
return resolveDockerRuntimeImageRef(execution.sandbox.ref, {
|
|
5
|
+
runtimeRegistry: normalizeRuntimeRegistry(args.runtimeRegistry ?? process.env.WORKBENCH_RUNTIME_REGISTRY ?? ""),
|
|
6
|
+
label: `Execution ${execution.id} sandbox ref`,
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
const image = sandboxTemplateImageForRef(execution.sandbox.ref);
|
|
10
|
+
if (!image) {
|
|
11
|
+
throw new Error(`Execution ${execution.id} uses snapshot template ${execution.sandbox.ref}, but WORKBENCH_SANDBOX_TEMPLATE_IMAGES does not map that ref.`);
|
|
12
|
+
}
|
|
13
|
+
return image.startsWith("docker://")
|
|
14
|
+
? resolveDockerRuntimeImageRef(image, {
|
|
15
|
+
runtimeRegistry: normalizeRuntimeRegistry(args.runtimeRegistry ?? process.env.WORKBENCH_RUNTIME_REGISTRY ?? ""),
|
|
16
|
+
label: `WORKBENCH_SANDBOX_TEMPLATE_IMAGES[${execution.sandbox.ref}]`,
|
|
17
|
+
})
|
|
18
|
+
: image;
|
|
19
|
+
}
|
|
20
|
+
function sandboxTemplateImageForRef(templateRef) {
|
|
21
|
+
const raw = process.env.WORKBENCH_SANDBOX_TEMPLATE_IMAGES?.trim() ?? "";
|
|
22
|
+
if (!raw) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
if (raw.startsWith("{")) {
|
|
26
|
+
const parsed = JSON.parse(raw);
|
|
27
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
28
|
+
throw new Error("WORKBENCH_SANDBOX_TEMPLATE_IMAGES must be a JSON object or comma-separated ref=image list.");
|
|
29
|
+
}
|
|
30
|
+
const value = parsed[templateRef];
|
|
31
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
32
|
+
}
|
|
33
|
+
const entries = raw.split(",")
|
|
34
|
+
.map((entry) => entry.trim())
|
|
35
|
+
.filter(Boolean);
|
|
36
|
+
for (const entry of entries) {
|
|
37
|
+
const separator = entry.indexOf("=");
|
|
38
|
+
if (separator <= 0) {
|
|
39
|
+
throw new Error("WORKBENCH_SANDBOX_TEMPLATE_IMAGES entries must use ref=image.");
|
|
40
|
+
}
|
|
41
|
+
const ref = entry.slice(0, separator).trim();
|
|
42
|
+
const image = entry.slice(separator + 1).trim();
|
|
43
|
+
if (ref === templateRef) {
|
|
44
|
+
return image || null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { BlobObjectRef, HostedWorkbenchJob, Json, SurfaceSnapshotFile, WorkbenchExecutionCapability, WorkbenchExecutionResult, WorkbenchExecutionSpec, WorkbenchSandboxExecutionMetadata } from "@workbench-ai/workbench-contract";
|
|
2
|
+
import { type SandboxCreateRequest, type SandboxExecutionFileStore, type SandboxMaterializedInput } from "./sandbox-plane.ts";
|
|
3
|
+
import type { WorkbenchExecutionRuntimeInput } from "./execution-runtime-types.ts";
|
|
4
|
+
export declare function readWorkbenchExecutionSpec(job: HostedWorkbenchJob): WorkbenchExecutionSpec;
|
|
5
|
+
export declare function createWorkbenchSandboxFileStore(args: WorkbenchExecutionRuntimeInput): SandboxExecutionFileStore;
|
|
6
|
+
export declare function materializeWorkbenchSandboxInput(args: WorkbenchExecutionRuntimeInput, execution: WorkbenchExecutionSpec, input: WorkbenchExecutionSpec["inputs"][number]): SandboxMaterializedInput;
|
|
7
|
+
export declare function materializedFileInput(input: WorkbenchExecutionSpec["inputs"][number], files: readonly SurfaceSnapshotFile[]): SandboxMaterializedInput;
|
|
8
|
+
export declare function createSandboxAdapterRequest(args: WorkbenchExecutionRuntimeInput, request: SandboxCreateRequest, startedAt: string): Json;
|
|
9
|
+
export declare function sanitizeWorkbenchExecutionJobForSandbox(job: HostedWorkbenchJob, execution: WorkbenchExecutionSpec): HostedWorkbenchJob;
|
|
10
|
+
export declare function materializedInputForSandboxRequest(input: SandboxMaterializedInput): Record<string, Json>;
|
|
11
|
+
export declare function executionResultFromCompletedSandboxJob(args: {
|
|
12
|
+
completedJob: HostedWorkbenchJob;
|
|
13
|
+
execution: WorkbenchExecutionSpec;
|
|
14
|
+
startedAt: string;
|
|
15
|
+
backend: string;
|
|
16
|
+
allocation: WorkbenchSandboxExecutionMetadata["allocation"];
|
|
17
|
+
capability: WorkbenchSandboxExecutionMetadata["capability"];
|
|
18
|
+
handle: WorkbenchSandboxExecutionMetadata["handle"];
|
|
19
|
+
fileStore: SandboxExecutionFileStore;
|
|
20
|
+
}): Promise<WorkbenchExecutionResult>;
|
|
21
|
+
export declare function outputPayloadForContract(output: Record<string, unknown>, outputName: string): Json | undefined;
|
|
22
|
+
export declare function sandboxOutputRef(capability: WorkbenchExecutionCapability, outputName: string, body: string): Promise<BlobObjectRef>;
|
|
23
|
+
export declare function sha256Hex(body: string): Promise<string>;
|
|
24
|
+
export declare function withSandboxCompletionMetadata(job: HostedWorkbenchJob, metadata: WorkbenchSandboxExecutionMetadata): HostedWorkbenchJob;
|
|
25
|
+
export declare function attachSandboxMetadataToJob(job: HostedWorkbenchJob, metadata: unknown): HostedWorkbenchJob;
|
|
26
|
+
export declare function isSurfaceSnapshotFile(value: unknown): value is SurfaceSnapshotFile;
|
|
27
|
+
//# sourceMappingURL=sandbox-inputs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-inputs.d.ts","sourceRoot":"","sources":["../src/sandbox-inputs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EAClB,IAAI,EACJ,mBAAmB,EACnB,4BAA4B,EAC5B,wBAAwB,EACxB,sBAAsB,EACtB,iCAAiC,EAClC,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC9B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,8BAA8B,EAC/B,MAAM,8BAA8B,CAAC;AActC,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,kBAAkB,GAAG,sBAAsB,CAO1F;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,8BAA8B,GAAG,yBAAyB,CAoB/G;AAED,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,8BAA8B,EACpC,SAAS,EAAE,sBAAsB,EACjC,KAAK,EAAE,sBAAsB,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAC9C,wBAAwB,CAW1B;AAqBD,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,sBAAsB,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAC/C,KAAK,EAAE,SAAS,mBAAmB,EAAE,GACpC,wBAAwB,CAO1B;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,8BAA8B,EACpC,OAAO,EAAE,oBAAoB,EAC7B,SAAS,EAAE,MAAM,GAChB,IAAI,CAkBN;AAED,wBAAgB,uCAAuC,CACrD,GAAG,EAAE,kBAAkB,EACvB,SAAS,EAAE,sBAAsB,GAChC,kBAAkB,CAgBpB;AAED,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAgBxG;AAED,wBAAsB,sCAAsC,CAAC,IAAI,EAAE;IACjE,YAAY,EAAE,kBAAkB,CAAC;IACjC,SAAS,EAAE,sBAAsB,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,iCAAiC,CAAC,YAAY,CAAC,CAAC;IAC5D,UAAU,EAAE,iCAAiC,CAAC,YAAY,CAAC,CAAC;IAC5D,MAAM,EAAE,iCAAiC,CAAC,QAAQ,CAAC,CAAC;IACpD,SAAS,EAAE,yBAAyB,CAAC;CACtC,GAAG,OAAO,CAAC,wBAAwB,CAAC,CA6CpC;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAQ9G;AAED,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,4BAA4B,EACxC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,aAAa,CAAC,CAYxB;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG7D;AAED,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,kBAAkB,EACvB,QAAQ,EAAE,iCAAiC,GAC1C,kBAAkB,CAEpB;AAED,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,kBAAkB,EACvB,QAAQ,EAAE,OAAO,GAChB,kBAAkB,CAepB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAWlF"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { createWorkbenchSandboxExecutionMetadata, } from "./sandbox-plane.js";
|
|
2
|
+
import { asRuntimeRecord, importNodeModule, isJsonPayload, nodeBuiltin, } from "./runtime-utils.js";
|
|
3
|
+
import { engineCaseForCase, } from "./execution-jobs.js";
|
|
4
|
+
import { engineCaseFilesForRuntimeInput, } from "./generic-spec.js";
|
|
5
|
+
export function readWorkbenchExecutionSpec(job) {
|
|
6
|
+
const input = asRuntimeRecord(job.input);
|
|
7
|
+
const execution = input.execution;
|
|
8
|
+
if (!execution || typeof execution !== "object" || Array.isArray(execution)) {
|
|
9
|
+
throw new Error(`Execution job ${job.id} is missing input.execution.`);
|
|
10
|
+
}
|
|
11
|
+
return execution;
|
|
12
|
+
}
|
|
13
|
+
export function createWorkbenchSandboxFileStore(args) {
|
|
14
|
+
const outputPayloads = new Map();
|
|
15
|
+
return {
|
|
16
|
+
async materializeInputs(execution) {
|
|
17
|
+
return execution.inputs.map((input) => materializeWorkbenchSandboxInput(args, execution, input));
|
|
18
|
+
},
|
|
19
|
+
async publishJson(capability, outputName, payload) {
|
|
20
|
+
const body = JSON.stringify(payload);
|
|
21
|
+
const ref = await sandboxOutputRef(capability, outputName, body);
|
|
22
|
+
outputPayloads.set(ref.key, payload);
|
|
23
|
+
return ref;
|
|
24
|
+
},
|
|
25
|
+
async readJson(ref) {
|
|
26
|
+
const payload = outputPayloads.get(ref.key);
|
|
27
|
+
if (payload === undefined) {
|
|
28
|
+
throw new Error(`Sandbox output payload is missing: ${ref.key}.`);
|
|
29
|
+
}
|
|
30
|
+
return payload;
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export function materializeWorkbenchSandboxInput(args, execution, input) {
|
|
35
|
+
if (input.name === "subject") {
|
|
36
|
+
return materializedFileInput(input, args.baseFiles);
|
|
37
|
+
}
|
|
38
|
+
if (input.name === "case") {
|
|
39
|
+
return materializedFileInput(input, selectSandboxCaseFiles(args, execution));
|
|
40
|
+
}
|
|
41
|
+
if (input.name === "traces") {
|
|
42
|
+
return materializedFileInput(input, args.traceFiles ?? []);
|
|
43
|
+
}
|
|
44
|
+
throw new Error(`Execution ${readWorkbenchExecutionSpec(args.job).id} declares unsupported sandbox input: ${input.name}.`);
|
|
45
|
+
}
|
|
46
|
+
function selectSandboxCaseFiles(args, execution) {
|
|
47
|
+
if (execution.purpose !== "attempt") {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
const metadata = asRuntimeRecord(execution.metadata);
|
|
51
|
+
const jobInput = asRuntimeRecord(args.job.input);
|
|
52
|
+
const caseId = typeof metadata.caseId === "string"
|
|
53
|
+
? metadata.caseId
|
|
54
|
+
: typeof jobInput.caseId === "string"
|
|
55
|
+
? jobInput.caseId
|
|
56
|
+
: "current";
|
|
57
|
+
const engineCase = engineCaseForCase(args.engineCases, caseId);
|
|
58
|
+
return engineCaseFilesForRuntimeInput({ spec: args.spec, engineCase });
|
|
59
|
+
}
|
|
60
|
+
export function materializedFileInput(input, files) {
|
|
61
|
+
return {
|
|
62
|
+
input,
|
|
63
|
+
mountPath: input.mountPath,
|
|
64
|
+
kind: "files",
|
|
65
|
+
files: files.map((file) => ({ ...file })),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export function createSandboxAdapterRequest(args, request, startedAt) {
|
|
69
|
+
return {
|
|
70
|
+
jobInput: {
|
|
71
|
+
job: sanitizeWorkbenchExecutionJobForSandbox(args.job, request.execution),
|
|
72
|
+
spec: args.spec,
|
|
73
|
+
environmentVersion: (args.environmentVersion ?? null),
|
|
74
|
+
engineCases: args.engineCases,
|
|
75
|
+
...(args.adapterAuthProfiles ? { adapterAuthProfiles: args.adapterAuthProfiles } : {}),
|
|
76
|
+
...(args.adapterManifests ? { adapterManifests: args.adapterManifests } : {}),
|
|
77
|
+
...(args.progress ? { progress: args.progress } : {}),
|
|
78
|
+
},
|
|
79
|
+
execution: request.execution,
|
|
80
|
+
capability: request.capability,
|
|
81
|
+
inputBundle: {
|
|
82
|
+
inputs: request.inputs.map((input) => materializedInputForSandboxRequest(input)),
|
|
83
|
+
},
|
|
84
|
+
startedAt,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export function sanitizeWorkbenchExecutionJobForSandbox(job, execution) {
|
|
88
|
+
const input = asRuntimeRecord(job.input);
|
|
89
|
+
const sanitizedInput = {};
|
|
90
|
+
for (const [key, value] of Object.entries(input)) {
|
|
91
|
+
if (key === "baseFiles" || key === "traceFiles") {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (isJsonPayload(value)) {
|
|
95
|
+
sanitizedInput[key] = value;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
sanitizedInput.execution = execution;
|
|
99
|
+
return {
|
|
100
|
+
...job,
|
|
101
|
+
input: sanitizedInput,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
export function materializedInputForSandboxRequest(input) {
|
|
105
|
+
const base = {
|
|
106
|
+
input: input.input,
|
|
107
|
+
mountPath: input.mountPath,
|
|
108
|
+
kind: input.kind,
|
|
109
|
+
};
|
|
110
|
+
if (input.kind === "files") {
|
|
111
|
+
return {
|
|
112
|
+
...base,
|
|
113
|
+
files: (input.files ?? []).map((file) => ({ ...file })),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
...base,
|
|
118
|
+
json: (input.json ?? null),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
export async function executionResultFromCompletedSandboxJob(args) {
|
|
122
|
+
const completedJob = withSandboxCompletionMetadata(args.completedJob, {
|
|
123
|
+
backend: args.backend,
|
|
124
|
+
allocation: args.allocation,
|
|
125
|
+
capability: args.capability,
|
|
126
|
+
handle: args.handle,
|
|
127
|
+
});
|
|
128
|
+
if (completedJob.status !== "succeeded") {
|
|
129
|
+
return {
|
|
130
|
+
executionId: args.execution.id,
|
|
131
|
+
status: completedJob.status === "cancelled" ? "cancelled" : "failed",
|
|
132
|
+
startedAt: completedJob.startedAt ?? args.startedAt,
|
|
133
|
+
finishedAt: completedJob.finishedAt ?? new Date().toISOString(),
|
|
134
|
+
outputs: {},
|
|
135
|
+
...(completedJob.error ? { error: completedJob.error } : {}),
|
|
136
|
+
metadata: {
|
|
137
|
+
backend: args.backend,
|
|
138
|
+
allocation: args.allocation,
|
|
139
|
+
completedJob: completedJob,
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
const output = asRuntimeRecord(completedJob.output);
|
|
144
|
+
const outputs = {};
|
|
145
|
+
for (const contract of args.execution.outputs) {
|
|
146
|
+
const payload = outputPayloadForContract(output, contract.name);
|
|
147
|
+
if (payload === undefined) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
const ref = await args.fileStore.publishJson(args.capability, contract.name, payload);
|
|
151
|
+
outputs[contract.name] = ref;
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
executionId: args.execution.id,
|
|
155
|
+
status: "succeeded",
|
|
156
|
+
startedAt: completedJob.startedAt ?? args.startedAt,
|
|
157
|
+
finishedAt: completedJob.finishedAt ?? new Date().toISOString(),
|
|
158
|
+
outputs,
|
|
159
|
+
metadata: {
|
|
160
|
+
backend: args.backend,
|
|
161
|
+
allocation: args.allocation,
|
|
162
|
+
completedJob: completedJob,
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
export function outputPayloadForContract(output, outputName) {
|
|
167
|
+
if (outputName === "subject_patch") {
|
|
168
|
+
return isJsonPayload(output.subjectPatch) ? output.subjectPatch : undefined;
|
|
169
|
+
}
|
|
170
|
+
if (outputName === "result") {
|
|
171
|
+
return isJsonPayload(output.result) ? output.result : undefined;
|
|
172
|
+
}
|
|
173
|
+
return isJsonPayload(output[outputName]) ? output[outputName] : undefined;
|
|
174
|
+
}
|
|
175
|
+
export async function sandboxOutputRef(capability, outputName, body) {
|
|
176
|
+
const prefix = capability.outputPrefix.endsWith("/") ? capability.outputPrefix : `${capability.outputPrefix}/`;
|
|
177
|
+
const key = `${prefix}${outputName}.json`;
|
|
178
|
+
if (!key.startsWith(prefix)) {
|
|
179
|
+
throw new Error(`Sandbox output ${outputName} escaped capability output prefix.`);
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
bucket: "memory",
|
|
183
|
+
key,
|
|
184
|
+
byteLength: Buffer.byteLength(body, "utf8"),
|
|
185
|
+
sha256: await sha256Hex(body),
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
export async function sha256Hex(body) {
|
|
189
|
+
const crypto = await importNodeModule(nodeBuiltin("crypto"));
|
|
190
|
+
return crypto.createHash("sha256").update(body).digest("hex");
|
|
191
|
+
}
|
|
192
|
+
export function withSandboxCompletionMetadata(job, metadata) {
|
|
193
|
+
return attachSandboxMetadataToJob(job, createWorkbenchSandboxExecutionMetadata(metadata));
|
|
194
|
+
}
|
|
195
|
+
export function attachSandboxMetadataToJob(job, metadata) {
|
|
196
|
+
const output = asRuntimeRecord(job.output);
|
|
197
|
+
if (!job.output || Array.isArray(job.output) || typeof job.output !== "object") {
|
|
198
|
+
return job;
|
|
199
|
+
}
|
|
200
|
+
if (!metadata || typeof metadata !== "object" || Array.isArray(metadata)) {
|
|
201
|
+
return job;
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
...job,
|
|
205
|
+
output: {
|
|
206
|
+
...output,
|
|
207
|
+
sandbox: metadata,
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
export function isSurfaceSnapshotFile(value) {
|
|
212
|
+
return Boolean(value &&
|
|
213
|
+
typeof value === "object" &&
|
|
214
|
+
!Array.isArray(value) &&
|
|
215
|
+
typeof value.path === "string" &&
|
|
216
|
+
(value.kind === "text" || value.kind === "binary") &&
|
|
217
|
+
(value.encoding === "utf8" || value.encoding === "base64") &&
|
|
218
|
+
typeof value.content === "string" &&
|
|
219
|
+
typeof value.executable === "boolean");
|
|
220
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { BlobObjectRef, Json, SurfaceSnapshotFile, WorkbenchExecutionCapability, WorkbenchExecutionInputRef, WorkbenchExecutionNetworkPolicy, WorkbenchExecutionResult, WorkbenchExecutionSpec, WorkbenchSandboxAllocation, WorkbenchSandboxExecutionMetadata, WorkbenchSandboxHandle } from "@workbench-ai/workbench-contract";
|
|
2
|
+
import { type WorkbenchExecutionOutputPayloads } from "./execution-outputs.ts";
|
|
3
|
+
export interface SandboxMaterializedInput {
|
|
4
|
+
input: WorkbenchExecutionInputRef;
|
|
5
|
+
mountPath: string;
|
|
6
|
+
kind: "files" | "json";
|
|
7
|
+
files?: SurfaceSnapshotFile[];
|
|
8
|
+
json?: Json;
|
|
9
|
+
}
|
|
10
|
+
export interface SandboxExecutionFileStore {
|
|
11
|
+
materializeInputs(execution: WorkbenchExecutionSpec): Promise<SandboxMaterializedInput[]>;
|
|
12
|
+
publishJson(capability: WorkbenchExecutionCapability, outputName: string, payload: Json): Promise<BlobObjectRef>;
|
|
13
|
+
readJson(ref: BlobObjectRef): Promise<Json>;
|
|
14
|
+
}
|
|
15
|
+
export interface SandboxExecutionOptions {
|
|
16
|
+
fileStore: SandboxExecutionFileStore;
|
|
17
|
+
runnerId?: string;
|
|
18
|
+
now?: string;
|
|
19
|
+
signal?: AbortSignal;
|
|
20
|
+
}
|
|
21
|
+
export interface WorkbenchSandboxAllocationOptions {
|
|
22
|
+
backend: string;
|
|
23
|
+
runnerId?: string;
|
|
24
|
+
now?: string;
|
|
25
|
+
ttlMs?: number;
|
|
26
|
+
lifecycleId?: string;
|
|
27
|
+
sandboxId?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface SandboxBackendCapabilities {
|
|
30
|
+
snapshots: boolean;
|
|
31
|
+
interactiveExec: boolean;
|
|
32
|
+
filesystemDiff: boolean;
|
|
33
|
+
networkPolicy: readonly WorkbenchExecutionNetworkPolicy["egress"][];
|
|
34
|
+
fileCapabilities: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface SandboxEnvironmentImage {
|
|
37
|
+
backend: string;
|
|
38
|
+
kind: WorkbenchSandboxAllocation["template"]["kind"];
|
|
39
|
+
ref: string;
|
|
40
|
+
metadata?: Record<string, Json>;
|
|
41
|
+
}
|
|
42
|
+
export type SandboxHandle = WorkbenchSandboxHandle;
|
|
43
|
+
export interface SandboxBackendDescriptor {
|
|
44
|
+
name: string;
|
|
45
|
+
version?: string;
|
|
46
|
+
capabilities: SandboxBackendCapabilities;
|
|
47
|
+
}
|
|
48
|
+
export interface SandboxCreateRequest {
|
|
49
|
+
execution: WorkbenchExecutionSpec;
|
|
50
|
+
environment: SandboxEnvironmentImage;
|
|
51
|
+
allocation: WorkbenchSandboxAllocation;
|
|
52
|
+
capability: WorkbenchExecutionCapability;
|
|
53
|
+
inputs: SandboxMaterializedInput[];
|
|
54
|
+
}
|
|
55
|
+
export interface SandboxExecRequest {
|
|
56
|
+
execution: WorkbenchExecutionSpec;
|
|
57
|
+
environment: SandboxEnvironmentImage;
|
|
58
|
+
sandbox: SandboxHandle;
|
|
59
|
+
allocation: WorkbenchSandboxAllocation;
|
|
60
|
+
capability: WorkbenchExecutionCapability;
|
|
61
|
+
inputs: SandboxMaterializedInput[];
|
|
62
|
+
}
|
|
63
|
+
export interface SandboxPlane {
|
|
64
|
+
backend: SandboxBackendDescriptor;
|
|
65
|
+
prepareEnvironment?(execution: WorkbenchExecutionSpec, options: SandboxExecutionOptions): Promise<SandboxEnvironmentImage>;
|
|
66
|
+
createSandbox(request: SandboxCreateRequest, options: SandboxExecutionOptions): Promise<SandboxHandle>;
|
|
67
|
+
exec(request: SandboxExecRequest, options: SandboxExecutionOptions): Promise<WorkbenchExecutionResult>;
|
|
68
|
+
destroySandbox(sandbox: SandboxHandle, options: SandboxExecutionOptions): Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
export interface ValidatedSandboxExecutionResult {
|
|
71
|
+
result: WorkbenchExecutionResult;
|
|
72
|
+
payloads: WorkbenchExecutionOutputPayloads;
|
|
73
|
+
}
|
|
74
|
+
export declare function executeValidatedSandboxExecution(plane: SandboxPlane, execution: WorkbenchExecutionSpec, options: SandboxExecutionOptions): Promise<ValidatedSandboxExecutionResult>;
|
|
75
|
+
export declare function createWorkbenchSandboxExecutionMetadata(args: WorkbenchSandboxExecutionMetadata): WorkbenchSandboxExecutionMetadata;
|
|
76
|
+
export declare function collectSandboxHandleScopeIssues(sandbox: SandboxHandle, allocation: WorkbenchSandboxAllocation, execution: WorkbenchExecutionSpec): string[];
|
|
77
|
+
export declare function createWorkbenchSandboxAllocation(execution: WorkbenchExecutionSpec, options: WorkbenchSandboxAllocationOptions): WorkbenchSandboxAllocation;
|
|
78
|
+
export declare function createWorkbenchExecutionCapability(execution: WorkbenchExecutionSpec, options?: {
|
|
79
|
+
now?: string;
|
|
80
|
+
ttlMs?: number;
|
|
81
|
+
outputPrefix?: string;
|
|
82
|
+
}): WorkbenchExecutionCapability;
|
|
83
|
+
export declare function collectExecutionCapabilityScopeIssues(capability: WorkbenchExecutionCapability, execution: WorkbenchExecutionSpec, options?: {
|
|
84
|
+
now?: string;
|
|
85
|
+
}): string[];
|
|
86
|
+
export declare function collectSandboxAllocationScopeIssues(allocation: WorkbenchSandboxAllocation, execution: WorkbenchExecutionSpec, options?: {
|
|
87
|
+
now?: string;
|
|
88
|
+
}): string[];
|
|
89
|
+
//# sourceMappingURL=sandbox-plane.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-plane.d.ts","sourceRoot":"","sources":["../src/sandbox-plane.ts"],"names":[],"mappings":"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"}
|